From: Mike Kozelkov augenzi@etersoft.ru
--- dlls/urlmon/Makefile.in | 3 +- dlls/urlmon/urlmon_main.c | 3 + dlls/urlmon/urlmon_main.h | 1 + dlls/urlmon/urlmon_urlmon.idl | 7 + dlls/urlmon/zone_id.c | 297 ++++++++++++++++++++++++++++++++++ include/urlmon.idl | 18 +++ 6 files changed, 328 insertions(+), 1 deletion(-) create mode 100644 dlls/urlmon/zone_id.c
diff --git a/dlls/urlmon/Makefile.in b/dlls/urlmon/Makefile.in index ba6f1db87ad..1a2f73d4c36 100644 --- a/dlls/urlmon/Makefile.in +++ b/dlls/urlmon/Makefile.in @@ -26,7 +26,8 @@ SOURCES = \ urlmon.rc \ urlmon_main.c \ urlmon_urlmon.idl \ - usrmarshal.c + usrmarshal.c \ + zone_id.c
dlldata_EXTRADEFS = -DENTRY_PREFIX=URLMON_ -DPROXY_DELEGATION -DWINE_REGISTER_DLL \ -DPROXY_CLSID_IS="{0x79EAC9F1,0xBAF9,0x11CE,{0x8C,0x82,0x00,0xAA,0x00,0x4B,0xA9,0x0B}}" diff --git a/dlls/urlmon/urlmon_main.c b/dlls/urlmon/urlmon_main.c index c5a8fdcffa2..806a893d7d1 100644 --- a/dlls/urlmon/urlmon_main.c +++ b/dlls/urlmon/urlmon_main.c @@ -351,6 +351,8 @@ static const IClassFactoryVtbl ClassFactoryVtbl = CF_LockServer };
+static ClassFactory PersistentZoneIdentifierCF = + { { &ClassFactoryVtbl }, PersistentZoneIdentifier_Construct}; static ClassFactory FileProtocolCF = { { &ClassFactoryVtbl }, FileProtocol_Construct}; static ClassFactory FtpProtocolCF = @@ -383,6 +385,7 @@ struct object_creation_info
static const struct object_creation_info object_creation[] = { + { &CLSID_PersistentZoneIdentifier, &PersistentZoneIdentifierCF.IClassFactory_iface, NULL }, { &CLSID_FileProtocol, &FileProtocolCF.IClassFactory_iface, L"file" }, { &CLSID_FtpProtocol, &FtpProtocolCF.IClassFactory_iface, L"ftp" }, { &CLSID_GopherProtocol, &GopherProtocolCF.IClassFactory_iface, L"gopher" }, diff --git a/dlls/urlmon/urlmon_main.h b/dlls/urlmon/urlmon_main.h index 81b0d629f53..ceb3e09b761 100644 --- a/dlls/urlmon/urlmon_main.h +++ b/dlls/urlmon/urlmon_main.h @@ -34,6 +34,7 @@ #include "wine/list.h"
extern HINSTANCE hProxyDll; +extern HRESULT PersistentZoneIdentifier_Construct(IUnknown *pUnkOuter, LPVOID *ppobj); extern HRESULT SecManagerImpl_Construct(IUnknown *pUnkOuter, LPVOID *ppobj); extern HRESULT ZoneMgrImpl_Construct(IUnknown *pUnkOuter, LPVOID *ppobj); extern HRESULT StdURLMoniker_Construct(IUnknown *pUnkOuter, LPVOID *ppobj); diff --git a/dlls/urlmon/urlmon_urlmon.idl b/dlls/urlmon/urlmon_urlmon.idl index c25bd8f34ae..d557708c6ca 100644 --- a/dlls/urlmon/urlmon_urlmon.idl +++ b/dlls/urlmon/urlmon_urlmon.idl @@ -111,3 +111,10 @@ coclass DeCompMimeFilter { interface IInternetProtocol; interface IInternetProto uuid(df2fce13-25ec-45bb-9d4c-cecd47c2430c) ] coclass CUri { interface IUri; } + +[ + helpstring("Persistent Zone Identifier"), + threading(both), + uuid(0968e258-16c7-4dba-aa86-462dd61e31a3) +] +coclass PersistentZoneIdentifier { interface IPersistFile; interface IZoneIdentifier; } diff --git a/dlls/urlmon/zone_id.c b/dlls/urlmon/zone_id.c new file mode 100644 index 00000000000..a028f6252d9 --- /dev/null +++ b/dlls/urlmon/zone_id.c @@ -0,0 +1,297 @@ +/* + * Copyright 2025 Mike Kozelkov + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "urlmon_main.h" + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(urlmon); + +typedef struct { + IUnknown IUnknown_inner; + IPersistFile IPersistFile_iface; + IZoneIdentifier IZoneIdentifier_iface; + + IUnknown *outer; + + LONG ref; +} PersistentZoneIdentifier; + +static inline PersistentZoneIdentifier *impl_from_IUnknown(IUnknown *iface) +{ + return CONTAINING_RECORD(iface, PersistentZoneIdentifier, IUnknown_inner); +} + +static inline PersistentZoneIdentifier *impl_from_IPersistFile(IPersistFile *iface) +{ + return CONTAINING_RECORD(iface, PersistentZoneIdentifier, IPersistFile_iface); +} + +static inline PersistentZoneIdentifier *impl_from_IZoneIdentifier(IZoneIdentifier *iface) +{ + return CONTAINING_RECORD(iface, PersistentZoneIdentifier, IZoneIdentifier_iface); +} + +static HRESULT WINAPI PZIUnk_QueryInterface(IUnknown *iface, REFIID riid, void **ppv) +{ + PersistentZoneIdentifier *This = impl_from_IUnknown(iface); + + *ppv = NULL; + + if (IsEqualGUID(&IID_IUnknown, riid)) + { + TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv); + *ppv = &This->IUnknown_inner; + } + else if (IsEqualGUID(&IID_IPersist, riid)) + { + TRACE("(%p)->(IID_IPersist %p)\n", This, ppv); + *ppv = &This->IPersistFile_iface; + } + else if (IsEqualGUID(&IID_IPersistFile, riid)) + { + TRACE("(%p)->(IID_IPersistFile %p)\n", This, ppv); + *ppv = &This->IPersistFile_iface; + } + else if (IsEqualGUID(&IID_IZoneIdentifier, riid)) + { + TRACE("(%p)->(IID_IZoneIdentifier %p)\n", This, ppv); + *ppv = &This->IZoneIdentifier_iface; + } + + if (*ppv) + { + IUnknown_AddRef((IUnknown*)*ppv); + return S_OK; + } + + WARN("not supported interface %s\n", debugstr_guid(riid)); + return E_NOINTERFACE; +} + +static ULONG WINAPI PZIUnk_AddRef(IUnknown *iface) +{ + PersistentZoneIdentifier *This = impl_from_IUnknown(iface); + LONG ref = InterlockedIncrement(&This->ref); + + TRACE("(%p) ref=%ld\n", This, ref); + + return ref; +} + +static ULONG WINAPI PZIUnk_Release(IUnknown *iface) +{ + PersistentZoneIdentifier *This = impl_from_IUnknown(iface); + LONG ref = InterlockedDecrement(&This->ref); + + TRACE("(%p) ref=%ld\n", This, ref); + + if (!ref) + { + free(This); + URLMON_UnlockModule(); + } + + return ref; +} + +static const IUnknownVtbl PZIUnkVtbl = { + PZIUnk_QueryInterface, + PZIUnk_AddRef, + PZIUnk_Release +}; + +static HRESULT WINAPI PZIPersistFile_QueryInterface(IPersistFile *iface, REFIID riid, void **ppv) +{ + PersistentZoneIdentifier *This = impl_from_IPersistFile(iface); + + TRACE("(%p, %s %p)\n", This, debugstr_guid(riid), ppv); + + return IUnknown_QueryInterface(This->outer, riid, ppv); +} + +static ULONG WINAPI PZIPersistFile_AddRef(IPersistFile *iface) +{ + PersistentZoneIdentifier *This = impl_from_IPersistFile(iface); + + TRACE("(%p)\n", This); + + return IUnknown_AddRef(This->outer); +} + +static ULONG WINAPI PZIPersistFile_Release(IPersistFile *iface) +{ + PersistentZoneIdentifier *This = impl_from_IPersistFile(iface); + + TRACE("(%p)\n", This); + + return IUnknown_Release(This->outer); +} + +static HRESULT WINAPI PZIPersistFile_GetClassID(IPersistFile *iface, CLSID *clsid) +{ + PersistentZoneIdentifier *This = impl_from_IPersistFile(iface); + + FIXME("(%p, %p) not implemented\n", This, clsid); + + return E_NOTIMPL; +} + +static HRESULT WINAPI PZIPersistFile_GetCurFile(IPersistFile *iface, LPOLESTR *file_name) +{ + PersistentZoneIdentifier *This = impl_from_IPersistFile(iface); + + FIXME("(%p, %p) not implemented\n", This, file_name); + + return E_NOTIMPL; +} + +static HRESULT WINAPI PZIPersistFile_IsDirty(IPersistFile *iface) +{ + PersistentZoneIdentifier *This = impl_from_IPersistFile(iface); + + FIXME("(%p) not implemented\n", This); + + return E_NOTIMPL; +} + +static HRESULT WINAPI PZIPersistFile_Load(IPersistFile *iface, LPCOLESTR file_name, DWORD mode) +{ + PersistentZoneIdentifier *This = impl_from_IPersistFile(iface); + + FIXME("(%p, %s, 0x%08lx) not implemented\n", This, debugstr_w(file_name), mode); + + return E_NOTIMPL; +} + +static HRESULT WINAPI PZIPersistFile_Save(IPersistFile *iface, LPCOLESTR file_name, BOOL remember) +{ + PersistentZoneIdentifier *This = impl_from_IPersistFile(iface); + + FIXME("(%p, %s, %d) not implemented\n", This, debugstr_w(file_name), remember); + + return E_NOTIMPL; +} + +static HRESULT WINAPI PZIPersistFile_SaveCompleted(IPersistFile* iface, LPCOLESTR pszFileName) +{ + PersistentZoneIdentifier *This = impl_from_IPersistFile(iface); + + FIXME("(%p, %p) not implemented\n", This, pszFileName); + + return E_NOTIMPL; +} + +static const IPersistFileVtbl PZIPersistFileVtbl = { + PZIPersistFile_QueryInterface, + PZIPersistFile_AddRef, + PZIPersistFile_Release, + PZIPersistFile_GetClassID, + PZIPersistFile_IsDirty, + PZIPersistFile_Load, + PZIPersistFile_Save, + PZIPersistFile_SaveCompleted, + PZIPersistFile_GetCurFile +}; + +static HRESULT WINAPI PZIZoneId_QueryInterface(IZoneIdentifier *iface, REFIID riid, void **ppv) +{ + PersistentZoneIdentifier *This = impl_from_IZoneIdentifier(iface); + + TRACE("(%p, %s %p)\n", This, debugstr_guid(riid), ppv); + + return IUnknown_QueryInterface(This->outer, riid, ppv); +} + +static ULONG WINAPI PZIZoneId_AddRef(IZoneIdentifier *iface) +{ + PersistentZoneIdentifier *This = impl_from_IZoneIdentifier(iface); + + TRACE("(%p)\n", This); + + return IUnknown_AddRef(This->outer); +} + +static ULONG WINAPI PZIZoneId_Release(IZoneIdentifier *iface) +{ + PersistentZoneIdentifier *This = impl_from_IZoneIdentifier(iface); + + TRACE("(%p)\n", This); + + return IUnknown_Release(This->outer); +} + +static HRESULT WINAPI PZIZoneId_GetId(IZoneIdentifier* iface, DWORD* pdwZone) +{ + PersistentZoneIdentifier *This = impl_from_IZoneIdentifier(iface); + + FIXME("(%p, %p) not implemented\n", This, pdwZone); + + return E_NOTIMPL; +} + +static HRESULT WINAPI PZIZoneId_Remove(IZoneIdentifier* iface) +{ + PersistentZoneIdentifier *This = impl_from_IZoneIdentifier(iface); + + FIXME("(%p) not implemented\n", This); + + return E_NOTIMPL; +} + +static HRESULT WINAPI PZIZoneId_SetId(IZoneIdentifier* iface, DWORD dwZone) +{ + PersistentZoneIdentifier *This = impl_from_IZoneIdentifier(iface); + + FIXME("(%p, 0x%08lx) not implemented\n", This, dwZone); + + return E_NOTIMPL; +} + +static const IZoneIdentifierVtbl PZIZoneIdVtbl = { + PZIZoneId_QueryInterface, + PZIZoneId_AddRef, + PZIZoneId_Release, + PZIZoneId_GetId, + PZIZoneId_SetId, + PZIZoneId_Remove +}; + +HRESULT PersistentZoneIdentifier_Construct(IUnknown *outer, LPVOID *ppobj) +{ + + PersistentZoneIdentifier *ret; + + TRACE("(%p %p)\n", outer, ppobj); + + URLMON_LockModule(); + + ret = malloc(sizeof(PersistentZoneIdentifier)); + if (!ret) { return E_OUTOFMEMORY; } + + ret->IUnknown_inner.lpVtbl = &PZIUnkVtbl; + ret->IPersistFile_iface.lpVtbl = &PZIPersistFileVtbl; + ret->IZoneIdentifier_iface.lpVtbl = &PZIZoneIdVtbl; + + ret->ref = 1; + ret->outer = outer ? outer : &ret->IUnknown_inner; + + *ppobj = &ret->IUnknown_inner; + + return S_OK; +} diff --git a/include/urlmon.idl b/include/urlmon.idl index 0aab6588658..04b6462d03a 100644 --- a/include/urlmon.idl +++ b/include/urlmon.idl @@ -1299,6 +1299,23 @@ interface IInternetHostSecurityManager : IUnknown [in] DWORD dwReserved); }
+/***************************************************************************** + * IZoneIdentifier interface + */ +[ + object, + uuid(cd45f185-1b21-48e2-967b-ead743a8914e), + pointer_default(unique) +] +interface IZoneIdentifier : IUnknown +{ + HRESULT GetId( + [out] DWORD *pdwZone); + HRESULT SetId( + [in] DWORD dwZone); + HRESULT Remove(); +}; + cpp_quote("#define URLACTION_MIN 0x00001000") cpp_quote("#define URLACTION_DOWNLOAD_MIN 0x00001000") cpp_quote("#define URLACTION_DOWNLOAD_SIGNED_ACTIVEX 0x00001001") @@ -2148,6 +2165,7 @@ cpp_quote("#define UAS_EXACTLEGACY 0x1000")
cpp_quote("EXTERN_C const GUID GUID_CUSTOM_CONFIRMOBJECTSAFETY;")
+cpp_quote("DEFINE_GUID(CLSID_PersistentZoneIdentifier, 0x0968e258, 0x16c7, 0x4dba, 0xaa, 0x86, 0x46, 0x2d, 0xd6, 0x1e, 0x31, 0xa3);") cpp_quote("DEFINE_GUID(CLSID_InternetSecurityManager, 0x7b8a2d94, 0x0ac9, 0x11d1, 0x89, 0x6c, 0x00, 0xc0, 0x4f, 0xB6, 0xbf, 0xc4);") cpp_quote("DEFINE_GUID(CLSID_InternetZoneManager, 0x7B8A2D95, 0x0AC9, 0x11D1, 0x89, 0x6C, 0x00, 0xC0, 0x4F, 0xB6, 0xBF, 0xC4);") cpp_quote("DEFINE_GUID(IID_IAsyncMoniker, 0x79EAC9D3, 0xBAF9, 0x11CE, 0x8C, 0x82, 0x00, 0xAA, 0x00, 0x4B, 0xA9, 0x0B);")