ReactOS 0.4.16-dev-963-g182f353
inetfolder.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS ieframe
3 * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4 * PURPOSE: Internet IShellFolder implementation
5 * COPYRIGHT: Copyright 2025 Whindmar Saksit <whindsaks@proton.me>
6 */
7
8#define NONAMELESSUNION
9
10#include "ieframe.h"
11
12#include "shlobj.h"
13#include "shobjidl.h"
14#include "shellapi.h"
15#include "shlwapi.h"
16#include "shlguid.h"
17#include "intshcut.h"
18
19#include "wine/debug.h"
20
22
23extern int WINAPI SHAnsiToUnicodeCP(UINT CodePage, LPCSTR pszSrc, LPWSTR pwszDst, int cwchBuf);
24
25#define MAX_URL_LENGTH 1024
26
27#define PT_INTERNET_URL 0x61
28#define IFUIF_UNICODE 0x80
29typedef struct _IFURLITEM
30{
32 BYTE Type; // PT_INTERNET_URL
33 BYTE Flags; // IFUIF_*
37
39{
40 if (('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z'))
41 return 0;
42 return c == '+' || c == '-' || c == '.' ? 1 : -1;
43}
44
45static unsigned int GetSchemeLength(PCWSTR s)
46{
47 if (GetSchemeCharType(s[0]) != 0) // The first character MUST be A-Z, a-z.
48 return 0;
49 for (unsigned int i = 0;;)
50 {
51 if (s[++i] == ':')
52 return ++i;
53 if (GetSchemeCharType(s[i]) < 0)
54 return 0;
55 }
56}
57
59{
60 UINT cch = lstrlenW(pszUrl) + 1;
62 IFURLITEM *pidl = SHAlloc(cb + sizeof(WORD));
63 if (!pidl)
64 return (LPITEMIDLIST)pidl;
65 pidl->cb = cb;
66 pidl->Type = PT_INTERNET_URL;
67 pidl->Flags = IFUIF_UNICODE;
68 pidl->Unknown = 0;
69 CopyMemory(pidl->Url, pszUrl, cch * sizeof(*pszUrl));
70 ILGetNext((LPITEMIDLIST)pidl)->mkid.cb = 0;
71 return (LPITEMIDLIST)pidl;
72}
73
75{
76 IFURLITEM *p = (IFURLITEM*)pidl;
77 if (p && p->cb > FIELD_OFFSET(IFURLITEM, Url) && p->Type == PT_INTERNET_URL)
78 return p;
79 return NULL;
80}
81
83{
84 if (pUrl->Flags & IFUIF_UNICODE)
85 return pUrl->Url;
87 return Buffer;
88}
89
90static HRESULT CreateUrlShortcut(PCWSTR Url, IUniformResourceLocatorW **ppv)
91{
92 HRESULT hr = CoCreateInstance(&CLSID_InternetShortcut, NULL, CLSCTX_INPROC_SERVER,
93 &IID_IUniformResourceLocatorW, (void**)ppv);
94 if (SUCCEEDED(hr))
95 hr = (*ppv)->lpVtbl->SetURL(*ppv, Url, 0);
96 return hr;
97}
98
99typedef struct _CInternetFolder
100{
105
107{
108 TRACE("(%p, %s, %p)\n", This, debugstr_guid(riid), ppvObject);
109 *ppvObject = NULL;
111 *ppvObject = &This->IShellFolder_iface;
112 else if (IsEqualGUID(&IID_IShellFolder, riid))
113 *ppvObject = &This->IShellFolder_iface;
114 else if (IsEqualGUID(&IID_IPersist, riid) || IsEqualGUID(&IID_IPersistFolder, riid))
115 *ppvObject = &This->IPersistFolder_iface;
116 else
117 return E_NOINTERFACE;
118 IUnknown_AddRef((IUnknown*)*ppvObject);
119 return S_OK;
120}
121
123{
124 return InterlockedIncrement(&This->refCount);
125}
126
128{
129 const ULONG count = InterlockedDecrement(&This->refCount);
130 if (count == 0)
131 {
132 SHFree(This);
134 }
135 return count;
136}
137
139{
141}
142
144{
145 return Unknown_AddRef(CONTAINING_RECORD(This, CInternetFolder, IShellFolder_iface));
146}
147
149{
150 return Unknown_Release(CONTAINING_RECORD(This, CInternetFolder, IShellFolder_iface));
151}
152
153static HRESULT WINAPI ParseDisplayName(IShellFolder *This, HWND hwnd, IBindCtx *pbc, LPWSTR pszDisplayName, ULONG *pchEaten, PIDLIST_RELATIVE *ppidl, ULONG *pdwAttributes)
154{
155 UINT len;
156
157 *ppidl = NULL;
158 len = GetSchemeLength(pszDisplayName);
159 if (len)
160 {
161 if (len + 1 == sizeof("shell:"))
162 {
163 WCHAR szBuf[100];
164 lstrcpynW(szBuf, pszDisplayName, sizeof("shell:"));
165 if (!lstrcmpiW(szBuf, L"shell:"))
166 return E_FAIL;
167 }
168
169 if ((*ppidl = CreateUrlItem(pszDisplayName)) == NULL)
170 return E_OUTOFMEMORY;
171 if (pchEaten)
172 *pchEaten = lstrlenW(pszDisplayName);
173 if (pdwAttributes)
174 IShellFolder_GetAttributesOf(This, 1, (PCUITEMID_CHILD_ARRAY)ppidl, pdwAttributes);
175 return S_OK;
176 }
177 return E_FAIL;
178}
179
180static HRESULT WINAPI ShellFolder_EnumObjects(IShellFolder *This, HWND hwndOwner, SHCONTF grfFlags, IEnumIDList **ppenumIDList)
181{
182 *ppenumIDList = NULL;
183 return E_NOTIMPL;
184}
185
187{
188 *ppvOut = NULL;
189 return E_NOTIMPL;
190}
191
193{
194 *ppvOut = NULL;
195 return E_NOTIMPL;
196}
197
199{
200 IFURLITEM *pUrl1 = IsUrlItem(pidl1), *pUrl2 = IsUrlItem(pidl2);
201 if (pUrl1 && pUrl2)
202 {
203 WCHAR szUrl1[MAX_URL_LENGTH], *pszUrl1 = GetUrl(pUrl1, szUrl1);
204 WCHAR szUrl2[MAX_URL_LENGTH], *pszUrl2 = GetUrl(pUrl2, szUrl2);
205 int cmp = lstrcmpiW(pszUrl1, pszUrl2);
206 return cmp < 0 ? 0xffff : cmp != 0;
207 }
208 return E_FAIL;
209}
210
212{
213 *ppv = NULL;
214 return E_NOTIMPL;
215}
216
218{
219 UINT i;
220
221 if (cidl == 0)
222 {
223 *rgfInOut &= SFGAO_FOLDER | SFGAO_CANLINK | SFGAO_STREAM; // Folder attributes
224 return S_OK;
225 }
226
227 for (i = 0; i < cidl; ++i)
228 {
229 IFURLITEM *pUrl = IsUrlItem(apidl[i]);
230 if (!pUrl)
231 return E_FAIL;
232 *rgfInOut &= SFGAO_CANLINK | SFGAO_BROWSABLE | SFGAO_STREAM;
233 }
234 return S_OK;
235}
236
237static HRESULT WINAPI GetUIObjectOf(IShellFolder *This, HWND hwndOwner, UINT cidl, PCUITEMID_CHILD_ARRAY apidl, REFIID riid, UINT *rgfReserved, void **ppv)
238{
239 IFURLITEM *pUrl;
240 if (cidl == 1 && (pUrl = IsUrlItem(apidl[0])) != NULL)
241 {
242 if (IsEqualIID(riid, &IID_IExtractIconW) || IsEqualIID(riid, &IID_IExtractIconA) ||
243 IsEqualIID(riid, &IID_IContextMenu) ||
245 IsEqualIID(riid, &IID_IQueryInfo))
246 {
247 IUniformResourceLocatorW *pUrlLnk;
248 WCHAR szUrl[MAX_URL_LENGTH], *pszUrl = GetUrl(pUrl, szUrl);
249 HRESULT hr = CreateUrlShortcut(pszUrl, &pUrlLnk);
250 if (SUCCEEDED(hr))
251 {
252 hr = IUnknown_QueryInterface(pUrlLnk, riid, ppv);
253 IUnknown_Release(pUrlLnk);
254 }
255 return hr;
256 }
257 }
258 return E_NOINTERFACE;
259}
260
262{
263 IFURLITEM *pUrl = IsUrlItem(pidl);
264 if (pUrl)
265 {
266 WCHAR szUrl[MAX_URL_LENGTH], *pszUrl = GetUrl(pUrl, szUrl);
267 pSR->uType = STRRET_WSTR;
268 return SHStrDupW(pszUrl, &pSR->u.pOleStr);
269 }
270 return E_FAIL;
271}
272
273static HRESULT WINAPI SetNameOf(IShellFolder *This, HWND hwndOwner, PCUITEMID_CHILD pidl, LPCWSTR pszName, SHGDNF uFlags, PITEMID_CHILD*ppidlOut)
274{
275 if (ppidlOut)
276 *ppidlOut = NULL;
277 return E_NOTIMPL;
278}
279
281{
283}
284
286{
287 return Unknown_AddRef(CONTAINING_RECORD(This, CInternetFolder, IPersistFolder_iface));
288}
289
291{
292 return Unknown_Release(CONTAINING_RECORD(This, CInternetFolder, IPersistFolder_iface));
293}
294
296{
297 *pClassID = CLSID_Internet;
298 return S_OK;
299}
300
302{
303 return S_OK;
304}
305
306static const IShellFolderVtbl ShellFolderVtbl = {
320};
321
322static const IPersistFolderVtbl PersistFolderVtbl = {
328};
329
331{
333 if (obj)
334 {
335 obj->IShellFolder_iface.lpVtbl = &ShellFolderVtbl;
336 obj->IPersistFolder_iface.lpVtbl = &PersistFolderVtbl;
337 obj->refCount = 1;
338 lock_module();
339 }
340 return obj;
341}
342
344{
345 CInternetFolder *pThis;
346
347 *ppv = NULL;
348 if (outer)
350
351 if ((pThis = CreateInstance()) != NULL)
352 {
354 Unknown_Release(pThis);
355 return hr;
356 }
357 return E_OUTOFMEMORY;
358}
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
const GUID IID_IUnknown
Definition: bufpool.h:45
LPARAM lParam
Definition: combotst.c:139
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_NOTIMPL
Definition: ddrawi.h:99
#define E_FAIL
Definition: ddrawi.h:102
#define NULL
Definition: types.h:112
UINT uFlags
Definition: api.c:59
#define CP_ACP
Definition: compat.h:109
#define lstrcpynW
Definition: compat.h:738
#define lstrlenW
Definition: compat.h:750
int WINAPI lstrcmpiW(LPCWSTR str1, LPCWSTR str2)
Definition: locale.c:4262
HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID iid, LPVOID *ppv)
Definition: compobj.c:3325
void WINAPI SHFree(LPVOID pv)
Definition: shellole.c:326
LPVOID WINAPI SHAlloc(SIZE_T len)
Definition: shellole.c:304
HRESULT WINAPI SHStrDupW(LPCWSTR src, LPWSTR *dest)
Definition: string.c:2018
static IShellFolder IShellItem **static IBindCtx LPITEMIDLIST SFGAOF
Definition: ebrowser.c:83
unsigned short WORD
Definition: ntddk_ex.h:93
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLdouble s
Definition: gl.h:2039
const GLubyte * c
Definition: glext.h:8905
GLfloat GLfloat p
Definition: glext.h:8902
GLenum GLsizei len
Definition: glext.h:6722
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
static void lock_module(void)
Definition: ieframe.h:335
static void unlock_module(void)
Definition: ieframe.h:339
REFIID riid
Definition: atlbase.h:39
REFIID LPVOID * ppv
Definition: atlbase.h:39
static ULONG Unknown_AddRef(CInternetFolder *This)
Definition: inetfolder.c:122
static PWSTR GetUrl(IFURLITEM *pUrl, PWSTR Buffer)
Definition: inetfolder.c:82
static HRESULT WINAPI BindToStorage(IShellFolder *This, PCUIDLIST_RELATIVE pidl, IBindCtx *pbc, REFIID riid, void **ppvOut)
Definition: inetfolder.c:192
static int GetSchemeCharType(WCHAR c)
Definition: inetfolder.c:38
static CInternetFolder * CreateInstance(void)
Definition: inetfolder.c:330
static HRESULT WINAPI CompareIDs(IShellFolder *This, LPARAM lParam, PCUIDLIST_RELATIVE pidl1, PCUIDLIST_RELATIVE pidl2)
Definition: inetfolder.c:198
struct _IFURLITEM IFURLITEM
static HRESULT WINAPI BindToObject(IShellFolder *This, PCUIDLIST_RELATIVE pidl, IBindCtx *pbc, REFIID riid, void **ppvOut)
Definition: inetfolder.c:186
static HRESULT WINAPI SetNameOf(IShellFolder *This, HWND hwndOwner, PCUITEMID_CHILD pidl, LPCWSTR pszName, SHGDNF uFlags, PITEMID_CHILD *ppidlOut)
Definition: inetfolder.c:273
static ULONG WINAPI ShellFolder_AddRef(IShellFolder *This)
Definition: inetfolder.c:143
#define MAX_URL_LENGTH
Definition: inetfolder.c:25
static ULONG WINAPI PersistFolder_AddRef(IPersistFolder *This)
Definition: inetfolder.c:285
static ULONG WINAPI ShellFolder_Release(IShellFolder *This)
Definition: inetfolder.c:148
static HRESULT WINAPI ShellFolder_QueryInterface(IShellFolder *This, REFIID riid, PVOID *ppvObject)
Definition: inetfolder.c:138
static HRESULT CreateUrlShortcut(PCWSTR Url, IUniformResourceLocatorW **ppv)
Definition: inetfolder.c:90
struct _CInternetFolder CInternetFolder
int WINAPI SHAnsiToUnicodeCP(UINT CodePage, LPCSTR pszSrc, LPWSTR pwszDst, int cwchBuf)
static HRESULT Unknown_QueryInterface(CInternetFolder *This, REFIID riid, PVOID *ppvObject)
Definition: inetfolder.c:106
static HRESULT WINAPI PersistFolder_QueryInterface(IPersistFolder *This, REFIID riid, PVOID *ppvObject)
Definition: inetfolder.c:280
static const IShellFolderVtbl ShellFolderVtbl
Definition: inetfolder.c:306
static unsigned int GetSchemeLength(PCWSTR s)
Definition: inetfolder.c:45
static HRESULT WINAPI PersistFolder_Initialize(IPersistFolder *This, PCIDLIST_ABSOLUTE pidl)
Definition: inetfolder.c:301
static ULONG WINAPI PersistFolder_Release(IPersistFolder *This)
Definition: inetfolder.c:290
static IFURLITEM * IsUrlItem(LPCITEMIDLIST pidl)
Definition: inetfolder.c:74
static HRESULT WINAPI CreateViewObject(IShellFolder *This, HWND hwndOwner, REFIID riid, void **ppv)
Definition: inetfolder.c:211
static HRESULT WINAPI GetAttributesOf(IShellFolder *This, UINT cidl, PCUITEMID_CHILD_ARRAY apidl, SFGAOF *rgfInOut)
Definition: inetfolder.c:217
#define PT_INTERNET_URL
Definition: inetfolder.c:27
#define IFUIF_UNICODE
Definition: inetfolder.c:28
static LPITEMIDLIST CreateUrlItem(PCWSTR pszUrl)
Definition: inetfolder.c:58
static HRESULT WINAPI PersistFolder_GetClassID(IPersistFolder *This, CLSID *pClassID)
Definition: inetfolder.c:295
HRESULT WINAPI CInternetFolder_CreateInstance(IClassFactory *iface, IUnknown *outer, REFIID riid, void **ppv)
Definition: inetfolder.c:343
static const IPersistFolderVtbl PersistFolderVtbl
Definition: inetfolder.c:322
static HRESULT WINAPI GetDisplayNameOf(IShellFolder *This, PCUITEMID_CHILD pidl, SHGDNF uFlags, STRRET *pSR)
Definition: inetfolder.c:261
static ULONG Unknown_Release(CInternetFolder *This)
Definition: inetfolder.c:127
static HRESULT WINAPI GetUIObjectOf(IShellFolder *This, HWND hwndOwner, UINT cidl, PCUITEMID_CHILD_ARRAY apidl, REFIID riid, UINT *rgfReserved, void **ppv)
Definition: inetfolder.c:237
static HRESULT WINAPI ShellFolder_EnumObjects(IShellFolder *This, HWND hwndOwner, SHCONTF grfFlags, IEnumIDList **ppenumIDList)
Definition: inetfolder.c:180
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define debugstr_guid
Definition: kernel32.h:35
static DWORD DWORD void LPSTR DWORD cch
Definition: str.c:202
static HMODULE MODULEINFO DWORD cb
Definition: module.c:33
#define cmp(status, error)
Definition: error.c:114
static IParseDisplayName ParseDisplayName
Definition: moniker.c:816
static SHCONTF
Definition: ordinal.c:64
unsigned int UINT
Definition: ndis.h:50
#define L(x)
Definition: ntvdm.h:50
const GUID IID_IDataObject
long LONG
Definition: pedump.c:60
LPITEMIDLIST WINAPI ILGetNext(LPCITEMIDLIST pidl)
Definition: pidl.c:970
const GUID IID_IPersist
Definition: proxy.cpp:14
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
#define IsEqualIID(riid1, riid2)
Definition: guiddef.h:95
#define REFIID
Definition: guiddef.h:118
HRESULT hr
Definition: shlfolder.c:183
ITEMIDLIST UNALIGNED * LPITEMIDLIST
Definition: shtypes.idl:41
@ STRRET_WSTR
Definition: shtypes.idl:85
const PCUITEMID_CHILD * PCUITEMID_CHILD_ARRAY
Definition: shtypes.idl:71
const ITEMID_CHILD UNALIGNED * PCUITEMID_CHILD
Definition: shtypes.idl:70
const ITEMIDLIST_RELATIVE UNALIGNED * PCUIDLIST_RELATIVE
Definition: shtypes.idl:57
const ITEMIDLIST UNALIGNED * LPCITEMIDLIST
Definition: shtypes.idl:42
#define TRACE(s)
Definition: solgame.cpp:4
IShellFolder IShellFolder_iface
Definition: inetfolder.c:101
IPersistFolder IPersistFolder_iface
Definition: inetfolder.c:102
BYTE Type
Definition: inetfolder.c:32
UINT Unknown
Definition: inetfolder.c:34
WCHAR Url[ANYSIZE_ARRAY]
Definition: inetfolder.c:35
BYTE Flags
Definition: inetfolder.c:33
UINT uType
Definition: shtypes.idl:93
LPWSTR pOleStr
Definition: shtypes.idl:96
uint16_t * PWSTR
Definition: typedefs.h:56
const uint16_t * PCWSTR
Definition: typedefs.h:57
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#define ANYSIZE_ARRAY
Definition: typedefs.h:46
const char * PCSTR
Definition: typedefs.h:52
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
#define CopyMemory
Definition: winbase.h:1741
_In_ void _In_ PCCERT_CONTEXT _In_opt_ LPFILETIME _In_ DWORD _In_ DWORD _Outptr_opt_ void ** ppvObject
Definition: wincrypt.h:6082
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4023
LONG_PTR LPARAM
Definition: windef.h:208
#define WINAPI
Definition: msvc.h:6
#define E_NOINTERFACE
Definition: winerror.h:2364
#define CLASS_E_NOAGGREGATION
Definition: winerror.h:2662
const char * LPCSTR
Definition: xmlstorage.h:183
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
unsigned char BYTE
Definition: xxhash.c:193