mirror of
https://github.com/reactos/reactos.git
synced 2024-12-29 02:25:17 +00:00
implemented RegOpenUserClassesRoot (doesn't work in reactos because there's no symbolic link \Registry\User\<SID>_Classes yet)
svn path=/trunk/; revision=15009
This commit is contained in:
parent
bcbeeea71f
commit
6b48fc81ad
2 changed files with 147 additions and 1 deletions
|
@ -492,7 +492,7 @@ RegOpenKeyA@12
|
||||||
RegOpenKeyExA@20
|
RegOpenKeyExA@20
|
||||||
RegOpenKeyExW@20
|
RegOpenKeyExW@20
|
||||||
RegOpenKeyW@12
|
RegOpenKeyW@12
|
||||||
;RegOpenUserClassesRoot
|
RegOpenUserClassesRoot@16
|
||||||
;RegOverridePredefKey
|
;RegOverridePredefKey
|
||||||
RegQueryInfoKeyA@48
|
RegQueryInfoKeyA@48
|
||||||
RegQueryInfoKeyW@48
|
RegQueryInfoKeyW@48
|
||||||
|
|
|
@ -1719,6 +1719,152 @@ RegOpenKeyExW (HKEY hKey,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/************************************************************************
|
||||||
|
* RegOpenUserClassesRoot
|
||||||
|
*
|
||||||
|
* @implemented
|
||||||
|
*/
|
||||||
|
LONG STDCALL
|
||||||
|
RegOpenUserClassesRoot (IN HANDLE hToken,
|
||||||
|
IN DWORD dwOptions,
|
||||||
|
IN REGSAM samDesired,
|
||||||
|
OUT PHKEY phkResult)
|
||||||
|
{
|
||||||
|
const WCHAR UserClassesKeyPrefix[] = L"\\Registry\\User\\";
|
||||||
|
const WCHAR UserClassesKeySuffix[] = L"_Classes";
|
||||||
|
PTOKEN_USER TokenUserData;
|
||||||
|
ULONG RequiredLength;
|
||||||
|
UNICODE_STRING UserSidString, UserClassesKeyRoot;
|
||||||
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||||
|
LONG ErrorCode;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
/* check parameters */
|
||||||
|
if (hToken == NULL || dwOptions != 0 || phkResult == NULL)
|
||||||
|
{
|
||||||
|
return ERROR_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get the user sid from the token
|
||||||
|
*/
|
||||||
|
|
||||||
|
ReadTokenSid:
|
||||||
|
/* determine how much memory we need */
|
||||||
|
Status = NtQueryInformationToken(hToken,
|
||||||
|
TokenUser,
|
||||||
|
NULL,
|
||||||
|
0,
|
||||||
|
&RequiredLength);
|
||||||
|
if (!NT_SUCCESS(Status) && (Status != STATUS_BUFFER_TOO_SMALL))
|
||||||
|
{
|
||||||
|
/* NOTE - as opposed to all other registry functions windows does indeed
|
||||||
|
change the last error code in case the caller supplied a invalid
|
||||||
|
handle for example! */
|
||||||
|
ErrorCode = RtlNtStatusToDosError (Status);
|
||||||
|
return ErrorCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
TokenUserData = RtlAllocateHeap(ProcessHeap,
|
||||||
|
0,
|
||||||
|
RequiredLength);
|
||||||
|
if (TokenUserData == NULL)
|
||||||
|
{
|
||||||
|
return ERROR_NOT_ENOUGH_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* attempt to read the information */
|
||||||
|
Status = NtQueryInformationToken(hToken,
|
||||||
|
TokenUser,
|
||||||
|
TokenUserData,
|
||||||
|
RequiredLength,
|
||||||
|
&RequiredLength);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
RtlFreeHeap(ProcessHeap,
|
||||||
|
0,
|
||||||
|
TokenUserData);
|
||||||
|
if (Status == STATUS_BUFFER_TOO_SMALL)
|
||||||
|
{
|
||||||
|
/* the information appears to have changed?! try again */
|
||||||
|
goto ReadTokenSid;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* NOTE - as opposed to all other registry functions windows does indeed
|
||||||
|
change the last error code in case the caller supplied a invalid
|
||||||
|
handle for example! */
|
||||||
|
ErrorCode = RtlNtStatusToDosError (Status);
|
||||||
|
return ErrorCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Build the absolute path for the user's registry in the form
|
||||||
|
* "\Registry\User\<SID>_Classes"
|
||||||
|
*/
|
||||||
|
Status = RtlConvertSidToUnicodeString(&UserSidString,
|
||||||
|
TokenUserData->User.Sid,
|
||||||
|
TRUE);
|
||||||
|
|
||||||
|
/* we don't need the user data anymore, free it */
|
||||||
|
RtlFreeHeap(ProcessHeap,
|
||||||
|
0,
|
||||||
|
TokenUserData);
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
return RtlNtStatusToDosError (Status);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* allocate enough memory for the entire key string */
|
||||||
|
UserClassesKeyRoot.Length = 0;
|
||||||
|
UserClassesKeyRoot.MaximumLength = UserSidString.Length +
|
||||||
|
sizeof(UserClassesKeyPrefix) +
|
||||||
|
sizeof(UserClassesKeySuffix);
|
||||||
|
UserClassesKeyRoot.Buffer = RtlAllocateHeap(ProcessHeap,
|
||||||
|
0,
|
||||||
|
UserClassesKeyRoot.MaximumLength);
|
||||||
|
if (UserClassesKeyRoot.Buffer == NULL)
|
||||||
|
{
|
||||||
|
RtlFreeUnicodeString(&UserSidString);
|
||||||
|
return RtlNtStatusToDosError (Status);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* build the string */
|
||||||
|
RtlAppendUnicodeToString(&UserClassesKeyRoot,
|
||||||
|
UserClassesKeyPrefix);
|
||||||
|
RtlAppendUnicodeStringToString(&UserClassesKeyRoot,
|
||||||
|
&UserSidString);
|
||||||
|
RtlAppendUnicodeToString(&UserClassesKeyRoot,
|
||||||
|
UserClassesKeySuffix);
|
||||||
|
|
||||||
|
DPRINT("RegOpenUserClassesRoot: Absolute path: %wZ\n", &UserClassesKeyRoot);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Open the key
|
||||||
|
*/
|
||||||
|
|
||||||
|
InitializeObjectAttributes (&ObjectAttributes,
|
||||||
|
&UserClassesKeyRoot,
|
||||||
|
OBJ_CASE_INSENSITIVE,
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
Status = NtOpenKey((PHANDLE)phkResult,
|
||||||
|
samDesired,
|
||||||
|
&ObjectAttributes);
|
||||||
|
|
||||||
|
RtlFreeUnicodeString(&UserSidString);
|
||||||
|
RtlFreeUnicodeString(&UserClassesKeyRoot);
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
return RtlNtStatusToDosError (Status);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ERROR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
* RegQueryInfoKeyA
|
* RegQueryInfoKeyA
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in a new issue