From: Mike Kozelkov augenzi@etersoft.ru
--- dlls/urlmon/zone_id.c | 149 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 131 insertions(+), 18 deletions(-)
diff --git a/dlls/urlmon/zone_id.c b/dlls/urlmon/zone_id.c index 2d289e3dc3a..ecf68fc84e8 100644 --- a/dlls/urlmon/zone_id.c +++ b/dlls/urlmon/zone_id.c @@ -9,6 +9,12 @@ typedef struct { IPersistFile IPersistFile_iface; IZoneIdentifier IZoneIdentifier_iface;
+ BOOL is_dirty; + LPWSTR file_name; + + URLZONE zone; + BOOL is_zone_removed; + IUnknown *outer;
LONG ref; @@ -122,54 +128,118 @@ static HRESULT WINAPI PZIPersistFile_GetClassID(IPersistFile *iface, CLSID *clsi { PersistentZoneIdentifier *This = impl_from_IPersistFile(iface);
- FIXME("(%p, %p) not implemented\n", This, clsid); + TRACE("(%p, %p)\n", This, clsid); + + *clsid = CLSID_PersistentZoneIdentifier; + + return S_OK; +} + +static HRESULT alloc_and_copy(WCHAR** dest, const WCHAR* src) +{ + WCHAR* res; + DWORD required_size; + + if (!dest || !src) { return E_FAIL; } + + required_size = (lstrlenW(src) + 1) * sizeof(WCHAR); + res = CoTaskMemAlloc(required_size); + if (!res) { return E_OUTOFMEMORY; } + + if (lstrcpyW(res, src) != res) + { + CoTaskMemFree(res); + return E_FAIL; + } + + *dest = res;
- return E_NOTIMPL; + return S_OK; }
static HRESULT WINAPI PZIPersistFile_GetCurFile(IPersistFile *iface, LPOLESTR *file_name) { PersistentZoneIdentifier *This = impl_from_IPersistFile(iface); + WCHAR default_file_name[] = { L'*', 0}; + WCHAR *res_file_name; + HRESULT hres; + + TRACE("(%p, %p)\n", This, file_name); + + res_file_name = This->file_name ? This->file_name : default_file_name;
- FIXME("(%p, %p) not implemented\n", This, file_name); + hres = alloc_and_copy(file_name, res_file_name); + if (hres != S_OK) { *file_name = NULL; } + else { hres = res_file_name == default_file_name ? S_FALSE : hres; }
- return E_NOTIMPL; + return hres; }
static HRESULT WINAPI PZIPersistFile_IsDirty(IPersistFile *iface) { PersistentZoneIdentifier *This = impl_from_IPersistFile(iface);
- FIXME("(%p) not implemented\n", This); + TRACE("(%p)\n", This);
- return E_NOTIMPL; + return This->is_dirty ? S_OK : S_FALSE; }
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); + FIXME("(%p, %s, 0x%08lx) semi-stub\n", iface, debugstr_w(file_name), mode); + + if (!file_name) { return E_FAIL; } + + /* FIXME: Read zone information from Zone.Identifier NTFS alternate data stream */ + This->zone = URLZONE_INTERNET; + This->is_dirty = TRUE;
- return E_NOTIMPL; + return S_OK; }
static HRESULT WINAPI PZIPersistFile_Save(IPersistFile *iface, LPCOLESTR file_name, BOOL remember) { PersistentZoneIdentifier *This = impl_from_IPersistFile(iface); + WCHAR *new_file_name; + HRESULT hres; + + FIXME("(%p, %s, %d) semi-stub\n", iface, debugstr_w(file_name), remember); + + if (!file_name) + { + if (!This->file_name) { return S_FALSE; } + file_name = This->file_name; + remember = FALSE; + } + + /* FIXME: Write zone information to Zone.Identifier NTFS alternate data stream */
- FIXME("(%p, %s, %d) not implemented\n", This, debugstr_w(file_name), remember); + if (!lstrcmpW(This->file_name, file_name)) { This->is_dirty = FALSE; }
- return E_NOTIMPL; + if (remember) + { + hres = alloc_and_copy(&new_file_name, file_name); + if (hres != S_OK) { return hres; } + + if (This->file_name) { CoTaskMemFree(This->file_name); } + This->file_name = new_file_name; + This->is_dirty = FALSE; + } + + return S_OK; }
static HRESULT WINAPI PZIPersistFile_SaveCompleted(IPersistFile* iface, LPCOLESTR pszFileName) { PersistentZoneIdentifier *This = impl_from_IPersistFile(iface);
- FIXME("(%p, %p) not implemented\n", This, pszFileName); + FIXME("(%p, %p) semi-stub \n", This, pszFileName); + + /* FIXME: Add a notification to the object that it can write to its file */
- return E_NOTIMPL; + return S_OK; }
static const IPersistFileVtbl PZIPersistFileVtbl = { @@ -211,31 +281,68 @@ static ULONG WINAPI PZIZoneId_Release(IZoneIdentifier *iface) return IUnknown_Release(This->outer); }
+ +static BOOL is_trusted_zone(URLZONE zone) +{ + switch (zone) + { + case URLZONE_LOCAL_MACHINE: + case URLZONE_INTRANET: + case URLZONE_TRUSTED: + case URLZONE_INTERNET: + case URLZONE_UNTRUSTED: + return TRUE; + default: + return FALSE; + } +} + + static HRESULT WINAPI PZIZoneId_GetId(IZoneIdentifier* iface, DWORD* pdwZone) { PersistentZoneIdentifier *This = impl_from_IZoneIdentifier(iface);
- FIXME("(%p, %p) not implemented\n", This, pdwZone); + TRACE("(%p, %p)\n", This, pdwZone);
- return E_NOTIMPL; + if (This->is_zone_removed) + { + *pdwZone = URLZONE_UNTRUSTED; + return HRESULT_FROM_WIN32(ERROR_NOT_FOUND); + } else if (!is_trusted_zone(This->zone)) + { + *pdwZone = URLZONE_UNTRUSTED; + return E_ACCESSDENIED; + } else + { + *pdwZone = This->zone; + return S_OK; + } }
static HRESULT WINAPI PZIZoneId_Remove(IZoneIdentifier* iface) { PersistentZoneIdentifier *This = impl_from_IZoneIdentifier(iface);
- FIXME("(%p) not implemented\n", This); + TRACE("(%p)\n", This); + + This->zone = URLZONE_LOCAL_MACHINE; + This->is_zone_removed = TRUE; + This->is_dirty = TRUE;
- return E_NOTIMPL; + return S_OK; }
static HRESULT WINAPI PZIZoneId_SetId(IZoneIdentifier* iface, DWORD dwZone) { PersistentZoneIdentifier *This = impl_from_IZoneIdentifier(iface);
- FIXME("(%p, 0x%08lx) not implemented\n", This, dwZone); + TRACE("(%p, 0x%08lx)\n", This, dwZone);
- return E_NOTIMPL; + This->zone = dwZone; + This->is_dirty = TRUE; + This->is_zone_removed = FALSE; + + return is_trusted_zone(This->zone) ? S_OK : E_ACCESSDENIED; }
static const IZoneIdentifierVtbl PZIZoneIdVtbl = { @@ -262,6 +369,12 @@ HRESULT PersistentZoneIdentifier_Construct(IUnknown *outer, LPVOID *ppobj) ret->IPersistFile_iface.lpVtbl = &PZIPersistFileVtbl; ret->IZoneIdentifier_iface.lpVtbl = &PZIZoneIdVtbl;
+ ret->file_name = NULL; + ret->is_dirty = FALSE; + + ret->zone = URLZONE_INVALID; + ret->is_zone_removed = TRUE; + ret->ref = 1; ret->outer = outer ? outer : &ret->IUnknown_inner;