diff --git a/dlls/propsys/propsys.spec b/dlls/propsys/propsys.spec index 5bcb483c458..4b617eab120 100644 --- a/dlls/propsys/propsys.spec +++ b/dlls/propsys/propsys.spec @@ -119,7 +119,7 @@ @ stub PropVariantToFileTime @ stub PropVariantToFileTimeVector @ stub PropVariantToFileTimeVectorAlloc -@ stub PropVariantToGUID +@ stdcall PropVariantToGUID(ptr ptr) @ stub PropVariantToInt16 @ stub PropVariantToInt16Vector @ stub PropVariantToInt16VectorAlloc @@ -175,7 +175,7 @@ @ stub VariantToDoubleArrayAlloc @ stub VariantToDoubleWithDefault @ stub VariantToFileTime -@ stub VariantToGUID +@ stdcall VariantToGUID(ptr ptr) @ stub VariantToInt16 @ stub VariantToInt16Array @ stub VariantToInt16ArrayAlloc diff --git a/dlls/propsys/propvar.c b/dlls/propsys/propvar.c index 01a1d5f7e8e..4ea01d969ab 100644 --- a/dlls/propsys/propvar.c +++ b/dlls/propsys/propvar.c @@ -177,3 +177,109 @@ HRESULT WINAPI InitVariantFromBuffer(const VOID *pv, UINT cb, VARIANT *pvar) V_ARRAY(pvar) = arr; return S_OK; } + +static inline DWORD PROPVAR_HexToNum(const WCHAR *hex) +{ + DWORD ret; + + if(hex[0]>='0' && hex[0]<='9') + ret = hex[0]-'0'; + else if(hex[0]>='a' && hex[0]<='f') + ret = hex[0]-'a'+10; + else if(hex[0]>='A' && hex[0]<='F') + ret = hex[0]-'A'+10; + else + return -1; + + ret <<= 4; + if(hex[1]>='0' && hex[1]<='9') + return ret + hex[1]-'0'; + else if(hex[1]>='a' && hex[1]<='f') + return ret + hex[1]-'a'+10; + else if(hex[1]>='A' && hex[1]<='F') + return ret + hex[1]-'A'+10; + else + return -1; +} + +static inline HRESULT PROPVAR_WCHARToGUID(const WCHAR *str, int len, GUID *guid) +{ + DWORD i, val=0; + const WCHAR *p; + + memset(guid, 0, sizeof(GUID)); + + if(len!=38 || str[0]!='{' || str[9]!='-' || str[14]!='-' + || str[19]!='-' || str[24]!='-' || str[37]!='}') { + WARN("Error parsing %s\n", debugstr_w(str)); + return E_INVALIDARG; + } + + p = str+1; + for(i=0; i<4 && val!=-1; i++) { + val = PROPVAR_HexToNum(p); + guid->Data1 = (guid->Data1<<8) + val; + p += 2; + } + p++; + for(i=0; i<2 && val!=-1; i++) { + val = PROPVAR_HexToNum(p); + guid->Data2 = (guid->Data2<<8) + val; + p += 2; + } + p++; + for(i=0; i<2 && val!=-1; i++) { + val = PROPVAR_HexToNum(p); + guid->Data3 = (guid->Data3<<8) + val; + p += 2; + } + p++; + for(i=0; i<8 && val!=-1; i++) { + if(i == 2) + p++; + + val = guid->Data4[i] = PROPVAR_HexToNum(p); + p += 2; + } + + if(val == -1) { + WARN("Error parsing %s\n", debugstr_w(str)); + memset(guid, 0, sizeof(GUID)); + return E_INVALIDARG; + } + return S_OK; +} + +HRESULT WINAPI PropVariantToGUID(const PROPVARIANT *ppropvar, GUID *guid) +{ + TRACE("%p %p)\n", ppropvar, guid); + + switch(ppropvar->vt) { + case VT_BSTR: + return PROPVAR_WCHARToGUID(ppropvar->u.bstrVal, SysStringLen(ppropvar->u.bstrVal), guid); + case VT_LPWSTR: + return PROPVAR_WCHARToGUID(ppropvar->u.pwszVal, strlenW(ppropvar->u.pwszVal), guid); + + default: + FIXME("unsupported vt: %d\n", ppropvar->vt); + return E_NOTIMPL; + } +} + +HRESULT WINAPI VariantToGUID(const VARIANT *pvar, GUID *guid) +{ + TRACE("(%p %p)\n", pvar, guid); + + switch(V_VT(pvar)) { + case VT_BSTR: { + HRESULT hres = PROPVAR_WCHARToGUID(V_BSTR(pvar), SysStringLen(V_BSTR(pvar)), guid); + if(hres == E_INVALIDARG) + return E_FAIL; + return hres; + } + + default: + FIXME("unsupported vt: %d\n", V_VT(pvar)); + return E_NOTIMPL; + } +} diff --git a/dlls/urlmon/urlmon.spec b/dlls/urlmon/urlmon.spec index 76bf718ec05..d3867e140d3 100644 --- a/dlls/urlmon/urlmon.spec +++ b/dlls/urlmon/urlmon.spec @@ -96,8 +96,10 @@ @ stub ZonesReInit 111 stdcall @(wstr) IsProtectedModeURL +329 stdcall @(ptr ptr) propsys.VariantToGUID 331 stdcall @(ptr long ptr) propsys.InitPropVariantFromBuffer 335 stdcall @(ptr long ptr) propsys.InitVariantFromBuffer +350 stdcall @(ptr ptr) propsys.PropVariantToGUID 362 stdcall @(ptr ptr) propsys.InitVariantFromGUIDAsString 410 stdcall @(long long) URLMON_410 423 stdcall @(long long long long) URLMON_423