[PATCH] urlmon: Implement the ZoneEnumerator

Detlef Riekenberg wine.dev at web.de
Mon Jun 29 16:01:54 CDT 2009


---
 dlls/urlmon/sec_mgr.c     |  160 +++++++++++++++++++++++++++++++++++++++++----
 dlls/urlmon/urlmon_main.h |    5 ++
 2 files changed, 151 insertions(+), 14 deletions(-)

diff --git a/dlls/urlmon/sec_mgr.c b/dlls/urlmon/sec_mgr.c
index 19286b1..7da3ad6 100644
--- a/dlls/urlmon/sec_mgr.c
+++ b/dlls/urlmon/sec_mgr.c
@@ -3,6 +3,7 @@
  *
  * Copyright (c) 2004 Huw D M Davies
  * Copyright 2004 Jacek Caban
+ * Copyright 2009 Detlef Riekenberg
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -38,6 +39,12 @@ static const WCHAR iconW[] = {'I','c','o','n',0};
 static const WCHAR minlevelW[] = {'M','i','n','L','e','v','e','l',0};
 static const WCHAR recommendedlevelW[] = {'R','e','c','o','m','m','e','n','d','e','d',
                                           'L','e','v','e','l',0};
+static const WCHAR wszZonesKey[] = {'S','o','f','t','w','a','r','e','\\',
+                                    'M','i','c','r','o','s','o','f','t','\\',
+                                    'W','i','n','d','o','w','s','\\',
+                                    'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
+                                    'I','n','t','e','r','n','e','t',' ','S','e','t','t','i','n','g','s','\\',
+                                    'Z','o','n','e','s','\\',0};
 
 /********************************************************************
  * get_string_from_reg [internal]
@@ -205,13 +212,6 @@ static HRESULT map_url_to_zone(LPCWSTR url, DWORD *zone, LPWSTR *ret_url)
 
 static HRESULT open_zone_key(HKEY parent_key, DWORD zone, HKEY *hkey)
 {
-    static const WCHAR wszZonesKey[] =
-        {'S','o','f','t','w','a','r','e','\\',
-         'M','i','c','r','o','s','o','f','t','\\',
-         'W','i','n','d','o','w','s','\\',
-         'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
-         'I','n','t','e','r','n','e','t',' ','S','e','t','t','i','n','g','s','\\',
-         'Z','o','n','e','s','\\',0};
     static const WCHAR wszFormat[] = {'%','s','%','l','d',0};
 
     WCHAR key_name[sizeof(wszZonesKey)/sizeof(WCHAR)+8];
@@ -673,8 +673,69 @@ HRESULT SecManagerImpl_Construct(IUnknown *pUnkOuter, LPVOID *ppobj)
 typedef struct {
     const IInternetZoneManagerVtbl* lpVtbl;
     LONG ref;
+    LPDWORD *zonemaps;
+    DWORD zonemap_count;
 } ZoneMgrImpl;
 
+
+/***********************************************************************
+ * build_zonemap_from_reg [internal]
+ *
+ * Enumerate the Zones in the Registry and return the Zones in a DWORD-array
+ * The number of the Zones is returned in data[0]
+ */
+static LPDWORD build_zonemap_from_reg(void)
+{
+    WCHAR name[32];
+    HKEY hkey;
+    LPDWORD data = NULL;
+    DWORD allocated = 6; /* space for the zonecount and Zone "0" upto Zone "4" */
+    DWORD used = 0;
+    DWORD res;
+    DWORD len;
+
+
+    res = RegOpenKeyW(HKEY_CURRENT_USER, wszZonesKey, &hkey);
+    if (res)
+        return NULL;
+
+    data = heap_alloc(allocated * sizeof(DWORD));
+    if (!data)
+        goto cleanup;
+
+    while (!res) {
+        name[0] = '\0';
+        len = sizeof(name) / sizeof(name[0]);
+        res = RegEnumKeyExW(hkey, used, name, &len, NULL, NULL, NULL, NULL);
+
+        if (!res) {
+            used++;
+            if (used == allocated) {
+                LPDWORD new_data;
+
+                allocated *= 2;
+                new_data = heap_realloc_zero(data, allocated * sizeof(DWORD));
+                if (!new_data)
+                    goto cleanup;
+
+                data = new_data;
+            }
+            data[used] = atoiW(name);
+        }
+    }
+    if (used) {
+        RegCloseKey(hkey);
+        data[0] = used;
+        return data;
+    }
+
+cleanup:
+    /* something failed */
+    RegCloseKey(hkey);
+    heap_free(data);
+    return NULL;
+}
+
 /********************************************************************
  *      IInternetZoneManager_QueryInterface
  */
@@ -723,6 +784,12 @@ static ULONG WINAPI ZoneMgrImpl_Release(IInternetZoneManager* iface)
     TRACE("(%p)->(ref before=%u)\n",This, refCount + 1);
 
     if(!refCount) {
+        while (This->zonemap_count) {
+            /* Free all Zone Enumerator */
+            This->zonemap_count--;
+            heap_free(This->zonemaps[This->zonemap_count]);
+        }
+        heap_free(This->zonemaps);
         heap_free(This);
         URLMON_UnlockModule();
     }
@@ -876,8 +943,49 @@ static HRESULT WINAPI ZoneMgrImpl_CreateZoneEnumerator(IInternetZoneManager* ifa
                                                        DWORD* pdwCount,
                                                        DWORD dwFlags)
 {
-    FIXME("(%p)->(%p %p %08x) stub\n", iface, pdwEnum, pdwCount, dwFlags);
-    return E_NOTIMPL;
+    ZoneMgrImpl* This = (ZoneMgrImpl*)iface;
+    LPDWORD * new_maps;
+    LPDWORD data;
+    DWORD i;
+
+    TRACE("(%p)->(%p, %p, 0x%08x)\n", This, pdwEnum, pdwCount, dwFlags);
+    if (!pdwEnum || !pdwCount || (dwFlags != 0))
+        return E_INVALIDARG;
+
+    data = build_zonemap_from_reg();
+    TRACE("found %d zones\n", data ? data[0] : -1);
+
+    if (!data)
+        return E_FAIL;
+
+    for (i = 0; i < This->zonemap_count; i++) {
+        if (This->zonemaps && !This->zonemaps[i]) {
+            This->zonemaps[i] = data;
+            *pdwEnum = i;
+            *pdwCount = data[0];
+            return S_OK;
+        }
+    }
+
+    if (This->zonemaps) {
+        This->zonemap_count *= 2;
+        new_maps = heap_realloc_zero(This->zonemaps, This->zonemap_count * sizeof(LPDWORD));
+    }
+    else
+    {
+        This->zonemap_count = 2;
+        new_maps = heap_alloc_zero(This->zonemap_count * sizeof(LPDWORD));
+    }
+
+    if (!new_maps) {
+        heap_free(data);
+        return E_FAIL;
+    }
+    This->zonemaps = new_maps;
+    This->zonemaps[i] = data;
+    *pdwEnum = i;
+    *pdwCount = data[0];
+    return S_OK;
 }
 
 /********************************************************************
@@ -888,8 +996,21 @@ static HRESULT WINAPI ZoneMgrImpl_GetZoneAt(IInternetZoneManager* iface,
                                             DWORD dwIndex,
                                             DWORD* pdwZone)
 {
-    FIXME("(%p)->(%08x %08x %p) stub\n", iface, dwEnum, dwIndex, pdwZone);
-    return E_NOTIMPL;
+    ZoneMgrImpl* This = (ZoneMgrImpl*)iface;
+    LPDWORD data;
+
+    TRACE("(%p)->(0x%08x, %d, %p)\n", This, dwEnum, dwIndex, pdwZone);
+
+    /* make sure, that dwEnum and dwIndex are in the valid range */
+    if (dwEnum < This->zonemap_count) {
+        if ((data = This->zonemaps[dwEnum])) {
+            if (dwIndex < data[0]) {
+                *pdwZone = data[dwIndex + 1];
+                return S_OK;
+            }
+        }
+    }
+    return E_INVALIDARG;
 }
 
 /********************************************************************
@@ -898,8 +1019,19 @@ static HRESULT WINAPI ZoneMgrImpl_GetZoneAt(IInternetZoneManager* iface,
 static HRESULT WINAPI ZoneMgrImpl_DestroyZoneEnumerator(IInternetZoneManager* iface,
                                                         DWORD dwEnum)
 {
-    FIXME("(%p)->(%08x) stub\n", iface, dwEnum);
-    return E_NOTIMPL;
+    ZoneMgrImpl* This = (ZoneMgrImpl*)iface;
+    LPDWORD data;
+
+    TRACE("(%p)->(0x%08x)\n", This, dwEnum);
+    /* make sure, that dwEnum is valid */
+    if (dwEnum < This->zonemap_count) {
+        if ((data = This->zonemaps[dwEnum])) {
+            This->zonemaps[dwEnum] = NULL;
+            heap_free(data);
+            return S_OK;
+        }
+    }
+    return E_INVALIDARG;
 }
 
 /********************************************************************
@@ -937,7 +1069,7 @@ static const IInternetZoneManagerVtbl ZoneMgrImplVtbl = {
 
 HRESULT ZoneMgrImpl_Construct(IUnknown *pUnkOuter, LPVOID *ppobj)
 {
-    ZoneMgrImpl* ret = heap_alloc(sizeof(ZoneMgrImpl));
+    ZoneMgrImpl* ret = heap_alloc_zero(sizeof(ZoneMgrImpl));
 
     TRACE("(%p %p)\n", pUnkOuter, ppobj);
     ret->lpVtbl = &ZoneMgrImplVtbl;
diff --git a/dlls/urlmon/urlmon_main.h b/dlls/urlmon/urlmon_main.h
index 1b5d8d5..62a7e91 100644
--- a/dlls/urlmon/urlmon_main.h
+++ b/dlls/urlmon/urlmon_main.h
@@ -151,6 +151,11 @@ static inline void *heap_realloc(void *mem, size_t len)
     return HeapReAlloc(GetProcessHeap(), 0, mem, len);
 }
 
+static inline void *heap_realloc_zero(void *mem, size_t len)
+{
+    return HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, mem, len);
+}
+
 static inline BOOL heap_free(void *mem)
 {
     return HeapFree(GetProcessHeap(), 0, mem);
-- 
1.5.4.3


--=-vG5bcx6RiBCHIj3goASu--




More information about the wine-patches mailing list