ReactOS 0.4.17-dev-1190-g4c812f4
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#include "ieframe.h"
9
10#include "shlobj.h"
11#include "shobjidl.h"
12#include "shellapi.h"
13#include "shlwapi.h"
14#include "shlguid.h"
15#include "intshcut.h"
16
17#include "wine/debug.h"
18
20
21extern int WINAPI SHAnsiToUnicodeCP(UINT CodePage, LPCSTR pszSrc, LPWSTR pwszDst, int cwchBuf);
22
23#define MAX_URL_LENGTH 1024
24
25#define PT_INTERNET_URL 0x61
26#define IFUIF_UNICODE 0x80
27typedef struct _IFURLITEM
28{
30 BYTE Type; // PT_INTERNET_URL
31 BYTE Flags; // IFUIF_*
35
37{
38 if (('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z'))
39 return 0;
40 return c == '+' || c == '-' || c == '.' ? 1 : -1;
41}
42
43static unsigned int GetSchemeLength(PCWSTR s)
44{
45 if (GetSchemeCharType(s[0]) != 0) // The first character MUST be A-Z, a-z.
46 return 0;
47 for (unsigned int i = 0;;)
48 {
49 if (s[++i] == ':')
50 return ++i;
51 if (GetSchemeCharType(s[i]) < 0)
52 return 0;
53 }
54}
55
57{
58 UINT cch = lstrlenW(pszUrl) + 1;
60 IFURLITEM *pidl = SHAlloc(cb + sizeof(WORD));
61 if (!pidl)
62 return (LPITEMIDLIST)pidl;
63 pidl->cb = cb;
64 pidl->Type = PT_INTERNET_URL;
65 pidl->Flags = IFUIF_UNICODE;
66 pidl->Unknown = 0;
67 CopyMemory(pidl->Url, pszUrl, cch * sizeof(*pszUrl));
68 ILGetNext((LPITEMIDLIST)pidl)->mkid.cb = 0;
69 return (LPITEMIDLIST)pidl;
70}
71
73{
74 IFURLITEM *p = (IFURLITEM*)pidl;
75 if (p && p->cb > FIELD_OFFSET(IFURLITEM, Url) && p->Type == PT_INTERNET_URL)
76 return p;
77 return NULL;
78}
79
81{
82 if (pUrl->Flags & IFUIF_UNICODE)
83 return pUrl->Url;
85 return Buffer;
86}
87
88static HRESULT CreateUrlShortcut(PCWSTR Url, IUniformResourceLocatorW **ppv)
89{
90 HRESULT hr = CoCreateInstance(&CLSID_InternetShortcut, NULL, CLSCTX_INPROC_SERVER,
91 &IID_IUniformResourceLocatorW, (void**)ppv);
92 if (SUCCEEDED(hr))
93 hr = (*ppv)->lpVtbl->SetURL(*ppv, Url, 0);
94 return hr;
95}
96
97typedef struct _CInternetFolder
98{
103
105{
106 TRACE("(%p, %s, %p)\n", This, debugstr_guid(riid), ppvObject);
107 *ppvObject = NULL;
109 *ppvObject = &This->IShellFolder_iface;
110 else if (IsEqualGUID(&IID_IShellFolder, riid))
111 *ppvObject = &This->IShellFolder_iface;
112 else if (IsEqualGUID(&IID_IPersist, riid) || IsEqualGUID(&IID_IPersistFolder, riid))
113 *ppvObject = &This->IPersistFolder_iface;
114 else
115 return E_NOINTERFACE;
116 IUnknown_AddRef((IUnknown*)*ppvObject);
117 return S_OK;
118}
119
121{
122 return InterlockedIncrement(&This->refCount);
123}
124
126{
127 const ULONG count = InterlockedDecrement(&This->refCount);
128 if (count == 0)
129 {
130 SHFree(This);
132 }
133 return count;
134}
135
137{
138 return Unknown_QueryInterface(CONTAINING_RECORD(This, CInternetFolder, IShellFolder_iface), riid, ppvObject);
139}
140
142{
143 return Unknown_AddRef(CONTAINING_RECORD(This, CInternetFolder, IShellFolder_iface));
144}
145
147{
148 return Unknown_Release(CONTAINING_RECORD(This, CInternetFolder, IShellFolder_iface));
149}
150
151static HRESULT WINAPI ParseDisplayName(IShellFolder *This, HWND hwnd, IBindCtx *pbc, LPWSTR pszDisplayName, ULONG *pchEaten, PIDLIST_RELATIVE *ppidl, ULONG *pdwAttributes)
152{
153 UINT len;
154
155 *ppidl = NULL;
156 len = GetSchemeLength(pszDisplayName);
157 if (len)
158 {
159 if (len + 1 == sizeof("shell:"))
160 {
161 WCHAR szBuf[100];
162 lstrcpynW(szBuf, pszDisplayName, sizeof("shell:"));
163 if (!lstrcmpiW(szBuf, L"shell:"))
164 return E_FAIL;
165 }
166
167 if ((*ppidl = CreateUrlItem(pszDisplayName)) == NULL)
168 return E_OUTOFMEMORY;
169 if (pchEaten)
170 *pchEaten = lstrlenW(pszDisplayName);
171 if (pdwAttributes)
172 IShellFolder_GetAttributesOf(This, 1, (PCUITEMID_CHILD_ARRAY)ppidl, pdwAttributes);
173 return S_OK;
174 }
175 return E_FAIL;
176}
177
178static HRESULT WINAPI ShellFolder_EnumObjects(IShellFolder *This, HWND hwndOwner, SHCONTF grfFlags, IEnumIDList **ppenumIDList)
179{
180 *ppenumIDList = NULL;
181 return E_NOTIMPL;
182}
183
185{
186 *ppvOut = NULL;
187 return E_NOTIMPL;
188}
189
191{
192 *ppvOut = NULL;
193 return E_NOTIMPL;
194}
195
197{
198 IFURLITEM *pUrl1 = IsUrlItem(pidl1), *pUrl2 = IsUrlItem(pidl2);
199 if (pUrl1 && pUrl2)
200 {
201 WCHAR szUrl1[MAX_URL_LENGTH], *pszUrl1 = GetUrl(pUrl1, szUrl1);
202 WCHAR szUrl2[MAX_URL_LENGTH], *pszUrl2 = GetUrl(pUrl2, szUrl2);
203 int cmp = lstrcmpiW(pszUrl1, pszUrl2);
204 return cmp < 0 ? 0xffff : cmp != 0;
205 }
206 return E_FAIL;
207}
208
210{
211 *ppv = NULL;
212 return E_NOTIMPL;
213}
214
216{
217 UINT i;
218
219 if (cidl == 0)
220 {
221 *rgfInOut &= SFGAO_FOLDER | SFGAO_CANLINK | SFGAO_STREAM; // Folder attributes
222 return S_OK;
223 }
224
225 for (i = 0; i < cidl; ++i)
226 {
227 IFURLITEM *pUrl = IsUrlItem(apidl[i]);
228 if (!pUrl)
229 return E_FAIL;
230 *rgfInOut &= SFGAO_CANLINK | SFGAO_BROWSABLE | SFGAO_STREAM;
231 }
232 return S_OK;
233}
234
235static HRESULT WINAPI GetUIObjectOf(IShellFolder *This, HWND hwndOwner, UINT cidl, PCUITEMID_CHILD_ARRAY apidl, REFIID riid, UINT *rgfReserved, void **ppv)
236{
237 IFURLITEM *pUrl;
238 if (cidl == 1 && (pUrl = IsUrlItem(apidl[0])) != NULL)
239 {
240 if (IsEqualIID(riid, &IID_IExtractIconW) || IsEqualIID(riid, &IID_IExtractIconA) ||
241 IsEqualIID(riid, &IID_IContextMenu) ||
243 IsEqualIID(riid, &IID_IQueryInfo))
244 {
245 IUniformResourceLocatorW *pUrlLnk;
246 WCHAR szUrl[MAX_URL_LENGTH], *pszUrl = GetUrl(pUrl, szUrl);
247 HRESULT hr = CreateUrlShortcut(pszUrl, &pUrlLnk);
248 if (SUCCEEDED(hr))
249 {
250 hr = IUnknown_QueryInterface(pUrlLnk, riid, ppv);
251 IUnknown_Release(pUrlLnk);
252 }
253 return hr;
254 }
255 }
256 return E_NOINTERFACE;
257}
258
260{
261 IFURLITEM *pUrl = IsUrlItem(pidl);
262 if (pUrl)
263 {
264 WCHAR szUrl[MAX_URL_LENGTH], *pszUrl = GetUrl(pUrl, szUrl);
265 pSR->uType = STRRET_WSTR;
266 return SHStrDupW(pszUrl, &pSR->pOleStr);
267 }
268 return E_FAIL;
269}
270
271static HRESULT WINAPI SetNameOf(IShellFolder *This, HWND hwndOwner, PCUITEMID_CHILD pidl, LPCWSTR pszName, SHGDNF uFlags, PITEMID_CHILD*ppidlOut)
272{
273 if (ppidlOut)
274 *ppidlOut = NULL;
275 return E_NOTIMPL;
276}
277
279{
280 return Unknown_QueryInterface(CONTAINING_RECORD(This, CInternetFolder, IPersistFolder_iface), riid, ppvObject);
281}
282
284{
285 return Unknown_AddRef(CONTAINING_RECORD(This, CInternetFolder, IPersistFolder_iface));
286}
287
289{
290 return Unknown_Release(CONTAINING_RECORD(This, CInternetFolder, IPersistFolder_iface));
291}
292
294{
295 *pClassID = CLSID_Internet;
296 return S_OK;
297}
298
300{
301 return S_OK;
302}
303
304static const IShellFolderVtbl ShellFolderVtbl = {
318};
319
320static const IPersistFolderVtbl PersistFolderVtbl = {
326};
327
329{
331 if (obj)
332 {
333 obj->IShellFolder_iface.lpVtbl = &ShellFolderVtbl;
334 obj->IPersistFolder_iface.lpVtbl = &PersistFolderVtbl;
335 obj->refCount = 1;
336 lock_module();
337 }
338 return obj;
339}
340
342{
343 CInternetFolder *pThis;
344
345 *ppv = NULL;
346 if (outer)
348
349 if ((pThis = CreateInstance()) != NULL)
350 {
352 Unknown_Release(pThis);
353 return hr;
354 }
355 return E_OUTOFMEMORY;
356}
#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
HRESULT hr
Definition: delayimp.cpp:582
#define NULL
Definition: types.h:112
UINT uFlags
Definition: api.c:59
HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(REFCLSID rclsid, IUnknown *outer, DWORD cls_context, REFIID riid, void **obj)
Definition: combase.c:1685
#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:4171
static MonoProfilerRuntimeShutdownBeginCallback cb
Definition: metahost.c:118
HRESULT WINAPI SHStrDupW(const WCHAR *src, WCHAR **dest)
Definition: main.c:1692
void WINAPI SHFree(LPVOID pv)
Definition: shellole.c:370
LPVOID WINAPI SHAlloc(SIZE_T len)
Definition: shellole.c:348
#define L(x)
Definition: resources.c:13
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
unsigned int UINT
Definition: sysinfo.c:13
static void lock_module(void)
Definition: ieframe.h:342
static void unlock_module(void)
Definition: ieframe.h:346
REFIID riid
Definition: atlbase.h:39
REFIID LPVOID * ppv
Definition: atlbase.h:39
static ULONG Unknown_AddRef(CInternetFolder *This)
Definition: inetfolder.c:120
static PWSTR GetUrl(IFURLITEM *pUrl, PWSTR Buffer)
Definition: inetfolder.c:80
static HRESULT WINAPI BindToStorage(IShellFolder *This, PCUIDLIST_RELATIVE pidl, IBindCtx *pbc, REFIID riid, void **ppvOut)
Definition: inetfolder.c:190
static int GetSchemeCharType(WCHAR c)
Definition: inetfolder.c:36
static CInternetFolder * CreateInstance(void)
Definition: inetfolder.c:328
static HRESULT WINAPI CompareIDs(IShellFolder *This, LPARAM lParam, PCUIDLIST_RELATIVE pidl1, PCUIDLIST_RELATIVE pidl2)
Definition: inetfolder.c:196
struct _IFURLITEM IFURLITEM
static HRESULT WINAPI BindToObject(IShellFolder *This, PCUIDLIST_RELATIVE pidl, IBindCtx *pbc, REFIID riid, void **ppvOut)
Definition: inetfolder.c:184
static HRESULT WINAPI SetNameOf(IShellFolder *This, HWND hwndOwner, PCUITEMID_CHILD pidl, LPCWSTR pszName, SHGDNF uFlags, PITEMID_CHILD *ppidlOut)
Definition: inetfolder.c:271
static ULONG WINAPI ShellFolder_AddRef(IShellFolder *This)
Definition: inetfolder.c:141
#define MAX_URL_LENGTH
Definition: inetfolder.c:23
static ULONG WINAPI PersistFolder_AddRef(IPersistFolder *This)
Definition: inetfolder.c:283
static ULONG WINAPI ShellFolder_Release(IShellFolder *This)
Definition: inetfolder.c:146
static HRESULT WINAPI ShellFolder_QueryInterface(IShellFolder *This, REFIID riid, PVOID *ppvObject)
Definition: inetfolder.c:136
static HRESULT CreateUrlShortcut(PCWSTR Url, IUniformResourceLocatorW **ppv)
Definition: inetfolder.c:88
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:104
static HRESULT WINAPI PersistFolder_QueryInterface(IPersistFolder *This, REFIID riid, PVOID *ppvObject)
Definition: inetfolder.c:278
static const IShellFolderVtbl ShellFolderVtbl
Definition: inetfolder.c:304
static unsigned int GetSchemeLength(PCWSTR s)
Definition: inetfolder.c:43
static HRESULT WINAPI PersistFolder_Initialize(IPersistFolder *This, PCIDLIST_ABSOLUTE pidl)
Definition: inetfolder.c:299
static ULONG WINAPI PersistFolder_Release(IPersistFolder *This)
Definition: inetfolder.c:288
static IFURLITEM * IsUrlItem(LPCITEMIDLIST pidl)
Definition: inetfolder.c:72
static HRESULT WINAPI CreateViewObject(IShellFolder *This, HWND hwndOwner, REFIID riid, void **ppv)
Definition: inetfolder.c:209
static HRESULT WINAPI GetAttributesOf(IShellFolder *This, UINT cidl, PCUITEMID_CHILD_ARRAY apidl, SFGAOF *rgfInOut)
Definition: inetfolder.c:215
#define PT_INTERNET_URL
Definition: inetfolder.c:25
#define IFUIF_UNICODE
Definition: inetfolder.c:26
static LPITEMIDLIST CreateUrlItem(PCWSTR pszUrl)
Definition: inetfolder.c:56
static HRESULT WINAPI PersistFolder_GetClassID(IPersistFolder *This, CLSID *pClassID)
Definition: inetfolder.c:293
HRESULT WINAPI CInternetFolder_CreateInstance(IClassFactory *iface, IUnknown *outer, REFIID riid, void **ppv)
Definition: inetfolder.c:341
static const IPersistFolderVtbl PersistFolderVtbl
Definition: inetfolder.c:320
static HRESULT WINAPI GetDisplayNameOf(IShellFolder *This, PCUITEMID_CHILD pidl, SHGDNF uFlags, STRRET *pSR)
Definition: inetfolder.c:259
static ULONG Unknown_Release(CInternetFolder *This)
Definition: inetfolder.c:125
static HRESULT WINAPI GetUIObjectOf(IShellFolder *This, HWND hwndOwner, UINT cidl, PCUITEMID_CHILD_ARRAY apidl, REFIID riid, UINT *rgfReserved, void **ppv)
Definition: inetfolder.c:235
static HRESULT WINAPI ShellFolder_EnumObjects(IShellFolder *This, HWND hwndOwner, SHCONTF grfFlags, IEnumIDList **ppenumIDList)
Definition: inetfolder.c:178
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define debugstr_guid
Definition: kernel32.h:35
#define CopyMemory
Definition: minwinbase.h:29
LONG_PTR LPARAM
Definition: minwindef.h:175
#define cmp(status, error)
Definition: error.c:118
static IUnknown * outer
Definition: compobj.c:82
static IParseDisplayName ParseDisplayName
Definition: moniker.c:1141
static SHCONTF
Definition: ordinal.c:61
const GUID IID_IDataObject
short WCHAR
Definition: pedump.c:58
long LONG
Definition: pedump.c:60
LPITEMIDLIST WINAPI ILGetNext(LPCITEMIDLIST pidl)
Definition: pidl.c:977
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
_In_ UINT _In_ UINT cch
Definition: shellapi.h:428
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:99
IPersistFolder IPersistFolder_iface
Definition: inetfolder.c:100
BYTE Type
Definition: inetfolder.c:30
UINT Unknown
Definition: inetfolder.c:32
WCHAR Url[ANYSIZE_ARRAY]
Definition: inetfolder.c:33
BYTE Flags
Definition: inetfolder.c:31
UINT uType
Definition: shtypes.idl:93
LPWSTR pOleStr
Definition: shtypes.idl:96
uint16_t * PWSTR
Definition: typedefs.h:56
const char * LPCSTR
Definition: typedefs.h:52
const uint16_t * PCWSTR
Definition: typedefs.h:57
const uint16_t * LPCWSTR
Definition: typedefs.h:57
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#define ANYSIZE_ARRAY
Definition: typedefs.h:46
uint16_t * LPWSTR
Definition: typedefs.h:56
const char * PCSTR
Definition: typedefs.h:52
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4023
#define WINAPI
Definition: msvc.h:6
#define E_NOINTERFACE
Definition: winerror.h:3479
#define CLASS_E_NOAGGREGATION
Definition: winerror.h:3771
unsigned char BYTE
Definition: xxhash.c:193