ole32: Use wrappers around NT functions to access the registry in CoGetPSClsid.
This commit is contained in:
parent
e2c61baba0
commit
a82c49028d
|
@ -47,6 +47,8 @@
|
|||
#define NONAMELESSUNION
|
||||
#define NONAMELESSSTRUCT
|
||||
|
||||
#include "ntstatus.h"
|
||||
#define WIN32_NO_STATUS
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winerror.h"
|
||||
|
@ -135,6 +137,121 @@ static CRITICAL_SECTION_DEBUG class_cs_debug =
|
|||
};
|
||||
static CRITICAL_SECTION csRegisteredClassList = { &class_cs_debug, -1, 0, 0, 0, 0 };
|
||||
|
||||
/* wrapper for NtCreateKey that creates the key recursively if necessary */
|
||||
static NTSTATUS create_key( HKEY *retkey, ACCESS_MASK access, OBJECT_ATTRIBUTES *attr )
|
||||
{
|
||||
NTSTATUS status = NtCreateKey( (HANDLE *)retkey, access, attr, 0, NULL, 0, NULL );
|
||||
|
||||
if (status == STATUS_OBJECT_NAME_NOT_FOUND)
|
||||
{
|
||||
HANDLE subkey, root = attr->RootDirectory;
|
||||
WCHAR *buffer = attr->ObjectName->Buffer;
|
||||
DWORD attrs, pos = 0, i = 0, len = attr->ObjectName->Length / sizeof(WCHAR);
|
||||
UNICODE_STRING str;
|
||||
|
||||
while (i < len && buffer[i] != '\\') i++;
|
||||
if (i == len) return status;
|
||||
|
||||
attrs = attr->Attributes;
|
||||
attr->ObjectName = &str;
|
||||
|
||||
while (i < len)
|
||||
{
|
||||
str.Buffer = buffer + pos;
|
||||
str.Length = (i - pos) * sizeof(WCHAR);
|
||||
status = NtCreateKey( &subkey, access, attr, 0, NULL, 0, NULL );
|
||||
if (attr->RootDirectory != root) NtClose( attr->RootDirectory );
|
||||
if (status) return status;
|
||||
attr->RootDirectory = subkey;
|
||||
while (i < len && buffer[i] == '\\') i++;
|
||||
pos = i;
|
||||
while (i < len && buffer[i] != '\\') i++;
|
||||
}
|
||||
str.Buffer = buffer + pos;
|
||||
str.Length = (i - pos) * sizeof(WCHAR);
|
||||
attr->Attributes = attrs;
|
||||
status = NtCreateKey( (PHANDLE)retkey, access, attr, 0, NULL, 0, NULL );
|
||||
if (attr->RootDirectory != root) NtClose( attr->RootDirectory );
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
static const WCHAR classes_rootW[] =
|
||||
{'M','a','c','h','i','n','e','\\','S','o','f','t','w','a','r','e','\\','C','l','a','s','s','e','s',0};
|
||||
|
||||
static HKEY classes_root_hkey;
|
||||
|
||||
/* create the special HKEY_CLASSES_ROOT key */
|
||||
static HKEY create_classes_root_hkey(void)
|
||||
{
|
||||
HKEY hkey, ret = 0;
|
||||
OBJECT_ATTRIBUTES attr;
|
||||
UNICODE_STRING name;
|
||||
|
||||
attr.Length = sizeof(attr);
|
||||
attr.RootDirectory = 0;
|
||||
attr.ObjectName = &name;
|
||||
attr.Attributes = 0;
|
||||
attr.SecurityDescriptor = NULL;
|
||||
attr.SecurityQualityOfService = NULL;
|
||||
RtlInitUnicodeString( &name, classes_rootW );
|
||||
if (create_key( &hkey, MAXIMUM_ALLOWED, &attr )) return 0;
|
||||
TRACE( "%s -> %p\n", debugstr_w(attr.ObjectName->Buffer), hkey );
|
||||
|
||||
if (!(ret = InterlockedCompareExchangePointer( (void **)&classes_root_hkey, hkey, 0 )))
|
||||
ret = hkey;
|
||||
else
|
||||
NtClose( hkey ); /* somebody beat us to it */
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* map the hkey from special root to normal key if necessary */
|
||||
static inline HKEY get_classes_root_hkey( HKEY hkey )
|
||||
{
|
||||
HKEY ret = hkey;
|
||||
|
||||
if (hkey == HKEY_CLASSES_ROOT && !(ret = classes_root_hkey))
|
||||
ret = create_classes_root_hkey();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
LSTATUS create_classes_key( HKEY hkey, const WCHAR *name, REGSAM access, HKEY *retkey )
|
||||
{
|
||||
OBJECT_ATTRIBUTES attr;
|
||||
UNICODE_STRING nameW;
|
||||
|
||||
if (!(hkey = get_classes_root_hkey( hkey ))) return ERROR_INVALID_HANDLE;
|
||||
|
||||
attr.Length = sizeof(attr);
|
||||
attr.RootDirectory = hkey;
|
||||
attr.ObjectName = &nameW;
|
||||
attr.Attributes = 0;
|
||||
attr.SecurityDescriptor = NULL;
|
||||
attr.SecurityQualityOfService = NULL;
|
||||
RtlInitUnicodeString( &nameW, name );
|
||||
|
||||
return RtlNtStatusToDosError( create_key( retkey, access, &attr ) );
|
||||
}
|
||||
|
||||
LSTATUS open_classes_key( HKEY hkey, const WCHAR *name, REGSAM access, HKEY *retkey )
|
||||
{
|
||||
OBJECT_ATTRIBUTES attr;
|
||||
UNICODE_STRING nameW;
|
||||
|
||||
if (!(hkey = get_classes_root_hkey( hkey ))) return ERROR_INVALID_HANDLE;
|
||||
|
||||
attr.Length = sizeof(attr);
|
||||
attr.RootDirectory = hkey;
|
||||
attr.ObjectName = &nameW;
|
||||
attr.Attributes = 0;
|
||||
attr.SecurityDescriptor = NULL;
|
||||
attr.SecurityQualityOfService = NULL;
|
||||
RtlInitUnicodeString( &nameW, name );
|
||||
|
||||
return RtlNtStatusToDosError( NtOpenKey( (HANDLE *)retkey, access, &attr ) );
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* This section contains OpenDllList definitions
|
||||
*
|
||||
|
@ -2055,7 +2172,7 @@ HRESULT WINAPI CoGetPSClsid(REFIID riid, CLSID *pclsid)
|
|||
strcpyW(path + ARRAYSIZE(wszInterface) - 1 + CHARS_IN_GUID - 1, wszPSC);
|
||||
|
||||
/* Open the key.. */
|
||||
if (RegOpenKeyExW(HKEY_CLASSES_ROOT, path, 0, KEY_READ, &hkey))
|
||||
if (open_classes_key(HKEY_CLASSES_ROOT, path, KEY_READ, &hkey))
|
||||
{
|
||||
WARN("No PSFactoryBuffer object is registered for IID %s\n", debugstr_guid(riid));
|
||||
return REGDB_E_IIDNOTREG;
|
||||
|
|
|
@ -309,4 +309,7 @@ extern UINT object_descriptor_clipboard_format DECLSPEC_HIDDEN;
|
|||
extern UINT link_source_descriptor_clipboard_format DECLSPEC_HIDDEN;
|
||||
extern UINT ole_private_data_clipboard_format DECLSPEC_HIDDEN;
|
||||
|
||||
extern LSTATUS create_classes_key(HKEY, const WCHAR *, REGSAM, HKEY *) DECLSPEC_HIDDEN;
|
||||
extern LSTATUS open_classes_key(HKEY, const WCHAR *, REGSAM, HKEY *) DECLSPEC_HIDDEN;
|
||||
|
||||
#endif /* __WINE_OLE_COMPOBJ_H */
|
||||
|
|
|
@ -755,7 +755,7 @@ static void test_CoGetPSClsid(void)
|
|||
ok(!res, "RegOverridePredefKey returned %d\n", res);
|
||||
|
||||
hr = CoGetPSClsid(&IID_IClassFactory, &clsid);
|
||||
todo_wine ok_ole_success(hr, "CoGetPSClsid");
|
||||
ok_ole_success(hr, "CoGetPSClsid");
|
||||
|
||||
res = pRegOverridePredefKey(HKEY_CLASSES_ROOT, NULL);
|
||||
ok(!res, "RegOverridePredefKey returned %d\n", res);
|
||||
|
|
Loading…
Reference in New Issue