diff --git a/dll/win32/propsys/CMakeLists.txt b/dll/win32/propsys/CMakeLists.txt index 8d788ae20d4..41412950df7 100644 --- a/dll/win32/propsys/CMakeLists.txt +++ b/dll/win32/propsys/CMakeLists.txt @@ -1,6 +1,7 @@ include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) -add_definitions(-D__WINESRC__) +remove_definitions(-D_CRT_NON_CONFORMING_SWPRINTFS -D__ROS_LONG64__) +add_definitions(-D__WINESRC__ -D_PROPSYS_) spec2def(propsys.dll propsys.spec ADD_IMPORTLIB) list(APPEND SOURCE @@ -16,7 +17,7 @@ add_library(propsys MODULE ${CMAKE_CURRENT_BINARY_DIR}/propsys.def) set_module_type(propsys win32dll) -target_link_libraries(propsys uuid wine) +target_link_libraries(propsys uuid wine wine_dll_register) add_importlibs(propsys ole32 oleaut32 msvcrt kernel32 ntdll) add_pch(propsys precomp.h SOURCE) add_cd_file(TARGET propsys DESTINATION reactos/system32 FOR all) diff --git a/dll/win32/propsys/precomp.h b/dll/win32/propsys/precomp.h index 1f432757e3a..a233f258ae0 100644 --- a/dll/win32/propsys/precomp.h +++ b/dll/win32/propsys/precomp.h @@ -9,13 +9,14 @@ #define COM_NO_WINDOWS_H #define COBJMACROS -#define NONAMELESSUNION #include #include #include #include #include +#include +#include #include diff --git a/dll/win32/propsys/propstore.c b/dll/win32/propsys/propstore.c index 6212f293123..adef3b38916 100644 --- a/dll/win32/propsys/propstore.c +++ b/dll/win32/propsys/propstore.c @@ -92,7 +92,7 @@ static ULONG WINAPI PropertyStore_AddRef(IPropertyStoreCache *iface) PropertyStore *This = impl_from_IPropertyStoreCache(iface); ULONG ref = InterlockedIncrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); return ref; } @@ -113,7 +113,7 @@ static ULONG WINAPI PropertyStore_Release(IPropertyStoreCache *iface) PropertyStore *This = impl_from_IPropertyStoreCache(iface); ULONG ref = InterlockedDecrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); if (ref == 0) { @@ -159,7 +159,7 @@ static HRESULT WINAPI PropertyStore_GetAt(IPropertyStoreCache *iface, propstore_value *value; HRESULT hr; - TRACE("%p,%d,%p\n", iface, iProp, pkey); + TRACE("%p,%ld,%p\n", iface, iProp, pkey); if (!pkey) return E_POINTER; @@ -464,7 +464,11 @@ HRESULT PropertyStore_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv This->IPropertyStoreCache_iface.lpVtbl = &PropertyStore_Vtbl; This->ref = 1; +#ifdef __REACTOS__ InitializeCriticalSection(&This->lock); +#else + InitializeCriticalSectionEx(&This->lock, 0, RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO); +#endif This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": PropertyStore.lock"); list_init(&This->formats); @@ -473,3 +477,19 @@ HRESULT PropertyStore_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv return ret; } + +HRESULT WINAPI PSCreatePropertyStoreFromObject(IUnknown *obj, DWORD access, REFIID riid, void **ret) +{ + HRESULT hr; + + TRACE("(%p, %ld, %s, %p)\n", obj, access, debugstr_guid(riid), ret); + + if (!obj || !ret) + return E_POINTER; + + if (IsEqualIID(riid, &IID_IPropertyStore) && SUCCEEDED(hr = IUnknown_QueryInterface(obj, riid, ret))) + return hr; + + FIXME("Unimplemented for %s.\n", debugstr_guid(riid)); + return E_NOTIMPL; +} diff --git a/dll/win32/propsys/propsys.spec b/dll/win32/propsys/propsys.spec index 19e16aedc1e..5771848917b 100644 --- a/dll/win32/propsys/propsys.spec +++ b/dll/win32/propsys/propsys.spec @@ -42,7 +42,7 @@ @ stub InitPropVariantFromResource @ stub InitPropVariantFromStrRet @ stub InitPropVariantFromStringAsVector -@ stub InitPropVariantFromStringVector +@ stdcall InitPropVariantFromStringVector(ptr long ptr) @ stub InitPropVariantFromUInt16Vector @ stub InitPropVariantFromUInt32Vector @ stub InitPropVariantFromUInt64Vector @@ -50,7 +50,7 @@ @ stub InitVariantFromBooleanArray @ stdcall InitVariantFromBuffer(ptr long ptr) @ stub InitVariantFromDoubleArray -@ stub InitVariantFromFileTime +@ stdcall InitVariantFromFileTime(ptr ptr) @ stub InitVariantFromFileTimeArray @ stdcall InitVariantFromGUIDAsString(ptr ptr) @ stub InitVariantFromInt16Array @@ -69,7 +69,7 @@ @ stdcall PSCreateMemoryPropertyStore(ptr ptr) @ stub PSCreateMultiplexPropertyStore @ stub PSCreatePropertyChangeArray -@ stub PSCreatePropertyStoreFromObject +@ stdcall PSCreatePropertyStoreFromObject(ptr long ptr ptr) @ stub PSCreatePropertyStoreFromPropertySetStorage @ stub PSCreateSimplePropertyChange @ stub PSEnumeratePropertyDescriptions @@ -107,7 +107,7 @@ @ stub PropVariantGetUInt16Elem @ stub PropVariantGetUInt32Elem @ stub PropVariantGetUInt64Elem -@ stub PropVariantToBSTR +@ stdcall PropVariantToBSTR(ptr ptr) @ stdcall PropVariantToBoolean(ptr ptr) @ stub PropVariantToBooleanVector @ stub PropVariantToBooleanVectorAlloc @@ -146,12 +146,12 @@ @ stdcall PropVariantToUInt32(ptr ptr) @ stub PropVariantToUInt32Vector @ stub PropVariantToUInt32VectorAlloc -@ stub PropVariantToUInt32WithDefault +@ stdcall PropVariantToUInt32WithDefault(ptr long) @ stdcall PropVariantToUInt64(ptr ptr) @ stub PropVariantToUInt64Vector @ stub PropVariantToUInt64VectorAlloc @ stub PropVariantToUInt64WithDefault -@ stub PropVariantToVariant +@ stdcall PropVariantToVariant(ptr ptr) @ stub StgDeserializePropVariant @ stub StgSerializePropVariant @ stub VariantCompare @@ -189,13 +189,13 @@ @ stub VariantToInt64Array @ stub VariantToInt64ArrayAlloc @ stub VariantToInt64WithDefault -@ stub VariantToPropVariant +@ stdcall VariantToPropVariant(ptr ptr) @ stub VariantToStrRet -@ stub VariantToString +@ stdcall VariantToString(ptr ptr long) @ stub VariantToStringAlloc @ stub VariantToStringArray @ stub VariantToStringArrayAlloc -@ stub VariantToStringWithDefault +@ stdcall VariantToStringWithDefault(ptr wstr) @ stub VariantToUInt16 @ stub VariantToUInt16Array @ stub VariantToUInt16ArrayAlloc diff --git a/dll/win32/propsys/propsys_main.c b/dll/win32/propsys/propsys_main.c index 6f7dc8a397c..5557131ed4b 100644 --- a/dll/win32/propsys/propsys_main.c +++ b/dll/win32/propsys/propsys_main.c @@ -22,9 +22,6 @@ #define COBJMACROS #include -#ifdef __REACTOS__ -#include -#endif #include "windef.h" #include "winbase.h" @@ -37,35 +34,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(propsys); -static HINSTANCE propsys_hInstance; - -BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) -{ - TRACE("(0x%p, %d, %p)\n", hinstDLL, fdwReason, lpvReserved); - - switch (fdwReason) - { - case DLL_WINE_PREATTACH: - return FALSE; /* prefer native version */ - case DLL_PROCESS_ATTACH: - propsys_hInstance = hinstDLL; - DisableThreadLibraryCalls(hinstDLL); - break; - } - - return TRUE; -} - -HRESULT WINAPI DllRegisterServer(void) -{ - return __wine_register_resources( propsys_hInstance ); -} - -HRESULT WINAPI DllUnregisterServer(void) -{ - return __wine_unregister_resources( propsys_hInstance ); -} - static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv) { *ppv = NULL; @@ -135,11 +103,6 @@ HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv) return CLASS_E_CLASSNOTAVAILABLE; } -HRESULT WINAPI DllCanUnloadNow(void) -{ - return S_FALSE; -} - static HRESULT WINAPI propsys_QueryInterface(IPropertySystem *iface, REFIID riid, void **obj) { *obj = NULL; @@ -194,7 +157,7 @@ static HRESULT WINAPI propsys_FormatForDisplay(IPropertySystem *iface, REFPROPERTYKEY key, REFPROPVARIANT propvar, PROPDESC_FORMAT_FLAGS flags, LPWSTR dest, DWORD destlen) { - FIXME("%p %p %x %p %d: stub\n", key, propvar, flags, dest, destlen); + FIXME("%p %p %x %p %ld: stub\n", key, propvar, flags, dest, destlen); return E_NOTIMPL; } @@ -283,12 +246,6 @@ HRESULT WINAPI PSRefreshPropertySchema(void) HRESULT WINAPI PSStringFromPropertyKey(REFPROPERTYKEY pkey, LPWSTR psz, UINT cch) { - static const WCHAR guid_fmtW[] = {'{','%','0','8','X','-','%','0','4','X','-', - '%','0','4','X','-','%','0','2','X','%','0','2','X','-', - '%','0','2','X','%','0','2','X','%','0','2','X', - '%','0','2','X','%','0','2','X','%','0','2','X','}',0}; - static const WCHAR pid_fmtW[] = {'%','u',0}; - WCHAR pidW[PKEY_PIDSTR_MAX + 1]; LPWSTR p = psz; int len; @@ -308,8 +265,8 @@ HRESULT WINAPI PSStringFromPropertyKey(REFPROPERTYKEY pkey, LPWSTR psz, UINT cch return E_NOT_SUFFICIENT_BUFFER; } - swprintf(psz, guid_fmtW, pkey->fmtid.Data1, pkey->fmtid.Data2, - pkey->fmtid.Data3, pkey->fmtid.Data4[0], pkey->fmtid.Data4[1], + swprintf(psz, cch, L"{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}", pkey->fmtid.Data1, + pkey->fmtid.Data2, pkey->fmtid.Data3, pkey->fmtid.Data4[0], pkey->fmtid.Data4[1], pkey->fmtid.Data4[2], pkey->fmtid.Data4[3], pkey->fmtid.Data4[4], pkey->fmtid.Data4[5], pkey->fmtid.Data4[6], pkey->fmtid.Data4[7]); @@ -318,7 +275,7 @@ HRESULT WINAPI PSStringFromPropertyKey(REFPROPERTYKEY pkey, LPWSTR psz, UINT cch *p++ = ' '; cch -= GUIDSTRING_MAX - 1 + 1; - len = swprintf(pidW, pid_fmtW, pkey->pid); + len = swprintf(pidW, ARRAY_SIZE(pidW), L"%u", pkey->pid); if (cch >= len + 1) { @@ -498,7 +455,7 @@ HRESULT WINAPI PSPropertyKeyFromString(LPCWSTR pszString, PROPERTYKEY *pkey) } /* Overflow is not checked. */ - while (iswdigit(*pszString)) + while ('0' <= *pszString && *pszString <= '9') { pkey->pid *= 10; pkey->pid += (*pszString - '0'); @@ -517,3 +474,10 @@ HRESULT WINAPI PSCreateMemoryPropertyStore(REFIID riid, void **ppv) return PropertyStore_CreateInstance(NULL, riid, ppv); } + +#ifdef __REACTOS__ +HRESULT WINAPI DllCanUnloadNow(void) +{ + return S_FALSE; +} +#endif diff --git a/dll/win32/propsys/propsys_private.h b/dll/win32/propsys/propsys_private.h index d43de7534d2..a91b5c5c289 100644 --- a/dll/win32/propsys/propsys_private.h +++ b/dll/win32/propsys/propsys_private.h @@ -20,4 +20,4 @@ #pragma once -HRESULT PropertyStore_CreateInstance(IUnknown *outer, REFIID riid, void **ppv) DECLSPEC_HIDDEN; +HRESULT PropertyStore_CreateInstance(IUnknown *outer, REFIID riid, void **ppv); diff --git a/dll/win32/propsys/propvar.c b/dll/win32/propsys/propvar.c index f03dc148435..e1375134f11 100644 --- a/dll/win32/propsys/propvar.c +++ b/dll/win32/propsys/propvar.c @@ -23,8 +23,6 @@ #include #include -#define NONAMELESSUNION - #include "windef.h" #include "winbase.h" #include "winerror.h" @@ -33,11 +31,31 @@ #include "shlobj.h" #include "propvarutil.h" #include "strsafe.h" - #include "wine/debug.h" WINE_DEFAULT_DEBUG_CHANNEL(propsys); +#define GUID_STR_LEN 38 +static HRESULT VARIANT_ValidateType(VARTYPE vt) +{ + VARTYPE vtExtra = vt & (VT_VECTOR | VT_ARRAY | VT_BYREF | VT_RESERVED); + + vt &= VT_TYPEMASK; + + if (!(vtExtra & (VT_VECTOR | VT_RESERVED))) + { + if (vt < VT_VOID || vt == VT_RECORD || vt == VT_CLSID) + { + if ((vtExtra & (VT_BYREF | VT_ARRAY)) && vt <= VT_NULL) + return DISP_E_BADVARTYPE; + if (vt != (VARTYPE)15) + return S_OK; + } + } + + return DISP_E_BADVARTYPE; +} + static HRESULT PROPVAR_ConvertFILETIME(const FILETIME *ft, PROPVARIANT *ppropvarDest, VARTYPE vt) { SYSTEMTIME time; @@ -47,11 +65,11 @@ static HRESULT PROPVAR_ConvertFILETIME(const FILETIME *ft, PROPVARIANT *ppropvar switch (vt) { case VT_LPSTR: - ppropvarDest->u.pszVal = HeapAlloc(GetProcessHeap(), 0, 64); - if (!ppropvarDest->u.pszVal) + ppropvarDest->pszVal = HeapAlloc(GetProcessHeap(), 0, 64); + if (!ppropvarDest->pszVal) return E_OUTOFMEMORY; - sprintf( ppropvarDest->u.pszVal, "%04d/%02d/%02d:%02d:%02d:%02d.%03d", + sprintf( ppropvarDest->pszVal, "%04d/%02d/%02d:%02d:%02d:%02d.%03d", time.wYear, time.wMonth, time.wDay, time.wHour, time.wMinute, time.wSecond, time.wMilliseconds ); @@ -74,35 +92,35 @@ static HRESULT PROPVAR_ConvertNumber(REFPROPVARIANT pv, int dest_bits, { case VT_I1: src_signed = TRUE; - *res = pv->u.cVal; + *res = pv->cVal; break; case VT_UI1: src_signed = FALSE; - *res = pv->u.bVal; + *res = pv->bVal; break; case VT_I2: src_signed = TRUE; - *res = pv->u.iVal; + *res = pv->iVal; break; case VT_UI2: src_signed = FALSE; - *res = pv->u.uiVal; + *res = pv->uiVal; break; case VT_I4: src_signed = TRUE; - *res = pv->u.lVal; + *res = pv->lVal; break; case VT_UI4: src_signed = FALSE; - *res = pv->u.ulVal; + *res = pv->ulVal; break; case VT_I8: src_signed = TRUE; - *res = pv->u.hVal.QuadPart; + *res = pv->hVal.QuadPart; break; case VT_UI8: src_signed = FALSE; - *res = pv->u.uhVal.QuadPart; + *res = pv->uhVal.QuadPart; break; case VT_EMPTY: src_signed = FALSE; @@ -111,8 +129,12 @@ static HRESULT PROPVAR_ConvertNumber(REFPROPVARIANT pv, int dest_bits, case VT_LPSTR: { char *end; - *res = _strtoi64(pv->u.pszVal, &end, 0); - if (pv->u.pszVal == end) +#ifdef __REACTOS__ + *res = _strtoi64(pv->pszVal, &end, 0); +#else + *res = strtoll(pv->pszVal, &end, 0); +#endif + if (pv->pszVal == end) return DISP_E_TYPEMISMATCH; src_signed = *res < 0; break; @@ -121,8 +143,8 @@ static HRESULT PROPVAR_ConvertNumber(REFPROPVARIANT pv, int dest_bits, case VT_BSTR: { WCHAR *end; - *res = wcstol(pv->u.pwszVal, &end, 0); - if (pv->u.pwszVal == end) + *res = wcstol(pv->pwszVal, &end, 0); + if (pv->pwszVal == end) return DISP_E_TYPEMISMATCH; src_signed = *res < 0; break; @@ -130,7 +152,7 @@ static HRESULT PROPVAR_ConvertNumber(REFPROPVARIANT pv, int dest_bits, case VT_R8: { src_signed = TRUE; - *res = pv->u.dblVal; + *res = pv->dblVal; break; } default: @@ -231,6 +253,20 @@ HRESULT WINAPI PropVariantToUInt32(REFPROPVARIANT propvarIn, ULONG *ret) return hr; } +ULONG WINAPI PropVariantToUInt32WithDefault(REFPROPVARIANT propvarIn, ULONG ulDefault) +{ + LONGLONG res; + HRESULT hr; + + TRACE("%p,%lu\n", propvarIn, ulDefault); + + hr = PROPVAR_ConvertNumber(propvarIn, 32, FALSE, &res); + if (SUCCEEDED(hr)) + return (ULONG)res; + + return ulDefault; +} + HRESULT WINAPI PropVariantToUInt64(REFPROPVARIANT propvarIn, ULONGLONG *ret) { LONGLONG res; @@ -245,10 +281,6 @@ HRESULT WINAPI PropVariantToUInt64(REFPROPVARIANT propvarIn, ULONGLONG *ret) HRESULT WINAPI PropVariantToBoolean(REFPROPVARIANT propvarIn, BOOL *ret) { - static const WCHAR trueW[] = {'t','r','u','e',0}; - static const WCHAR falseW[] = {'f','a','l','s','e',0}; - static const WCHAR true2W[] = {'#','T','R','U','E','#',0}; - static const WCHAR false2W[] = {'#','F','A','L','S','E','#',0}; LONGLONG res; HRESULT hr; @@ -259,21 +291,21 @@ HRESULT WINAPI PropVariantToBoolean(REFPROPVARIANT propvarIn, BOOL *ret) switch (propvarIn->vt) { case VT_BOOL: - *ret = propvarIn->u.boolVal == VARIANT_TRUE; + *ret = propvarIn->boolVal == VARIANT_TRUE; return S_OK; case VT_LPWSTR: case VT_BSTR: - if (!propvarIn->u.pwszVal) + if (!propvarIn->pwszVal) return DISP_E_TYPEMISMATCH; - if (!lstrcmpiW(propvarIn->u.pwszVal, trueW) || !lstrcmpW(propvarIn->u.pwszVal, true2W)) + if (!lstrcmpiW(propvarIn->pwszVal, L"true") || !lstrcmpW(propvarIn->pwszVal, L"#TRUE#")) { *ret = TRUE; return S_OK; } - if (!lstrcmpiW(propvarIn->u.pwszVal, falseW) || !lstrcmpW(propvarIn->u.pwszVal, false2W)) + if (!lstrcmpiW(propvarIn->pwszVal, L"false") || !lstrcmpW(propvarIn->pwszVal, L"#FALSE#")) { *ret = FALSE; return S_OK; @@ -281,16 +313,16 @@ HRESULT WINAPI PropVariantToBoolean(REFPROPVARIANT propvarIn, BOOL *ret) break; case VT_LPSTR: - if (!propvarIn->u.pszVal) + if (!propvarIn->pszVal) return DISP_E_TYPEMISMATCH; - if (!lstrcmpiA(propvarIn->u.pszVal, "true") || !lstrcmpA(propvarIn->u.pszVal, "#TRUE#")) + if (!lstrcmpiA(propvarIn->pszVal, "true") || !lstrcmpA(propvarIn->pszVal, "#TRUE#")) { *ret = TRUE; return S_OK; } - if (!lstrcmpiA(propvarIn->u.pszVal, "false") || !lstrcmpA(propvarIn->u.pszVal, "#FALSE#")) + if (!lstrcmpiA(propvarIn->pszVal, "false") || !lstrcmpA(propvarIn->pszVal, "#FALSE#")) { *ret = FALSE; return S_OK; @@ -303,6 +335,26 @@ HRESULT WINAPI PropVariantToBoolean(REFPROPVARIANT propvarIn, BOOL *ret) return hr; } +HRESULT WINAPI PropVariantToBSTR(REFPROPVARIANT propvar, BSTR *bstr) +{ + WCHAR *str; + HRESULT hr; + + TRACE("propvar %p, propvar->vt %#x, bstr %p.\n", + propvar, propvar ? propvar->vt : 0, bstr); + + if (FAILED(hr = PropVariantToStringAlloc(propvar, &str))) + return hr; + + *bstr = SysAllocString(str); + CoTaskMemFree(str); + + if (!*bstr) + return E_OUTOFMEMORY; + + return S_OK; +} + HRESULT WINAPI PropVariantToBuffer(REFPROPVARIANT propvarIn, void *ret, UINT cb) { HRESULT hr = S_OK; @@ -312,9 +364,9 @@ HRESULT WINAPI PropVariantToBuffer(REFPROPVARIANT propvarIn, void *ret, UINT cb) switch(propvarIn->vt) { case VT_VECTOR|VT_UI1: - if(cb > propvarIn->u.caub.cElems) + if(cb > propvarIn->caub.cElems) return E_FAIL; - memcpy(ret, propvarIn->u.caub.pElems, cb); + memcpy(ret, propvarIn->caub.pElems, cb); break; case VT_ARRAY|VT_UI1: FIXME("Unsupported type: VT_ARRAY|VT_UI1\n"); @@ -328,7 +380,6 @@ HRESULT WINAPI PropVariantToBuffer(REFPROPVARIANT propvarIn, void *ret, UINT cb) return hr; } - HRESULT WINAPI PropVariantToString(REFPROPVARIANT propvarIn, PWSTR ret, UINT cch) { HRESULT hr; @@ -369,27 +420,36 @@ HRESULT WINAPI PropVariantToStringAlloc(REFPROPVARIANT propvarIn, WCHAR **ret) break; case VT_LPSTR: - if(propvarIn->u.pszVal) + if(propvarIn->pszVal) { DWORD len; - len = MultiByteToWideChar(CP_ACP, 0, propvarIn->u.pszVal, -1, NULL, 0); + len = MultiByteToWideChar(CP_ACP, 0, propvarIn->pszVal, -1, NULL, 0); res = CoTaskMemAlloc(len*sizeof(WCHAR)); if(!res) return E_OUTOFMEMORY; - MultiByteToWideChar(CP_ACP, 0, propvarIn->u.pszVal, -1, res, len); + MultiByteToWideChar(CP_ACP, 0, propvarIn->pszVal, -1, res, len); } break; case VT_LPWSTR: case VT_BSTR: - if (propvarIn->u.pwszVal) + if (propvarIn->pwszVal) { - DWORD size = (lstrlenW(propvarIn->u.pwszVal) + 1) * sizeof(WCHAR); + DWORD size = (lstrlenW(propvarIn->pwszVal) + 1) * sizeof(WCHAR); res = CoTaskMemAlloc(size); if(!res) return E_OUTOFMEMORY; - memcpy(res, propvarIn->u.pwszVal, size); + memcpy(res, propvarIn->pwszVal, size); + } + break; + + case VT_CLSID: + if (propvarIn->puuid) + { + if (!(res = CoTaskMemAlloc((GUID_STR_LEN + 1) * sizeof(WCHAR)))) + return E_OUTOFMEMORY; + StringFromGUID2(propvarIn->puuid, res, GUID_STR_LEN + 1); } break; @@ -406,21 +466,70 @@ HRESULT WINAPI PropVariantToStringAlloc(REFPROPVARIANT propvarIn, WCHAR **ret) PCWSTR WINAPI PropVariantToStringWithDefault(REFPROPVARIANT propvarIn, LPCWSTR pszDefault) { - static const WCHAR str_empty[] = {0}; if (propvarIn->vt == VT_BSTR) { - if (propvarIn->u.bstrVal == NULL) - return str_empty; + if (propvarIn->bstrVal == NULL) + return L""; - return propvarIn->u.bstrVal; + return propvarIn->bstrVal; } - if (propvarIn->vt == VT_LPWSTR && propvarIn->u.pwszVal != NULL) - return propvarIn->u.pwszVal; + if (propvarIn->vt == VT_LPWSTR && propvarIn->pwszVal != NULL) + return propvarIn->pwszVal; return pszDefault; } +/****************************************************************** + * VariantToStringWithDefault (PROPSYS.@) + */ +PCWSTR WINAPI VariantToStringWithDefault(const VARIANT *pvar, const WCHAR *default_value) +{ + TRACE("%s, %s.\n", debugstr_variant(pvar), debugstr_w(default_value)); + + if (V_VT(pvar) == (VT_BYREF | VT_VARIANT)) pvar = V_VARIANTREF(pvar); + if (V_VT(pvar) == (VT_BYREF | VT_BSTR) || V_VT(pvar) == VT_BSTR) + { + BSTR ret = V_ISBYREF(pvar) ? *V_BSTRREF(pvar) : V_BSTR(pvar); + return ret ? ret : L""; + } + + return default_value; +} + +/****************************************************************** + * VariantToString (PROPSYS.@) + */ +HRESULT WINAPI VariantToString(REFVARIANT var, PWSTR ret, UINT cch) +{ + WCHAR buffer[64], *str = buffer; + + TRACE("%p, %p, %u.\n", var, ret, cch); + + *ret = 0; + + if (!cch) + return E_INVALIDARG; + + switch (V_VT(var)) + { + case VT_BSTR: + str = V_BSTR(var); + break; + case VT_I4: + swprintf(buffer, ARRAY_SIZE(buffer), L"%d", V_I4(var)); + break; + default: + FIXME("Unsupported type %d.\n", V_VT(var)); + return E_NOTIMPL; + } + + if (wcslen(str) > cch - 1) + return STRSAFE_E_INSUFFICIENT_BUFFER; + wcscpy(ret, str); + + return S_OK; +} /****************************************************************** * PropVariantChangeType (PROPSYS.@) @@ -437,7 +546,7 @@ HRESULT WINAPI PropVariantChangeType(PROPVARIANT *ppropvarDest, REFPROPVARIANT p return PropVariantCopy(ppropvarDest, propvarSrc); if (propvarSrc->vt == VT_FILETIME) - return PROPVAR_ConvertFILETIME(&propvarSrc->u.filetime, ppropvarDest, vt); + return PROPVAR_ConvertFILETIME(&propvarSrc->filetime, ppropvarDest, vt); switch (vt) { @@ -449,7 +558,7 @@ HRESULT WINAPI PropVariantChangeType(PROPVARIANT *ppropvarDest, REFPROPVARIANT p if (SUCCEEDED(hr)) { ppropvarDest->vt = VT_I1; - ppropvarDest->u.cVal = (char)res; + ppropvarDest->cVal = (char)res; } return hr; } @@ -462,7 +571,7 @@ HRESULT WINAPI PropVariantChangeType(PROPVARIANT *ppropvarDest, REFPROPVARIANT p if (SUCCEEDED(hr)) { ppropvarDest->vt = VT_UI1; - ppropvarDest->u.bVal = (UCHAR)res; + ppropvarDest->bVal = (UCHAR)res; } return hr; } @@ -474,7 +583,7 @@ HRESULT WINAPI PropVariantChangeType(PROPVARIANT *ppropvarDest, REFPROPVARIANT p if (SUCCEEDED(hr)) { ppropvarDest->vt = VT_I2; - ppropvarDest->u.iVal = res; + ppropvarDest->iVal = res; } return hr; } @@ -485,7 +594,7 @@ HRESULT WINAPI PropVariantChangeType(PROPVARIANT *ppropvarDest, REFPROPVARIANT p if (SUCCEEDED(hr)) { ppropvarDest->vt = VT_UI2; - ppropvarDest->u.uiVal = res; + ppropvarDest->uiVal = res; } return hr; } @@ -496,7 +605,7 @@ HRESULT WINAPI PropVariantChangeType(PROPVARIANT *ppropvarDest, REFPROPVARIANT p if (SUCCEEDED(hr)) { ppropvarDest->vt = VT_I4; - ppropvarDest->u.lVal = res; + ppropvarDest->lVal = res; } return hr; } @@ -507,7 +616,7 @@ HRESULT WINAPI PropVariantChangeType(PROPVARIANT *ppropvarDest, REFPROPVARIANT p if (SUCCEEDED(hr)) { ppropvarDest->vt = VT_UI4; - ppropvarDest->u.ulVal = res; + ppropvarDest->ulVal = res; } return hr; } @@ -518,7 +627,7 @@ HRESULT WINAPI PropVariantChangeType(PROPVARIANT *ppropvarDest, REFPROPVARIANT p if (SUCCEEDED(hr)) { ppropvarDest->vt = VT_I8; - ppropvarDest->u.hVal.QuadPart = res; + ppropvarDest->hVal.QuadPart = res; } return hr; } @@ -529,7 +638,7 @@ HRESULT WINAPI PropVariantChangeType(PROPVARIANT *ppropvarDest, REFPROPVARIANT p if (SUCCEEDED(hr)) { ppropvarDest->vt = VT_UI8; - ppropvarDest->u.uhVal.QuadPart = res; + ppropvarDest->uhVal.QuadPart = res; } return hr; } @@ -542,7 +651,7 @@ HRESULT WINAPI PropVariantChangeType(PROPVARIANT *ppropvarDest, REFPROPVARIANT p if (SUCCEEDED(hr)) { ppropvarDest->vt = VT_LPWSTR; - ppropvarDest->u.pwszVal = res; + ppropvarDest->pwszVal = res; } return hr; } @@ -562,7 +671,7 @@ HRESULT WINAPI PropVariantChangeType(PROPVARIANT *ppropvarDest, REFPROPVARIANT p { WideCharToMultiByte(CP_ACP, 0, resW, -1, res, len, NULL, NULL); ppropvarDest->vt = VT_LPSTR; - ppropvarDest->u.pszVal = res; + ppropvarDest->pszVal = res; } else hr = E_OUTOFMEMORY; @@ -577,18 +686,6 @@ HRESULT WINAPI PropVariantChangeType(PROPVARIANT *ppropvarDest, REFPROPVARIANT p return E_FAIL; } } - -static void PROPVAR_GUIDToWSTR(REFGUID guid, WCHAR *str) -{ - static const WCHAR format[] = {'{','%','0','8','X','-','%','0','4','X','-','%','0','4','X', - '-','%','0','2','X','%','0','2','X','-','%','0','2','X','%','0','2','X','%','0','2','X', - '%','0','2','X','%','0','2','X','%','0','2','X','}',0}; - - swprintf(str, format, guid->Data1, guid->Data2, guid->Data3, - guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3], - guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7]); -} - HRESULT WINAPI InitPropVariantFromGUIDAsString(REFGUID guid, PROPVARIANT *ppropvar) { TRACE("(%p %p)\n", guid, ppropvar); @@ -597,11 +694,11 @@ HRESULT WINAPI InitPropVariantFromGUIDAsString(REFGUID guid, PROPVARIANT *ppropv return E_FAIL; ppropvar->vt = VT_LPWSTR; - ppropvar->u.pwszVal = CoTaskMemAlloc(39*sizeof(WCHAR)); - if(!ppropvar->u.pwszVal) + ppropvar->pwszVal = CoTaskMemAlloc((GUID_STR_LEN + 1) * sizeof(WCHAR)); + if(!ppropvar->pwszVal) return E_OUTOFMEMORY; - PROPVAR_GUIDToWSTR(guid, ppropvar->u.pwszVal); + StringFromGUID2(guid, ppropvar->pwszVal, GUID_STR_LEN + 1); return S_OK; } @@ -615,11 +712,11 @@ HRESULT WINAPI InitVariantFromGUIDAsString(REFGUID guid, VARIANT *pvar) } V_VT(pvar) = VT_BSTR; - V_BSTR(pvar) = SysAllocStringLen(NULL, 38); + V_BSTR(pvar) = SysAllocStringLen(NULL, GUID_STR_LEN); if(!V_BSTR(pvar)) return E_OUTOFMEMORY; - PROPVAR_GUIDToWSTR(guid, V_BSTR(pvar)); + StringFromGUID2(guid, V_BSTR(pvar), GUID_STR_LEN + 1); return S_OK; } @@ -627,13 +724,13 @@ HRESULT WINAPI InitPropVariantFromBuffer(const VOID *pv, UINT cb, PROPVARIANT *p { TRACE("(%p %u %p)\n", pv, cb, ppropvar); - ppropvar->u.caub.pElems = CoTaskMemAlloc(cb); - if(!ppropvar->u.caub.pElems) + ppropvar->caub.pElems = CoTaskMemAlloc(cb); + if(!ppropvar->caub.pElems) return E_OUTOFMEMORY; ppropvar->vt = VT_VECTOR|VT_UI1; - ppropvar->u.caub.cElems = cb; - memcpy(ppropvar->u.caub.pElems, pv, cb); + ppropvar->caub.cElems = cb; + memcpy(ppropvar->caub.pElems, pv, cb); return S_OK; } @@ -641,12 +738,44 @@ HRESULT WINAPI InitPropVariantFromCLSID(REFCLSID clsid, PROPVARIANT *ppropvar) { TRACE("(%s %p)\n", debugstr_guid(clsid), ppropvar); - ppropvar->u.puuid = CoTaskMemAlloc(sizeof(*ppropvar->u.puuid)); - if(!ppropvar->u.puuid) + ppropvar->puuid = CoTaskMemAlloc(sizeof(*ppropvar->puuid)); + if(!ppropvar->puuid) return E_OUTOFMEMORY; ppropvar->vt = VT_CLSID; - memcpy(ppropvar->u.puuid, clsid, sizeof(*ppropvar->u.puuid)); + memcpy(ppropvar->puuid, clsid, sizeof(*ppropvar->puuid)); + return S_OK; +} + +HRESULT WINAPI InitPropVariantFromStringVector(PCWSTR *strs, ULONG count, PROPVARIANT *ppropvar) +{ + unsigned int i; + + TRACE("(%p %lu %p)\n", strs, count, ppropvar); + + ppropvar->calpwstr.pElems = CoTaskMemAlloc(count * sizeof(*ppropvar->calpwstr.pElems)); + if(!ppropvar->calpwstr.pElems) + return E_OUTOFMEMORY; + + ppropvar->vt = VT_LPWSTR | VT_VECTOR; + ppropvar->calpwstr.cElems = 0; + if (count) + memset(ppropvar->calpwstr.pElems, 0, count * sizeof(*ppropvar->calpwstr.pElems)); + + for (i = 0; i < count; ++i) + { + if (strs[i]) + { + if (!(ppropvar->calpwstr.pElems[i] = CoTaskMemAlloc((wcslen(strs[i]) + 1)*sizeof(**strs)))) + { + PropVariantClear(ppropvar); + return E_OUTOFMEMORY; + } + } + wcscpy(ppropvar->calpwstr.pElems[i], strs[i]); + ppropvar->calpwstr.cElems++; + } + return S_OK; } @@ -681,6 +810,21 @@ HRESULT WINAPI InitVariantFromBuffer(const VOID *pv, UINT cb, VARIANT *pvar) return S_OK; } +HRESULT WINAPI InitVariantFromFileTime(const FILETIME *ft, VARIANT *var) +{ + SYSTEMTIME st; + + TRACE("%p, %p\n", ft, var); + + VariantInit(var); + if (!FileTimeToSystemTime(ft, &st)) + return E_INVALIDARG; + if (!SystemTimeToVariantTime(&st, &V_DATE(var))) + return E_INVALIDARG; + V_VT(var) = VT_DATE; + return S_OK; +} + static inline DWORD PROPVAR_HexToNum(const WCHAR *hex) { DWORD ret; @@ -759,11 +903,11 @@ HRESULT WINAPI PropVariantToGUID(const PROPVARIANT *ppropvar, GUID *guid) switch(ppropvar->vt) { case VT_BSTR: - return PROPVAR_WCHARToGUID(ppropvar->u.bstrVal, SysStringLen(ppropvar->u.bstrVal), guid); + return PROPVAR_WCHARToGUID(ppropvar->bstrVal, SysStringLen(ppropvar->bstrVal), guid); case VT_LPWSTR: - return PROPVAR_WCHARToGUID(ppropvar->u.pwszVal, lstrlenW(ppropvar->u.pwszVal), guid); + return PROPVAR_WCHARToGUID(ppropvar->pwszVal, lstrlenW(ppropvar->pwszVal), guid); case VT_CLSID: - memcpy(guid, ppropvar->u.puuid, sizeof(*ppropvar->u.puuid)); + memcpy(guid, ppropvar->puuid, sizeof(*ppropvar->puuid)); return S_OK; default: @@ -797,17 +941,20 @@ static BOOL isemptyornull(const PROPVARIANT *propvar) if ((propvar->vt & VT_ARRAY) == VT_ARRAY) { int i; - for (i=0; iu.parray->cDims; i++) + for (i=0; iparray->cDims; i++) { - if (propvar->u.parray->rgsabound[i].cElements != 0) + if (propvar->parray->rgsabound[i].cElements != 0) break; } - return i == propvar->u.parray->cDims; + return i == propvar->parray->cDims; } if (propvar->vt == VT_CLSID) - return !propvar->u.puuid; + return !propvar->puuid; - /* FIXME: vectors, byrefs, errors? */ + if (propvar->vt & VT_VECTOR) + return !propvar->caub.cElems; + + /* FIXME: byrefs, errors? */ return FALSE; } @@ -816,6 +963,7 @@ INT WINAPI PropVariantCompareEx(REFPROPVARIANT propvar1, REFPROPVARIANT propvar2 { const PROPVARIANT *propvar2_converted; PROPVARIANT propvar2_static; + unsigned int count; HRESULT hr; INT res=-1; @@ -844,9 +992,9 @@ INT WINAPI PropVariantCompareEx(REFPROPVARIANT propvar1, REFPROPVARIANT propvar2 propvar2_converted = propvar2; #define CMP_NUM_VALUE(var) do { \ - if (propvar1->u.var > propvar2_converted->u.var) \ + if (propvar1->var > propvar2_converted->var) \ res = 1; \ - else if (propvar1->u.var < propvar2_converted->u.var) \ + else if (propvar1->var < propvar2_converted->var) \ res = -1; \ else \ res = 0; \ @@ -870,7 +1018,7 @@ INT WINAPI PropVariantCompareEx(REFPROPVARIANT propvar1, REFPROPVARIANT propvar2 CMP_NUM_VALUE(lVal); break; case VT_UI4: - CMP_NUM_VALUE(uiVal); + CMP_NUM_VALUE(ulVal); break; case VT_I8: CMP_NUM_VALUE(hVal.QuadPart); @@ -888,21 +1036,28 @@ INT WINAPI PropVariantCompareEx(REFPROPVARIANT propvar1, REFPROPVARIANT propvar2 case VT_LPWSTR: /* FIXME: Use other string flags. */ if (flags & (PVCF_USESTRCMPI | PVCF_USESTRCMPIC)) - res = lstrcmpiW(propvar1->u.bstrVal, propvar2_converted->u.bstrVal); + res = lstrcmpiW(propvar1->bstrVal, propvar2_converted->bstrVal); else - res = lstrcmpW(propvar1->u.bstrVal, propvar2_converted->u.bstrVal); + res = lstrcmpW(propvar1->bstrVal, propvar2_converted->bstrVal); break; case VT_LPSTR: /* FIXME: Use other string flags. */ if (flags & (PVCF_USESTRCMPI | PVCF_USESTRCMPIC)) - res = lstrcmpiA(propvar1->u.pszVal, propvar2_converted->u.pszVal); + res = lstrcmpiA(propvar1->pszVal, propvar2_converted->pszVal); else - res = lstrcmpA(propvar1->u.pszVal, propvar2_converted->u.pszVal); + res = lstrcmpA(propvar1->pszVal, propvar2_converted->pszVal); break; case VT_CLSID: - res = memcmp(propvar1->u.puuid, propvar2->u.puuid, sizeof(*propvar1->u.puuid)); + res = memcmp(propvar1->puuid, propvar2->puuid, sizeof(*propvar1->puuid)); if (res) res = res > 0 ? 1 : -1; break; + case VT_VECTOR | VT_UI1: + count = min(propvar1->caub.cElems, propvar2->caub.cElems); + res = count ? memcmp(propvar1->caub.pElems, propvar2->caub.pElems, sizeof(*propvar1->caub.pElems) * count) : 0; + if (res) res = res > 0 ? 1 : -1; + if (!res && propvar1->caub.cElems != propvar2->caub.cElems) + res = propvar1->caub.cElems > propvar2->caub.cElems ? 1 : -1; + break; default: FIXME("vartype %#x not handled\n", propvar1->vt); res = -1; @@ -914,3 +1069,158 @@ INT WINAPI PropVariantCompareEx(REFPROPVARIANT propvar1, REFPROPVARIANT propvar2 return res; } + +HRESULT WINAPI PropVariantToVariant(const PROPVARIANT *propvar, VARIANT *var) +{ + HRESULT hr = S_OK; + + TRACE("propvar %p, var %p, propvar->vt %#x.\n", propvar, var, propvar ? propvar->vt : 0); + + if (!var || !propvar) + return E_INVALIDARG; + + VariantInit(var); +#ifdef __REACTOS__ + V_VT(var) = propvar->vt; +#else + var->vt = propvar->vt; +#endif + + switch (propvar->vt) + { + case VT_EMPTY: + case VT_NULL: + break; + case VT_I1: + V_I1(var) = propvar->cVal; + break; + case VT_I2: + V_I2(var) = propvar->iVal; + break; + case VT_I4: + V_I4(var) = propvar->lVal; + break; + case VT_I8: + V_I8(var) = propvar->hVal.QuadPart; + break; + case VT_UI1: + V_UI1(var) = propvar->bVal; + break; + case VT_UI2: + V_UI2(var) = propvar->uiVal; + break; + case VT_UI4: + V_UI4(var) = propvar->ulVal; + break; + case VT_UI8: + V_UI8(var) = propvar->uhVal.QuadPart; + break; + case VT_BOOL: + V_BOOL(var) = propvar->boolVal; + break; + case VT_R4: + V_R4(var) = propvar->fltVal; + break; + case VT_R8: + V_R8(var) = propvar->dblVal; + break; + case VT_LPSTR: + case VT_LPWSTR: + case VT_BSTR: + case VT_CLSID: +#ifdef __REACTOS__ + V_VT(var) = VT_BSTR; +#else + var->vt = VT_BSTR; +#endif + hr = PropVariantToBSTR(propvar, &V_BSTR(var)); + break; + default: + FIXME("Unsupported type %d.\n", propvar->vt); + return E_INVALIDARG; + } + + return hr; +} + +HRESULT WINAPI VariantToPropVariant(const VARIANT *var, PROPVARIANT *propvar) +{ + HRESULT hr; + + TRACE("var %p, propvar %p.\n", debugstr_variant(var), propvar); + + if (!var || !propvar) + return E_INVALIDARG; + +#ifdef __REACTOS__ + if (FAILED(hr = VARIANT_ValidateType(V_VT(var)))) +#else + if (FAILED(hr = VARIANT_ValidateType(var->vt))) +#endif + return hr; + + PropVariantInit(propvar); + + +#ifdef __REACTOS__ + propvar->vt = V_VT(var); +#else + propvar->vt = var->vt; +#endif + +#ifdef __REACTOS__ + switch (V_VT(var)) +#else + switch (var->vt) +#endif + { + case VT_EMPTY: + case VT_NULL: + break; + case VT_I1: + propvar->cVal = V_I1(var); + break; + case VT_I2: + propvar->iVal = V_I2(var); + break; + case VT_I4: + propvar->lVal = V_I4(var); + break; + case VT_I8: + propvar->hVal.QuadPart = V_I8(var); + break; + case VT_UI1: + propvar->bVal = V_UI1(var); + break; + case VT_UI2: + propvar->uiVal = V_UI2(var); + break; + case VT_UI4: + propvar->ulVal = V_UI4(var); + break; + case VT_UI8: + propvar->uhVal.QuadPart = V_UI8(var); + break; + case VT_BOOL: + propvar->boolVal = V_BOOL(var); + break; + case VT_R4: + propvar->fltVal = V_R4(var); + break; + case VT_R8: + propvar->dblVal = V_R8(var); + break; + case VT_BSTR: + propvar->bstrVal = SysAllocString(V_BSTR(var)); + break; + default: +#ifdef __REACTOS__ + FIXME("Unsupported type %d.\n", V_VT(var)); +#else + FIXME("Unsupported type %d.\n", var->vt); +#endif + return E_INVALIDARG; + } + + return S_OK; +} diff --git a/media/doc/WINESYNC.txt b/media/doc/WINESYNC.txt index 203f7ae3333..2b000140713 100644 --- a/media/doc/WINESYNC.txt +++ b/media/doc/WINESYNC.txt @@ -160,7 +160,7 @@ dll/win32/pdh # Synced to WineStaging-4.18 dll/win32/pidgen # Synced to WineStaging-4.18 dll/win32/powrprof # Forked at Wine-1.0rc5 dll/win32/printui # Synced to WineStaging-4.18 -dll/win32/propsys # Synced to WineStaging-4.18 +dll/win32/propsys # Synced to Wine-10.0 dll/win32/pstorec # Synced to WineStaging-3.3 dll/win32/qmgr # Synced to WineStaging-4.18 dll/win32/qmgrprxy # Synced to WineStaging-2.9 diff --git a/modules/rostests/winetests/propsys/CMakeLists.txt b/modules/rostests/winetests/propsys/CMakeLists.txt index ac14259b769..a38b9654b9d 100644 --- a/modules/rostests/winetests/propsys/CMakeLists.txt +++ b/modules/rostests/winetests/propsys/CMakeLists.txt @@ -1,6 +1,7 @@ add_definitions(-DUSE_WINE_TODOS -DWINETEST_USE_DBGSTR_LONGLONG) -add_executable(propsys_winetest propstore.c propsys.c testlist.c) +remove_definitions(-D__ROS_LONG64__) +add_executable(propsys_winetest propsys.c testlist.c) set_module_type(propsys_winetest win32cui) add_importlibs(propsys_winetest propsys ole32 oleaut32 msvcrt kernel32) diff --git a/modules/rostests/winetests/propsys/propstore.c b/modules/rostests/winetests/propsys/propstore.c deleted file mode 100644 index 5aeb562cf27..00000000000 --- a/modules/rostests/winetests/propsys/propstore.c +++ /dev/null @@ -1,374 +0,0 @@ -/* - * Unit tests for IPropertyStore and related interfaces - * - * Copyright 2012 Vincent Povirk - * - * 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 - */ - -#define COBJMACROS - -#include -#include - -#define NONAMELESSUNION - -#include "windef.h" -#include "winbase.h" -#include "objbase.h" -#include "propsys.h" -#include "wine/test.h" - -#include "initguid.h" - -DEFINE_GUID(PKEY_WineTest, 0x7b317433, 0xdfa3, 0x4c44, 0xad, 0x3e, 0x2f, 0x80, 0x4b, 0x90, 0xdb, 0xf4); -DEFINE_GUID(DUMMY_GUID1, 0x12345678, 0x1234,0x1234, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19); - -#define EXPECT_REF(obj,ref) _expect_ref((IUnknown *)obj, ref, __LINE__) -static void _expect_ref(IUnknown *obj, ULONG ref, int line) -{ - ULONG rc; - IUnknown_AddRef(obj); - rc = IUnknown_Release(obj); - ok_(__FILE__,line)(rc == ref, "expected refcount %d, got %d\n", ref, rc); -} - -static void test_inmemorystore(void) -{ - IPropertyStoreCache *propcache; - HRESULT hr; - PROPERTYKEY pkey; - PROPVARIANT propvar; - DWORD count; - PSC_STATE state; - - hr = CoCreateInstance(&CLSID_InMemoryPropertyStore, NULL, CLSCTX_INPROC_SERVER, - &IID_IPropertyStoreCache, (void**)&propcache); - ok(hr == S_OK, "CoCreateInstance failed, hr=%x\n", hr); - - if (FAILED(hr)) - { - skip("CLSID_InMemoryPropertyStore not supported\n"); - return; - } - - hr = IPropertyStoreCache_GetCount(propcache, NULL); - ok(hr == E_POINTER, "GetCount failed, hr=%x\n", hr); - - hr = IPropertyStoreCache_GetCount(propcache, &count); - ok(hr == S_OK, "GetCount failed, hr=%x\n", hr); - ok(count == 0, "GetCount returned %i, expected 0\n", count); - - hr = IPropertyStoreCache_Commit(propcache); - ok(hr == S_OK, "Commit failed, hr=%x\n", hr); - - hr = IPropertyStoreCache_Commit(propcache); - ok(hr == S_OK, "Commit failed, hr=%x\n", hr); - - hr = IPropertyStoreCache_GetAt(propcache, 0, &pkey); - ok(hr == E_INVALIDARG, "GetAt failed, hr=%x\n", hr); - - pkey.fmtid = PKEY_WineTest; - pkey.pid = 4; - - memset(&propvar, 0, sizeof(propvar)); - propvar.vt = VT_I4; - propvar.u.lVal = 12345; - - if (0) - { - /* Crashes on Windows 7 */ - hr = IPropertyStoreCache_SetValue(propcache, NULL, &propvar); - ok(hr == E_POINTER, "SetValue failed, hr=%x\n", hr); - - hr = IPropertyStoreCache_SetValue(propcache, &pkey, NULL); - ok(hr == E_POINTER, "SetValue failed, hr=%x\n", hr); - } - - hr = IPropertyStoreCache_SetValue(propcache, &pkey, &propvar); - ok(hr == S_OK, "SetValue failed, hr=%x\n", hr); - - hr = IPropertyStoreCache_GetCount(propcache, &count); - ok(hr == S_OK, "GetCount failed, hr=%x\n", hr); - ok(count == 1, "GetCount returned %i, expected 0\n", count); - - memset(&pkey, 0, sizeof(pkey)); - - hr = IPropertyStoreCache_GetAt(propcache, 0, &pkey); - ok(hr == S_OK, "GetAt failed, hr=%x\n", hr); - ok(IsEqualGUID(&pkey.fmtid, &PKEY_WineTest), "got wrong pkey\n"); - ok(pkey.pid == 4, "got pid of %i, expected 4\n", pkey.pid); - - pkey.fmtid = PKEY_WineTest; - pkey.pid = 4; - - memset(&propvar, 0, sizeof(propvar)); - - if (0) - { - /* Crashes on Windows 7 */ - hr = IPropertyStoreCache_GetValue(propcache, NULL, &propvar); - ok(hr == E_POINTER, "GetValue failed, hr=%x\n", hr); - } - - hr = IPropertyStoreCache_GetValue(propcache, &pkey, NULL); - ok(hr == E_POINTER, "GetValue failed, hr=%x\n", hr); - - hr = IPropertyStoreCache_GetValue(propcache, &pkey, &propvar); - ok(hr == S_OK, "GetValue failed, hr=%x\n", hr); - ok(propvar.vt == VT_I4, "expected VT_I4, got %d\n", propvar.vt); - ok(propvar.u.lVal == 12345, "expected 12345, got %d\n", propvar.u.lVal); - - pkey.fmtid = PKEY_WineTest; - pkey.pid = 10; - - /* Get information for field that isn't set yet */ - propvar.vt = VT_I2; - hr = IPropertyStoreCache_GetValue(propcache, &pkey, &propvar); - ok(hr == S_OK, "GetValue failed, hr=%x\n", hr); - ok(propvar.vt == VT_EMPTY, "expected VT_EMPTY, got %d\n", propvar.vt); - - state = 0xdeadbeef; - hr = IPropertyStoreCache_GetState(propcache, &pkey, &state); - ok(hr == TYPE_E_ELEMENTNOTFOUND, "GetState failed, hr=%x\n", hr); - ok(state == PSC_NORMAL, "expected PSC_NORMAL, got %d\n", state); - - propvar.vt = VT_I2; - state = 0xdeadbeef; - hr = IPropertyStoreCache_GetValueAndState(propcache, &pkey, &propvar, &state); - ok(hr == TYPE_E_ELEMENTNOTFOUND, "GetValueAndState failed, hr=%x\n", hr); - ok(propvar.vt == VT_EMPTY, "expected VT_EMPTY, got %d\n", propvar.vt); - ok(state == PSC_NORMAL, "expected PSC_NORMAL, got %d\n", state); - - /* Set state on an unset field */ - hr = IPropertyStoreCache_SetState(propcache, &pkey, PSC_NORMAL); - ok(hr == TYPE_E_ELEMENTNOTFOUND, "SetState failed, hr=%x\n", hr); - - /* Manipulate state on already set field */ - pkey.fmtid = PKEY_WineTest; - pkey.pid = 4; - - state = 0xdeadbeef; - hr = IPropertyStoreCache_GetState(propcache, &pkey, &state); - ok(hr == S_OK, "GetState failed, hr=%x\n", hr); - ok(state == PSC_NORMAL, "expected PSC_NORMAL, got %d\n", state); - - hr = IPropertyStoreCache_SetState(propcache, &pkey, 10); - ok(hr == S_OK, "SetState failed, hr=%x\n", hr); - - state = 0xdeadbeef; - hr = IPropertyStoreCache_GetState(propcache, &pkey, &state); - ok(hr == S_OK, "GetState failed, hr=%x\n", hr); - ok(state == 10, "expected 10, got %d\n", state); - - propvar.vt = VT_I4; - propvar.u.lVal = 12346; - hr = IPropertyStoreCache_SetValueAndState(propcache, &pkey, &propvar, 5); - ok(hr == S_OK, "SetValueAndState failed, hr=%x\n", hr); - - memset(&propvar, 0, sizeof(propvar)); - state = 0xdeadbeef; - hr = IPropertyStoreCache_GetValueAndState(propcache, &pkey, &propvar, &state); - ok(hr == S_OK, "GetValueAndState failed, hr=%x\n", hr); - ok(propvar.vt == VT_I4, "expected VT_I4, got %d\n", propvar.vt); - ok(propvar.u.lVal == 12346, "expected 12346, got %d\n", propvar.vt); - ok(state == 5, "expected 5, got %d\n", state); - - /* Set new field with state */ - pkey.fmtid = PKEY_WineTest; - pkey.pid = 8; - - propvar.vt = VT_I4; - propvar.u.lVal = 12347; - hr = IPropertyStoreCache_SetValueAndState(propcache, &pkey, &propvar, PSC_DIRTY); - ok(hr == S_OK, "SetValueAndState failed, hr=%x\n", hr); - - memset(&propvar, 0, sizeof(propvar)); - state = 0xdeadbeef; - hr = IPropertyStoreCache_GetValueAndState(propcache, &pkey, &propvar, &state); - ok(hr == S_OK, "GetValueAndState failed, hr=%x\n", hr); - ok(propvar.vt == VT_I4, "expected VT_I4, got %d\n", propvar.vt); - ok(propvar.u.lVal == 12347, "expected 12347, got %d\n", propvar.vt); - ok(state == PSC_DIRTY, "expected PSC_DIRTY, got %d\n", state); - - IPropertyStoreCache_Release(propcache); -} - -static void test_persistserialized(void) -{ - IPropertyStore *propstore; - IPersistSerializedPropStorage *serialized; - HRESULT hr; - SERIALIZEDPROPSTORAGE *result; - DWORD result_size; - - hr = CoCreateInstance(&CLSID_InMemoryPropertyStore, NULL, CLSCTX_INPROC_SERVER, - &IID_IPropertyStore, (void**)&propstore); - ok(hr == S_OK, "CoCreateInstance failed, hr=%x\n", hr); - - hr = IPropertyStore_QueryInterface(propstore, &IID_IPersistSerializedPropStorage, - (void**)&serialized); - todo_wine ok(hr == S_OK, "QueryInterface failed, hr=%x\n", hr); - - if (FAILED(hr)) - { - IPropertyStore_Release(propstore); - skip("IPersistSerializedPropStorage not supported\n"); - return; - } - - hr = IPersistSerializedPropStorage_GetPropertyStorage(serialized, NULL, &result_size); - ok(hr == E_POINTER, "GetPropertyStorage failed, hr=%x\n", hr); - - hr = IPersistSerializedPropStorage_GetPropertyStorage(serialized, &result, NULL); - ok(hr == E_POINTER, "GetPropertyStorage failed, hr=%x\n", hr); - - hr = IPersistSerializedPropStorage_GetPropertyStorage(serialized, &result, &result_size); - ok(hr == S_OK, "GetPropertyStorage failed, hr=%x\n", hr); - - if (SUCCEEDED(hr)) - { - ok(result_size == 0, "expected 0 bytes, got %i\n", result_size); - - CoTaskMemFree(result); - } - - hr = IPersistSerializedPropStorage_SetPropertyStorage(serialized, NULL, 4); - ok(hr == E_POINTER, "SetPropertyStorage failed, hr=%x\n", hr); - - hr = IPersistSerializedPropStorage_SetPropertyStorage(serialized, NULL, 0); - ok(hr == S_OK, "SetPropertyStorage failed, hr=%x\n", hr); - - hr = IPropertyStore_GetCount(propstore, &result_size); - ok(hr == S_OK, "GetCount failed, hr=%x\n", hr); - ok(result_size == 0, "expecting 0, got %d\n", result_size); - - IPropertyStore_Release(propstore); - IPersistSerializedPropStorage_Release(serialized); -} - -static void test_PSCreateMemoryPropertyStore(void) -{ - IPropertyStore *propstore, *propstore1; - IPersistSerializedPropStorage *serialized; - IPropertyStoreCache *propstorecache; - HRESULT hr; - - /* PSCreateMemoryPropertyStore(&IID_IPropertyStore, NULL); crashes */ - - hr = PSCreateMemoryPropertyStore(&IID_IPropertyStore, (void **)&propstore); - ok(hr == S_OK, "PSCreateMemoryPropertyStore failed: 0x%08x.\n", hr); - ok(propstore != NULL, "got %p.\n", propstore); - EXPECT_REF(propstore, 1); - - hr = PSCreateMemoryPropertyStore(&IID_IPersistSerializedPropStorage, (void **)&serialized); - todo_wine ok(hr == S_OK, "PSCreateMemoryPropertyStore failed: 0x%08x.\n", hr); - todo_wine ok(serialized != NULL, "got %p.\n", serialized); - EXPECT_REF(propstore, 1); - if(serialized) - { - EXPECT_REF(serialized, 1); - IPersistSerializedPropStorage_Release(serialized); - } - - hr = PSCreateMemoryPropertyStore(&IID_IPropertyStoreCache, (void **)&propstorecache); - ok(hr == S_OK, "PSCreateMemoryPropertyStore failed: 0x%08x.\n", hr); - ok(propstorecache != NULL, "got %p.\n", propstore); - ok(propstorecache != (IPropertyStoreCache *)propstore, "pointer are equal: %p, %p.\n", propstorecache, propstore); - EXPECT_REF(propstore, 1); - EXPECT_REF(propstorecache, 1); - - hr = PSCreateMemoryPropertyStore(&IID_IPropertyStore, (void **)&propstore1); - ok(hr == S_OK, "PSCreateMemoryPropertyStore failed: 0x%08x.\n", hr); - ok(propstore1 != NULL, "got %p.\n", propstore); - ok(propstore1 != propstore, "pointer are equal: %p, %p.\n", propstore1, propstore); - EXPECT_REF(propstore, 1); - EXPECT_REF(propstore1, 1); - EXPECT_REF(propstorecache, 1); - - IPropertyStore_Release(propstore1); - IPropertyStore_Release(propstore); - IPropertyStoreCache_Release(propstorecache); -} - -static void test_propertystore(void) -{ - IPropertyStore *propstore; - HRESULT hr; - PROPVARIANT propvar, ret_propvar; - PROPERTYKEY propkey; - DWORD count = 0; - - hr = PSCreateMemoryPropertyStore(&IID_IPropertyStore, (void **)&propstore); - ok(hr == S_OK, "PSCreateMemoryPropertyStore failed: 0x%08x.\n", hr); - ok(propstore != NULL, "got %p.\n", propstore); - - hr = IPropertyStore_GetCount(propstore, &count); - ok(hr == S_OK, "IPropertyStore_GetCount failed: 0x%08x.\n", hr); - ok(!count, "got wrong property count: %d, expected 0.\n", count); - - PropVariantInit(&propvar); - propvar.vt = VT_I4; - U(propvar).lVal = 123; - propkey.fmtid = DUMMY_GUID1; - propkey.pid = PID_FIRST_USABLE; - hr = IPropertyStore_SetValue(propstore, &propkey, &propvar); - ok(hr == S_OK, "IPropertyStore_SetValue failed: 0x%08x.\n", hr); - hr = IPropertyStore_Commit(propstore); - ok(hr == S_OK, "IPropertyStore_Commit failed: 0x%08x.\n", hr); - hr = IPropertyStore_GetCount(propstore, &count); - ok(hr == S_OK, "IPropertyStore_GetCount failed: 0x%08x.\n", hr); - ok(count == 1, "got wrong property count: %d, expected 1.\n", count); - PropVariantInit(&ret_propvar); - ret_propvar.vt = VT_I4; - hr = IPropertyStore_GetValue(propstore, &propkey, &ret_propvar); - ok(hr == S_OK, "IPropertyStore_GetValue failed: 0x%08x.\n", hr); - ok(ret_propvar.vt == VT_I4, "got wrong property type: %x.\n", ret_propvar.vt); - ok(U(ret_propvar).lVal == 123, "got wrong value: %d, expected 123.\n", U(ret_propvar).lVal); - PropVariantClear(&propvar); - PropVariantClear(&ret_propvar); - - PropVariantInit(&propvar); - propkey.fmtid = DUMMY_GUID1; - propkey.pid = PID_FIRST_USABLE; - hr = IPropertyStore_SetValue(propstore, &propkey, &propvar); - ok(hr == S_OK, "IPropertyStore_SetValue failed: 0x%08x.\n", hr); - hr = IPropertyStore_Commit(propstore); - ok(hr == S_OK, "IPropertyStore_Commit failed: 0x%08x.\n", hr); - hr = IPropertyStore_GetCount(propstore, &count); - ok(hr == S_OK, "IPropertyStore_GetCount failed: 0x%08x.\n", hr); - ok(count == 1, "got wrong property count: %d, expected 1.\n", count); - PropVariantInit(&ret_propvar); - hr = IPropertyStore_GetValue(propstore, &propkey, &ret_propvar); - ok(hr == S_OK, "IPropertyStore_GetValue failed: 0x%08x.\n", hr); - ok(ret_propvar.vt == VT_EMPTY, "got wrong property type: %x.\n", ret_propvar.vt); - ok(!U(ret_propvar).lVal, "got wrong value: %d, expected 0.\n", U(ret_propvar).lVal); - PropVariantClear(&propvar); - PropVariantClear(&ret_propvar); - - IPropertyStore_Release(propstore); -} - -START_TEST(propstore) -{ - CoInitialize(NULL); - - test_inmemorystore(); - test_persistserialized(); - test_PSCreateMemoryPropertyStore(); - test_propertystore(); - - CoUninitialize(); -} diff --git a/modules/rostests/winetests/propsys/propsys.c b/modules/rostests/winetests/propsys/propsys.c index 77ffe05f6d9..d63b9ddd3b2 100644 --- a/modules/rostests/winetests/propsys/propsys.c +++ b/modules/rostests/winetests/propsys/propsys.c @@ -3,6 +3,7 @@ * * Copyright 2006 Paul Vriens * Copyright 2010 Andrew Nguyen + * Copyright 2012 Vincent Povirk * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -24,12 +25,10 @@ #include #include -#define NONAMELESSUNION - #include "windef.h" #include "winbase.h" -#include "objbase.h" #include "initguid.h" +#include "objbase.h" #include "propsys.h" #include "propvarutil.h" #include "strsafe.h" @@ -38,18 +37,23 @@ DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0); DEFINE_GUID(dummy_guid, 0xdeadbeef, 0xdead, 0xbeef, 0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe, 0xba, 0xbe); DEFINE_GUID(expect_guid, 0x12345678, 0x1234, 0x1234, 0x12, 0x34, 0x12, 0x34, 0x56, 0x78, 0x90, 0x12); +DEFINE_GUID(PKEY_WineTest, 0x7b317433, 0xdfa3, 0x4c44, 0xad, 0x3e, 0x2f, 0x80, 0x4b, 0x90, 0xdb, 0xf4); +DEFINE_GUID(DUMMY_GUID1, 0x12345678, 0x1234,0x1234, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19); #define GUID_MEMBERS(g) {(g).Data1, (g).Data2, (g).Data3, {(g).Data4[0], (g).Data4[1], (g).Data4[2], (g).Data4[3], (g).Data4[4], (g).Data4[5], (g).Data4[6], (g).Data4[7]}} static const char topic[] = "wine topic"; static const WCHAR topicW[] = {'w','i','n','e',' ','t','o','p','i','c',0}; static const WCHAR emptyW[] = {0}; +static const WCHAR dummy_guid_str[] = L"{DEADBEEF-DEAD-BEEF-DEAD-BEEFCAFEBABE}"; -static int strcmp_wa(LPCWSTR strw, const char *stra) +#define EXPECT_REF(obj,ref) _expect_ref((IUnknown *)obj, ref, __LINE__) +static void _expect_ref(IUnknown *obj, ULONG ref, int line) { - CHAR buf[512]; - WideCharToMultiByte(CP_ACP, 0, strw, -1, buf, sizeof(buf), NULL, NULL); - return lstrcmpA(stra, buf); + ULONG rc; + IUnknown_AddRef(obj); + rc = IUnknown_Release(obj); + ok_(__FILE__,line)(rc == ref, "expected refcount %ld, got %ld\n", ref, rc); } static void test_PSStringFromPropertyKey(void) @@ -144,7 +148,7 @@ static void test_PSStringFromPropertyKey(void) testcases[i].cch); ok(ret == testcases[i].hr_expect || broken(testcases[i].hr_broken && ret == testcases[i].hr2), /* Vista/Win2k8 */ - "[%d] Expected PSStringFromPropertyKey to return 0x%08x, got 0x%08x\n", + "[%d] Expected PSStringFromPropertyKey to return 0x%08lx, got 0x%08lx\n", i, testcases[i].hr_expect, ret); if (testcases[i].psz) @@ -334,6 +338,9 @@ static void test_PSPropertyKeyFromString(void) static const WCHAR fmtid_normalpidW[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-', '1','2','3','4','-','1','2','3','4','-', '1','2','3','4','5','6','7','8','9','0','1','2','}',' ','1','3','5','7','9',0}; + static const WCHAR fmtid_udigitW[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-', + '1','2','3','4','-','1','2','3','4','-', + '1','2','3','4','5','6','7','8','9','0','1','2','}',' ','1','2','3',0x661,'5','7','9',0}; PROPERTYKEY out_init = {GUID_MEMBERS(dummy_guid), 0xdeadbeef}; PROPERTYKEY out; HRESULT ret; @@ -410,6 +417,7 @@ static void test_PSPropertyKeyFromString(void) {fmtid_commanegspcpidW, &out, S_OK, {GUID_MEMBERS(expect_guid), 0U}}, {fmtid_negcommapidW, &out, S_OK, {GUID_MEMBERS(expect_guid), 0}}, {fmtid_normalpidW, &out, S_OK, {GUID_MEMBERS(expect_guid), 13579}}, + {fmtid_udigitW, &out, S_OK, {GUID_MEMBERS(expect_guid), 123}}, }; int i; @@ -421,7 +429,7 @@ static void test_PSPropertyKeyFromString(void) ret = PSPropertyKeyFromString(testcases[i].pwzString, testcases[i].pkey); ok(ret == testcases[i].hr_expect, - "[%d] Expected PSPropertyKeyFromString to return 0x%08x, got 0x%08x\n", + "[%d] Expected PSPropertyKeyFromString to return 0x%08lx, got 0x%08lx\n", i, testcases[i].hr_expect, ret); if (testcases[i].pkey) @@ -430,7 +438,7 @@ static void test_PSPropertyKeyFromString(void) "[%d] Expected GUID %s, got %s\n", i, wine_dbgstr_guid(&testcases[i].pkey_expect.fmtid), wine_dbgstr_guid(&testcases[i].pkey->fmtid)); ok(testcases[i].pkey->pid == testcases[i].pkey_expect.pid, - "[%d] Expected property ID %u, got %u\n", + "[%d] Expected property ID %lu, got %lu\n", i, testcases[i].pkey_expect.pid, testcases[i].pkey->pid); } } @@ -443,13 +451,13 @@ static void test_PSRefreshPropertySchema(void) ret = PSRefreshPropertySchema(); todo_wine ok(ret == CO_E_NOTINITIALIZED, - "Expected PSRefreshPropertySchema to return CO_E_NOTINITIALIZED, got 0x%08x\n", ret); + "Expected PSRefreshPropertySchema to return CO_E_NOTINITIALIZED, got 0x%08lx\n", ret); CoInitialize(NULL); ret = PSRefreshPropertySchema(); ok(ret == S_OK, - "Expected PSRefreshPropertySchema to return S_OK, got 0x%08x\n", ret); + "Expected PSRefreshPropertySchema to return S_OK, got 0x%08lx\n", ret); CoUninitialize(); } @@ -463,14 +471,14 @@ static void test_InitPropVariantFromGUIDAsString(void) const struct { REFGUID guid; - const char *str; + const WCHAR *str; } testcases[] = { - {&IID_NULL, "{00000000-0000-0000-0000-000000000000}" }, - {&dummy_guid, "{DEADBEEF-DEAD-BEEF-DEAD-BEEFCAFEBABE}" }, + {&IID_NULL, L"{00000000-0000-0000-0000-000000000000}" }, + {&dummy_guid, dummy_guid_str }, }; hres = InitPropVariantFromGUIDAsString(NULL, &propvar); - ok(hres == E_FAIL, "InitPropVariantFromGUIDAsString returned %x\n", hres); + ok(hres == E_FAIL, "InitPropVariantFromGUIDAsString returned %lx\n", hres); if(0) { /* Returns strange data on Win7, crashes on older systems */ @@ -484,19 +492,19 @@ static void test_InitPropVariantFromGUIDAsString(void) for(i=0; i < ARRAY_SIZE(testcases); i++) { memset(&propvar, 0, sizeof(PROPVARIANT)); hres = InitPropVariantFromGUIDAsString(testcases[i].guid, &propvar); - ok(hres == S_OK, "%d) InitPropVariantFromGUIDAsString returned %x\n", i, hres); + ok(hres == S_OK, "%d) InitPropVariantFromGUIDAsString returned %lx\n", i, hres); ok(propvar.vt == VT_LPWSTR, "%d) propvar.vt = %d\n", i, propvar.vt); - ok(!strcmp_wa(propvar.u.pwszVal, testcases[i].str), "%d) propvar.u.pwszVal = %s\n", - i, wine_dbgstr_w(propvar.u.pwszVal)); - CoTaskMemFree(propvar.u.pwszVal); + ok(!lstrcmpW(propvar.pwszVal, testcases[i].str), "%d) propvar.pwszVal = %s\n", + i, wine_dbgstr_w(propvar.pwszVal)); + CoTaskMemFree(propvar.pwszVal); memset(&var, 0, sizeof(VARIANT)); hres = InitVariantFromGUIDAsString(testcases[i].guid, &var); - ok(hres == S_OK, "%d) InitVariantFromGUIDAsString returned %x\n", i, hres); + ok(hres == S_OK, "%d) InitVariantFromGUIDAsString returned %lx\n", i, hres); ok(V_VT(&var) == VT_BSTR, "%d) V_VT(&var) = %d\n", i, V_VT(&var)); ok(SysStringLen(V_BSTR(&var)) == 38, "SysStringLen returned %d\n", SysStringLen(V_BSTR(&var))); - ok(!strcmp_wa(V_BSTR(&var), testcases[i].str), "%d) V_BSTR(&var) = %s\n", + ok(!lstrcmpW(V_BSTR(&var), testcases[i].str), "%d) V_BSTR(&var) = %s\n", i, wine_dbgstr_w(V_BSTR(&var))); VariantClear(&var); } @@ -512,47 +520,47 @@ static void test_InitPropVariantFromBuffer(void) LONG size; hres = InitPropVariantFromBuffer(NULL, 0, &propvar); - ok(hres == S_OK, "InitPropVariantFromBuffer returned %x\n", hres); + ok(hres == S_OK, "InitPropVariantFromBuffer returned %lx\n", hres); ok(propvar.vt == (VT_VECTOR|VT_UI1), "propvar.vt = %d\n", propvar.vt); - ok(propvar.u.caub.cElems == 0, "cElems = %d\n", propvar.u.caub.cElems == 0); + ok(propvar.caub.cElems == 0, "cElems = %d\n", propvar.caub.cElems == 0); PropVariantClear(&propvar); hres = InitPropVariantFromBuffer(data_in, 4, &propvar); - ok(hres == S_OK, "InitPropVariantFromBuffer returned %x\n", hres); + ok(hres == S_OK, "InitPropVariantFromBuffer returned %lx\n", hres); ok(propvar.vt == (VT_VECTOR|VT_UI1), "propvar.vt = %d\n", propvar.vt); - ok(propvar.u.caub.cElems == 4, "cElems = %d\n", propvar.u.caub.cElems == 0); - ok(!memcmp(propvar.u.caub.pElems, data_in, 4), "Data inside array is incorrect\n"); + ok(propvar.caub.cElems == 4, "cElems = %d\n", propvar.caub.cElems == 0); + ok(!memcmp(propvar.caub.pElems, data_in, 4), "Data inside array is incorrect\n"); PropVariantClear(&propvar); hres = InitVariantFromBuffer(NULL, 0, &var); - ok(hres == S_OK, "InitVariantFromBuffer returned %x\n", hres); + ok(hres == S_OK, "InitVariantFromBuffer returned %lx\n", hres); ok(V_VT(&var) == (VT_ARRAY|VT_UI1), "V_VT(&var) = %d\n", V_VT(&var)); size = SafeArrayGetDim(V_ARRAY(&var)); - ok(size == 1, "SafeArrayGetDim returned %d\n", size); + ok(size == 1, "SafeArrayGetDim returned %ld\n", size); hres = SafeArrayGetLBound(V_ARRAY(&var), 1, &size); - ok(hres == S_OK, "SafeArrayGetLBound returned %x\n", hres); - ok(size == 0, "LBound = %d\n", size); + ok(hres == S_OK, "SafeArrayGetLBound returned %lx\n", hres); + ok(size == 0, "LBound = %ld\n", size); hres = SafeArrayGetUBound(V_ARRAY(&var), 1, &size); - ok(hres == S_OK, "SafeArrayGetUBound returned %x\n", hres); - ok(size == -1, "UBound = %d\n", size); + ok(hres == S_OK, "SafeArrayGetUBound returned %lx\n", hres); + ok(size == -1, "UBound = %ld\n", size); VariantClear(&var); hres = InitVariantFromBuffer(data_in, 4, &var); - ok(hres == S_OK, "InitVariantFromBuffer returned %x\n", hres); + ok(hres == S_OK, "InitVariantFromBuffer returned %lx\n", hres); ok(V_VT(&var) == (VT_ARRAY|VT_UI1), "V_VT(&var) = %d\n", V_VT(&var)); size = SafeArrayGetDim(V_ARRAY(&var)); - ok(size == 1, "SafeArrayGetDim returned %d\n", size); + ok(size == 1, "SafeArrayGetDim returned %ld\n", size); hres = SafeArrayGetLBound(V_ARRAY(&var), 1, &size); - ok(hres == S_OK, "SafeArrayGetLBound returned %x\n", hres); - ok(size == 0, "LBound = %d\n", size); + ok(hres == S_OK, "SafeArrayGetLBound returned %lx\n", hres); + ok(size == 0, "LBound = %ld\n", size); hres = SafeArrayGetUBound(V_ARRAY(&var), 1, &size); - ok(hres == S_OK, "SafeArrayGetUBound returned %x\n", hres); - ok(size == 3, "UBound = %d\n", size); + ok(hres == S_OK, "SafeArrayGetUBound returned %lx\n", hres); + ok(size == 3, "UBound = %ld\n", size); hres = SafeArrayAccessData(V_ARRAY(&var), &data_out); - ok(hres == S_OK, "SafeArrayAccessData failed %x\n", hres); + ok(hres == S_OK, "SafeArrayAccessData failed %lx\n", hres); ok(!memcmp(data_in, data_out, 4), "Data inside safe array is incorrect\n"); hres = SafeArrayUnaccessData(V_ARRAY(&var)); - ok(hres == S_OK, "SafeArrayUnaccessData failed %x\n", hres); + ok(hres == S_OK, "SafeArrayUnaccessData failed %lx\n", hres); VariantClear(&var); } @@ -564,67 +572,67 @@ static void test_PropVariantToGUID(void) HRESULT hres; hres = InitPropVariantFromGUIDAsString(&IID_NULL, &propvar); - ok(hres == S_OK, "InitPropVariantFromGUIDAsString failed %x\n", hres); + ok(hres == S_OK, "InitPropVariantFromGUIDAsString failed %lx\n", hres); hres = PropVariantToGUID(&propvar, &guid); - ok(hres == S_OK, "PropVariantToGUID failed %x\n", hres); + ok(hres == S_OK, "PropVariantToGUID failed %lx\n", hres); ok(IsEqualGUID(&IID_NULL, &guid), "incorrect GUID created: %s\n", wine_dbgstr_guid(&guid)); PropVariantClear(&propvar); hres = InitPropVariantFromGUIDAsString(&dummy_guid, &propvar); - ok(hres == S_OK, "InitPropVariantFromGUIDAsString failed %x\n", hres); + ok(hres == S_OK, "InitPropVariantFromGUIDAsString failed %lx\n", hres); hres = PropVariantToGUID(&propvar, &guid); - ok(hres == S_OK, "PropVariantToGUID failed %x\n", hres); + ok(hres == S_OK, "PropVariantToGUID failed %lx\n", hres); ok(IsEqualGUID(&dummy_guid, &guid), "incorrect GUID created: %s\n", wine_dbgstr_guid(&guid)); ok(propvar.vt == VT_LPWSTR, "incorrect PROPVARIANT type: %d\n", propvar.vt); - propvar.u.pwszVal[1] = 'd'; - propvar.u.pwszVal[2] = 'E'; - propvar.u.pwszVal[3] = 'a'; + propvar.pwszVal[1] = 'd'; + propvar.pwszVal[2] = 'E'; + propvar.pwszVal[3] = 'a'; hres = PropVariantToGUID(&propvar, &guid); - ok(hres == S_OK, "PropVariantToGUID failed %x\n", hres); + ok(hres == S_OK, "PropVariantToGUID failed %lx\n", hres); ok(IsEqualGUID(&dummy_guid, &guid), "incorrect GUID created: %s\n", wine_dbgstr_guid(&guid)); - propvar.u.pwszVal[1] = 'z'; + propvar.pwszVal[1] = 'z'; hres = PropVariantToGUID(&propvar, &guid); - ok(hres == E_INVALIDARG, "PropVariantToGUID returned %x\n", hres); + ok(hres == E_INVALIDARG, "PropVariantToGUID returned %lx\n", hres); PropVariantClear(&propvar); hres = InitVariantFromGUIDAsString(&IID_NULL, &var); - ok(hres == S_OK, "InitVariantFromGUIDAsString failed %x\n", hres); + ok(hres == S_OK, "InitVariantFromGUIDAsString failed %lx\n", hres); hres = VariantToGUID(&var, &guid); - ok(hres == S_OK, "VariantToGUID failed %x\n", hres); + ok(hres == S_OK, "VariantToGUID failed %lx\n", hres); ok(IsEqualGUID(&IID_NULL, &guid), "incorrect GUID created: %s\n", wine_dbgstr_guid(&guid)); VariantClear(&var); hres = InitVariantFromGUIDAsString(&dummy_guid, &var); - ok(hres == S_OK, "InitVariantFromGUIDAsString failed %x\n", hres); + ok(hres == S_OK, "InitVariantFromGUIDAsString failed %lx\n", hres); hres = VariantToGUID(&var, &guid); - ok(hres == S_OK, "VariantToGUID failed %x\n", hres); + ok(hres == S_OK, "VariantToGUID failed %lx\n", hres); ok(IsEqualGUID(&dummy_guid, &guid), "incorrect GUID created: %s\n", wine_dbgstr_guid(&guid)); ok(V_VT(&var) == VT_BSTR, "incorrect VARIANT type: %d\n", V_VT(&var)); V_BSTR(&var)[1] = 'z'; hres = VariantToGUID(&var, &guid); - ok(hres == E_FAIL, "VariantToGUID returned %x\n", hres); + ok(hres == E_FAIL, "VariantToGUID returned %lx\n", hres); V_BSTR(&var)[1] = 'd'; propvar.vt = V_VT(&var); - propvar.u.bstrVal = V_BSTR(&var); + propvar.bstrVal = V_BSTR(&var); V_VT(&var) = VT_EMPTY; hres = PropVariantToGUID(&propvar, &guid); - ok(hres == S_OK, "PropVariantToGUID failed %x\n", hres); + ok(hres == S_OK, "PropVariantToGUID failed %lx\n", hres); ok(IsEqualGUID(&dummy_guid, &guid), "incorrect GUID created: %s\n", wine_dbgstr_guid(&guid)); PropVariantClear(&propvar); memset(&guid, 0, sizeof(guid)); InitPropVariantFromCLSID(&dummy_guid, &propvar); hres = PropVariantToGUID(&propvar, &guid); - ok(hres == S_OK, "PropVariantToGUID failed %x\n", hres); + ok(hres == S_OK, "PropVariantToGUID failed %lx\n", hres); ok(IsEqualGUID(&dummy_guid, &guid), "incorrect GUID created: %s\n", wine_dbgstr_guid(&guid)); PropVariantClear(&propvar); } @@ -637,35 +645,46 @@ static void test_PropVariantToStringAlloc(void) prop.vt = VT_NULL; hres = PropVariantToStringAlloc(&prop, &str); - ok(hres == S_OK, "returned %x\n", hres); + ok(hres == S_OK, "returned %lx\n", hres); ok(!lstrcmpW(str, emptyW), "got %s\n", wine_dbgstr_w(str)); CoTaskMemFree(str); prop.vt = VT_LPSTR; - prop.u.pszVal = CoTaskMemAlloc(strlen(topic)+1); - strcpy(prop.u.pszVal, topic); + prop.pszVal = CoTaskMemAlloc(strlen(topic)+1); + strcpy(prop.pszVal, topic); hres = PropVariantToStringAlloc(&prop, &str); - ok(hres == S_OK, "returned %x\n", hres); + ok(hres == S_OK, "returned %lx\n", hres); ok(!lstrcmpW(str, topicW), "got %s\n", wine_dbgstr_w(str)); CoTaskMemFree(str); PropVariantClear(&prop); prop.vt = VT_EMPTY; hres = PropVariantToStringAlloc(&prop, &str); - ok(hres == S_OK, "returned %x\n", hres); + ok(hres == S_OK, "returned %lx\n", hres); ok(!lstrcmpW(str, emptyW), "got %s\n", wine_dbgstr_w(str)); CoTaskMemFree(str); + + prop.vt = VT_CLSID; + prop.puuid = (CLSID *)&dummy_guid; + hres = PropVariantToStringAlloc(&prop, &str); + ok(hres == S_OK, "PropVariantToStringAlloc returned %#lx.\n", hres); + ok(!wcscmp(str, dummy_guid_str), "Unexpected str %s.\n", debugstr_w(str)); + CoTaskMemFree(str); } -static void test_PropVariantCompare(void) +static void test_PropVariantCompareEx(void) { PROPVARIANT empty, null, emptyarray, i2_0, i2_2, i4_large, i4_largeneg, i4_2, str_2, str_02, str_b; PROPVARIANT clsid_null, clsid, clsid2, r4_0, r4_2, r8_0, r8_2; + PROPVARIANT ui4, ui4_large; + PROPVARIANT var1, var2; INT res; static const WCHAR str_2W[] = {'2', 0}; static const WCHAR str_02W[] = {'0', '2', 0}; static const WCHAR str_bW[] = {'b', 0}; SAFEARRAY emptysafearray; + unsigned char bytevector1[] = {1,2,3}; + unsigned char bytevector2[] = {4,5,6}; PropVariantInit(&empty); PropVariantInit(&null); @@ -681,7 +700,7 @@ static void test_PropVariantCompare(void) empty.vt = VT_EMPTY; null.vt = VT_NULL; emptyarray.vt = VT_ARRAY | VT_I4; - emptyarray.u.parray = &emptysafearray; + emptyarray.parray = &emptysafearray; emptysafearray.cDims = 1; emptysafearray.fFeatures = FADF_FIXEDSIZE; emptysafearray.cbElements = 4; @@ -690,35 +709,39 @@ static void test_PropVariantCompare(void) emptysafearray.rgsabound[0].cElements = 0; emptysafearray.rgsabound[0].lLbound = 0; i2_0.vt = VT_I2; - i2_0.u.iVal = 0; + i2_0.iVal = 0; i2_2.vt = VT_I2; - i2_2.u.iVal = 2; + i2_2.iVal = 2; i4_large.vt = VT_I4; - i4_large.u.lVal = 65536; + i4_large.lVal = 65536; i4_largeneg.vt = VT_I4; - i4_largeneg.u.lVal = -65536; + i4_largeneg.lVal = -65536; i4_2.vt = VT_I4; - i4_2.u.lVal = 2; + i4_2.lVal = 2; + ui4.vt = VT_UI4; + ui4.ulVal = 2; + ui4_large.vt = VT_UI4; + ui4_large.ulVal = 65536; str_2.vt = VT_BSTR; - str_2.u.bstrVal = SysAllocString(str_2W); + str_2.bstrVal = SysAllocString(str_2W); str_02.vt = VT_BSTR; - str_02.u.bstrVal = SysAllocString(str_02W); + str_02.bstrVal = SysAllocString(str_02W); str_b.vt = VT_BSTR; - str_b.u.bstrVal = SysAllocString(str_bW); + str_b.bstrVal = SysAllocString(str_bW); clsid_null.vt = VT_CLSID; - clsid_null.u.puuid = NULL; + clsid_null.puuid = NULL; clsid.vt = VT_CLSID; - clsid.u.puuid = (GUID *)&dummy_guid; + clsid.puuid = (GUID *)&dummy_guid; clsid2.vt = VT_CLSID; - clsid2.u.puuid = (GUID *)&GUID_NULL; + clsid2.puuid = (GUID *)&GUID_NULL; r4_0.vt = VT_R4; - r4_0.u.fltVal = 0.0f; + r4_0.fltVal = 0.0f; r4_2.vt = VT_R4; - r4_2.u.fltVal = 2.0f; + r4_2.fltVal = 2.0f; r8_0.vt = VT_R8; - r8_0.u.dblVal = 0.0; + r8_0.dblVal = 0.0; r8_2.vt = VT_R8; - r8_2.u.dblVal = 2.0; + r8_2.dblVal = 2.0; res = PropVariantCompareEx(&empty, &empty, 0, 0); ok(res == 0, "res=%i\n", res); @@ -747,6 +770,12 @@ static void test_PropVariantCompare(void) res = PropVariantCompareEx(&i2_0, &i2_2, 0, 0); ok(res == -1, "res=%i\n", res); + res = PropVariantCompareEx(&ui4, &ui4_large, 0, 0); + ok(res == -1, "res=%i\n", res); + + res = PropVariantCompareEx(&ui4_large, &ui4, 0, 0); + ok(res == 1, "res=%i\n", res); + /* Always return -1 if second value cannot be converted to first type */ res = PropVariantCompareEx(&i2_0, &i4_large, 0, 0); ok(res == -1, "res=%i\n", res); @@ -817,7 +846,7 @@ static void test_PropVariantCompare(void) /* VT_R4/VT_R8 */ res = PropVariantCompareEx(&r4_0, &r8_0, 0, 0); -todo_wine + todo_wine ok(res == 0, "res=%i\n", res); res = PropVariantCompareEx(&r4_0, &r4_0, 0, 0); @@ -838,9 +867,77 @@ todo_wine res = PropVariantCompareEx(&r8_2, &r8_0, 0, 0); ok(res == 1, "res=%i\n", res); - SysFreeString(str_2.u.bstrVal); - SysFreeString(str_02.u.bstrVal); - SysFreeString(str_b.u.bstrVal); + /* VT_VECTOR | VT_UI1 */ + var1.vt = VT_VECTOR | VT_UI1; + var1.caub.cElems = 1; + var1.caub.pElems = bytevector1; + var2.vt = VT_VECTOR | VT_UI1; + var2.caub.cElems = 1; + var2.caub.pElems = bytevector2; + + res = PropVariantCompareEx(&var1, &var2, 0, 0); + ok(res == -1, "res=%i\n", res); + + res = PropVariantCompareEx(&var2, &var1, 0, 0); + ok(res == 1, "res=%i\n", res); + + /* Vector length mismatch */ + var1.caub.cElems = 2; + res = PropVariantCompareEx(&var1, &var2, 0, 0); + ok(res == -1, "res=%i\n", res); + + res = PropVariantCompareEx(&var2, &var1, 0, 0); + ok(res == 1, "res=%i\n", res); + + var1.caub.pElems = bytevector2; + var2.caub.pElems = bytevector1; + res = PropVariantCompareEx(&var1, &var2, 0, 0); + ok(res == 1, "res=%i\n", res); + + var1.caub.pElems = bytevector1; + var2.caub.pElems = bytevector2; + + var1.caub.cElems = 1; + var2.caub.cElems = 2; + res = PropVariantCompareEx(&var1, &var2, 0, 0); + ok(res == -1, "res=%i\n", res); + + res = PropVariantCompareEx(&var2, &var1, 0, 0); + ok(res == 1, "res=%i\n", res); + + /* Length mismatch over same data */ + var1.caub.pElems = bytevector1; + var2.caub.pElems = bytevector1; + + res = PropVariantCompareEx(&var1, &var2, 0, 0); + ok(res == -1, "res=%i\n", res); + + res = PropVariantCompareEx(&var2, &var1, 0, 0); + ok(res == 1, "res=%i\n", res); + + var1.caub.cElems = 1; + var2.caub.cElems = 1; + res = PropVariantCompareEx(&var1, &var2, 0, 0); + ok(res == 0, "res=%i\n", res); + + var1.caub.cElems = 0; + res = PropVariantCompareEx(&var1, &var2, 0, PVCF_TREATEMPTYASGREATERTHAN); + ok(res == 1, "res=%i\n", res); + res = PropVariantCompareEx(&var2, &var1, 0, PVCF_TREATEMPTYASGREATERTHAN); + ok(res == -1, "res=%i\n", res); + + res = PropVariantCompareEx(&var1, &var2, 0, 0); + ok(res == -1, "res=%i\n", res); + res = PropVariantCompareEx(&var2, &var1, 0, 0); + ok(res == 1, "res=%i\n", res); + + var2.caub.cElems = 0; + res = PropVariantCompareEx(&var1, &var2, 0, 0); + ok(res == 0, "res=%i\n", res); + + SysFreeString(str_2.bstrVal); + SysFreeString(str_02.bstrVal); + SysFreeString(str_b.bstrVal); } static void test_intconversions(void) @@ -862,104 +959,113 @@ static void test_intconversions(void) PropVariantClear(&propvar); propvar.vt = VT_I8; - propvar.u.hVal.QuadPart = (ULONGLONG)1 << 63; + propvar.hVal.QuadPart = (ULONGLONG)1 << 63; hr = PropVariantToInt64(&propvar, &llval); - ok(hr == S_OK, "hr=%x\n", hr); + ok(hr == S_OK, "hr=%lx\n", hr); ok(llval == (ULONGLONG)1 << 63, "got wrong value %s\n", wine_dbgstr_longlong(llval)); hr = PropVariantToUInt64(&propvar, &ullval); - ok(hr == HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW), "hr=%x\n", hr); + ok(hr == HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW), "hr=%lx\n", hr); hr = PropVariantToInt32(&propvar, &lval); - ok(hr == HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW), "hr=%x\n", hr); + ok(hr == HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW), "hr=%lx\n", hr); hr = PropVariantToUInt32(&propvar, &ulval); - ok(hr == HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW), "hr=%x\n", hr); + ok(hr == HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW), "hr=%lx\n", hr); + + ulval = PropVariantToUInt32WithDefault(&propvar, 77); + ok(ulval == 77, "ulval=%lu\n", ulval); hr = PropVariantToInt16(&propvar, &sval); - ok(hr == HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW), "hr=%x\n", hr); + ok(hr == HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW), "hr=%lx\n", hr); hr = PropVariantToUInt16(&propvar, &usval); - ok(hr == HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW), "hr=%x\n", hr); + ok(hr == HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW), "hr=%lx\n", hr); propvar.vt = VT_UI8; - propvar.u.uhVal.QuadPart = 5; + propvar.uhVal.QuadPart = 5; hr = PropVariantToInt64(&propvar, &llval); - ok(hr == S_OK, "hr=%x\n", hr); + ok(hr == S_OK, "hr=%lx\n", hr); ok(llval == 5, "got wrong value %s\n", wine_dbgstr_longlong(llval)); hr = PropVariantToUInt64(&propvar, &ullval); - ok(hr == S_OK, "hr=%x\n", hr); + ok(hr == S_OK, "hr=%lx\n", hr); ok(ullval == 5, "got wrong value %s\n", wine_dbgstr_longlong(ullval)); hr = PropVariantToInt32(&propvar, &lval); - ok(hr == S_OK, "hr=%x\n", hr); - ok(lval == 5, "got wrong value %d\n", lval); + ok(hr == S_OK, "hr=%lx\n", hr); + ok(lval == 5, "got wrong value %ld\n", lval); hr = PropVariantToUInt32(&propvar, &ulval); - ok(hr == S_OK, "hr=%x\n", hr); - ok(ulval == 5, "got wrong value %d\n", ulval); + ok(hr == S_OK, "hr=%lx\n", hr); + ok(ulval == 5, "got wrong value %ld\n", ulval); + + ulval = PropVariantToUInt32WithDefault(&propvar, 77); + ok(ulval == 5, "got wrong value %lu\n", ulval); hr = PropVariantToInt16(&propvar, &sval); - ok(hr == S_OK, "hr=%x\n", hr); + ok(hr == S_OK, "hr=%lx\n", hr); ok(sval == 5, "got wrong value %d\n", sval); hr = PropVariantToUInt16(&propvar, &usval); - ok(hr == S_OK, "hr=%x\n", hr); + ok(hr == S_OK, "hr=%lx\n", hr); ok(usval == 5, "got wrong value %d\n", usval); propvar.vt = VT_I8; - propvar.u.hVal.QuadPart = -5; + propvar.hVal.QuadPart = -5; hr = PropVariantToInt64(&propvar, &llval); - ok(hr == S_OK, "hr=%x\n", hr); + ok(hr == S_OK, "hr=%lx\n", hr); ok(llval == -5, "got wrong value %s\n", wine_dbgstr_longlong(llval)); hr = PropVariantToUInt64(&propvar, &ullval); - ok(hr == HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW), "hr=%x\n", hr); + ok(hr == HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW), "hr=%lx\n", hr); hr = PropVariantToInt32(&propvar, &lval); - ok(hr == S_OK, "hr=%x\n", hr); - ok(lval == -5, "got wrong value %d\n", lval); + ok(hr == S_OK, "hr=%lx\n", hr); + ok(lval == -5, "got wrong value %ld\n", lval); hr = PropVariantToUInt32(&propvar, &ulval); - ok(hr == HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW), "hr=%x\n", hr); + ok(hr == HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW), "hr=%lx\n", hr); + + ulval = PropVariantToUInt32WithDefault(&propvar, 77); + ok(ulval == 77, "ulval=%lu\n", ulval); hr = PropVariantToInt16(&propvar, &sval); - ok(hr == S_OK, "hr=%x\n", hr); + ok(hr == S_OK, "hr=%lx\n", hr); ok(sval == -5, "got wrong value %d\n", sval); hr = PropVariantToUInt16(&propvar, &usval); - ok(hr == HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW), "hr=%x\n", hr); + ok(hr == HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW), "hr=%lx\n", hr); propvar.vt = VT_UI4; - propvar.u.ulVal = 6; + propvar.ulVal = 6; hr = PropVariantToInt64(&propvar, &llval); - ok(hr == S_OK, "hr=%x\n", hr); + ok(hr == S_OK, "hr=%lx\n", hr); ok(llval == 6, "got wrong value %s\n", wine_dbgstr_longlong(llval)); propvar.vt = VT_I4; - propvar.u.lVal = -6; + propvar.lVal = -6; hr = PropVariantToInt64(&propvar, &llval); - ok(hr == S_OK, "hr=%x\n", hr); + ok(hr == S_OK, "hr=%lx\n", hr); ok(llval == -6, "got wrong value %s\n", wine_dbgstr_longlong(llval)); propvar.vt = VT_UI2; - propvar.u.uiVal = 7; + propvar.uiVal = 7; hr = PropVariantToInt64(&propvar, &llval); - ok(hr == S_OK, "hr=%x\n", hr); + ok(hr == S_OK, "hr=%lx\n", hr); ok(llval == 7, "got wrong value %s\n", wine_dbgstr_longlong(llval)); propvar.vt = VT_I2; - propvar.u.iVal = -7; + propvar.iVal = -7; hr = PropVariantToInt64(&propvar, &llval); - ok(hr == S_OK, "hr=%x\n", hr); + ok(hr == S_OK, "hr=%lx\n", hr); ok(llval == -7, "got wrong value %s\n", wine_dbgstr_longlong(llval)); } @@ -982,195 +1088,195 @@ static void test_PropVariantToBoolean(void) /* VT_BOOL */ propvar.vt = VT_BOOL; - propvar.u.boolVal = VARIANT_FALSE; + propvar.boolVal = VARIANT_FALSE; val = TRUE; hr = PropVariantToBoolean(&propvar, &val); - ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); ok(val == FALSE, "Unexpected value %d\n", val); propvar.vt = VT_BOOL; - propvar.u.boolVal = 1; + propvar.boolVal = 1; val = TRUE; hr = PropVariantToBoolean(&propvar, &val); - ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); ok(val == FALSE, "Unexpected value %d\n", val); propvar.vt = VT_BOOL; - propvar.u.boolVal = VARIANT_TRUE; + propvar.boolVal = VARIANT_TRUE; val = FALSE; hr = PropVariantToBoolean(&propvar, &val); - ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); ok(val == TRUE, "Unexpected value %d\n", val); /* VT_EMPTY */ propvar.vt = VT_EMPTY; - propvar.u.boolVal = VARIANT_TRUE; + propvar.boolVal = VARIANT_TRUE; val = TRUE; hr = PropVariantToBoolean(&propvar, &val); - ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); ok(val == FALSE, "Unexpected value %d\n", val); /* test integer conversion */ propvar.vt = VT_I4; - propvar.u.lVal = 0; + propvar.lVal = 0; val = TRUE; hr = PropVariantToBoolean(&propvar, &val); - ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); ok(val == FALSE, "Unexpected value %d\n", val); propvar.vt = VT_I4; - propvar.u.lVal = 1; + propvar.lVal = 1; val = FALSE; hr = PropVariantToBoolean(&propvar, &val); - ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); ok(val == TRUE, "Unexpected value %d\n", val); propvar.vt = VT_I4; - propvar.u.lVal = 67; + propvar.lVal = 67; val = FALSE; hr = PropVariantToBoolean(&propvar, &val); - ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); ok(val == TRUE, "Unexpected value %d\n", val); propvar.vt = VT_I4; - propvar.u.lVal = -67; + propvar.lVal = -67; val = FALSE; hr = PropVariantToBoolean(&propvar, &val); - ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); ok(val == TRUE, "Unexpected value %d\n", val); /* test string conversion */ propvar.vt = VT_LPWSTR; - propvar.u.pwszVal = str_0; + propvar.pwszVal = str_0; val = TRUE; hr = PropVariantToBoolean(&propvar, &val); - ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); ok(val == FALSE, "Unexpected value %d\n", val); propvar.vt = VT_LPWSTR; - propvar.u.pwszVal = str_1; + propvar.pwszVal = str_1; val = FALSE; hr = PropVariantToBoolean(&propvar, &val); - ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); ok(val == TRUE, "Unexpected value %d\n", val); propvar.vt = VT_LPWSTR; - propvar.u.pwszVal = str_7; + propvar.pwszVal = str_7; val = FALSE; hr = PropVariantToBoolean(&propvar, &val); - ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); ok(val == TRUE, "Unexpected value %d\n", val); propvar.vt = VT_LPWSTR; - propvar.u.pwszVal = str_n7; + propvar.pwszVal = str_n7; val = FALSE; hr = PropVariantToBoolean(&propvar, &val); - ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); ok(val == TRUE, "Unexpected value %d\n", val); propvar.vt = VT_LPWSTR; - propvar.u.pwszVal = str_true; + propvar.pwszVal = str_true; val = FALSE; hr = PropVariantToBoolean(&propvar, &val); - ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); ok(val == TRUE, "Unexpected value %d\n", val); propvar.vt = VT_LPWSTR; - propvar.u.pwszVal = str_true_case; + propvar.pwszVal = str_true_case; val = FALSE; hr = PropVariantToBoolean(&propvar, &val); - ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); ok(val == TRUE, "Unexpected value %d\n", val); propvar.vt = VT_LPWSTR; - propvar.u.pwszVal = str_true2; + propvar.pwszVal = str_true2; val = FALSE; hr = PropVariantToBoolean(&propvar, &val); - ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); ok(val == TRUE, "Unexpected value %d\n", val); propvar.vt = VT_LPWSTR; - propvar.u.pwszVal = str_false; + propvar.pwszVal = str_false; val = TRUE; hr = PropVariantToBoolean(&propvar, &val); - ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); ok(val == FALSE, "Unexpected value %d\n", val); propvar.vt = VT_LPWSTR; - propvar.u.pwszVal = str_false2; + propvar.pwszVal = str_false2; val = TRUE; hr = PropVariantToBoolean(&propvar, &val); - ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); ok(val == FALSE, "Unexpected value %d\n", val); propvar.vt = VT_LPWSTR; - propvar.u.pwszVal = str_true_space; + propvar.pwszVal = str_true_space; val = TRUE; hr = PropVariantToBoolean(&propvar, &val); - ok(hr == DISP_E_TYPEMISMATCH, "Unexpected hr %#x.\n", hr); + ok(hr == DISP_E_TYPEMISMATCH, "Unexpected hr %#lx.\n", hr); ok(val == FALSE, "Unexpected value %d\n", val); propvar.vt = VT_LPWSTR; - propvar.u.pwszVal = str_yes; + propvar.pwszVal = str_yes; val = TRUE; hr = PropVariantToBoolean(&propvar, &val); - ok(hr == DISP_E_TYPEMISMATCH, "Unexpected hr %#x.\n", hr); + ok(hr == DISP_E_TYPEMISMATCH, "Unexpected hr %#lx.\n", hr); ok(val == FALSE, "Unexpected value %d\n", val); propvar.vt = VT_LPWSTR; - propvar.u.pwszVal = NULL; + propvar.pwszVal = NULL; val = TRUE; hr = PropVariantToBoolean(&propvar, &val); - ok(hr == DISP_E_TYPEMISMATCH, "Unexpected hr %#x.\n", hr); + ok(hr == DISP_E_TYPEMISMATCH, "Unexpected hr %#lx.\n", hr); ok(val == FALSE, "Unexpected value %d\n", val); /* VT_LPSTR */ propvar.vt = VT_LPSTR; - propvar.u.pszVal = (char *)"#TruE#"; + propvar.pszVal = (char *)"#TruE#"; val = TRUE; hr = PropVariantToBoolean(&propvar, &val); - ok(hr == DISP_E_TYPEMISMATCH, "Unexpected hr %#x.\n", hr); + ok(hr == DISP_E_TYPEMISMATCH, "Unexpected hr %#lx.\n", hr); ok(val == FALSE, "Unexpected value %d\n", val); propvar.vt = VT_LPSTR; - propvar.u.pszVal = (char *)"#TRUE#"; + propvar.pszVal = (char *)"#TRUE#"; val = FALSE; hr = PropVariantToBoolean(&propvar, &val); - ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); ok(val == TRUE, "Unexpected value %d\n", val); propvar.vt = VT_LPSTR; - propvar.u.pszVal = (char *)"tRUe"; + propvar.pszVal = (char *)"tRUe"; val = FALSE; hr = PropVariantToBoolean(&propvar, &val); - ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); ok(val == TRUE, "Unexpected value %d\n", val); propvar.vt = VT_LPSTR; - propvar.u.pszVal = (char *)"#FALSE#"; + propvar.pszVal = (char *)"#FALSE#"; val = TRUE; hr = PropVariantToBoolean(&propvar, &val); - ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); ok(val == FALSE, "Unexpected value %d\n", val); propvar.vt = VT_LPSTR; - propvar.u.pszVal = (char *)"fALSe"; + propvar.pszVal = (char *)"fALSe"; val = TRUE; hr = PropVariantToBoolean(&propvar, &val); - ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); ok(val == FALSE, "Unexpected value %d\n", val); propvar.vt = VT_LPSTR; - propvar.u.pszVal = (char *)"1"; + propvar.pszVal = (char *)"1"; val = FALSE; hr = PropVariantToBoolean(&propvar, &val); - ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); ok(val == TRUE, "Unexpected value %d\n", val); propvar.vt = VT_LPSTR; - propvar.u.pszVal = (char *)"-1"; + propvar.pszVal = (char *)"-1"; hr = PropVariantToBoolean(&propvar, &val); - ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); ok(val == TRUE, "Unexpected value %d\n", val); } @@ -1195,83 +1301,88 @@ static void test_PropVariantToStringWithDefault(void) ok(result == default_value, "Unexpected value %s\n", wine_dbgstr_w(result)); propvar.vt = VT_BOOL; - propvar.u.boolVal = VARIANT_TRUE; + propvar.boolVal = VARIANT_TRUE; result = PropVariantToStringWithDefault(&propvar, default_value); ok(result == default_value, "Unexpected value %s\n", wine_dbgstr_w(result)); propvar.vt = VT_I4; - propvar.u.lVal = 15; + propvar.lVal = 15; result = PropVariantToStringWithDefault(&propvar, default_value); ok(result == default_value, "Unexpected value %s\n", wine_dbgstr_w(result)); + propvar.vt = VT_CLSID; + propvar.puuid = (CLSID *)&dummy_guid; + result = PropVariantToStringWithDefault(&propvar, default_value); + ok(result == default_value, "Unexpected value %s.\n", debugstr_w(result)); + /* VT_LPWSTR */ propvar.vt = VT_LPWSTR; - propvar.u.pwszVal = NULL; + propvar.pwszVal = NULL; result = PropVariantToStringWithDefault(&propvar, default_value); ok(result == default_value, "Unexpected value %s\n", wine_dbgstr_w(result)); propvar.vt = VT_LPWSTR; - propvar.u.pwszVal = wstr_empty; + propvar.pwszVal = wstr_empty; result = PropVariantToStringWithDefault(&propvar, default_value); ok(result == wstr_empty, "Unexpected value %s\n", wine_dbgstr_w(result)); propvar.vt = VT_LPWSTR; - propvar.u.pwszVal = wstr_space; + propvar.pwszVal = wstr_space; result = PropVariantToStringWithDefault(&propvar, default_value); ok(result == wstr_space, "Unexpected value %s\n", wine_dbgstr_w(result)); propvar.vt = VT_LPWSTR; - propvar.u.pwszVal = wstr_test2; + propvar.pwszVal = wstr_test2; result = PropVariantToStringWithDefault(&propvar, default_value); ok(result == wstr_test2, "Unexpected value %s\n", wine_dbgstr_w(result)); /* VT_LPSTR */ propvar.vt = VT_LPSTR; - propvar.u.pszVal = NULL; + propvar.pszVal = NULL; result = PropVariantToStringWithDefault(&propvar, default_value); ok(result == default_value, "Unexpected value %s\n", wine_dbgstr_w(result)); propvar.vt = VT_LPSTR; - propvar.u.pszVal = str_empty; + propvar.pszVal = str_empty; result = PropVariantToStringWithDefault(&propvar, default_value); ok(result == default_value, "Unexpected value %s\n", wine_dbgstr_w(result)); propvar.vt = VT_LPSTR; - propvar.u.pszVal = str_space; + propvar.pszVal = str_space; result = PropVariantToStringWithDefault(&propvar, default_value); ok(result == default_value, "Unexpected value %s\n", wine_dbgstr_w(result)); propvar.vt = VT_LPSTR; - propvar.u.pszVal = str_test2; + propvar.pszVal = str_test2; result = PropVariantToStringWithDefault(&propvar, default_value); ok(result == default_value, "Unexpected value %s\n", wine_dbgstr_w(result)); /* VT_BSTR */ propvar.vt = VT_BSTR; - propvar.u.bstrVal = NULL; + propvar.bstrVal = NULL; result = PropVariantToStringWithDefault(&propvar, default_value); ok(!lstrcmpW(result, wstr_empty), "Unexpected value %s\n", wine_dbgstr_w(result)); propvar.vt = VT_BSTR; - propvar.u.bstrVal = SysAllocString(wstr_empty); + propvar.bstrVal = SysAllocString(wstr_empty); result = PropVariantToStringWithDefault(&propvar, default_value); ok(!lstrcmpW(result, wstr_empty), "Unexpected value %s\n", wine_dbgstr_w(result)); - SysFreeString(propvar.u.bstrVal); + SysFreeString(propvar.bstrVal); propvar.vt = VT_BSTR; - propvar.u.bstrVal = SysAllocString(wstr_space); + propvar.bstrVal = SysAllocString(wstr_space); result = PropVariantToStringWithDefault(&propvar, default_value); ok(!lstrcmpW(result, wstr_space), "Unexpected value %s\n", wine_dbgstr_w(result)); - SysFreeString(propvar.u.bstrVal); + SysFreeString(propvar.bstrVal); propvar.vt = VT_BSTR; - propvar.u.bstrVal = SysAllocString(wstr_test2); + propvar.bstrVal = SysAllocString(wstr_test2); result = PropVariantToStringWithDefault(&propvar, default_value); ok(!lstrcmpW(result, wstr_test2), "Unexpected value %s\n", wine_dbgstr_w(result)); - SysFreeString(propvar.u.bstrVal); + SysFreeString(propvar.bstrVal); } static void test_PropVariantChangeType_LPWSTR(void) @@ -1283,29 +1394,29 @@ static void test_PropVariantChangeType_LPWSTR(void) src.vt = VT_NULL; hr = PropVariantChangeType(&dest, &src, 0, VT_LPWSTR); - ok(hr == S_OK, "hr=%x\n", hr); + ok(hr == S_OK, "hr=%lx\n", hr); ok(dest.vt == VT_LPWSTR, "got %d\n", dest.vt); - ok(!lstrcmpW(dest.u.pwszVal, emptyW), "got %s\n", wine_dbgstr_w(dest.u.pwszVal)); + ok(!lstrcmpW(dest.pwszVal, emptyW), "got %s\n", wine_dbgstr_w(dest.pwszVal)); PropVariantClear(&dest); PropVariantClear(&src); src.vt = VT_LPSTR; - src.u.pszVal = CoTaskMemAlloc(strlen(topic)+1); - strcpy(src.u.pszVal, topic); + src.pszVal = CoTaskMemAlloc(strlen(topic)+1); + strcpy(src.pszVal, topic); hr = PropVariantChangeType(&dest, &src, 0, VT_LPWSTR); - ok(hr == S_OK, "hr=%x\n", hr); + ok(hr == S_OK, "hr=%lx\n", hr); ok(dest.vt == VT_LPWSTR, "got %d\n", dest.vt); - ok(!lstrcmpW(dest.u.pwszVal, topicW), "got %s\n", wine_dbgstr_w(dest.u.pwszVal)); + ok(!lstrcmpW(dest.pwszVal, topicW), "got %s\n", wine_dbgstr_w(dest.pwszVal)); PropVariantClear(&dest); PropVariantClear(&src); src.vt = VT_LPWSTR; - src.u.pwszVal = CoTaskMemAlloc( (lstrlenW(topicW)+1) * sizeof(WCHAR)); - lstrcpyW(src.u.pwszVal, topicW); + src.pwszVal = CoTaskMemAlloc( (lstrlenW(topicW)+1) * sizeof(WCHAR)); + lstrcpyW(src.pwszVal, topicW); hr = PropVariantChangeType(&dest, &src, 0, VT_LPWSTR); - ok(hr == S_OK, "hr=%x\n", hr); + ok(hr == S_OK, "hr=%lx\n", hr); ok(dest.vt == VT_LPWSTR, "got %d\n", dest.vt); - ok(!lstrcmpW(dest.u.pwszVal, topicW), "got %s\n", wine_dbgstr_w(dest.u.pwszVal)); + ok(!lstrcmpW(dest.pwszVal, topicW), "got %s\n", wine_dbgstr_w(dest.pwszVal)); PropVariantClear(&dest); PropVariantClear(&src); } @@ -1318,13 +1429,42 @@ static void test_InitPropVariantFromCLSID(void) memset(&propvar, 0, sizeof(propvar)); propvar.vt = VT_I4; - propvar.u.lVal = 15; + propvar.lVal = 15; memset(&clsid, 0xcc, sizeof(clsid)); hr = InitPropVariantFromCLSID(&clsid, &propvar); - ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); ok(propvar.vt == VT_CLSID, "Unexpected type %d.\n", propvar.vt); - ok(IsEqualGUID(propvar.u.puuid, &clsid), "Unexpected puuid value.\n"); + ok(IsEqualGUID(propvar.puuid, &clsid), "Unexpected puuid value.\n"); + PropVariantClear(&propvar); +} + +static void test_InitPropVariantFromStringVector(void) +{ + static const WCHAR *strs[2] = { L"abc", L"def" }; + PROPVARIANT propvar; + HRESULT hr; + + memset(&propvar, 0, sizeof(propvar)); + propvar.vt = VT_I4; + propvar.lVal = 15; + + hr = InitPropVariantFromStringVector(NULL, 0, &propvar); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(propvar.vt == (VT_LPWSTR|VT_VECTOR), "Unexpected type %#x.\n", propvar.vt); + ok(!propvar.calpwstr.cElems, "Unexpected number of elements.\n"); + ok(!!propvar.calpwstr.pElems, "Unexpected vector pointer.\n"); + PropVariantClear(&propvar); + + hr = InitPropVariantFromStringVector(strs, 2, &propvar); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(propvar.vt == (VT_LPWSTR|VT_VECTOR), "Unexpected type %#x.\n", propvar.vt); + ok(propvar.calpwstr.cElems == 2, "Unexpected number of elements.\n"); + ok(!!propvar.calpwstr.pElems, "Unexpected vector pointer.\n"); + ok(propvar.calpwstr.pElems[0] != strs[0], "Unexpected string pointer.\n"); + ok(!wcscmp(propvar.calpwstr.pElems[0], strs[0]), "Unexpected string %s.\n", debugstr_w(propvar.calpwstr.pElems[0])); + ok(propvar.calpwstr.pElems[1] != strs[1], "Unexpected string pointer.\n"); + ok(!wcscmp(propvar.calpwstr.pElems[1], strs[1]), "Unexpected string %s.\n", debugstr_w(propvar.calpwstr.pElems[1])); PropVariantClear(&propvar); } @@ -1336,141 +1476,262 @@ static void test_PropVariantToDouble(void) PropVariantInit(&propvar); propvar.vt = VT_R8; - propvar.u.dblVal = 15.0; + propvar.dblVal = 15.0; hr = PropVariantToDouble(&propvar, &value); - ok(hr == S_OK, "PropVariantToDouble failed: 0x%08x.\n", hr); + ok(hr == S_OK, "PropVariantToDouble failed: 0x%08lx.\n", hr); ok(value == 15.0, "Unexpected value: %f.\n", value); PropVariantClear(&propvar); propvar.vt = VT_I4; - propvar.u.lVal = 123; + propvar.lVal = 123; hr = PropVariantToDouble(&propvar, &value); - ok(hr == S_OK, "PropVariantToDouble failed: 0x%08x.\n", hr); + ok(hr == S_OK, "PropVariantToDouble failed: 0x%08lx.\n", hr); ok(value == 123.0, "Unexpected value: %f.\n", value); PropVariantClear(&propvar); propvar.vt = VT_I4; - propvar.u.lVal = -256; + propvar.lVal = -256; hr = PropVariantToDouble(&propvar, &value); - ok(hr == S_OK, "PropVariantToDouble failed: 0x%08x.\n", hr); + ok(hr == S_OK, "PropVariantToDouble failed: 0x%08lx.\n", hr); ok(value == -256, "Unexpected value: %f\n", value); PropVariantClear(&propvar); propvar.vt = VT_I8; - propvar.u.lVal = 65536; + propvar.lVal = 65536; hr = PropVariantToDouble(&propvar, &value); - ok(hr == S_OK, "PropVariantToDouble failed: 0x%08x.\n", hr); + ok(hr == S_OK, "PropVariantToDouble failed: 0x%08lx.\n", hr); ok(value == 65536.0, "Unexpected value: %f.\n", value); PropVariantClear(&propvar); propvar.vt = VT_I8; - propvar.u.lVal = -321; + propvar.lVal = -321; hr = PropVariantToDouble(&propvar, &value); - ok(hr == S_OK, "PropVariantToDouble failed: 0x%08x.\n", hr); + ok(hr == S_OK, "PropVariantToDouble failed: 0x%08lx.\n", hr); ok(value == 4294966975.0, "Unexpected value: %f.\n", value); PropVariantClear(&propvar); propvar.vt = VT_UI4; - propvar.u.ulVal = 6; + propvar.ulVal = 6; hr = PropVariantToDouble(&propvar, &value); - ok(hr == S_OK, "PropVariantToDouble failed: 0x%08x.\n", hr); + ok(hr == S_OK, "PropVariantToDouble failed: 0x%08lx.\n", hr); ok(value == 6.0, "Unexpected value: %f.\n", value); PropVariantClear(&propvar); propvar.vt = VT_UI8; - propvar.u.uhVal.QuadPart = 8; + propvar.uhVal.QuadPart = 8; hr = PropVariantToDouble(&propvar, &value); - ok(hr == S_OK, "PropVariantToDouble failed: 0x%08x.\n", hr); + ok(hr == S_OK, "PropVariantToDouble failed: 0x%08lx.\n", hr); ok(value == 8.0, "Unexpected value: %f.\n", value); } static void test_PropVariantToString(void) { - PROPVARIANT propvar; + static WCHAR stringW[] = L"Wine"; static CHAR string[] = "Wine"; - static WCHAR stringW[] = {'W','i','n','e',0}; WCHAR bufferW[256] = {0}; + PROPVARIANT propvar; HRESULT hr; PropVariantInit(&propvar); propvar.vt = VT_EMPTY; - U(propvar).pwszVal = stringW; + propvar.pwszVal = stringW; bufferW[0] = 65; hr = PropVariantToString(&propvar, bufferW, 0); - ok(hr == E_INVALIDARG, "PropVariantToString should fail: 0x%08x.\n", hr); + ok(hr == E_INVALIDARG, "PropVariantToString should fail: 0x%08lx.\n", hr); ok(!bufferW[0], "got wrong string: \"%s\".\n", wine_dbgstr_w(bufferW)); memset(bufferW, 0, sizeof(bufferW)); PropVariantClear(&propvar); PropVariantInit(&propvar); propvar.vt = VT_EMPTY; - U(propvar).pwszVal = stringW; + propvar.pwszVal = stringW; bufferW[0] = 65; hr = PropVariantToString(&propvar, bufferW, ARRAY_SIZE(bufferW)); - ok(hr == S_OK, "PropVariantToString failed: 0x%08x.\n", hr); + ok(hr == S_OK, "PropVariantToString failed: 0x%08lx.\n", hr); ok(!bufferW[0], "got wrong string: \"%s\".\n", wine_dbgstr_w(bufferW)); memset(bufferW, 0, sizeof(bufferW)); PropVariantClear(&propvar); PropVariantInit(&propvar); propvar.vt = VT_NULL; - U(propvar).pwszVal = stringW; + propvar.pwszVal = stringW; bufferW[0] = 65; hr = PropVariantToString(&propvar, bufferW, ARRAY_SIZE(bufferW)); - ok(hr == S_OK, "PropVariantToString failed: 0x%08x.\n", hr); + ok(hr == S_OK, "PropVariantToString failed: 0x%08lx.\n", hr); ok(!bufferW[0], "got wrong string: \"%s\".\n", wine_dbgstr_w(bufferW)); memset(bufferW, 0, sizeof(bufferW)); PropVariantClear(&propvar); PropVariantInit(&propvar); propvar.vt = VT_I4; - U(propvar).lVal = 22; + propvar.lVal = 22; hr = PropVariantToString(&propvar, bufferW, ARRAY_SIZE(bufferW)); - todo_wine ok(hr == S_OK, "PropVariantToString failed: 0x%08x.\n", hr); - todo_wine ok(!strcmp_wa(bufferW, "22"), "got wrong string: \"%s\".\n", wine_dbgstr_w(bufferW)); + todo_wine ok(hr == S_OK, "PropVariantToString failed: 0x%08lx.\n", hr); + todo_wine ok(!lstrcmpW(bufferW, L"22"), "got wrong string: \"%s\".\n", wine_dbgstr_w(bufferW)); memset(bufferW, 0, sizeof(bufferW)); PropVariantClear(&propvar); PropVariantInit(&propvar); propvar.vt = VT_LPWSTR; - U(propvar).pwszVal = stringW; + propvar.pwszVal = stringW; hr = PropVariantToString(&propvar, bufferW, ARRAY_SIZE(bufferW)); - ok(hr == S_OK, "PropVariantToString failed: 0x%08x.\n", hr); + ok(hr == S_OK, "PropVariantToString failed: 0x%08lx.\n", hr); ok(!lstrcmpW(bufferW, stringW), "got wrong string: \"%s\".\n", wine_dbgstr_w(bufferW)); memset(bufferW, 0, sizeof(bufferW)); PropVariantInit(&propvar); propvar.vt = VT_LPSTR; - U(propvar).pszVal = string; + propvar.pszVal = string; hr = PropVariantToString(&propvar, bufferW, ARRAY_SIZE(bufferW)); - ok(hr == S_OK, "PropVariantToString failed: 0x%08x.\n", hr); + ok(hr == S_OK, "PropVariantToString failed: 0x%08lx.\n", hr); ok(!lstrcmpW(bufferW, stringW), "got wrong string: \"%s\".\n", wine_dbgstr_w(bufferW)); memset(bufferW, 0, sizeof(bufferW)); + /* Result string will be truncated if output buffer is too small. */ + PropVariantInit(&propvar); + propvar.vt = VT_UI4; + propvar.lVal = 123456; + hr = PropVariantToString(&propvar, bufferW, 4); + todo_wine + ok(hr == STRSAFE_E_INSUFFICIENT_BUFFER, "PropVariantToString returned: %#lx.\n", hr); + todo_wine + ok(!wcscmp(bufferW, L"123"), "Unexpected string %s.\n", debugstr_w(bufferW)); + memset(bufferW, 0, sizeof(bufferW)); + PropVariantInit(&propvar); propvar.vt = VT_LPWSTR; - U(propvar).pwszVal = stringW; + propvar.pwszVal = stringW; hr = PropVariantToString(&propvar, bufferW, 4); - ok(hr == STRSAFE_E_INSUFFICIENT_BUFFER, "PropVariantToString returned: 0x%08x.\n", hr); - ok(!memcmp(bufferW, stringW, 4), "got wrong string.\n"); + ok(hr == STRSAFE_E_INSUFFICIENT_BUFFER, "PropVariantToString returned: 0x%08lx.\n", hr); + ok(!wcscmp(bufferW, L"Win"), "Unexpected string %s.\n", debugstr_w(bufferW)); memset(bufferW, 0, sizeof(bufferW)); PropVariantInit(&propvar); propvar.vt = VT_LPSTR; - U(propvar).pszVal = string; + propvar.pszVal = string; hr = PropVariantToString(&propvar, bufferW, 4); - ok(hr == STRSAFE_E_INSUFFICIENT_BUFFER, "PropVariantToString returned: 0x%08x.\n", hr); - ok(!memcmp(bufferW, stringW, 4), "got wrong string.\n"); + ok(hr == STRSAFE_E_INSUFFICIENT_BUFFER, "PropVariantToString returned: 0x%08lx.\n", hr); + ok(!wcscmp(bufferW, L"Win"), "Unexpected string %s.\n", debugstr_w(bufferW)); memset(bufferW, 0, sizeof(bufferW)); PropVariantInit(&propvar); propvar.vt = VT_BSTR; - propvar.u.bstrVal = SysAllocString(stringW); + propvar.bstrVal = SysAllocString(stringW); hr = PropVariantToString(&propvar, bufferW, ARRAY_SIZE(bufferW)); - ok(hr == S_OK, "PropVariantToString failed: 0x%08x.\n", hr); + ok(hr == S_OK, "PropVariantToString failed: 0x%08lx.\n", hr); ok(!lstrcmpW(bufferW, stringW), "got wrong string: \"%s\".\n", wine_dbgstr_w(bufferW)); memset(bufferW, 0, sizeof(bufferW)); - SysFreeString(propvar.u.bstrVal); + SysFreeString(propvar.bstrVal); + + PropVariantInit(&propvar); + propvar.vt = VT_CLSID; + propvar.puuid = (CLSID *)&dummy_guid; + hr = PropVariantToString(&propvar, bufferW, ARRAY_SIZE(bufferW)); + ok(hr == S_OK, "PropVariantToString returned %#lx.\n", hr); + ok(!wcscmp(bufferW, dummy_guid_str), "Unexpected string %s.\n", debugstr_w(bufferW)); + memset(bufferW, 0, sizeof(bufferW)); +} + +#define check_PropVariantToBSTR(type, member, value, expect_str) \ +do \ +{ \ + PROPVARIANT check_propvar_ = {.vt = (type), .member = (value)}; \ + HRESULT check_hr_; \ + BSTR check_bstr_; \ + \ + check_hr_ = PropVariantToBSTR(&check_propvar_, &check_bstr_); \ + ok_(__FILE__, __LINE__)(check_hr_ == S_OK, \ + "PropVariantToBSTR returned %#lx.\n", check_hr_); \ + \ + if (check_hr_ == S_OK) \ + { \ + ok_(__FILE__, __LINE__)(!wcscmp(check_bstr_, (expect_str)), \ + "Unexpected bstr %s.\n", debugstr_w(check_bstr_)); \ + SysFreeString(check_bstr_); \ + } \ +} while (0) + +static void test_PropVariantToBSTR(void) +{ + unsigned char test_bytes[] = {1, 20, 30, 4}; + WCHAR test_bstr[] = {'a', 0, 'b', 0, 'c'}; + PROPVARIANT propvar; + UINT length; + HRESULT hr; + BSTR bstr; + + if (0) /* Crashes. */ + { + hr = PropVariantToBSTR(&propvar, NULL); + hr = PropVariantToBSTR(NULL, &bstr); + } + + todo_wine + { + check_PropVariantToBSTR(VT_I1, cVal, -123, L"-123"); + check_PropVariantToBSTR(VT_I2, iVal, -456, L"-456"); + check_PropVariantToBSTR(VT_I4, lVal, -789, L"-789"); + check_PropVariantToBSTR(VT_I8, hVal.QuadPart, -101112, L"-101112"); + check_PropVariantToBSTR(VT_UI1, bVal, 0xcd, L"205"); + check_PropVariantToBSTR(VT_UI2, uiVal, 0xdead, L"57005"); + check_PropVariantToBSTR(VT_UI4, ulVal, 0xdeadbeef, L"3735928559"); + check_PropVariantToBSTR(VT_UI8, uhVal.QuadPart, 0xdeadbeefdeadbeef, L"16045690984833335023"); + check_PropVariantToBSTR(VT_BOOL, boolVal, TRUE, L"1"); + check_PropVariantToBSTR(VT_R4, fltVal, 0.125f, L"0.125"); + check_PropVariantToBSTR(VT_R8, dblVal, 0.456, L"0.456"); + } + check_PropVariantToBSTR(VT_CLSID, puuid, (CLSID *)&dummy_guid, dummy_guid_str); + check_PropVariantToBSTR(VT_LPSTR, pszVal, (char *)topic, topicW); + check_PropVariantToBSTR(VT_LPWSTR, pwszVal, (WCHAR *)topicW, topicW); + + PropVariantInit(&propvar); + propvar.vt = VT_FILETIME; + propvar.filetime.dwLowDateTime = 0xdead; + propvar.filetime.dwHighDateTime = 0xbeef; + hr = PropVariantToBSTR(&propvar, &bstr); + todo_wine + ok(hr == S_OK, "PropVariantToBSTR returned %#lx.\n", hr); + if (hr == S_OK) + { + ok(!wcscmp(bstr, L"1601/08/31:23:29:30.651"), "Unexpected bstr %s.\n", debugstr_w(bstr)); + SysFreeString(bstr); + } + + PropVariantInit(&propvar); + propvar.vt = VT_DATE; + propvar.date = 123.123f; + hr = PropVariantToBSTR(&propvar, &bstr); + todo_wine + ok(hr == S_OK, "PropVariantToBSTR returned %#lx.\n", hr); + if (hr == S_OK) + { + ok(!wcscmp(bstr, L"1900/05/02:02:57:07.000"), "Unexpected bstr %s.\n", debugstr_w(bstr)); + SysFreeString(bstr); + } + + PropVariantInit(&propvar); + propvar.vt = VT_VECTOR | VT_I1; + propvar.caub.cElems = ARRAY_SIZE(test_bytes); + propvar.caub.pElems = test_bytes; + hr = PropVariantToBSTR(&propvar, &bstr); + todo_wine + ok(hr == S_OK, "PropVariantToBSTR returned %#lx.\n", hr); + if (hr == S_OK) + { + ok(!wcscmp(bstr, L"1; 20; 30; 4"), "Unexpected bstr %s.\n", debugstr_w(bstr)); + SysFreeString(bstr); + } + + PropVariantInit(&propvar); + propvar.vt = VT_BSTR; + propvar.bstrVal = SysAllocStringLen(test_bstr, ARRAY_SIZE(test_bstr)); + hr = PropVariantToBSTR(&propvar, &bstr); + ok(hr == S_OK, "PropVariantToBSTR returned %#lx.\n", hr); + length = SysStringLen(bstr); + ok(length == wcslen(test_bstr), "Unexpected length %u.\n", length); + ok(!wcscmp(bstr, test_bstr), "Unexpected bstr %s.", debugstr_wn(bstr, ARRAY_SIZE(test_bstr))); + SysFreeString(bstr); + PropVariantClear(&propvar); } static void test_PropVariantToBuffer(void) @@ -1482,35 +1743,35 @@ static void test_PropVariantToBuffer(void) SAFEARRAY *sa; SAFEARRAYBOUND sabound; void *pdata; - UINT8 buffer[256]; + UINT8 buffer[256] = {0}; hr = InitPropVariantFromBuffer(data, 10, &propvar); - ok(hr == S_OK, "InitPropVariantFromBuffer failed 0x%08x.\n", hr); + ok(hr == S_OK, "InitPropVariantFromBuffer failed 0x%08lx.\n", hr); hr = PropVariantToBuffer(&propvar, NULL, 0); /* crash when cb isn't zero */ - ok(hr == S_OK, "PropVariantToBuffer failed: 0x%08x.\n", hr); + ok(hr == S_OK, "PropVariantToBuffer failed: 0x%08lx.\n", hr); PropVariantClear(&propvar); hr = InitPropVariantFromBuffer(data, 10, &propvar); - ok(hr == S_OK, "InitPropVariantFromBuffer failed 0x%08x.\n", hr); + ok(hr == S_OK, "InitPropVariantFromBuffer failed 0x%08lx.\n", hr); hr = PropVariantToBuffer(&propvar, buffer, 10); - ok(hr == S_OK, "PropVariantToBuffer failed: 0x%08x.\n", hr); + ok(hr == S_OK, "PropVariantToBuffer failed: 0x%08lx.\n", hr); ok(!memcmp(buffer, data, 10) && !buffer[10], "got wrong buffer.\n"); memset(buffer, 0, sizeof(buffer)); PropVariantClear(&propvar); hr = InitPropVariantFromBuffer(data, 10, &propvar); - ok(hr == S_OK, "InitPropVariantFromBuffer failed 0x%08x.\n", hr); + ok(hr == S_OK, "InitPropVariantFromBuffer failed 0x%08lx.\n", hr); buffer[0] = 99; hr = PropVariantToBuffer(&propvar, buffer, 11); - ok(hr == E_FAIL, "PropVariantToBuffer returned: 0x%08x.\n", hr); + ok(hr == E_FAIL, "PropVariantToBuffer returned: 0x%08lx.\n", hr); ok(buffer[0] == 99, "got wrong buffer.\n"); memset(buffer, 0, sizeof(buffer)); PropVariantClear(&propvar); hr = InitPropVariantFromBuffer(data, 10, &propvar); - ok(hr == S_OK, "InitPropVariantFromBuffer failed 0x%08x.\n", hr); + ok(hr == S_OK, "InitPropVariantFromBuffer failed 0x%08lx.\n", hr); hr = PropVariantToBuffer(&propvar, buffer, 9); - ok(hr == S_OK, "PropVariantToBuffer failed: 0x%08x.\n", hr); + ok(hr == S_OK, "PropVariantToBuffer failed: 0x%08lx.\n", hr); ok(!memcmp(buffer, data, 9) && !buffer[9], "got wrong buffer.\n"); memset(buffer, 0, sizeof(buffer)); PropVariantClear(&propvar); @@ -1523,14 +1784,14 @@ static void test_PropVariantToBuffer(void) sa = SafeArrayCreate(VT_UI1, 1, &sabound); ok(sa != NULL, "SafeArrayCreate failed.\n"); hr = SafeArrayAccessData(sa, &pdata); - ok(hr == S_OK, "SafeArrayAccessData failed: 0x%08x.\n", hr); + ok(hr == S_OK, "SafeArrayAccessData failed: 0x%08lx.\n", hr); memcpy(pdata, data, sizeof(data)); hr = SafeArrayUnaccessData(sa); - ok(hr == S_OK, "SafeArrayUnaccessData failed: 0x%08x.\n", hr); - U(propvar).parray = sa; + ok(hr == S_OK, "SafeArrayUnaccessData failed: 0x%08lx.\n", hr); + propvar.parray = sa; buffer[0] = 99; hr = PropVariantToBuffer(&propvar, buffer, 11); - todo_wine ok(hr == E_FAIL, "PropVariantToBuffer returned: 0x%08x.\n", hr); + todo_wine ok(hr == E_FAIL, "PropVariantToBuffer returned: 0x%08lx.\n", hr); ok(buffer[0] == 99, "got wrong buffer.\n"); memset(buffer, 0, sizeof(buffer)); PropVariantClear(&propvar); @@ -1543,24 +1804,24 @@ static void test_PropVariantToBuffer(void) sa = SafeArrayCreate(VT_UI1, 1, &sabound); ok(sa != NULL, "SafeArrayCreate failed.\n"); hr = SafeArrayAccessData(sa, &pdata); - ok(hr == S_OK, "SafeArrayAccessData failed: 0x%08x.\n", hr); + ok(hr == S_OK, "SafeArrayAccessData failed: 0x%08lx.\n", hr); memcpy(pdata, data, sizeof(data)); hr = SafeArrayUnaccessData(sa); - ok(hr == S_OK, "SafeArrayUnaccessData failed: 0x%08x.\n", hr); - U(propvar).parray = sa; + ok(hr == S_OK, "SafeArrayUnaccessData failed: 0x%08lx.\n", hr); + propvar.parray = sa; hr = PropVariantToBuffer(&propvar, buffer, sizeof(data)); - todo_wine ok(hr == S_OK, "PropVariantToBuffer failed: 0x%08x.\n", hr); + todo_wine ok(hr == S_OK, "PropVariantToBuffer failed: 0x%08lx.\n", hr); todo_wine ok(!memcmp(buffer, data, 10) && !buffer[10], "got wrong buffer.\n"); memset(buffer, 0, sizeof(buffer)); PropVariantClear(&propvar); PropVariantInit(&propvar); propvar.vt = VT_VECTOR|VT_I1; - U(propvar).caub.pElems = CoTaskMemAlloc(sizeof(data_int8)); - U(propvar).caub.cElems = sizeof(data_int8); - memcpy(U(propvar).caub.pElems, data_int8, sizeof(data_int8)); + propvar.caub.pElems = CoTaskMemAlloc(sizeof(data_int8)); + propvar.caub.cElems = sizeof(data_int8); + memcpy(propvar.caub.pElems, data_int8, sizeof(data_int8)); hr = PropVariantToBuffer(&propvar, buffer, sizeof(data_int8)); - ok(hr == E_INVALIDARG, "PropVariantToBuffer failed: 0x%08x.\n", hr); + ok(hr == E_INVALIDARG, "PropVariantToBuffer failed: 0x%08lx.\n", hr); PropVariantClear(&propvar); PropVariantInit(&propvar); @@ -1571,32 +1832,829 @@ static void test_PropVariantToBuffer(void) sa = SafeArrayCreate(VT_I1, 1, &sabound); ok(sa != NULL, "SafeArrayCreate failed.\n"); hr = SafeArrayAccessData(sa, &pdata); - ok(hr == S_OK, "SafeArrayAccessData failed: 0x%08x.\n", hr); + ok(hr == S_OK, "SafeArrayAccessData failed: 0x%08lx.\n", hr); memcpy(pdata, data_int8, sizeof(data_int8)); hr = SafeArrayUnaccessData(sa); - ok(hr == S_OK, "SafeArrayUnaccessData failed: 0x%08x.\n", hr); - U(propvar).parray = sa; + ok(hr == S_OK, "SafeArrayUnaccessData failed: 0x%08lx.\n", hr); + propvar.parray = sa; hr = PropVariantToBuffer(&propvar, buffer, sizeof(data_int8)); - ok(hr == E_INVALIDARG, "PropVariantToBuffer failed: 0x%08x.\n", hr); + ok(hr == E_INVALIDARG, "PropVariantToBuffer failed: 0x%08lx.\n", hr); PropVariantClear(&propvar); } +static void test_inmemorystore(void) +{ + IPropertyStoreCache *propcache; + HRESULT hr; + PROPERTYKEY pkey; + PROPVARIANT propvar; + DWORD count; + PSC_STATE state; + + CoInitialize(NULL); + + hr = CoCreateInstance(&CLSID_InMemoryPropertyStore, NULL, CLSCTX_INPROC_SERVER, + &IID_IPropertyStoreCache, (void**)&propcache); + ok(hr == S_OK, "CoCreateInstance failed, hr=%lx\n", hr); + + if (FAILED(hr)) + { + win_skip("CLSID_InMemoryPropertyStore not supported\n"); + CoUninitialize(); + return; + } + + hr = IPropertyStoreCache_GetCount(propcache, NULL); + ok(hr == E_POINTER, "GetCount failed, hr=%lx\n", hr); + + hr = IPropertyStoreCache_GetCount(propcache, &count); + ok(hr == S_OK, "GetCount failed, hr=%lx\n", hr); + ok(count == 0, "GetCount returned %li, expected 0\n", count); + + hr = IPropertyStoreCache_Commit(propcache); + ok(hr == S_OK, "Commit failed, hr=%lx\n", hr); + + hr = IPropertyStoreCache_Commit(propcache); + ok(hr == S_OK, "Commit failed, hr=%lx\n", hr); + + hr = IPropertyStoreCache_GetAt(propcache, 0, &pkey); + ok(hr == E_INVALIDARG, "GetAt failed, hr=%lx\n", hr); + + pkey.fmtid = PKEY_WineTest; + pkey.pid = 4; + + memset(&propvar, 0, sizeof(propvar)); + propvar.vt = VT_I4; + propvar.lVal = 12345; + + if (0) + { + /* Crashes on Windows 7 */ + hr = IPropertyStoreCache_SetValue(propcache, NULL, &propvar); + ok(hr == E_POINTER, "SetValue failed, hr=%lx\n", hr); + + hr = IPropertyStoreCache_SetValue(propcache, &pkey, NULL); + ok(hr == E_POINTER, "SetValue failed, hr=%lx\n", hr); + } + + hr = IPropertyStoreCache_SetValue(propcache, &pkey, &propvar); + ok(hr == S_OK, "SetValue failed, hr=%lx\n", hr); + + hr = IPropertyStoreCache_GetCount(propcache, &count); + ok(hr == S_OK, "GetCount failed, hr=%lx\n", hr); + ok(count == 1, "GetCount returned %li, expected 0\n", count); + + memset(&pkey, 0, sizeof(pkey)); + + hr = IPropertyStoreCache_GetAt(propcache, 0, &pkey); + ok(hr == S_OK, "GetAt failed, hr=%lx\n", hr); + ok(IsEqualGUID(&pkey.fmtid, &PKEY_WineTest), "got wrong pkey\n"); + ok(pkey.pid == 4, "got pid of %li, expected 4\n", pkey.pid); + + pkey.fmtid = PKEY_WineTest; + pkey.pid = 4; + + memset(&propvar, 0, sizeof(propvar)); + + if (0) + { + /* Crashes on Windows 7 */ + hr = IPropertyStoreCache_GetValue(propcache, NULL, &propvar); + ok(hr == E_POINTER, "GetValue failed, hr=%lx\n", hr); + } + + hr = IPropertyStoreCache_GetValue(propcache, &pkey, NULL); + ok(hr == E_POINTER, "GetValue failed, hr=%lx\n", hr); + + hr = IPropertyStoreCache_GetValue(propcache, &pkey, &propvar); + ok(hr == S_OK, "GetValue failed, hr=%lx\n", hr); + ok(propvar.vt == VT_I4, "expected VT_I4, got %d\n", propvar.vt); + ok(propvar.lVal == 12345, "expected 12345, got %ld\n", propvar.lVal); + + pkey.fmtid = PKEY_WineTest; + pkey.pid = 10; + + /* Get information for field that isn't set yet */ + propvar.vt = VT_I2; + hr = IPropertyStoreCache_GetValue(propcache, &pkey, &propvar); + ok(hr == S_OK, "GetValue failed, hr=%lx\n", hr); + ok(propvar.vt == VT_EMPTY, "expected VT_EMPTY, got %d\n", propvar.vt); + + state = 0xdeadbeef; + hr = IPropertyStoreCache_GetState(propcache, &pkey, &state); + ok(hr == TYPE_E_ELEMENTNOTFOUND, "GetState failed, hr=%lx\n", hr); + ok(state == PSC_NORMAL, "expected PSC_NORMAL, got %d\n", state); + + propvar.vt = VT_I2; + state = 0xdeadbeef; + hr = IPropertyStoreCache_GetValueAndState(propcache, &pkey, &propvar, &state); + ok(hr == TYPE_E_ELEMENTNOTFOUND, "GetValueAndState failed, hr=%lx\n", hr); + ok(propvar.vt == VT_EMPTY, "expected VT_EMPTY, got %d\n", propvar.vt); + ok(state == PSC_NORMAL, "expected PSC_NORMAL, got %d\n", state); + + /* Set state on an unset field */ + hr = IPropertyStoreCache_SetState(propcache, &pkey, PSC_NORMAL); + ok(hr == TYPE_E_ELEMENTNOTFOUND, "SetState failed, hr=%lx\n", hr); + + /* Manipulate state on already set field */ + pkey.fmtid = PKEY_WineTest; + pkey.pid = 4; + + state = 0xdeadbeef; + hr = IPropertyStoreCache_GetState(propcache, &pkey, &state); + ok(hr == S_OK, "GetState failed, hr=%lx\n", hr); + ok(state == PSC_NORMAL, "expected PSC_NORMAL, got %d\n", state); + + hr = IPropertyStoreCache_SetState(propcache, &pkey, 10); + ok(hr == S_OK, "SetState failed, hr=%lx\n", hr); + + state = 0xdeadbeef; + hr = IPropertyStoreCache_GetState(propcache, &pkey, &state); + ok(hr == S_OK, "GetState failed, hr=%lx\n", hr); + ok(state == 10, "expected 10, got %d\n", state); + + propvar.vt = VT_I4; + propvar.lVal = 12346; + hr = IPropertyStoreCache_SetValueAndState(propcache, &pkey, &propvar, 5); + ok(hr == S_OK, "SetValueAndState failed, hr=%lx\n", hr); + + memset(&propvar, 0, sizeof(propvar)); + state = 0xdeadbeef; + hr = IPropertyStoreCache_GetValueAndState(propcache, &pkey, &propvar, &state); + ok(hr == S_OK, "GetValueAndState failed, hr=%lx\n", hr); + ok(propvar.vt == VT_I4, "expected VT_I4, got %d\n", propvar.vt); + ok(propvar.lVal == 12346, "expected 12346, got %d\n", propvar.vt); + ok(state == 5, "expected 5, got %d\n", state); + + /* Set new field with state */ + pkey.fmtid = PKEY_WineTest; + pkey.pid = 8; + + propvar.vt = VT_I4; + propvar.lVal = 12347; + hr = IPropertyStoreCache_SetValueAndState(propcache, &pkey, &propvar, PSC_DIRTY); + ok(hr == S_OK, "SetValueAndState failed, hr=%lx\n", hr); + + memset(&propvar, 0, sizeof(propvar)); + state = 0xdeadbeef; + hr = IPropertyStoreCache_GetValueAndState(propcache, &pkey, &propvar, &state); + ok(hr == S_OK, "GetValueAndState failed, hr=%lx\n", hr); + ok(propvar.vt == VT_I4, "expected VT_I4, got %d\n", propvar.vt); + ok(propvar.lVal == 12347, "expected 12347, got %d\n", propvar.vt); + ok(state == PSC_DIRTY, "expected PSC_DIRTY, got %d\n", state); + + IPropertyStoreCache_Release(propcache); + + CoUninitialize(); +} + +static void test_persistserialized(void) +{ + IPropertyStore *propstore; + IPersistSerializedPropStorage *serialized; + HRESULT hr; + SERIALIZEDPROPSTORAGE *result; + DWORD result_size; + + CoInitialize(NULL); + + hr = CoCreateInstance(&CLSID_InMemoryPropertyStore, NULL, CLSCTX_INPROC_SERVER, + &IID_IPropertyStore, (void**)&propstore); + ok(hr == S_OK, "CoCreateInstance failed, hr=%lx\n", hr); + + hr = IPropertyStore_QueryInterface(propstore, &IID_IPersistSerializedPropStorage, + (void**)&serialized); + todo_wine ok(hr == S_OK, "QueryInterface failed, hr=%lx\n", hr); + + if (FAILED(hr)) + { + IPropertyStore_Release(propstore); + skip("IPersistSerializedPropStorage not supported\n"); + CoUninitialize(); + return; + } + + hr = IPersistSerializedPropStorage_GetPropertyStorage(serialized, NULL, &result_size); + ok(hr == E_POINTER, "GetPropertyStorage failed, hr=%lx\n", hr); + + hr = IPersistSerializedPropStorage_GetPropertyStorage(serialized, &result, NULL); + ok(hr == E_POINTER, "GetPropertyStorage failed, hr=%lx\n", hr); + + hr = IPersistSerializedPropStorage_GetPropertyStorage(serialized, &result, &result_size); + ok(hr == S_OK, "GetPropertyStorage failed, hr=%lx\n", hr); + + if (SUCCEEDED(hr)) + { + ok(result_size == 0, "expected 0 bytes, got %li\n", result_size); + + CoTaskMemFree(result); + } + + hr = IPersistSerializedPropStorage_SetPropertyStorage(serialized, NULL, 4); + ok(hr == E_POINTER, "SetPropertyStorage failed, hr=%lx\n", hr); + + hr = IPersistSerializedPropStorage_SetPropertyStorage(serialized, NULL, 0); + ok(hr == S_OK, "SetPropertyStorage failed, hr=%lx\n", hr); + + hr = IPropertyStore_GetCount(propstore, &result_size); + ok(hr == S_OK, "GetCount failed, hr=%lx\n", hr); + ok(result_size == 0, "expecting 0, got %ld\n", result_size); + + IPropertyStore_Release(propstore); + IPersistSerializedPropStorage_Release(serialized); + + CoUninitialize(); +} + +static void test_PSCreateMemoryPropertyStore(void) +{ + IPropertyStore *propstore, *propstore1; + IPersistSerializedPropStorage *serialized; + IPropertyStoreCache *propstorecache; + HRESULT hr; + + /* PSCreateMemoryPropertyStore(&IID_IPropertyStore, NULL); crashes */ + + hr = PSCreateMemoryPropertyStore(&IID_IPropertyStore, (void **)&propstore); + ok(hr == S_OK, "PSCreateMemoryPropertyStore failed: 0x%08lx.\n", hr); + ok(propstore != NULL, "got %p.\n", propstore); + EXPECT_REF(propstore, 1); + + hr = PSCreateMemoryPropertyStore(&IID_IPersistSerializedPropStorage, (void **)&serialized); + todo_wine ok(hr == S_OK, "PSCreateMemoryPropertyStore failed: 0x%08lx.\n", hr); + todo_wine ok(serialized != NULL, "got %p.\n", serialized); + EXPECT_REF(propstore, 1); + if(serialized) + { + EXPECT_REF(serialized, 1); + IPersistSerializedPropStorage_Release(serialized); + } + + hr = PSCreateMemoryPropertyStore(&IID_IPropertyStoreCache, (void **)&propstorecache); + ok(hr == S_OK, "PSCreateMemoryPropertyStore failed: 0x%08lx.\n", hr); + ok(propstorecache != NULL, "got %p.\n", propstore); + ok(propstorecache != (IPropertyStoreCache *)propstore, "pointer are equal: %p, %p.\n", propstorecache, propstore); + EXPECT_REF(propstore, 1); + EXPECT_REF(propstorecache, 1); + + hr = PSCreateMemoryPropertyStore(&IID_IPropertyStore, (void **)&propstore1); + ok(hr == S_OK, "PSCreateMemoryPropertyStore failed: 0x%08lx.\n", hr); + ok(propstore1 != NULL, "got %p.\n", propstore); + ok(propstore1 != propstore, "pointer are equal: %p, %p.\n", propstore1, propstore); + EXPECT_REF(propstore, 1); + EXPECT_REF(propstore1, 1); + EXPECT_REF(propstorecache, 1); + + IPropertyStore_Release(propstore1); + IPropertyStore_Release(propstore); + IPropertyStoreCache_Release(propstorecache); +} + +static void test_propertystore(void) +{ + IPropertyStore *propstore; + HRESULT hr; + PROPVARIANT propvar, ret_propvar; + PROPERTYKEY propkey; + DWORD count = 0; + + hr = PSCreateMemoryPropertyStore(&IID_IPropertyStore, (void **)&propstore); + ok(hr == S_OK, "PSCreateMemoryPropertyStore failed: 0x%08lx.\n", hr); + ok(propstore != NULL, "got %p.\n", propstore); + + hr = IPropertyStore_GetCount(propstore, &count); + ok(hr == S_OK, "IPropertyStore_GetCount failed: 0x%08lx.\n", hr); + ok(!count, "got wrong property count: %ld, expected 0.\n", count); + + PropVariantInit(&propvar); + propvar.vt = VT_I4; + propvar.lVal = 123; + propkey.fmtid = DUMMY_GUID1; + propkey.pid = PID_FIRST_USABLE; + hr = IPropertyStore_SetValue(propstore, &propkey, &propvar); + ok(hr == S_OK, "IPropertyStore_SetValue failed: 0x%08lx.\n", hr); + hr = IPropertyStore_Commit(propstore); + ok(hr == S_OK, "IPropertyStore_Commit failed: 0x%08lx.\n", hr); + hr = IPropertyStore_GetCount(propstore, &count); + ok(hr == S_OK, "IPropertyStore_GetCount failed: 0x%08lx.\n", hr); + ok(count == 1, "got wrong property count: %ld, expected 1.\n", count); + PropVariantInit(&ret_propvar); + ret_propvar.vt = VT_I4; + hr = IPropertyStore_GetValue(propstore, &propkey, &ret_propvar); + ok(hr == S_OK, "IPropertyStore_GetValue failed: 0x%08lx.\n", hr); + ok(ret_propvar.vt == VT_I4, "got wrong property type: %x.\n", ret_propvar.vt); + ok(ret_propvar.lVal == 123, "got wrong value: %ld, expected 123.\n", ret_propvar.lVal); + PropVariantClear(&propvar); + PropVariantClear(&ret_propvar); + + PropVariantInit(&propvar); + propkey.fmtid = DUMMY_GUID1; + propkey.pid = PID_FIRST_USABLE; + hr = IPropertyStore_SetValue(propstore, &propkey, &propvar); + ok(hr == S_OK, "IPropertyStore_SetValue failed: 0x%08lx.\n", hr); + hr = IPropertyStore_Commit(propstore); + ok(hr == S_OK, "IPropertyStore_Commit failed: 0x%08lx.\n", hr); + hr = IPropertyStore_GetCount(propstore, &count); + ok(hr == S_OK, "IPropertyStore_GetCount failed: 0x%08lx.\n", hr); + ok(count == 1, "got wrong property count: %ld, expected 1.\n", count); + PropVariantInit(&ret_propvar); + hr = IPropertyStore_GetValue(propstore, &propkey, &ret_propvar); + ok(hr == S_OK, "IPropertyStore_GetValue failed: 0x%08lx.\n", hr); + ok(ret_propvar.vt == VT_EMPTY, "got wrong property type: %x.\n", ret_propvar.vt); + ok(!ret_propvar.lVal, "got wrong value: %ld, expected 0.\n", ret_propvar.lVal); + PropVariantClear(&propvar); + PropVariantClear(&ret_propvar); + + IPropertyStore_Release(propstore); +} + +static void test_PSCreatePropertyStoreFromObject(void) +{ + IPropertyStore *propstore; + IUnknown *unk; + HRESULT hr; + + hr = PSCreateMemoryPropertyStore(&IID_IPropertyStore, (void **)&propstore); + ok(hr == S_OK, "Failed to create property store, hr %#lx.\n", hr); + + hr = PSCreatePropertyStoreFromObject(NULL, STGM_READWRITE, &IID_IUnknown, (void **)&unk); + ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr); + + hr = PSCreatePropertyStoreFromObject((IUnknown *)propstore, STGM_READWRITE, &IID_IUnknown, NULL); + ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr); + + hr = PSCreatePropertyStoreFromObject((IUnknown *)propstore, STGM_READWRITE, &IID_IUnknown, (void **)&unk); + todo_wine + ok(hr == S_OK, "Failed to create wrapper, hr %#lx.\n", hr); + if (SUCCEEDED(hr)) + { + ok(unk != (IUnknown *)propstore, "Unexpected object returned.\n"); + IUnknown_Release(unk); + } + + hr = PSCreatePropertyStoreFromObject((IUnknown *)propstore, STGM_READWRITE, &IID_IPropertyStore, (void **)&unk); + ok(hr == S_OK, "Failed to create wrapper, hr %#lx.\n", hr); + ok(unk == (IUnknown *)propstore, "Unexpected object returned.\n"); + IUnknown_Release(unk); + + IPropertyStore_Release(propstore); +} + +static void test_InitVariantFromFileTime(void) +{ + FILETIME ft = {0}; + SYSTEMTIME st; + VARIANT var; + HRESULT hr; + double d; + + VariantInit(&var); + if (0) /* crash on Windows */ + { + InitVariantFromFileTime(&ft, NULL); + InitVariantFromFileTime(NULL, &var); + } + + ft.dwHighDateTime = -1; + ft.dwLowDateTime = -1; + V_VT(&var) = 0xdead; + V_DATE(&var) = 42.0; + hr = InitVariantFromFileTime(&ft, &var); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); + ok(V_VT(&var) == VT_EMPTY, "Unexpected VT %d\n", V_VT(&var)); + ok(V_DATE(&var) == 0.0, "got wrong value: %f, expected 0.0\n", V_DATE(&var)); + + GetSystemTimeAsFileTime(&ft); + hr = InitVariantFromFileTime(&ft, &var); + ok(V_VT(&var) == VT_DATE, "Unexpected VT %d\n", V_VT(&var)); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + FileTimeToSystemTime(&ft, &st); + SystemTimeToVariantTime(&st, &d); + ok(V_DATE(&var) == d, "got wrong value: %f, expected %f\n", V_DATE(&var), d); +} + +static void test_VariantToStringWithDefault(void) +{ + static WCHAR default_value[] = L"test"; + VARIANT var, var2; + PCWSTR result; + BSTR b; + + V_VT(&var) = VT_EMPTY; + result = VariantToStringWithDefault(&var, NULL); + ok(result == NULL, "Unexpected value %s\n", wine_dbgstr_w(result)); + result = VariantToStringWithDefault(&var, default_value); + ok(result == default_value, "Unexpected value %s\n", wine_dbgstr_w(result)); + + V_VT(&var) = VT_NULL; + result = VariantToStringWithDefault(&var, NULL); + ok(result == NULL, "Unexpected value %s\n", wine_dbgstr_w(result)); + result = VariantToStringWithDefault(&var, default_value); + ok(result == default_value, "Unexpected value %s\n", wine_dbgstr_w(result)); + + V_VT(&var) = VT_BOOL; + result = VariantToStringWithDefault(&var, NULL); + ok(result == NULL, "Unexpected value %s\n", wine_dbgstr_w(result)); + V_BOOL(&var) = VARIANT_TRUE; + result = VariantToStringWithDefault(&var, default_value); + ok(result == default_value, "Unexpected value %s\n", wine_dbgstr_w(result)); + + V_VT(&var) = VT_CY; + V_CY(&var).int64 = 100000; + result = VariantToStringWithDefault(&var, NULL); + ok(result == NULL, "Unexpected value %s\n", wine_dbgstr_w(result)); + result = VariantToStringWithDefault(&var, default_value); + ok(result == default_value, "Unexpected value %s\n", wine_dbgstr_w(result)); + + V_VT(&var) = VT_DATE; + V_DATE(&var) = 42.0; + result = VariantToStringWithDefault(&var, NULL); + ok(result == NULL, "Unexpected value %s\n", wine_dbgstr_w(result)); + result = VariantToStringWithDefault(&var, default_value); + ok(result == default_value, "Unexpected value %s\n", wine_dbgstr_w(result)); + + V_VT(&var) = VT_ERROR; + V_ERROR(&var) = DISP_E_PARAMNOTFOUND; + result = VariantToStringWithDefault(&var, NULL); + ok(result == NULL, "Unexpected value %s\n", wine_dbgstr_w(result)); + result = VariantToStringWithDefault(&var, default_value); + ok(result == default_value, "Unexpected value %s\n", wine_dbgstr_w(result)); + + V_VT(&var) = VT_I4; + V_I4(&var) = 15; + result = VariantToStringWithDefault(&var, NULL); + ok(result == NULL, "Unexpected value %s\n", wine_dbgstr_w(result)); + result = VariantToStringWithDefault(&var, default_value); + ok(result == default_value, "Unexpected value %s\n", wine_dbgstr_w(result)); + + V_VT(&var) = VT_I1; + V_I1(&var) = 1; + result = VariantToStringWithDefault(&var, NULL); + ok(result == NULL, "Unexpected value %s\n", wine_dbgstr_w(result)); + result = VariantToStringWithDefault(&var, default_value); + ok(result == default_value, "Unexpected value %s\n", wine_dbgstr_w(result)); + + /* V_BSTR */ + + V_VT(&var) = VT_BSTR; + V_BSTR(&var) = NULL; + result = VariantToStringWithDefault(&var, default_value); + ok(result[0] == '\0', "Unexpected value %s\n", wine_dbgstr_w(result)); + + V_VT(&var) = VT_BSTR; + V_BSTR(&var) = SysAllocString(L""); + result = VariantToStringWithDefault(&var, default_value); + ok(result == V_BSTR(&var), "Unexpected value %s\n", wine_dbgstr_w(result)); + VariantClear(&var); + + V_VT(&var) = VT_BSTR; + V_BSTR(&var) = SysAllocString(L" "); + result = VariantToStringWithDefault(&var, default_value); + ok(result == V_BSTR(&var), "Unexpected value %s\n", wine_dbgstr_w(result)); + VariantClear(&var); + + V_VT(&var) = VT_BSTR; + V_BSTR(&var) = SysAllocString(L"test1"); + result = VariantToStringWithDefault(&var, default_value); + ok(result == V_BSTR(&var), "Unexpected value %s\n", wine_dbgstr_w(result)); + VariantClear(&var); + + /* V_BSTRREF */ + + V_VT(&var) = VT_BYREF | VT_BSTR; + b = NULL; + V_BSTRREF(&var) = &b; + result = VariantToStringWithDefault(&var, default_value); + ok(result[0] == '\0', "Unexpected value %s\n", wine_dbgstr_w(result)); + + V_VT(&var) = VT_BYREF | VT_BSTR; + b = SysAllocString(L""); + V_BSTRREF(&var) = &b; + result = VariantToStringWithDefault(&var, default_value); + ok(result == b, "Unexpected value %s\n", wine_dbgstr_w(result)); + SysFreeString(b); + + V_VT(&var) = VT_BYREF | VT_BSTR; + b = SysAllocString(L" "); + V_BSTRREF(&var) = &b; + result = VariantToStringWithDefault(&var, default_value); + ok(result == b, "Unexpected value %s\n", wine_dbgstr_w(result)); + SysFreeString(b); + + V_VT(&var) = VT_BYREF | VT_BSTR; + b = SysAllocString(L"test1"); + V_BSTRREF(&var) = &b; + result = VariantToStringWithDefault(&var, default_value); + ok(result == b, "Unexpected value %s\n", wine_dbgstr_w(result)); + SysFreeString(b); + + /* Nested V_BSTR */ + + V_VT(&var) = VT_BYREF | VT_VARIANT; + V_VT(&var2) = VT_BSTR; + V_BSTR(&var2) = NULL; + V_VARIANTREF(&var) = &var2; + result = VariantToStringWithDefault(&var, default_value); + ok(result[0] == '\0', "Unexpected value %s\n", wine_dbgstr_w(result)); + + V_VT(&var) = VT_BYREF | VT_VARIANT; + V_VT(&var2) = VT_BSTR; + V_BSTR(&var2) = SysAllocString(L""); + V_VARIANTREF(&var) = &var2; + result = VariantToStringWithDefault(&var, default_value); + ok(result == V_BSTR(&var2), "Unexpected value %s\n", wine_dbgstr_w(result)); + VariantClear(&var2); + + V_VT(&var) = VT_BYREF | VT_VARIANT; + V_VT(&var2) = VT_BSTR; + V_BSTR(&var2) = SysAllocString(L" "); + V_VARIANTREF(&var) = &var2; + result = VariantToStringWithDefault(&var, default_value); + ok(result == V_BSTR(&var2), "Unexpected value %s\n", wine_dbgstr_w(result)); + VariantClear(&var2); + + V_VT(&var) = VT_BYREF | VT_VARIANT; + V_VT(&var2) = VT_BSTR; + V_BSTR(&var2) = SysAllocString(L"test1"); + V_VARIANTREF(&var) = &var2; + result = VariantToStringWithDefault(&var, default_value); + ok(result == V_BSTR(&var2), "Unexpected value %s\n", wine_dbgstr_w(result)); + VariantClear(&var2); + + /* Nested V_BSTRREF */ + + V_VT(&var) = VT_BYREF | VT_VARIANT; + V_VT(&var2) = VT_BYREF | VT_BSTR; + b = NULL; + V_BSTRREF(&var2) = &b; + V_VARIANTREF(&var) = &var2; + result = VariantToStringWithDefault(&var, default_value); + ok(result[0] == '\0', "Unexpected value %s\n", wine_dbgstr_w(result)); + + V_VT(&var) = VT_BYREF | VT_VARIANT; + V_VT(&var2) = VT_BYREF | VT_BSTR; + b = SysAllocString(L""); + V_BSTRREF(&var2) = &b; + V_VARIANTREF(&var) = &var2; + result = VariantToStringWithDefault(&var, default_value); + ok(result == b, "Unexpected value %s\n", wine_dbgstr_w(result)); + SysFreeString(b); + + V_VT(&var) = VT_BYREF | VT_VARIANT; + V_VT(&var2) = VT_BYREF | VT_BSTR; + b = SysAllocString(L" "); + V_BSTRREF(&var2) = &b; + V_VARIANTREF(&var) = &var2; + result = VariantToStringWithDefault(&var, default_value); + ok(result == b, "Unexpected value %s\n", wine_dbgstr_w(result)); + SysFreeString(b); + + V_VT(&var) = VT_BYREF | VT_VARIANT; + V_VT(&var2) = VT_BYREF | VT_BSTR; + b = SysAllocString(L"test1"); + V_BSTRREF(&var2) = &b; + V_VARIANTREF(&var) = &var2; + result = VariantToStringWithDefault(&var, default_value); + ok(result == b, "Unexpected value %s\n", wine_dbgstr_w(result)); + SysFreeString(b); +} + +static void test_VariantToString(void) +{ + HRESULT hr; + VARIANT v; + WCHAR buff[64]; + + buff[0] = 1; + V_VT(&v) = VT_EMPTY; + hr = VariantToString(&v, buff, 64); + todo_wine + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(!buff[0], "Unexpected buffer.\n"); + + buff[0] = 0; + V_VT(&v) = VT_I4; + V_I4(&v) = 567; + hr = VariantToString(&v, buff, 64); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(!wcscmp(buff, L"567"), "Unexpected buffer %s.\n", wine_dbgstr_w(buff)); + + V_VT(&v) = VT_BSTR; + V_BSTR(&v) = SysAllocString(L"test1"); + + buff[0] = 1; + hr = VariantToString(&v, buff, 0); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); + ok(!buff[0], "Unexpected buffer.\n"); + + hr = VariantToString(&v, buff, 5); + ok(hr == STRSAFE_E_INSUFFICIENT_BUFFER, "Unexpected hr %#lx.\n", hr); + hr = VariantToString(&v, buff, 6); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(!wcscmp(buff, L"test1"), "Unexpected string.\n"); + VariantClear(&v); +} + +#define check_VariantToPropVariant(var, propvar, type, member, value, format) do \ +{ \ + V_VT(&(var)) = VT_##type; \ + V_##type(&(var)) = (value); \ + hr = VariantToPropVariant(&(var), &(propvar)); \ + ok_(__FILE__, __LINE__)(hr == S_OK, "VariantToPropVariant returned %#lx.\n", hr); \ + ok_(__FILE__, __LINE__)((propvar).vt == VT_##type, "Unexpected propvar.vt %d.\n", (propvar).vt); \ + ok_(__FILE__, __LINE__)((propvar).member == (value), \ + "Unexpected propvar."#member" "format".\n", (propvar).member); \ +} while (0) + +#define check_PropVariantToVariant(propvar, var, type, member, value, format) do \ +{ \ + (propvar).vt = VT_##type; \ + (propvar).member = (value); \ + hr = PropVariantToVariant(&(propvar), &(var)); \ + ok_(__FILE__, __LINE__)(hr == S_OK, "PropVariantToVariant returned %#lx.\n", hr); \ + ok_(__FILE__, __LINE__)(V_VT(&(var)) == VT_##type, "Unexpected vt %d.\n", V_VT(&(var))); \ + ok_(__FILE__, __LINE__)(V_##type(&(var)) == (value), \ + "Unexpected V_"#type"(&var) "format".\n", (propvar).member); \ +} while (0) + +static void test_VariantToPropVariant(void) +{ + PROPVARIANT propvar; + VARIANT var; + HRESULT hr; + + VariantInit(&var); + PropVariantInit(&propvar); + + hr = VariantToPropVariant(NULL, &propvar); + ok(hr == E_INVALIDARG, "VariantToPropVariant returned %#lx.\n", hr); + hr = VariantToPropVariant(&var, NULL); + ok(hr == E_INVALIDARG, "VariantToPropVariant returned %#lx.\n", hr); + + V_VT(&var) = 0xdead; + hr = VariantToPropVariant(&var, &propvar); + ok(hr == DISP_E_BADVARTYPE, "VariantToPropVariant returned %#lx.\n", hr); + V_VT(&var) = VT_ILLEGAL; + hr = VariantToPropVariant(&var, &propvar); + todo_wine + ok(hr == TYPE_E_TYPEMISMATCH, "VariantToPropVariant returned %#lx.\n", hr); + V_VT(&var) = VT_CLSID; + hr = VariantToPropVariant(&var, &propvar); + todo_wine + ok(hr == DISP_E_BADVARTYPE, "VariantToPropVariant returned %#lx.\n", hr); + + V_VT(&var) = VT_EMPTY; + hr = VariantToPropVariant(&var, &propvar); + ok(hr == S_OK, "VariantToPropVariant returned %#lx.\n", hr); + ok(propvar.vt == VT_EMPTY, "Unexpected propvar.vt %d.\n", propvar.vt); + + V_VT(&var) = VT_NULL; + hr = VariantToPropVariant(&var, &propvar); + ok(hr == S_OK, "VariantToPropVariant returned %#lx.\n", hr); + ok(propvar.vt == VT_NULL, "Unexpected propvar.vt %d.\n", propvar.vt); + + check_VariantToPropVariant(var, propvar, I1, cVal, -123, "%c"); + check_VariantToPropVariant(var, propvar, I2, iVal, -456, "%d"); + check_VariantToPropVariant(var, propvar, I4, lVal, -789, "%ld"); + check_VariantToPropVariant(var, propvar, I8, hVal.QuadPart, -101112, "%I64d"); + + check_VariantToPropVariant(var, propvar, UI1, bVal, 0xcd, "%#x"); + check_VariantToPropVariant(var, propvar, UI2, uiVal, 0xdead, "%#x"); + check_VariantToPropVariant(var, propvar, UI4, ulVal, 0xdeadbeef, "%#lx"); + check_VariantToPropVariant(var, propvar, UI8, uhVal.QuadPart, 0xdeadbeefdeadbeef, "%I64x"); + + check_VariantToPropVariant(var, propvar, BOOL, boolVal, TRUE, "%d"); + + check_VariantToPropVariant(var, propvar, R4, fltVal, 0.123f, "%f"); + check_VariantToPropVariant(var, propvar, R8, dblVal, 0.456f, "%f"); + + V_VT(&var) = VT_BSTR; + V_BSTR(&var) = SysAllocString(L"test"); + hr = VariantToPropVariant(&var, &propvar); + ok(hr == S_OK, "VariantToPropVariant returned %#lx.\n", hr); + ok(propvar.vt == VT_BSTR, "Unexpected propvar.vt %d.\n", propvar.vt); + ok(propvar.bstrVal != V_BSTR(&var), "Got same string pointer.\n"); + ok(!wcscmp(propvar.bstrVal, V_BSTR(&var)), "Unexpected propvar.bstrVal %s.\n", debugstr_w(propvar.bstrVal)); + + PropVariantClear(&propvar); + VariantClear(&var); +} + +static void test_PropVariantToVariant(void) +{ + PROPVARIANT propvar; + VARIANT var; + HRESULT hr; + + VariantInit(&var); + PropVariantInit(&propvar); + + hr = PropVariantToVariant(NULL, &var); + ok(hr == E_INVALIDARG, "PropVariantToVariant returned %#lx.\n", hr); + hr = PropVariantToVariant(&propvar, NULL); + ok(hr == E_INVALIDARG, "PropVariantToVariant returned %#lx.\n", hr); + + propvar.vt = 0xdead; + hr = PropVariantToVariant(&propvar, &var); + todo_wine + ok(hr == E_OUTOFMEMORY, "PropVariantToVariant returned %#lx.\n", hr); + propvar.vt = VT_ILLEGAL; + hr = PropVariantToVariant(&propvar, &var); + todo_wine + ok(hr == E_OUTOFMEMORY, "PropVariantToVariant returned %#lx.\n", hr); + + propvar.vt = VT_EMPTY; + hr = PropVariantToVariant(&propvar, &var); + ok(hr == S_OK, "PropVariantToVariant returned %#lx.\n", hr); + ok(V_VT(&var) == VT_EMPTY, "Unexpected V_VT(&var) %d.\n", V_VT(&var)); + + propvar.vt = VT_NULL; + hr = PropVariantToVariant(&propvar, &var); + ok(hr == S_OK, "PropVariantToVariant returned %#lx.\n", hr); + ok(V_VT(&var) == VT_NULL, "Unexpected V_VT(&var) %d.\n", V_VT(&var)); + + check_PropVariantToVariant(propvar, var, I1, cVal, 'X', "%c"); + check_PropVariantToVariant(propvar, var, I2, iVal, -456, "%d"); + check_PropVariantToVariant(propvar, var, I4, lVal, -789, "%ld"); + check_PropVariantToVariant(propvar, var, I8, hVal.QuadPart, -101112, "%I64d"); + + check_PropVariantToVariant(propvar, var, UI1, bVal, 0xcd, "%#x"); + check_PropVariantToVariant(propvar, var, UI2, uiVal, 0xdead, "%#x"); + check_PropVariantToVariant(propvar, var, UI4, ulVal, 0xdeadbeef, "%#lx"); + check_PropVariantToVariant(propvar, var, UI8, uhVal.QuadPart, 0xdeadbeefdeadbeef, "%I64x"); + + check_PropVariantToVariant(propvar, var, BOOL, boolVal, TRUE, "%d"); + + check_PropVariantToVariant(propvar, var, R4, fltVal, 0.123f, "%f"); + check_PropVariantToVariant(propvar, var, R8, dblVal, 0.456f, "%f"); + + propvar.vt = VT_BSTR; + propvar.bstrVal = SysAllocString(L"test"); + hr = PropVariantToVariant(&propvar, &var); + ok(hr == S_OK, "PropVariantToVariant returned %#lx.\n", hr); + ok(V_VT(&var) == VT_BSTR, "Unexpected V_VT(&var) %d.\n", V_VT(&var)); + ok(V_BSTR(&var) != propvar.bstrVal, "Got same string pointer.\n"); + ok(!wcscmp(V_BSTR(&var), propvar.bstrVal), "Unexpected V_BSTR(&var) %s.\n", debugstr_w(V_BSTR(&var))); + PropVariantClear(&propvar); + VariantClear(&var); + + propvar.vt = VT_CLSID; + propvar.puuid = (GUID *)&dummy_guid; + hr = PropVariantToVariant(&propvar, &var); + todo_wine + ok(hr == 39, "PropVariantToVariant returned %#lx.\n", hr); + ok(V_VT(&var) == VT_BSTR, "Unexpected V_VT(&var) %d.\n", V_VT(&var)); + ok(!wcscmp(V_BSTR(&var), dummy_guid_str), "Unexpected V_BSTR(&var) %s.\n", debugstr_w(V_BSTR(&var))); + VariantClear(&var); + + propvar.vt = VT_LPSTR; + propvar.pszVal = (char *)topic; + hr = PropVariantToVariant(&propvar, &var); + ok(hr == S_OK, "PropVariantToVariant returned %#lx.\n", hr); + ok(V_VT(&var) == VT_BSTR, "Unexpected V_VT(&var) %d.\n", V_VT(&var)); + ok(!wcscmp(V_BSTR(&var), topicW), "Unexpected V_BSTR(&var) %s.\n", debugstr_w(V_BSTR(&var))); + VariantClear(&var); + + propvar.vt = VT_LPWSTR; + propvar.pwszVal = (WCHAR *)topicW; + hr = PropVariantToVariant(&propvar, &var); + ok(hr == S_OK, "PropVariantToVariant returned %#lx.\n", hr); + ok(V_VT(&var) == VT_BSTR, "Unexpected V_VT(&var) %d.\n", V_VT(&var)); + ok(V_BSTR(&var) != topicW, "Got same string pointer.\n"); + ok(!wcscmp(V_BSTR(&var), topicW), "Unexpected V_BSTR(&var) %s.\n", debugstr_w(V_BSTR(&var))); + VariantClear(&var); +} + START_TEST(propsys) { + test_InitPropVariantFromGUIDAsString(); + test_InitPropVariantFromBuffer(); + test_InitPropVariantFromCLSID(); + test_InitPropVariantFromStringVector(); + test_InitVariantFromFileTime(); + test_PSStringFromPropertyKey(); test_PSPropertyKeyFromString(); test_PSRefreshPropertySchema(); - test_InitPropVariantFromGUIDAsString(); - test_InitPropVariantFromBuffer(); test_PropVariantToGUID(); test_PropVariantToStringAlloc(); - test_PropVariantCompare(); + test_PropVariantCompareEx(); test_intconversions(); test_PropVariantChangeType_LPWSTR(); test_PropVariantToBoolean(); test_PropVariantToStringWithDefault(); - test_InitPropVariantFromCLSID(); test_PropVariantToDouble(); test_PropVariantToString(); + test_PropVariantToBSTR(); test_PropVariantToBuffer(); + test_inmemorystore(); + test_persistserialized(); + test_PSCreateMemoryPropertyStore(); + test_propertystore(); + test_PSCreatePropertyStoreFromObject(); + test_VariantToStringWithDefault(); + test_VariantToString(); + test_VariantToPropVariant(); + test_PropVariantToVariant(); } diff --git a/modules/rostests/winetests/propsys/testlist.c b/modules/rostests/winetests/propsys/testlist.c index 3773d6ad652..364dec7c1a9 100644 --- a/modules/rostests/winetests/propsys/testlist.c +++ b/modules/rostests/winetests/propsys/testlist.c @@ -3,12 +3,10 @@ #define STANDALONE #include -extern void func_propstore(void); extern void func_propsys(void); const struct test winetest_testlist[] = { - { "propstore", func_propstore }, { "propsys", func_propsys }, { 0, 0 } }; diff --git a/sdk/include/psdk/oaidl.idl b/sdk/include/psdk/oaidl.idl index 0dc4c057460..27e27a92125 100644 --- a/sdk/include/psdk/oaidl.idl +++ b/sdk/include/psdk/oaidl.idl @@ -230,6 +230,17 @@ typedef VARIANT *LPVARIANT; typedef VARIANT VARIANTARG; typedef VARIANTARG *LPVARIANTARG; +cpp_quote("#ifdef MIDL_PASS") +typedef const VARIANT *REFVARIANT; +cpp_quote("#elif !defined(_REFVARIANT_DEFINED)") +cpp_quote("#define _REFVARIANT_DEFINED") +cpp_quote("#ifdef __cplusplus") +cpp_quote("#define REFVARIANT const VARIANT &") +cpp_quote("#else") +cpp_quote("#define REFVARIANT const VARIANT *__MIDL_CONST") +cpp_quote("#endif") +cpp_quote("#endif") + struct _wireBRECORD { ULONG fFlags; ULONG clSize; diff --git a/sdk/include/psdk/propsys.idl b/sdk/include/psdk/propsys.idl index bdd67fa6a59..240bbfd86ca 100644 --- a/sdk/include/psdk/propsys.idl +++ b/sdk/include/psdk/propsys.idl @@ -27,7 +27,13 @@ import "shtypes.idl"; import "structuredquerycondition.idl"; cpp_quote("#ifndef PSSTDAPI") -cpp_quote("#define PSSTDAPI EXTERN_C DECLSPEC_IMPORT HRESULT STDAPICALLTYPE") +cpp_quote("#ifdef _PROPSYS_") +cpp_quote("#define PSSTDAPI STDAPI") +cpp_quote("#define PSSTDAPI_(type) STDAPI_(type)") +cpp_quote("#else") +cpp_quote("#define PSSTDAPI EXTERN_C DECLSPEC_IMPORT HRESULT STDAPICALLTYPE") +cpp_quote("#define PSSTDAPI_(type) EXTERN_C DECLSPEC_IMPORT type STDAPICALLTYPE") +cpp_quote("#endif") cpp_quote("#endif") cpp_quote("#if 0") @@ -272,7 +278,7 @@ interface IPropertyEnumType : IUnknown } [ - uuid(9b6e051c-5ddd-4321-9070-fe2acb55e974), + uuid(9b6e051c-5ddd-4321-9070-fe2acb55e794), object, pointer_default(unique) ] @@ -799,14 +805,15 @@ cpp_quote("#define PKEY_PIDSTR_MAX 10") cpp_quote("#define GUIDSTRING_MAX 39") cpp_quote("#define PKEYSTR_MAX (GUIDSTRING_MAX + 1 + PKEY_PIDSTR_MAX)") -cpp_quote("HRESULT WINAPI PSCreateMemoryPropertyStore(REFIID,void **);") -cpp_quote("HRESULT WINAPI PSStringFromPropertyKey(REFPROPERTYKEY,LPWSTR,UINT);") -cpp_quote("HRESULT WINAPI PSPropertyKeyFromString(LPCWSTR,PROPERTYKEY*);") -cpp_quote("HRESULT WINAPI PSGetPropertyDescription(REFPROPERTYKEY,REFIID,void **);") -cpp_quote("HRESULT WINAPI PSGetPropertyDescriptionListFromString(LPCWSTR,REFIID,void **);") -cpp_quote("HRESULT WINAPI PSRefreshPropertySchema(void);") -cpp_quote("HRESULT WINAPI PSRegisterPropertySchema(LPCWSTR);") -cpp_quote("HRESULT WINAPI PSUnregisterPropertySchema(LPCWSTR);") +cpp_quote("PSSTDAPI PSCreateMemoryPropertyStore(REFIID,void **);") +cpp_quote("PSSTDAPI PSCreatePropertyStoreFromObject(IUnknown*,DWORD,REFIID,void **);") +cpp_quote("PSSTDAPI PSStringFromPropertyKey(REFPROPERTYKEY,LPWSTR,UINT);") +cpp_quote("PSSTDAPI PSPropertyKeyFromString(LPCWSTR,PROPERTYKEY*);") +cpp_quote("PSSTDAPI PSGetPropertyDescription(REFPROPERTYKEY,REFIID,void **);") +cpp_quote("PSSTDAPI PSGetPropertyDescriptionListFromString(LPCWSTR,REFIID,void **);") +cpp_quote("PSSTDAPI PSRefreshPropertySchema(void);") +cpp_quote("PSSTDAPI PSRegisterPropertySchema(LPCWSTR);") +cpp_quote("PSSTDAPI PSUnregisterPropertySchema(LPCWSTR);") /* TODO: Add remainder of the C api here */ @@ -821,7 +828,7 @@ library PropSysObjects { interface IPropertyStore; } - [uuid(b8967f86-58ae-4f96-9fb2-5d7904798f4b)] coclass PropertySystem + [uuid(b8967f85-58ae-4f46-9fb2-5d7904798f4b)] coclass PropertySystem { interface IPropertySystem; } diff --git a/sdk/include/psdk/propvarutil.h b/sdk/include/psdk/propvarutil.h index e0a21faf8c7..9f689033548 100644 --- a/sdk/include/psdk/propvarutil.h +++ b/sdk/include/psdk/propvarutil.h @@ -22,6 +22,16 @@ #include #include +#ifndef PSSTDAPI +#ifdef _PROPSYS_ +#define PSSTDAPI STDAPI +#define PSSTDAPI_(type) STDAPI_(type) +#else +#define PSSTDAPI DECLSPEC_IMPORT STDAPI +#define PSSTDAPI_(type) DECLSPEC_IMPORT STDAPI_(type) +#endif +#endif + #ifdef __cplusplus extern "C" { #endif @@ -63,37 +73,56 @@ enum tagPROPVAR_COMPARE_FLAGS typedef int PROPVAR_COMPARE_FLAGS; -HRESULT WINAPI PropVariantChangeType(PROPVARIANT *ppropvarDest, REFPROPVARIANT propvarSrc, +PSSTDAPI PropVariantChangeType(PROPVARIANT *ppropvarDest, REFPROPVARIANT propvarSrc, PROPVAR_CHANGE_FLAGS flags, VARTYPE vt); -HRESULT WINAPI InitPropVariantFromGUIDAsString(REFGUID guid, PROPVARIANT *ppropvar); -HRESULT WINAPI InitVariantFromGUIDAsString(REFGUID guid, VARIANT *pvar); -HRESULT WINAPI InitPropVariantFromBuffer(const VOID *pv, UINT cb, PROPVARIANT *ppropvar); -HRESULT WINAPI InitPropVariantFromCLSID(REFCLSID clsid, PROPVARIANT *ppropvar); -HRESULT WINAPI InitVariantFromBuffer(const VOID *pv, UINT cb, VARIANT *pvar); -HRESULT WINAPI PropVariantToGUID(const PROPVARIANT *ppropvar, GUID *guid); -HRESULT WINAPI VariantToGUID(const VARIANT *pvar, GUID *guid); -INT WINAPI PropVariantCompareEx(REFPROPVARIANT propvar1, REFPROPVARIANT propvar2, +PSSTDAPI InitPropVariantFromGUIDAsString(REFGUID guid, PROPVARIANT *ppropvar); +PSSTDAPI InitVariantFromFileTime(const FILETIME *ft, VARIANT *var); +PSSTDAPI InitVariantFromGUIDAsString(REFGUID guid, VARIANT *pvar); +PSSTDAPI InitPropVariantFromBuffer(const VOID *pv, UINT cb, PROPVARIANT *ppropvar); +PSSTDAPI InitPropVariantFromCLSID(REFCLSID clsid, PROPVARIANT *ppropvar); +PSSTDAPI InitVariantFromBuffer(const VOID *pv, UINT cb, VARIANT *pvar); +PSSTDAPI PropVariantToGUID(const PROPVARIANT *ppropvar, GUID *guid); +PSSTDAPI VariantToGUID(const VARIANT *pvar, GUID *guid); +PSSTDAPI_(INT) PropVariantCompareEx(REFPROPVARIANT propvar1, REFPROPVARIANT propvar2, PROPVAR_COMPARE_UNIT uint, PROPVAR_COMPARE_FLAGS flags); +PSSTDAPI InitPropVariantFromFileTime(const FILETIME *pftIn, PROPVARIANT *ppropvar); +PSSTDAPI InitPropVariantFromStringVector(PCWSTR *strs, ULONG count, PROPVARIANT *ppropvar); -HRESULT WINAPI PropVariantToDouble(REFPROPVARIANT propvarIn, double *ret); -HRESULT WINAPI PropVariantToInt16(REFPROPVARIANT propvarIn, SHORT *ret); -HRESULT WINAPI PropVariantToInt32(REFPROPVARIANT propvarIn, LONG *ret); -HRESULT WINAPI PropVariantToInt64(REFPROPVARIANT propvarIn, LONGLONG *ret); -HRESULT WINAPI PropVariantToUInt16(REFPROPVARIANT propvarIn, USHORT *ret); -HRESULT WINAPI PropVariantToUInt32(REFPROPVARIANT propvarIn, ULONG *ret); -HRESULT WINAPI PropVariantToUInt64(REFPROPVARIANT propvarIn, ULONGLONG *ret); -HRESULT WINAPI PropVariantToBoolean(REFPROPVARIANT propvarIn, BOOL *ret); -HRESULT WINAPI PropVariantToBuffer(REFPROPVARIANT propvarIn, void *ret, UINT cb); -HRESULT WINAPI PropVariantToString(REFPROPVARIANT propvarIn, PWSTR ret, UINT cch); -PCWSTR WINAPI PropVariantToStringWithDefault(REFPROPVARIANT propvarIn, LPCWSTR pszDefault); +PSSTDAPI PropVariantToDouble(REFPROPVARIANT propvarIn, double *ret); +PSSTDAPI PropVariantToInt16(REFPROPVARIANT propvarIn, SHORT *ret); +PSSTDAPI PropVariantToInt32(REFPROPVARIANT propvarIn, LONG *ret); +PSSTDAPI PropVariantToInt64(REFPROPVARIANT propvarIn, LONGLONG *ret); +PSSTDAPI PropVariantToUInt16(REFPROPVARIANT propvarIn, USHORT *ret); +PSSTDAPI PropVariantToUInt32(REFPROPVARIANT propvarIn, ULONG *ret); +PSSTDAPI_(ULONG) PropVariantToUInt32WithDefault(REFPROPVARIANT propvarIn, ULONG uLDefault); +PSSTDAPI PropVariantToUInt64(REFPROPVARIANT propvarIn, ULONGLONG *ret); +PSSTDAPI PropVariantToBoolean(REFPROPVARIANT propvarIn, BOOL *ret); +PSSTDAPI PropVariantToBSTR(REFPROPVARIANT propvar, BSTR *bstr); +PSSTDAPI PropVariantToBuffer(REFPROPVARIANT propvarIn, void *ret, UINT cb); +PSSTDAPI PropVariantToString(REFPROPVARIANT propvarIn, PWSTR ret, UINT cch); +PSSTDAPI_(PCWSTR) PropVariantToStringWithDefault(REFPROPVARIANT propvarIn, LPCWSTR pszDefault); +PSSTDAPI_(PCWSTR) VariantToStringWithDefault(const VARIANT *pvar, LPCWSTR pszDefault); +PSSTDAPI VariantToString(REFVARIANT var, PWSTR ret, UINT cch); -HRESULT WINAPI PropVariantToStringAlloc(REFPROPVARIANT propvarIn, WCHAR **ret); +PSSTDAPI PropVariantToStringAlloc(REFPROPVARIANT propvarIn, WCHAR **ret); + +PSSTDAPI PropVariantToVariant(const PROPVARIANT *propvar, VARIANT *var); +PSSTDAPI VariantToPropVariant(const VARIANT* var, PROPVARIANT* propvar); #ifdef __cplusplus HRESULT InitPropVariantFromBoolean(BOOL fVal, PROPVARIANT *ppropvar); -HRESULT InitPropVariantFromString(PCWSTR psz, PROPVARIANT *ppropvar); +HRESULT InitPropVariantFromInt16(SHORT nVal, PROPVARIANT *ppropvar); +HRESULT InitPropVariantFromUInt16(USHORT uiVal, PROPVARIANT *ppropvar); +HRESULT InitPropVariantFromInt32(LONG lVal, PROPVARIANT *ppropvar); +HRESULT InitPropVariantFromUInt32(ULONG ulVal, PROPVARIANT *ppropvar); HRESULT InitPropVariantFromInt64(LONGLONG llVal, PROPVARIANT *ppropvar); +HRESULT InitPropVariantFromUInt64(ULONGLONG ullVal, PROPVARIANT *ppropvar); +HRESULT InitPropVariantFromDouble(DOUBLE dblVal, PROPVARIANT *ppropvar); +HRESULT InitPropVariantFromString(PCWSTR psz, PROPVARIANT *ppropvar); +HRESULT InitPropVariantFromGUIDAsBuffer(REFGUID guid, PROPVARIANT *ppropvar); +BOOL IsPropVariantVector(REFPROPVARIANT propvar); +BOOL IsPropVariantString(REFPROPVARIANT propvar); #ifndef NO_PROPVAR_INLINES @@ -104,6 +133,55 @@ inline HRESULT InitPropVariantFromBoolean(BOOL fVal, PROPVARIANT *ppropvar) return S_OK; } +inline HRESULT InitPropVariantFromInt16(SHORT nVal, PROPVARIANT *ppropvar) +{ + ppropvar->vt = VT_I2; + ppropvar->iVal = nVal; + return S_OK; +} + +inline HRESULT InitPropVariantFromUInt16(USHORT uiVal, PROPVARIANT *ppropvar) +{ + ppropvar->vt = VT_UI2; + ppropvar->uiVal = uiVal; + return S_OK; +} + +inline HRESULT InitPropVariantFromInt32(LONG lVal, PROPVARIANT *ppropvar) +{ + ppropvar->vt = VT_I4; + ppropvar->lVal = lVal; + return S_OK; +} + +inline HRESULT InitPropVariantFromUInt32(ULONG ulVal, PROPVARIANT *ppropvar) +{ + ppropvar->vt = VT_UI4; + ppropvar->ulVal = ulVal; + return S_OK; +} + +inline HRESULT InitPropVariantFromInt64(LONGLONG llVal, PROPVARIANT *ppropvar) +{ + ppropvar->vt = VT_I8; + ppropvar->hVal.QuadPart = llVal; + return S_OK; +} + +inline HRESULT InitPropVariantFromUInt64(ULONGLONG ullVal, PROPVARIANT *ppropvar) +{ + ppropvar->vt = VT_UI8; + ppropvar->uhVal.QuadPart = ullVal; + return S_OK; +} + +inline HRESULT InitPropVariantFromDouble(DOUBLE dblVal, PROPVARIANT *ppropvar) +{ + ppropvar->vt = VT_R8; + ppropvar->dblVal = dblVal; + return S_OK; +} + inline HRESULT InitPropVariantFromString(PCWSTR psz, PROPVARIANT *ppropvar) { HRESULT hres; @@ -117,16 +195,26 @@ inline HRESULT InitPropVariantFromString(PCWSTR psz, PROPVARIANT *ppropvar) return hres; } -inline HRESULT InitPropVariantFromInt64(LONGLONG llVal, PROPVARIANT *ppropvar) +inline HRESULT InitPropVariantFromGUIDAsBuffer(REFGUID guid, PROPVARIANT *ppropvar) { - ppropvar->vt = VT_I8; - ppropvar->hVal.QuadPart = llVal; - return S_OK; + return InitPropVariantFromBuffer(&guid, sizeof(GUID), ppropvar); +} + +inline BOOL IsPropVariantVector(REFPROPVARIANT propvar) +{ + return (propvar.vt & (VT_ARRAY | VT_VECTOR)); +} + +inline BOOL IsPropVariantString(REFPROPVARIANT propvar) +{ + return (PropVariantToStringWithDefault(propvar, NULL) != NULL); } #endif /* NO_PROPVAR_INLINES */ #endif /* __cplusplus */ +PSSTDAPI StgSerializePropVariant(const PROPVARIANT *ppropvar, SERIALIZEDPROPERTYVALUE **ppprop, ULONG *pcb); +PSSTDAPI StgDeserializePropVariant(const SERIALIZEDPROPERTYVALUE *pprop, ULONG cbmax, PROPVARIANT *ppropvar); #ifdef __cplusplus } diff --git a/sdk/tools/winesync/propsys.cfg b/sdk/tools/winesync/propsys.cfg new file mode 100644 index 00000000000..1c8b99a3dfc --- /dev/null +++ b/sdk/tools/winesync/propsys.cfg @@ -0,0 +1,9 @@ +directories: + dlls/propsys: dll/win32/propsys + dlls/propsys/tests: modules/rostests/winetests/propsys +files: + include/oaidl.idl: sdk/include/psdk/oaidl.idl + include/propsys.idl: sdk/include/psdk/propsys.idl + include/propvarutil.h: sdk/include/psdk/propvarutil.h +tags: + wine: wine-10.0