+ if(!pwszUrl || !pbSecurityId || !pcbSecurityId)
+ return E_INVALIDARG;
+
+ if(dwReserved)
+ FIXME("dwReserved is not supported\n");
+
+ len = strlenW(pwszUrl)+1;
+ buf = HeapAlloc(GetProcessHeap(), 0, (len+16)*sizeof(WCHAR));
+
+ hres = CoInternetParseUrl(pwszUrl, PARSE_SECURITY_URL, 0, buf, len, &size, 0);
+ if(FAILED(hres))
+ memcpy(buf, pwszUrl, len*sizeof(WCHAR));
+
+ hres = map_url_to_zone(buf, &zone);
+ if(FAILED(hres)) {
+ HeapFree(GetProcessHeap(), 0, buf);
+ return hres == 0x80041001 ? E_INVALIDARG : hres;
+ }
+
+ /* file protocol is a special case */
+ if(strlenW(pwszUrl) >= sizeof(wszFile)/sizeof(WCHAR)
+ && !memcmp(buf, wszFile, sizeof(wszFile))) {
+
+ static const BYTE secidFile[] = {'f','i','l','e',':'};
+
+ if(*pcbSecurityId < sizeof(secidFile)+sizeof(zone))
+ return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
+
+ memcpy(pbSecurityId, secidFile, sizeof(secidFile));
+ *(DWORD*)(pbSecurityId+sizeof(secidFile)) = zone;
+
+ *pcbSecurityId = sizeof(secidFile)+sizeof(zone);
+ return S_OK;
+ }
+
+ ptr = strchrW(buf, ':');
+ ptr2 = ++ptr;
+ while(*ptr2 == '/')
+ ptr2++;
+ if(ptr2 != ptr)
+ memmove(ptr, ptr2, (strlenW(ptr2)+1)*sizeof(WCHAR));
+
+ ptr = strchrW(ptr, '/');
+ if(ptr)
+ *ptr = 0;
+
+ len = WideCharToMultiByte(CP_ACP, 0, buf, -1, NULL, 0, NULL, NULL)-1;
+
+ if(len+sizeof(DWORD) > *pcbSecurityId)
+ return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
+
+ WideCharToMultiByte(CP_ACP, 0, buf, -1, (LPSTR)pbSecurityId, -1, NULL, NULL);
+ HeapFree(GetProcessHeap(), 0, buf);
+
+ *(DWORD*)(pbSecurityId+len) = zone;
+
+ *pcbSecurityId = len+sizeof(DWORD);
+
+ return S_OK;