mirror of
https://github.com/reactos/reactos.git
synced 2025-05-02 12:15:23 +00:00
[PROPSYS]
* Import from Wine 1.5.26. svn path=/trunk/; revision=58567
This commit is contained in:
parent
539c2e45ec
commit
7b8f48d896
11 changed files with 1781 additions and 0 deletions
|
@ -145,6 +145,7 @@ add_subdirectory(pdh)
|
|||
add_subdirectory(pidgen)
|
||||
add_subdirectory(powrprof)
|
||||
add_subdirectory(printui)
|
||||
add_subdirectory(propsys)
|
||||
add_subdirectory(psapi)
|
||||
add_subdirectory(pstorec)
|
||||
add_subdirectory(qmgr)
|
||||
|
|
20
reactos/dll/win32/propsys/CMakeLists.txt
Normal file
20
reactos/dll/win32/propsys/CMakeLists.txt
Normal file
|
@ -0,0 +1,20 @@
|
|||
|
||||
include_directories(${REACTOS_SOURCE_DIR}/include/reactos/wine)
|
||||
add_definitions(-D__WINESRC__)
|
||||
|
||||
spec2def(propsys.dll propsys.spec ADD_IMPORTLIB)
|
||||
|
||||
list(APPEND SOURCE
|
||||
propstore.c
|
||||
propsys_main.c
|
||||
propvar.c
|
||||
propsys.rc
|
||||
${CMAKE_CURRENT_BINARY_DIR}/propsys_stubs.c
|
||||
${CMAKE_CURRENT_BINARY_DIR}/propsys.def)
|
||||
|
||||
add_library(propsys SHARED ${SOURCE})
|
||||
set_module_type(propsys win32dll)
|
||||
target_link_libraries(propsys uuid wine)
|
||||
add_importlibs(propsys ole32 oleaut32 msvcrt kernel32 ntdll)
|
||||
add_dependencies(propsys psdk)
|
||||
add_cd_file(TARGET propsys DESTINATION reactos/system32 FOR all)
|
481
reactos/dll/win32/propsys/propstore.c
Normal file
481
reactos/dll/win32/propsys/propstore.c
Normal file
|
@ -0,0 +1,481 @@
|
|||
/*
|
||||
* standard IPropertyStore implementation
|
||||
*
|
||||
* Copyright 2012 Vincent Povirk for CodeWeavers
|
||||
*
|
||||
* 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 WIN32_NO_STATUS
|
||||
#define _INC_WINDOWS
|
||||
#define COM_NO_WINDOWS_H
|
||||
|
||||
#define COBJMACROS
|
||||
#include <config.h>
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include <windef.h>
|
||||
#include <winbase.h>
|
||||
#include <objbase.h>
|
||||
//#include "rpcproxy.h"
|
||||
#include <propsys.h>
|
||||
#include <wine/debug.h>
|
||||
//#include "wine/unicode.h"
|
||||
#include <wine/list.h>
|
||||
|
||||
#include <initguid.h>
|
||||
//#include "propsys_private.h"
|
||||
|
||||
DEFINE_GUID(FMTID_NamedProperties, 0xd5cdd505, 0x2e9c, 0x101b, 0x93, 0x97, 0x08, 0x00, 0x2b, 0x2c, 0xf9, 0xae);
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(propsys);
|
||||
|
||||
typedef struct {
|
||||
struct list entry;
|
||||
DWORD pid;
|
||||
PROPVARIANT propvar;
|
||||
PSC_STATE state;
|
||||
} propstore_value;
|
||||
|
||||
typedef struct {
|
||||
struct list entry;
|
||||
GUID fmtid;
|
||||
struct list values; /* list of struct propstore_value */
|
||||
DWORD count;
|
||||
} propstore_format;
|
||||
|
||||
typedef struct {
|
||||
IPropertyStoreCache IPropertyStoreCache_iface;
|
||||
LONG ref;
|
||||
CRITICAL_SECTION lock;
|
||||
struct list formats; /* list of struct propstore_format */
|
||||
} PropertyStore;
|
||||
|
||||
static inline PropertyStore *impl_from_IPropertyStoreCache(IPropertyStoreCache *iface)
|
||||
{
|
||||
return CONTAINING_RECORD(iface, PropertyStore, IPropertyStoreCache_iface);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI PropertyStore_QueryInterface(IPropertyStoreCache *iface, REFIID iid,
|
||||
void **ppv)
|
||||
{
|
||||
PropertyStore *This = impl_from_IPropertyStoreCache(iface);
|
||||
TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
|
||||
|
||||
if (!ppv) return E_INVALIDARG;
|
||||
|
||||
if (IsEqualIID(&IID_IUnknown, iid) || IsEqualIID(&IID_IPropertyStore, iid) ||
|
||||
IsEqualIID(&IID_IPropertyStoreCache, iid))
|
||||
{
|
||||
*ppv = &This->IPropertyStoreCache_iface;
|
||||
}
|
||||
else
|
||||
{
|
||||
FIXME("No interface for %s\n", debugstr_guid(iid));
|
||||
*ppv = NULL;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
IUnknown_AddRef((IUnknown*)*ppv);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
static void destroy_format(propstore_format *format)
|
||||
{
|
||||
propstore_value *cursor, *cursor2;
|
||||
LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, &format->values, propstore_value, entry)
|
||||
{
|
||||
PropVariantClear(&cursor->propvar);
|
||||
HeapFree(GetProcessHeap(), 0, cursor);
|
||||
}
|
||||
HeapFree(GetProcessHeap(), 0, format);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
if (ref == 0)
|
||||
{
|
||||
propstore_format *cursor, *cursor2;
|
||||
This->lock.DebugInfo->Spare[0] = 0;
|
||||
DeleteCriticalSection(&This->lock);
|
||||
LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, &This->formats, propstore_format, entry)
|
||||
destroy_format(cursor);
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
}
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI PropertyStore_GetCount(IPropertyStoreCache *iface,
|
||||
DWORD *cProps)
|
||||
{
|
||||
PropertyStore *This = impl_from_IPropertyStoreCache(iface);
|
||||
propstore_format *format;
|
||||
|
||||
TRACE("%p,%p\n", iface, cProps);
|
||||
|
||||
if (!cProps)
|
||||
return E_POINTER;
|
||||
|
||||
*cProps = 0;
|
||||
|
||||
EnterCriticalSection(&This->lock);
|
||||
|
||||
LIST_FOR_EACH_ENTRY(format, &This->formats, propstore_format, entry)
|
||||
*cProps += format->count;
|
||||
|
||||
LeaveCriticalSection(&This->lock);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI PropertyStore_GetAt(IPropertyStoreCache *iface,
|
||||
DWORD iProp, PROPERTYKEY *pkey)
|
||||
{
|
||||
PropertyStore *This = impl_from_IPropertyStoreCache(iface);
|
||||
propstore_format *format=NULL, *format_candidate;
|
||||
propstore_value *value;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("%p,%d,%p\n", iface, iProp, pkey);
|
||||
|
||||
if (!pkey)
|
||||
return E_POINTER;
|
||||
|
||||
EnterCriticalSection(&This->lock);
|
||||
|
||||
LIST_FOR_EACH_ENTRY(format_candidate, &This->formats, propstore_format, entry)
|
||||
{
|
||||
if (format_candidate->count > iProp)
|
||||
{
|
||||
format = format_candidate;
|
||||
pkey->fmtid = format->fmtid;
|
||||
break;
|
||||
}
|
||||
|
||||
iProp -= format_candidate->count;
|
||||
}
|
||||
|
||||
if (format)
|
||||
{
|
||||
LIST_FOR_EACH_ENTRY(value, &format->values, propstore_value, entry)
|
||||
{
|
||||
if (iProp == 0)
|
||||
{
|
||||
pkey->pid = value->pid;
|
||||
break;
|
||||
}
|
||||
|
||||
iProp--;
|
||||
}
|
||||
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
hr = E_INVALIDARG;
|
||||
|
||||
LeaveCriticalSection(&This->lock);
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT PropertyStore_LookupValue(PropertyStore *This, REFPROPERTYKEY key,
|
||||
int insert, propstore_value **result)
|
||||
{
|
||||
propstore_format *format=NULL, *format_candidate;
|
||||
propstore_value *value=NULL, *value_candidate;
|
||||
|
||||
if (IsEqualGUID(&key->fmtid, &FMTID_NamedProperties))
|
||||
{
|
||||
/* This is used in the property store format [MS-PROPSTORE]
|
||||
* for named values and probably gets special treatment. */
|
||||
ERR("don't know how to handle FMTID_NamedProperties\n");
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
LIST_FOR_EACH_ENTRY(format_candidate, &This->formats, propstore_format, entry)
|
||||
{
|
||||
if (IsEqualGUID(&format_candidate->fmtid, &key->fmtid))
|
||||
{
|
||||
format = format_candidate;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!format)
|
||||
{
|
||||
if (!insert)
|
||||
return TYPE_E_ELEMENTNOTFOUND;
|
||||
|
||||
format = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*format));
|
||||
if (!format)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
format->fmtid = key->fmtid;
|
||||
list_init(&format->values);
|
||||
list_add_tail(&This->formats, &format->entry);
|
||||
}
|
||||
|
||||
LIST_FOR_EACH_ENTRY(value_candidate, &format->values, propstore_value, entry)
|
||||
{
|
||||
if (value_candidate->pid == key->pid)
|
||||
{
|
||||
value = value_candidate;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!value)
|
||||
{
|
||||
if (!insert)
|
||||
return TYPE_E_ELEMENTNOTFOUND;
|
||||
|
||||
value = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*value));
|
||||
if (!value)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
value->pid = key->pid;
|
||||
list_add_tail(&format->values, &value->entry);
|
||||
format->count++;
|
||||
}
|
||||
|
||||
*result = value;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI PropertyStore_GetValue(IPropertyStoreCache *iface,
|
||||
REFPROPERTYKEY key, PROPVARIANT *pv)
|
||||
{
|
||||
PropertyStore *This = impl_from_IPropertyStoreCache(iface);
|
||||
propstore_value *value;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("%p,%p,%p\n", iface, key, pv);
|
||||
|
||||
if (!pv)
|
||||
return E_POINTER;
|
||||
|
||||
EnterCriticalSection(&This->lock);
|
||||
|
||||
hr = PropertyStore_LookupValue(This, key, 0, &value);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
hr = PropVariantCopy(pv, &value->propvar);
|
||||
else if (hr == TYPE_E_ELEMENTNOTFOUND)
|
||||
{
|
||||
PropVariantInit(pv);
|
||||
hr = S_OK;
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&This->lock);
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI PropertyStore_SetValue(IPropertyStoreCache *iface,
|
||||
REFPROPERTYKEY key, REFPROPVARIANT propvar)
|
||||
{
|
||||
PropertyStore *This = impl_from_IPropertyStoreCache(iface);
|
||||
propstore_value *value;
|
||||
HRESULT hr;
|
||||
PROPVARIANT temp;
|
||||
|
||||
TRACE("%p,%p,%p\n", iface, key, propvar);
|
||||
|
||||
EnterCriticalSection(&This->lock);
|
||||
|
||||
hr = PropertyStore_LookupValue(This, key, 1, &value);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
hr = PropVariantCopy(&temp, propvar);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
PropVariantClear(&value->propvar);
|
||||
value->propvar = temp;
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&This->lock);
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI PropertyStore_Commit(IPropertyStoreCache *iface)
|
||||
{
|
||||
FIXME("%p: stub\n", iface);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI PropertyStore_GetState(IPropertyStoreCache *iface,
|
||||
REFPROPERTYKEY key, PSC_STATE *pstate)
|
||||
{
|
||||
PropertyStore *This = impl_from_IPropertyStoreCache(iface);
|
||||
propstore_value *value;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("%p,%p,%p\n", iface, key, pstate);
|
||||
|
||||
EnterCriticalSection(&This->lock);
|
||||
|
||||
hr = PropertyStore_LookupValue(This, key, 0, &value);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
*pstate = value->state;
|
||||
|
||||
LeaveCriticalSection(&This->lock);
|
||||
|
||||
if (FAILED(hr))
|
||||
*pstate = PSC_NORMAL;
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI PropertyStore_GetValueAndState(IPropertyStoreCache *iface,
|
||||
REFPROPERTYKEY key, PROPVARIANT *ppropvar, PSC_STATE *pstate)
|
||||
{
|
||||
PropertyStore *This = impl_from_IPropertyStoreCache(iface);
|
||||
propstore_value *value;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("%p,%p,%p,%p\n", iface, key, ppropvar, pstate);
|
||||
|
||||
EnterCriticalSection(&This->lock);
|
||||
|
||||
hr = PropertyStore_LookupValue(This, key, 0, &value);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
hr = PropVariantCopy(ppropvar, &value->propvar);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
*pstate = value->state;
|
||||
|
||||
LeaveCriticalSection(&This->lock);
|
||||
|
||||
if (FAILED(hr))
|
||||
{
|
||||
PropVariantInit(ppropvar);
|
||||
*pstate = PSC_NORMAL;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI PropertyStore_SetState(IPropertyStoreCache *iface,
|
||||
REFPROPERTYKEY key, PSC_STATE pstate)
|
||||
{
|
||||
PropertyStore *This = impl_from_IPropertyStoreCache(iface);
|
||||
propstore_value *value;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("%p,%p,%d\n", iface, key, pstate);
|
||||
|
||||
EnterCriticalSection(&This->lock);
|
||||
|
||||
hr = PropertyStore_LookupValue(This, key, 0, &value);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
value->state = pstate;
|
||||
|
||||
LeaveCriticalSection(&This->lock);
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI PropertyStore_SetValueAndState(IPropertyStoreCache *iface,
|
||||
REFPROPERTYKEY key, const PROPVARIANT *ppropvar, PSC_STATE state)
|
||||
{
|
||||
PropertyStore *This = impl_from_IPropertyStoreCache(iface);
|
||||
propstore_value *value;
|
||||
HRESULT hr;
|
||||
PROPVARIANT temp;
|
||||
|
||||
TRACE("%p,%p,%p,%d\n", iface, key, ppropvar, state);
|
||||
|
||||
EnterCriticalSection(&This->lock);
|
||||
|
||||
hr = PropertyStore_LookupValue(This, key, 1, &value);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
hr = PropVariantCopy(&temp, ppropvar);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
PropVariantClear(&value->propvar);
|
||||
value->propvar = temp;
|
||||
value->state = state;
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&This->lock);
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
static const IPropertyStoreCacheVtbl PropertyStore_Vtbl = {
|
||||
PropertyStore_QueryInterface,
|
||||
PropertyStore_AddRef,
|
||||
PropertyStore_Release,
|
||||
PropertyStore_GetCount,
|
||||
PropertyStore_GetAt,
|
||||
PropertyStore_GetValue,
|
||||
PropertyStore_SetValue,
|
||||
PropertyStore_Commit,
|
||||
PropertyStore_GetState,
|
||||
PropertyStore_GetValueAndState,
|
||||
PropertyStore_SetState,
|
||||
PropertyStore_SetValueAndState
|
||||
};
|
||||
|
||||
HRESULT PropertyStore_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv)
|
||||
{
|
||||
PropertyStore *This;
|
||||
HRESULT ret;
|
||||
|
||||
TRACE("(%p,%s,%p)\n", pUnkOuter, debugstr_guid(iid), ppv);
|
||||
|
||||
*ppv = NULL;
|
||||
|
||||
if (pUnkOuter) return CLASS_E_NOAGGREGATION;
|
||||
|
||||
This = HeapAlloc(GetProcessHeap(), 0, sizeof(PropertyStore));
|
||||
if (!This) return E_OUTOFMEMORY;
|
||||
|
||||
This->IPropertyStoreCache_iface.lpVtbl = &PropertyStore_Vtbl;
|
||||
This->ref = 1;
|
||||
InitializeCriticalSection(&This->lock);
|
||||
This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": PropertyStore.lock");
|
||||
list_init(&This->formats);
|
||||
|
||||
ret = IPropertyStoreCache_QueryInterface(&This->IPropertyStoreCache_iface, iid, ppv);
|
||||
IPropertyStoreCache_Release(&This->IPropertyStoreCache_iface);
|
||||
|
||||
return ret;
|
||||
}
|
1
reactos/dll/win32/propsys/propsys.rc
Normal file
1
reactos/dll/win32/propsys/propsys.rc
Normal file
|
@ -0,0 +1 @@
|
|||
1 WINE_REGISTRY propsys_classes.rgs
|
210
reactos/dll/win32/propsys/propsys.spec
Normal file
210
reactos/dll/win32/propsys/propsys.spec
Normal file
|
@ -0,0 +1,210 @@
|
|||
3 stub GetProxyDllInfo
|
||||
|
||||
400 stub PROPSYS_400
|
||||
402 stub PROPSYS_402
|
||||
403 stub PROPSYS_403
|
||||
404 stub PROPSYS_404
|
||||
405 stub PROPSYS_405
|
||||
406 stub PROPSYS_406
|
||||
407 stub PROPSYS_407
|
||||
408 stub PROPSYS_408
|
||||
409 stub PROPSYS_409
|
||||
410 stub PROPSYS_410
|
||||
411 stub PROPSYS_411
|
||||
412 stub PROPSYS_412
|
||||
413 stub PROPSYS_413
|
||||
414 stub PROPSYS_414
|
||||
415 stub PROPSYS_415
|
||||
416 stub PROPSYS_416
|
||||
417 stub PROPSYS_417
|
||||
418 stub PROPSYS_418
|
||||
420 stub PROPSYS_420
|
||||
421 stub PROPSYS_421
|
||||
422 stub PROPSYS_422
|
||||
|
||||
@ stub ClearPropVariantArray
|
||||
@ stub ClearVariantArray
|
||||
@ stdcall -private DllCanUnloadNow()
|
||||
@ stdcall -private DllGetClassObject(ptr ptr ptr)
|
||||
@ stdcall -private DllRegisterServer()
|
||||
@ stdcall -private DllUnregisterServer()
|
||||
@ stub InitPropVariantFromBooleanVector
|
||||
@ stdcall InitPropVariantFromBuffer(ptr long ptr)
|
||||
@ stub InitPropVariantFromCLSID
|
||||
@ stub InitPropVariantFromDoubleVector
|
||||
@ stub InitPropVariantFromFileTime
|
||||
@ stub InitPropVariantFromFileTimeVector
|
||||
@ stdcall InitPropVariantFromGUIDAsString(ptr ptr)
|
||||
@ stub InitPropVariantFromInt16Vector
|
||||
@ stub InitPropVariantFromInt32Vector
|
||||
@ stub InitPropVariantFromInt64Vector
|
||||
@ stub InitPropVariantFromPropVariantVectorElem
|
||||
@ stub InitPropVariantFromResource
|
||||
@ stub InitPropVariantFromStrRet
|
||||
@ stub InitPropVariantFromStringAsVector
|
||||
@ stub InitPropVariantFromStringVector
|
||||
@ stub InitPropVariantFromUInt16Vector
|
||||
@ stub InitPropVariantFromUInt32Vector
|
||||
@ stub InitPropVariantFromUInt64Vector
|
||||
@ stub InitPropVariantVectorFromPropVariant
|
||||
@ stub InitVariantFromBooleanArray
|
||||
@ stdcall InitVariantFromBuffer(ptr long ptr)
|
||||
@ stub InitVariantFromDoubleArray
|
||||
@ stub InitVariantFromFileTime
|
||||
@ stub InitVariantFromFileTimeArray
|
||||
@ stdcall InitVariantFromGUIDAsString(ptr ptr)
|
||||
@ stub InitVariantFromInt16Array
|
||||
@ stub InitVariantFromInt32Array
|
||||
@ stub InitVariantFromInt64Array
|
||||
@ stub InitVariantFromResource
|
||||
@ stub InitVariantFromStrRet
|
||||
@ stub InitVariantFromStringArray
|
||||
@ stub InitVariantFromUInt16Array
|
||||
@ stub InitVariantFromUInt32Array
|
||||
@ stub InitVariantFromUInt64Array
|
||||
@ stub InitVariantFromVariantArrayElem
|
||||
@ stub PSCoerceToCanonicalValue
|
||||
@ stub PSCreateAdapterFromPropertyStore
|
||||
@ stub PSCreateDelayedMultiplexPropertyStore
|
||||
@ stub PSCreateMemoryPropertyStore
|
||||
@ stub PSCreateMultiplexPropertyStore
|
||||
@ stub PSCreatePropertyChangeArray
|
||||
@ stub PSCreatePropertyStoreFromObject
|
||||
@ stub PSCreatePropertyStoreFromPropertySetStorage
|
||||
@ stub PSCreateSimplePropertyChange
|
||||
@ stub PSEnumeratePropertyDescriptions
|
||||
@ stub PSFormatForDisplay
|
||||
@ stub PSFormatForDisplayAlloc
|
||||
@ stub PSFormatPropertyValue
|
||||
@ stub PSGetItemPropertyHandler
|
||||
@ stub PSGetItemPropertyHandlerWithCreateObject
|
||||
@ stub PSGetNameFromPropertyKey
|
||||
@ stub PSGetNamedPropertyFromPropertyStorage
|
||||
@ stdcall PSGetPropertyDescription(ptr ptr ptr)
|
||||
@ stub PSGetPropertyDescriptionByName
|
||||
@ stub PSGetPropertyDescriptionListFromString
|
||||
@ stub PSGetPropertyFromPropertyStorage
|
||||
@ stub PSGetPropertyKeyFromName
|
||||
@ stub PSGetPropertySystem
|
||||
@ stub PSGetPropertyValue
|
||||
@ stub PSLookupPropertyHandlerCLSID
|
||||
@ stdcall PSPropertyKeyFromString(wstr ptr)
|
||||
@ stdcall PSRefreshPropertySchema()
|
||||
@ stdcall PSRegisterPropertySchema(wstr)
|
||||
@ stub PSSetPropertyValue
|
||||
@ stdcall PSStringFromPropertyKey(ptr ptr long)
|
||||
@ stdcall PSUnregisterPropertySchema(wstr)
|
||||
@ stdcall PropVariantChangeType(ptr ptr long long)
|
||||
@ stdcall PropVariantCompareEx(ptr ptr long long)
|
||||
@ stub PropVariantGetBooleanElem
|
||||
@ stub PropVariantGetDoubleElem
|
||||
@ stub PropVariantGetElementCount
|
||||
@ stub PropVariantGetFileTimeElem
|
||||
@ stub PropVariantGetInt16Elem
|
||||
@ stub PropVariantGetInt32Elem
|
||||
@ stub PropVariantGetInt64Elem
|
||||
@ stub PropVariantGetStringElem
|
||||
@ stub PropVariantGetUInt16Elem
|
||||
@ stub PropVariantGetUInt32Elem
|
||||
@ stub PropVariantGetUInt64Elem
|
||||
@ stub PropVariantToBSTR
|
||||
@ stub PropVariantToBoolean
|
||||
@ stub PropVariantToBooleanVector
|
||||
@ stub PropVariantToBooleanVectorAlloc
|
||||
@ stub PropVariantToBooleanWithDefault
|
||||
@ stub PropVariantToBuffer
|
||||
@ stub PropVariantToDouble
|
||||
@ stub PropVariantToDoubleVector
|
||||
@ stub PropVariantToDoubleVectorAlloc
|
||||
@ stub PropVariantToDoubleWithDefault
|
||||
@ stub PropVariantToFileTime
|
||||
@ stub PropVariantToFileTimeVector
|
||||
@ stub PropVariantToFileTimeVectorAlloc
|
||||
@ stdcall PropVariantToGUID(ptr ptr)
|
||||
@ stdcall PropVariantToInt16(ptr ptr)
|
||||
@ stub PropVariantToInt16Vector
|
||||
@ stub PropVariantToInt16VectorAlloc
|
||||
@ stub PropVariantToInt16WithDefault
|
||||
@ stdcall PropVariantToInt32(ptr ptr)
|
||||
@ stub PropVariantToInt32Vector
|
||||
@ stub PropVariantToInt32VectorAlloc
|
||||
@ stub PropVariantToInt32WithDefault
|
||||
@ stdcall PropVariantToInt64(ptr ptr)
|
||||
@ stub PropVariantToInt64Vector
|
||||
@ stub PropVariantToInt64VectorAlloc
|
||||
@ stub PropVariantToInt64WithDefault
|
||||
@ stub PropVariantToStrRet
|
||||
@ stub PropVariantToString
|
||||
@ stub PropVariantToStringAlloc
|
||||
@ stub PropVariantToStringVector
|
||||
@ stub PropVariantToStringVectorAlloc
|
||||
@ stub PropVariantToStringWithDefault
|
||||
@ stdcall PropVariantToUInt16(ptr ptr)
|
||||
@ stub PropVariantToUInt16Vector
|
||||
@ stub PropVariantToUInt16VectorAlloc
|
||||
@ stub PropVariantToUInt16WithDefault
|
||||
@ stdcall PropVariantToUInt32(ptr ptr)
|
||||
@ stub PropVariantToUInt32Vector
|
||||
@ stub PropVariantToUInt32VectorAlloc
|
||||
@ stub PropVariantToUInt32WithDefault
|
||||
@ stdcall PropVariantToUInt64(ptr ptr)
|
||||
@ stub PropVariantToUInt64Vector
|
||||
@ stub PropVariantToUInt64VectorAlloc
|
||||
@ stub PropVariantToUInt64WithDefault
|
||||
@ stub PropVariantToVariant
|
||||
@ stub StgDeserializePropVariant
|
||||
@ stub StgSerializePropVariant
|
||||
@ stub VariantCompare
|
||||
@ stub VariantGetBooleanElem
|
||||
@ stub VariantGetDoubleElem
|
||||
@ stub VariantGetElementCount
|
||||
@ stub VariantGetInt16Elem
|
||||
@ stub VariantGetInt32Elem
|
||||
@ stub VariantGetInt64Elem
|
||||
@ stub VariantGetStringElem
|
||||
@ stub VariantGetUInt16Elem
|
||||
@ stub VariantGetUInt32Elem
|
||||
@ stub VariantGetUInt64Elem
|
||||
@ stub VariantToBoolean
|
||||
@ stub VariantToBooleanArray
|
||||
@ stub VariantToBooleanArrayAlloc
|
||||
@ stub VariantToBooleanWithDefault
|
||||
@ stub VariantToBuffer
|
||||
@ stub VariantToDosDateTime
|
||||
@ stub VariantToDouble
|
||||
@ stub VariantToDoubleArray
|
||||
@ stub VariantToDoubleArrayAlloc
|
||||
@ stub VariantToDoubleWithDefault
|
||||
@ stub VariantToFileTime
|
||||
@ stdcall VariantToGUID(ptr ptr)
|
||||
@ stub VariantToInt16
|
||||
@ stub VariantToInt16Array
|
||||
@ stub VariantToInt16ArrayAlloc
|
||||
@ stub VariantToInt16WithDefault
|
||||
@ stub VariantToInt32
|
||||
@ stub VariantToInt32Array
|
||||
@ stub VariantToInt32ArrayAlloc
|
||||
@ stub VariantToInt32WithDefault
|
||||
@ stub VariantToInt64
|
||||
@ stub VariantToInt64Array
|
||||
@ stub VariantToInt64ArrayAlloc
|
||||
@ stub VariantToInt64WithDefault
|
||||
@ stub VariantToPropVariant
|
||||
@ stub VariantToStrRet
|
||||
@ stub VariantToString
|
||||
@ stub VariantToStringAlloc
|
||||
@ stub VariantToStringArray
|
||||
@ stub VariantToStringArrayAlloc
|
||||
@ stub VariantToStringWithDefault
|
||||
@ stub VariantToUInt16
|
||||
@ stub VariantToUInt16Array
|
||||
@ stub VariantToUInt16ArrayAlloc
|
||||
@ stub VariantToUInt16WithDefault
|
||||
@ stub VariantToUInt32
|
||||
@ stub VariantToUInt32Array
|
||||
@ stub VariantToUInt32ArrayAlloc
|
||||
@ stub VariantToUInt32WithDefault
|
||||
@ stub VariantToUInt64
|
||||
@ stub VariantToUInt64Array
|
||||
@ stub VariantToUInt64ArrayAlloc
|
||||
@ stub VariantToUInt64WithDefault
|
26
reactos/dll/win32/propsys/propsys_classes.idl
Normal file
26
reactos/dll/win32/propsys/propsys_classes.idl
Normal file
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* Coclasses for propsys
|
||||
*
|
||||
* Copyright 2012 Vincent Povirk for CodeWeavers
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
[
|
||||
helpstring("Packed Property Storage Object"),
|
||||
threading(both),
|
||||
uuid(9a02e012-6303-4e1e-b9a1-630f802592c5)
|
||||
]
|
||||
coclass InMemoryPropertyStore { interface IPropertyStoreCache; }
|
13
reactos/dll/win32/propsys/propsys_classes.rgs
Normal file
13
reactos/dll/win32/propsys/propsys_classes.rgs
Normal file
|
@ -0,0 +1,13 @@
|
|||
HKCR
|
||||
{
|
||||
NoRemove Interface
|
||||
{
|
||||
}
|
||||
NoRemove CLSID
|
||||
{
|
||||
'{9A02E012-6303-4E1E-B9A1-630F802592C5}' = s 'Packed Property Storage Object'
|
||||
{
|
||||
InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' }
|
||||
}
|
||||
}
|
||||
}
|
404
reactos/dll/win32/propsys/propsys_main.c
Normal file
404
reactos/dll/win32/propsys/propsys_main.c
Normal file
|
@ -0,0 +1,404 @@
|
|||
/*
|
||||
* propsys main
|
||||
*
|
||||
* Copyright 1997, 2002 Alexandre Julliard
|
||||
* Copyright 2008 James Hawkins
|
||||
*
|
||||
* 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 WIN32_NO_STATUS
|
||||
#define _INC_WINDOWS
|
||||
#define COM_NO_WINDOWS_H
|
||||
|
||||
#define COBJMACROS
|
||||
#include <config.h>
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include <windef.h>
|
||||
#include <winbase.h>
|
||||
#include <objbase.h>
|
||||
#include <rpcproxy.h>
|
||||
#include <propsys.h>
|
||||
#include <wine/debug.h>
|
||||
#include <wine/unicode.h>
|
||||
|
||||
#include "propsys_private.h"
|
||||
|
||||
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;
|
||||
case DLL_PROCESS_DETACH:
|
||||
break;
|
||||
default:
|
||||
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;
|
||||
|
||||
if(IsEqualGUID(&IID_IUnknown, riid)) {
|
||||
TRACE("(%p)->(IID_IUnknown %p)\n", iface, ppv);
|
||||
*ppv = iface;
|
||||
}else if(IsEqualGUID(&IID_IClassFactory, riid)) {
|
||||
TRACE("(%p)->(IID_IClassFactory %p)\n", iface, ppv);
|
||||
*ppv = iface;
|
||||
}
|
||||
|
||||
if(*ppv) {
|
||||
IUnknown_AddRef((IUnknown*)*ppv);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
FIXME("(%p)->(%s %p)\n", iface, debugstr_guid(riid), ppv);
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
static ULONG WINAPI ClassFactory_AddRef(IClassFactory *iface)
|
||||
{
|
||||
TRACE("(%p)\n", iface);
|
||||
return 2;
|
||||
}
|
||||
|
||||
static ULONG WINAPI ClassFactory_Release(IClassFactory *iface)
|
||||
{
|
||||
TRACE("(%p)\n", iface);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ClassFactory_LockServer(IClassFactory *iface, BOOL fLock)
|
||||
{
|
||||
TRACE("(%p)->(%x)\n", iface, fLock);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI InMemoryPropertyStoreFactory_CreateInstance(IClassFactory *iface, IUnknown *outer,
|
||||
REFIID riid, void **ppv)
|
||||
{
|
||||
TRACE("(%p %s %p)\n", outer, debugstr_guid(riid), ppv);
|
||||
|
||||
return PropertyStore_CreateInstance(outer, riid, ppv);
|
||||
}
|
||||
|
||||
static const IClassFactoryVtbl InMemoryPropertyStoreFactoryVtbl = {
|
||||
ClassFactory_QueryInterface,
|
||||
ClassFactory_AddRef,
|
||||
ClassFactory_Release,
|
||||
InMemoryPropertyStoreFactory_CreateInstance,
|
||||
ClassFactory_LockServer
|
||||
};
|
||||
|
||||
static IClassFactory InMemoryPropertyStoreFactory = { &InMemoryPropertyStoreFactoryVtbl };
|
||||
|
||||
HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
|
||||
{
|
||||
if(IsEqualGUID(&CLSID_InMemoryPropertyStore, rclsid)) {
|
||||
TRACE("(CLSID_InMemoryPropertyStore %s %p)\n", debugstr_guid(riid), ppv);
|
||||
return IClassFactory_QueryInterface(&InMemoryPropertyStoreFactory, riid, ppv);
|
||||
}
|
||||
|
||||
FIXME("%s %s %p\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
|
||||
return CLASS_E_CLASSNOTAVAILABLE;
|
||||
}
|
||||
|
||||
HRESULT WINAPI DllCanUnloadNow(void)
|
||||
{
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
HRESULT WINAPI PSRegisterPropertySchema(PCWSTR path)
|
||||
{
|
||||
FIXME("%s stub\n", debugstr_w(path));
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT WINAPI PSUnregisterPropertySchema(PCWSTR path)
|
||||
{
|
||||
FIXME("%s stub\n", debugstr_w(path));
|
||||
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
HRESULT WINAPI PSGetPropertyDescription(REFPROPERTYKEY propkey, REFIID riid, void **ppv)
|
||||
{
|
||||
FIXME("%p, %p, %p\n", propkey, riid, ppv);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
HRESULT WINAPI PSRefreshPropertySchema(void)
|
||||
{
|
||||
FIXME("\n");
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
TRACE("(%p, %p, %u)\n", pkey, psz, cch);
|
||||
|
||||
if (!psz)
|
||||
return E_POINTER;
|
||||
|
||||
/* GUIDSTRING_MAX accounts for null terminator, +1 for space character. */
|
||||
if (cch <= GUIDSTRING_MAX + 1)
|
||||
return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
|
||||
|
||||
if (!pkey)
|
||||
{
|
||||
psz[0] = '\0';
|
||||
return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
|
||||
}
|
||||
|
||||
sprintfW(psz, guid_fmtW, 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]);
|
||||
|
||||
/* Overwrite the null terminator with the space character. */
|
||||
p += GUIDSTRING_MAX - 1;
|
||||
*p++ = ' ';
|
||||
cch -= GUIDSTRING_MAX - 1 + 1;
|
||||
|
||||
len = sprintfW(pidW, pid_fmtW, pkey->pid);
|
||||
|
||||
if (cch >= len + 1)
|
||||
{
|
||||
strcpyW(p, pidW);
|
||||
return S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
WCHAR *ptr = pidW + len - 1;
|
||||
|
||||
psz[0] = '\0';
|
||||
*p++ = '\0';
|
||||
cch--;
|
||||
|
||||
/* Replicate a quirk of the native implementation where the contents
|
||||
* of the property ID string are written backwards to the output
|
||||
* buffer, skipping the rightmost digit. */
|
||||
if (cch)
|
||||
{
|
||||
ptr--;
|
||||
while (cch--)
|
||||
*p++ = *ptr--;
|
||||
}
|
||||
|
||||
return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
|
||||
}
|
||||
}
|
||||
|
||||
static const BYTE hex2bin[] =
|
||||
{
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x00 */
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x10 */
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x20 */
|
||||
0,1,2,3,4,5,6,7,8,9,0,0,0,0,0,0, /* 0x30 */
|
||||
0,10,11,12,13,14,15,0,0,0,0,0,0,0,0,0, /* 0x40 */
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x50 */
|
||||
0,10,11,12,13,14,15 /* 0x60 */
|
||||
};
|
||||
|
||||
static BOOL validate_indices(LPCWSTR s, int min, int max)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = min; i <= max; i++)
|
||||
{
|
||||
if (!s[i])
|
||||
return FALSE;
|
||||
|
||||
if (i == 0)
|
||||
{
|
||||
if (s[i] != '{')
|
||||
return FALSE;
|
||||
}
|
||||
else if (i == 9 || i == 14 || i == 19 || i == 24)
|
||||
{
|
||||
if (s[i] != '-')
|
||||
return FALSE;
|
||||
}
|
||||
else if (i == 37)
|
||||
{
|
||||
if (s[i] != '}')
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (s[i] > 'f' || (!hex2bin[s[i]] && s[i] != '0'))
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Adapted from CLSIDFromString helper in dlls/ole32/compobj.c and
|
||||
* UuidFromString in dlls/rpcrt4/rpcrt4_main.c. */
|
||||
static BOOL string_to_guid(LPCWSTR s, LPGUID id)
|
||||
{
|
||||
/* in form {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} */
|
||||
|
||||
if (!validate_indices(s, 0, 8)) return FALSE;
|
||||
id->Data1 = (hex2bin[s[1]] << 28 | hex2bin[s[2]] << 24 | hex2bin[s[3]] << 20 | hex2bin[s[4]] << 16 |
|
||||
hex2bin[s[5]] << 12 | hex2bin[s[6]] << 8 | hex2bin[s[7]] << 4 | hex2bin[s[8]]);
|
||||
if (!validate_indices(s, 9, 14)) return FALSE;
|
||||
id->Data2 = hex2bin[s[10]] << 12 | hex2bin[s[11]] << 8 | hex2bin[s[12]] << 4 | hex2bin[s[13]];
|
||||
if (!validate_indices(s, 15, 19)) return FALSE;
|
||||
id->Data3 = hex2bin[s[15]] << 12 | hex2bin[s[16]] << 8 | hex2bin[s[17]] << 4 | hex2bin[s[18]];
|
||||
|
||||
/* these are just sequential bytes */
|
||||
|
||||
if (!validate_indices(s, 20, 21)) return FALSE;
|
||||
id->Data4[0] = hex2bin[s[20]] << 4 | hex2bin[s[21]];
|
||||
if (!validate_indices(s, 22, 24)) return FALSE;
|
||||
id->Data4[1] = hex2bin[s[22]] << 4 | hex2bin[s[23]];
|
||||
|
||||
if (!validate_indices(s, 25, 26)) return FALSE;
|
||||
id->Data4[2] = hex2bin[s[25]] << 4 | hex2bin[s[26]];
|
||||
if (!validate_indices(s, 27, 28)) return FALSE;
|
||||
id->Data4[3] = hex2bin[s[27]] << 4 | hex2bin[s[28]];
|
||||
if (!validate_indices(s, 29, 30)) return FALSE;
|
||||
id->Data4[4] = hex2bin[s[29]] << 4 | hex2bin[s[30]];
|
||||
if (!validate_indices(s, 31, 32)) return FALSE;
|
||||
id->Data4[5] = hex2bin[s[31]] << 4 | hex2bin[s[32]];
|
||||
if (!validate_indices(s, 33, 34)) return FALSE;
|
||||
id->Data4[6] = hex2bin[s[33]] << 4 | hex2bin[s[34]];
|
||||
if (!validate_indices(s, 35, 37)) return FALSE;
|
||||
id->Data4[7] = hex2bin[s[35]] << 4 | hex2bin[s[36]];
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
HRESULT WINAPI PSPropertyKeyFromString(LPCWSTR pszString, PROPERTYKEY *pkey)
|
||||
{
|
||||
int has_minus = 0, has_comma = 0;
|
||||
|
||||
TRACE("(%s, %p)\n", debugstr_w(pszString), pkey);
|
||||
|
||||
if (!pszString || !pkey)
|
||||
return E_POINTER;
|
||||
|
||||
memset(pkey, 0, sizeof(PROPERTYKEY));
|
||||
|
||||
if (!string_to_guid(pszString, &pkey->fmtid))
|
||||
return E_INVALIDARG;
|
||||
|
||||
pszString += GUIDSTRING_MAX - 1;
|
||||
|
||||
if (!*pszString)
|
||||
return E_INVALIDARG;
|
||||
|
||||
/* Only the space seems to be recognized as whitespace. The comma is only
|
||||
* recognized once and processing terminates if another comma is found. */
|
||||
while (*pszString == ' ' || *pszString == ',')
|
||||
{
|
||||
if (*pszString == ',')
|
||||
{
|
||||
if (has_comma)
|
||||
return S_OK;
|
||||
else
|
||||
has_comma = 1;
|
||||
}
|
||||
pszString++;
|
||||
}
|
||||
|
||||
if (!*pszString)
|
||||
return E_INVALIDARG;
|
||||
|
||||
/* Only two minus signs are recognized if no comma is detected. The first
|
||||
* sign is ignored, and the second is interpreted. If a comma is detected
|
||||
* before the minus sign, then only one minus sign counts, and property ID
|
||||
* interpretation begins with the next character. */
|
||||
if (has_comma)
|
||||
{
|
||||
if (*pszString == '-')
|
||||
{
|
||||
has_minus = 1;
|
||||
pszString++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (*pszString == '-')
|
||||
pszString++;
|
||||
|
||||
/* Skip any intermediate spaces after the first minus sign. */
|
||||
while (*pszString == ' ')
|
||||
pszString++;
|
||||
|
||||
if (*pszString == '-')
|
||||
{
|
||||
has_minus = 1;
|
||||
pszString++;
|
||||
}
|
||||
|
||||
/* Skip any remaining spaces after minus sign. */
|
||||
while (*pszString == ' ')
|
||||
pszString++;
|
||||
}
|
||||
|
||||
/* Overflow is not checked. */
|
||||
while (isdigitW(*pszString))
|
||||
{
|
||||
pkey->pid *= 10;
|
||||
pkey->pid += (*pszString - '0');
|
||||
pszString++;
|
||||
}
|
||||
|
||||
if (has_minus)
|
||||
pkey->pid = ~pkey->pid + 1;
|
||||
|
||||
return S_OK;
|
||||
}
|
21
reactos/dll/win32/propsys/propsys_private.h
Normal file
21
reactos/dll/win32/propsys/propsys_private.h
Normal file
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* propsys private definitions
|
||||
*
|
||||
* Copyright 2012 Vincent Povirk for CodeWeavers
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
HRESULT PropertyStore_CreateInstance(IUnknown *outer, REFIID riid, void **ppv) DECLSPEC_HIDDEN;
|
603
reactos/dll/win32/propsys/propvar.c
Normal file
603
reactos/dll/win32/propsys/propvar.c
Normal file
|
@ -0,0 +1,603 @@
|
|||
/*
|
||||
* PropVariant implementation
|
||||
*
|
||||
* Copyright 2008 James Hawkins for CodeWeavers
|
||||
*
|
||||
* 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 WIN32_NO_STATUS
|
||||
#define _INC_WINDOWS
|
||||
#define COM_NO_WINDOWS_H
|
||||
|
||||
//#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define NONAMELESSUNION
|
||||
|
||||
#include <windef.h>
|
||||
#include <winbase.h>
|
||||
//#include "winerror.h"
|
||||
#include <winreg.h>
|
||||
//#include "winuser.h"
|
||||
#include <shlobj.h>
|
||||
#include <propvarutil.h>
|
||||
|
||||
#include <wine/debug.h>
|
||||
#include <wine/unicode.h>
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(propsys);
|
||||
|
||||
static HRESULT PROPVAR_ConvertFILETIME(PROPVARIANT *ppropvarDest,
|
||||
REFPROPVARIANT propvarSrc, VARTYPE vt)
|
||||
{
|
||||
SYSTEMTIME time;
|
||||
|
||||
FileTimeToSystemTime(&propvarSrc->u.filetime, &time);
|
||||
|
||||
switch (vt)
|
||||
{
|
||||
case VT_LPSTR:
|
||||
{
|
||||
static const char format[] = "%04d/%02d/%02d:%02d:%02d:%02d.%03d";
|
||||
|
||||
ppropvarDest->u.pszVal = HeapAlloc(GetProcessHeap(), 0,
|
||||
lstrlenA(format) + 1);
|
||||
if (!ppropvarDest->u.pszVal)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
sprintf(ppropvarDest->u.pszVal, format, time.wYear, time.wMonth,
|
||||
time.wDay, time.wHour, time.wMinute,
|
||||
time.wSecond, time.wMilliseconds);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
default:
|
||||
FIXME("Unhandled target type: %d\n", vt);
|
||||
}
|
||||
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
static HRESULT PROPVAR_ConvertNumber(REFPROPVARIANT pv, int dest_bits,
|
||||
int dest_signed, LONGLONG *res)
|
||||
{
|
||||
int src_signed;
|
||||
|
||||
switch (pv->vt)
|
||||
{
|
||||
case VT_I1:
|
||||
src_signed = 1;
|
||||
*res = pv->u.cVal;
|
||||
break;
|
||||
case VT_UI1:
|
||||
src_signed = 0;
|
||||
*res = pv->u.bVal;
|
||||
break;
|
||||
case VT_I2:
|
||||
src_signed = 1;
|
||||
*res = pv->u.iVal;
|
||||
break;
|
||||
case VT_UI2:
|
||||
src_signed = 0;
|
||||
*res = pv->u.uiVal;
|
||||
break;
|
||||
case VT_I4:
|
||||
src_signed = 1;
|
||||
*res = pv->u.lVal;
|
||||
break;
|
||||
case VT_UI4:
|
||||
src_signed = 0;
|
||||
*res = pv->u.ulVal;
|
||||
break;
|
||||
case VT_I8:
|
||||
src_signed = 1;
|
||||
*res = pv->u.hVal.QuadPart;
|
||||
break;
|
||||
case VT_UI8:
|
||||
src_signed = 0;
|
||||
*res = pv->u.uhVal.QuadPart;
|
||||
break;
|
||||
case VT_EMPTY:
|
||||
src_signed = 0;
|
||||
*res = 0;
|
||||
break;
|
||||
default:
|
||||
FIXME("unhandled vt %d\n", pv->vt);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
if (*res < 0 && src_signed != dest_signed)
|
||||
return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW);
|
||||
|
||||
if (dest_bits < 64)
|
||||
{
|
||||
if (dest_signed)
|
||||
{
|
||||
if (*res >= ((LONGLONG)1 << (dest_bits-1)) ||
|
||||
*res < ((LONGLONG)-1 << (dest_bits-1)))
|
||||
return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((ULONGLONG)(*res) >= ((ULONGLONG)1 << dest_bits))
|
||||
return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW);
|
||||
}
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT WINAPI PropVariantToInt16(REFPROPVARIANT propvarIn, SHORT *ret)
|
||||
{
|
||||
LONGLONG res;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("%p,%p\n", propvarIn, ret);
|
||||
|
||||
hr = PROPVAR_ConvertNumber(propvarIn, 16, 1, &res);
|
||||
if (SUCCEEDED(hr)) *ret = (SHORT)res;
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT WINAPI PropVariantToInt32(REFPROPVARIANT propvarIn, LONG *ret)
|
||||
{
|
||||
LONGLONG res;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("%p,%p\n", propvarIn, ret);
|
||||
|
||||
hr = PROPVAR_ConvertNumber(propvarIn, 32, 1, &res);
|
||||
if (SUCCEEDED(hr)) *ret = (LONG)res;
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT WINAPI PropVariantToInt64(REFPROPVARIANT propvarIn, LONGLONG *ret)
|
||||
{
|
||||
LONGLONG res;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("%p,%p\n", propvarIn, ret);
|
||||
|
||||
hr = PROPVAR_ConvertNumber(propvarIn, 64, 1, &res);
|
||||
if (SUCCEEDED(hr)) *ret = (LONGLONG)res;
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT WINAPI PropVariantToUInt16(REFPROPVARIANT propvarIn, USHORT *ret)
|
||||
{
|
||||
LONGLONG res;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("%p,%p\n", propvarIn, ret);
|
||||
|
||||
hr = PROPVAR_ConvertNumber(propvarIn, 16, 0, &res);
|
||||
if (SUCCEEDED(hr)) *ret = (USHORT)res;
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT WINAPI PropVariantToUInt32(REFPROPVARIANT propvarIn, ULONG *ret)
|
||||
{
|
||||
LONGLONG res;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("%p,%p\n", propvarIn, ret);
|
||||
|
||||
hr = PROPVAR_ConvertNumber(propvarIn, 32, 0, &res);
|
||||
if (SUCCEEDED(hr)) *ret = (ULONG)res;
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT WINAPI PropVariantToUInt64(REFPROPVARIANT propvarIn, ULONGLONG *ret)
|
||||
{
|
||||
LONGLONG res;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("%p,%p\n", propvarIn, ret);
|
||||
|
||||
hr = PROPVAR_ConvertNumber(propvarIn, 64, 0, &res);
|
||||
if (SUCCEEDED(hr)) *ret = (ULONGLONG)res;
|
||||
return hr;
|
||||
}
|
||||
|
||||
/******************************************************************
|
||||
* PropVariantChangeType (PROPSYS.@)
|
||||
*/
|
||||
HRESULT WINAPI PropVariantChangeType(PROPVARIANT *ppropvarDest, REFPROPVARIANT propvarSrc,
|
||||
PROPVAR_CHANGE_FLAGS flags, VARTYPE vt)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
FIXME("(%p, %p, %d, %d, %d): semi-stub!\n", ppropvarDest, propvarSrc,
|
||||
propvarSrc->vt, flags, vt);
|
||||
|
||||
switch (vt)
|
||||
{
|
||||
case VT_I2:
|
||||
{
|
||||
SHORT res;
|
||||
hr = PropVariantToInt16(propvarSrc, &res);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
ppropvarDest->vt = VT_I2;
|
||||
ppropvarDest->u.iVal = res;
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
case VT_UI2:
|
||||
{
|
||||
USHORT res;
|
||||
hr = PropVariantToUInt16(propvarSrc, &res);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
ppropvarDest->vt = VT_UI2;
|
||||
ppropvarDest->u.uiVal = res;
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
case VT_I4:
|
||||
{
|
||||
LONG res;
|
||||
hr = PropVariantToInt32(propvarSrc, &res);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
ppropvarDest->vt = VT_I4;
|
||||
ppropvarDest->u.lVal = res;
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
case VT_UI4:
|
||||
{
|
||||
ULONG res;
|
||||
hr = PropVariantToUInt32(propvarSrc, &res);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
ppropvarDest->vt = VT_UI4;
|
||||
ppropvarDest->u.ulVal = res;
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
case VT_I8:
|
||||
{
|
||||
LONGLONG res;
|
||||
hr = PropVariantToInt64(propvarSrc, &res);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
ppropvarDest->vt = VT_I8;
|
||||
ppropvarDest->u.hVal.QuadPart = res;
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
case VT_UI8:
|
||||
{
|
||||
ULONGLONG res;
|
||||
hr = PropVariantToUInt64(propvarSrc, &res);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
ppropvarDest->vt = VT_UI8;
|
||||
ppropvarDest->u.uhVal.QuadPart = res;
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
}
|
||||
|
||||
switch (propvarSrc->vt)
|
||||
{
|
||||
case VT_FILETIME:
|
||||
return PROPVAR_ConvertFILETIME(ppropvarDest, propvarSrc, vt);
|
||||
default:
|
||||
FIXME("Unhandled source type: %d\n", propvarSrc->vt);
|
||||
}
|
||||
|
||||
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};
|
||||
|
||||
sprintfW(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);
|
||||
|
||||
if(!guid)
|
||||
return E_FAIL;
|
||||
|
||||
ppropvar->vt = VT_LPWSTR;
|
||||
ppropvar->u.pwszVal = CoTaskMemAlloc(39*sizeof(WCHAR));
|
||||
if(!ppropvar->u.pwszVal)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
PROPVAR_GUIDToWSTR(guid, ppropvar->u.pwszVal);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT WINAPI InitVariantFromGUIDAsString(REFGUID guid, VARIANT *pvar)
|
||||
{
|
||||
TRACE("(%p %p)\n", guid, pvar);
|
||||
|
||||
if(!guid) {
|
||||
FIXME("guid == NULL\n");
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
V_VT(pvar) = VT_BSTR;
|
||||
V_BSTR(pvar) = SysAllocStringLen(NULL, 38);
|
||||
if(!V_BSTR(pvar))
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
PROPVAR_GUIDToWSTR(guid, V_BSTR(pvar));
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT WINAPI InitPropVariantFromBuffer(const VOID *pv, UINT cb, PROPVARIANT *ppropvar)
|
||||
{
|
||||
TRACE("(%p %u %p)\n", pv, cb, ppropvar);
|
||||
|
||||
ppropvar->u.caub.pElems = CoTaskMemAlloc(cb);
|
||||
if(!ppropvar->u.caub.pElems)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
ppropvar->vt = VT_VECTOR|VT_UI1;
|
||||
ppropvar->u.caub.cElems = cb;
|
||||
memcpy(ppropvar->u.caub.pElems, pv, cb);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT WINAPI InitVariantFromBuffer(const VOID *pv, UINT cb, VARIANT *pvar)
|
||||
{
|
||||
SAFEARRAY *arr;
|
||||
void *data;
|
||||
HRESULT hres;
|
||||
|
||||
TRACE("(%p %u %p)\n", pv, cb, pvar);
|
||||
|
||||
arr = SafeArrayCreateVector(VT_UI1, 0, cb);
|
||||
if(!arr)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
hres = SafeArrayAccessData(arr, &data);
|
||||
if(FAILED(hres)) {
|
||||
SafeArrayDestroy(arr);
|
||||
return hres;
|
||||
}
|
||||
|
||||
memcpy(data, pv, cb);
|
||||
|
||||
hres = SafeArrayUnaccessData(arr);
|
||||
if(FAILED(hres)) {
|
||||
SafeArrayDestroy(arr);
|
||||
return hres;
|
||||
}
|
||||
|
||||
V_VT(pvar) = VT_ARRAY|VT_UI1;
|
||||
V_ARRAY(pvar) = arr;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static inline DWORD PROPVAR_HexToNum(const WCHAR *hex)
|
||||
{
|
||||
DWORD ret;
|
||||
|
||||
if(hex[0]>='0' && hex[0]<='9')
|
||||
ret = hex[0]-'0';
|
||||
else if(hex[0]>='a' && hex[0]<='f')
|
||||
ret = hex[0]-'a'+10;
|
||||
else if(hex[0]>='A' && hex[0]<='F')
|
||||
ret = hex[0]-'A'+10;
|
||||
else
|
||||
return -1;
|
||||
|
||||
ret <<= 4;
|
||||
if(hex[1]>='0' && hex[1]<='9')
|
||||
return ret + hex[1]-'0';
|
||||
else if(hex[1]>='a' && hex[1]<='f')
|
||||
return ret + hex[1]-'a'+10;
|
||||
else if(hex[1]>='A' && hex[1]<='F')
|
||||
return ret + hex[1]-'A'+10;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
static inline HRESULT PROPVAR_WCHARToGUID(const WCHAR *str, int len, GUID *guid)
|
||||
{
|
||||
DWORD i, val=0;
|
||||
const WCHAR *p;
|
||||
|
||||
memset(guid, 0, sizeof(GUID));
|
||||
|
||||
if(len!=38 || str[0]!='{' || str[9]!='-' || str[14]!='-'
|
||||
|| str[19]!='-' || str[24]!='-' || str[37]!='}') {
|
||||
WARN("Error parsing %s\n", debugstr_w(str));
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
p = str+1;
|
||||
for(i=0; i<4 && val!=-1; i++) {
|
||||
val = PROPVAR_HexToNum(p);
|
||||
guid->Data1 = (guid->Data1<<8) + val;
|
||||
p += 2;
|
||||
}
|
||||
p++;
|
||||
for(i=0; i<2 && val!=-1; i++) {
|
||||
val = PROPVAR_HexToNum(p);
|
||||
guid->Data2 = (guid->Data2<<8) + val;
|
||||
p += 2;
|
||||
}
|
||||
p++;
|
||||
for(i=0; i<2 && val!=-1; i++) {
|
||||
val = PROPVAR_HexToNum(p);
|
||||
guid->Data3 = (guid->Data3<<8) + val;
|
||||
p += 2;
|
||||
}
|
||||
p++;
|
||||
for(i=0; i<8 && val!=-1; i++) {
|
||||
if(i == 2)
|
||||
p++;
|
||||
|
||||
val = guid->Data4[i] = PROPVAR_HexToNum(p);
|
||||
p += 2;
|
||||
}
|
||||
|
||||
if(val == -1) {
|
||||
WARN("Error parsing %s\n", debugstr_w(str));
|
||||
memset(guid, 0, sizeof(GUID));
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT WINAPI PropVariantToGUID(const PROPVARIANT *ppropvar, GUID *guid)
|
||||
{
|
||||
TRACE("%p %p)\n", ppropvar, guid);
|
||||
|
||||
switch(ppropvar->vt) {
|
||||
case VT_BSTR:
|
||||
return PROPVAR_WCHARToGUID(ppropvar->u.bstrVal, SysStringLen(ppropvar->u.bstrVal), guid);
|
||||
case VT_LPWSTR:
|
||||
return PROPVAR_WCHARToGUID(ppropvar->u.pwszVal, strlenW(ppropvar->u.pwszVal), guid);
|
||||
|
||||
default:
|
||||
FIXME("unsupported vt: %d\n", ppropvar->vt);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT WINAPI VariantToGUID(const VARIANT *pvar, GUID *guid)
|
||||
{
|
||||
TRACE("(%p %p)\n", pvar, guid);
|
||||
|
||||
switch(V_VT(pvar)) {
|
||||
case VT_BSTR: {
|
||||
HRESULT hres = PROPVAR_WCHARToGUID(V_BSTR(pvar), SysStringLen(V_BSTR(pvar)), guid);
|
||||
if(hres == E_INVALIDARG)
|
||||
return E_FAIL;
|
||||
return hres;
|
||||
}
|
||||
|
||||
default:
|
||||
FIXME("unsupported vt: %d\n", V_VT(pvar));
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
}
|
||||
|
||||
static int isemptyornull(const PROPVARIANT *propvar)
|
||||
{
|
||||
if (propvar->vt == VT_EMPTY || propvar->vt == VT_NULL)
|
||||
return 1;
|
||||
if ((propvar->vt & VT_ARRAY) == VT_ARRAY)
|
||||
{
|
||||
int i;
|
||||
for (i=0; i<propvar->u.parray->cDims; i++)
|
||||
{
|
||||
if (propvar->u.parray->rgsabound[i].cElements != 0)
|
||||
break;
|
||||
}
|
||||
return i == propvar->u.parray->cDims;
|
||||
}
|
||||
/* FIXME: vectors, byrefs, errors? */
|
||||
return 0;
|
||||
}
|
||||
|
||||
INT WINAPI PropVariantCompareEx(REFPROPVARIANT propvar1, REFPROPVARIANT propvar2,
|
||||
PROPVAR_COMPARE_UNIT unit, PROPVAR_COMPARE_FLAGS flags)
|
||||
{
|
||||
const PROPVARIANT *propvar2_converted;
|
||||
PROPVARIANT propvar2_static;
|
||||
HRESULT hr;
|
||||
INT res=-1;
|
||||
|
||||
TRACE("%p,%p,%x,%x\n", propvar1, propvar2, unit, flags);
|
||||
|
||||
if (isemptyornull(propvar1))
|
||||
{
|
||||
if (isemptyornull(propvar2))
|
||||
return 0;
|
||||
return (flags & PVCF_TREATEMPTYASGREATERTHAN) ? 1 : -1;
|
||||
}
|
||||
|
||||
if (isemptyornull(propvar2))
|
||||
return (flags & PVCF_TREATEMPTYASGREATERTHAN) ? -1 : 1;
|
||||
|
||||
if (propvar1->vt != propvar2->vt)
|
||||
{
|
||||
hr = PropVariantChangeType(&propvar2_static, propvar2, 0, propvar1->vt);
|
||||
|
||||
if (FAILED(hr))
|
||||
return -1;
|
||||
|
||||
propvar2_converted = &propvar2_static;
|
||||
}
|
||||
else
|
||||
propvar2_converted = propvar2;
|
||||
|
||||
#define CMP_INT_VALUE(var) do { \
|
||||
if (propvar1->u.var > propvar2_converted->u.var) \
|
||||
res = 1; \
|
||||
else if (propvar1->u.var < propvar2_converted->u.var) \
|
||||
res = -1; \
|
||||
else \
|
||||
res = 0; \
|
||||
} while (0)
|
||||
|
||||
switch (propvar1->vt)
|
||||
{
|
||||
case VT_I1:
|
||||
CMP_INT_VALUE(cVal);
|
||||
break;
|
||||
case VT_UI1:
|
||||
CMP_INT_VALUE(bVal);
|
||||
break;
|
||||
case VT_I2:
|
||||
CMP_INT_VALUE(iVal);
|
||||
break;
|
||||
case VT_UI2:
|
||||
CMP_INT_VALUE(uiVal);
|
||||
break;
|
||||
case VT_I4:
|
||||
CMP_INT_VALUE(lVal);
|
||||
break;
|
||||
case VT_UI4:
|
||||
CMP_INT_VALUE(uiVal);
|
||||
break;
|
||||
case VT_I8:
|
||||
CMP_INT_VALUE(hVal.QuadPart);
|
||||
break;
|
||||
case VT_UI8:
|
||||
CMP_INT_VALUE(uhVal.QuadPart);
|
||||
break;
|
||||
case VT_BSTR:
|
||||
/* FIXME: Use string flags. */
|
||||
res = lstrcmpW(propvar1->u.bstrVal, propvar2->u.bstrVal);
|
||||
break;
|
||||
default:
|
||||
FIXME("vartype %d not handled\n", propvar1->vt);
|
||||
res = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (propvar2_converted == &propvar2_static)
|
||||
PropVariantClear(&propvar2_static);
|
||||
|
||||
return res;
|
||||
}
|
|
@ -142,6 +142,7 @@ reactos/dll/win32/pdh # Autosync
|
|||
reactos/dll/win32/pidgen # Synced to Wine-1.5.19
|
||||
reactos/dll/win32/powrprof # Forked at Wine-1.0rc5
|
||||
reactos/dll/win32/printui # Synced to Wine-1.5.4
|
||||
reactos/dll/win32/propsys # Synced to Wine-1.5.26
|
||||
reactos/dll/win32/pstorec # Synced to Wine-1.5.4
|
||||
reactos/dll/win32/qmgr # Synced to Wine-1.2-rc5?
|
||||
reactos/dll/win32/qmgrprxy # Synced to Wine-1.14?
|
||||
|
|
Loading…
Reference in a new issue