mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 19:52:56 +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(pidgen)
|
||||||
add_subdirectory(powrprof)
|
add_subdirectory(powrprof)
|
||||||
add_subdirectory(printui)
|
add_subdirectory(printui)
|
||||||
|
add_subdirectory(propsys)
|
||||||
add_subdirectory(psapi)
|
add_subdirectory(psapi)
|
||||||
add_subdirectory(pstorec)
|
add_subdirectory(pstorec)
|
||||||
add_subdirectory(qmgr)
|
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/pidgen # Synced to Wine-1.5.19
|
||||||
reactos/dll/win32/powrprof # Forked at Wine-1.0rc5
|
reactos/dll/win32/powrprof # Forked at Wine-1.0rc5
|
||||||
reactos/dll/win32/printui # Synced to Wine-1.5.4
|
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/pstorec # Synced to Wine-1.5.4
|
||||||
reactos/dll/win32/qmgr # Synced to Wine-1.2-rc5?
|
reactos/dll/win32/qmgr # Synced to Wine-1.2-rc5?
|
||||||
reactos/dll/win32/qmgrprxy # Synced to Wine-1.14?
|
reactos/dll/win32/qmgrprxy # Synced to Wine-1.14?
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue