You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1345 lines
42 KiB
1345 lines
42 KiB
/****************************** Module Header ******************************\
|
|
* Module Name: profile.c
|
|
*
|
|
* Copyright (c) 1985 - 1999, Microsoft Corporation
|
|
*
|
|
* This module contains code to emulate ini file mapping.
|
|
*
|
|
* History:
|
|
* 30-Nov-1993 SanfordS Created.
|
|
\***************************************************************************/
|
|
#include "precomp.h"
|
|
#pragma hdrstop
|
|
|
|
/***************************************************************************\
|
|
* aFastRegMap[]
|
|
*
|
|
* This array maps section ids (PMAP_) to cached registry keys and section
|
|
* addresses within the registry. IF INI FILE MAPPING CHANGES ARE MADE,
|
|
* THIS TABLE MUST BE UPDATED.
|
|
*
|
|
* The first character of the szSection field indicates what root the
|
|
* section is in. (or locked open status)
|
|
* M = LocalMachine
|
|
* U = CurrentUser
|
|
* L = Locked open - used only on M mappings.
|
|
*
|
|
* History:
|
|
\***************************************************************************/
|
|
#define PROOT_CPANEL 0
|
|
#define PROOT_ACCESS 1
|
|
#define PROOT_CURRENTM 2
|
|
#define PROOT_CURRENTU 3
|
|
#define PROOT_CONTROL 4
|
|
#define PROOT_SERVICES 5
|
|
#define PROOT_KEYBOARD 6
|
|
#define PROOT_SYSTEM 7
|
|
|
|
typedef struct tagFASTREGMAP {
|
|
UINT idRoot;
|
|
PCWSTR szSection;
|
|
} FASTREGMAP, *PFASTREGMAP;
|
|
|
|
CONST PCWSTR aFastRegRoot[] = {
|
|
L"UControl Panel\\", // PROOT_CPANEL
|
|
L"UControl Panel\\Accessibility\\", // PROOT_ACCESS
|
|
L"MSoftware\\Microsoft\\Windows NT\\CurrentVersion\\", // PROOT_CURRENTM
|
|
L"USoftware\\Microsoft\\Windows NT\\CurrentVersion\\", // PROOT_CURRENTU
|
|
L"MSystem\\CurrentControlSet\\Control\\", // PROOT_CONTROL
|
|
L"MSystem\\CurrentControlSet\\Services\\", // PROOT_SERVICES
|
|
L"UKeyboard Layout\\", // PROOT_KEYBOARD
|
|
L"MSystem\\", // PROOT_SYSTEM
|
|
};
|
|
|
|
CONST FASTREGMAP aFastRegMap[PMAP_LAST + 1] = {
|
|
{ PROOT_CPANEL, L"Colors" }, // PMAP_COLORS
|
|
{ PROOT_CPANEL, L"Cursors" }, // PMAP_CURSORS
|
|
{ PROOT_CURRENTM, L"Windows" }, // PMAP_WINDOWSM
|
|
{ PROOT_CURRENTU, L"Windows" }, // PMAP_WINDOWSU
|
|
{ PROOT_CPANEL, L"Desktop" }, // PMAP_DESKTOP
|
|
{ PROOT_CPANEL, L"Icons" }, // PMAP_ICONS
|
|
{ PROOT_CURRENTM, L"Fonts" }, // PMAP_FONTS
|
|
{ PROOT_CURRENTU, L"TrueType" }, // PMAP_TRUETYPE
|
|
{ PROOT_CONTROL, L"Keyboard Layout" }, // PMAP_KBDLAYOUT
|
|
{ PROOT_SERVICES, L"RIT" }, // PMAP_INPUT
|
|
{ PROOT_CURRENTM, L"Compatibility" }, // PMAP_COMPAT
|
|
{ PROOT_CONTROL, L"Session Manager\\SubSystems" }, // PMAP_SUBSYSTEMS
|
|
{ PROOT_CPANEL, L"Sound" }, // PMAP_BEEP
|
|
{ PROOT_CPANEL, L"Mouse" }, // PMAP_MOUSE
|
|
{ PROOT_CPANEL, L"Keyboard" }, // PMAP_KEYBOARD
|
|
{ PROOT_ACCESS, L"StickyKeys" }, // PMAP_STICKYKEYS
|
|
{ PROOT_ACCESS, L"Keyboard Response" }, // PMAP_KEYBOARDRESPONSE
|
|
{ PROOT_ACCESS, L"MouseKeys" }, // PMAP_MOUSEKEYS
|
|
{ PROOT_ACCESS, L"ToggleKeys" }, // PMAP_TOGGLEKEYS
|
|
{ PROOT_ACCESS, L"TimeOut" }, // PMAP_TIMEOUT
|
|
{ PROOT_ACCESS, L"SoundSentry" }, // PMAP_SOUNDSENTRY
|
|
{ PROOT_ACCESS, L"ShowSounds" }, // PMAP_SHOWSOUNDS
|
|
{ PROOT_CURRENTM, L"AeDebug" }, // PMAP_AEDEBUG
|
|
{ PROOT_CONTROL, L"NetworkProvider" }, // PMAP_NETWORK
|
|
{ PROOT_CPANEL, L"Desktop\\WindowMetrics" }, // PMAP_METRICS
|
|
{ PROOT_KEYBOARD, L"" }, // PMAP_UKBDLAYOUT
|
|
{ PROOT_KEYBOARD, L"Toggle" }, // PMAP_UKBDLAYOUTTOGGLE
|
|
{ PROOT_CURRENTM, L"Winlogon" }, // PMAP_WINLOGON
|
|
{ PROOT_ACCESS, L"Keyboard Preference" }, // PMAP_KEYBOARDPREF
|
|
{ PROOT_ACCESS, L"Blind Access" }, // PMAP_SCREENREADER
|
|
{ PROOT_ACCESS, L"HighContrast" }, // PMAP_HIGHCONTRAST
|
|
{ PROOT_CURRENTM, L"IME Compatibility" }, // PMAP_IMECOMPAT
|
|
{ PROOT_CURRENTM, L"IMM" }, // PMAP_IMM
|
|
{ PROOT_CONTROL, L"Session Manager\\SubSystems\\Pool" }, // PMAP_POOLLIMITS
|
|
{ PROOT_CURRENTM, L"Compatibility32" }, // PMAP_COMPAT32
|
|
{ PROOT_CURRENTM, L"WOW\\SetupPrograms" }, // PMAP_SETUPPROGRAMNAMES
|
|
{ PROOT_CPANEL, L"Input Method" }, // PMAP_INPUTMETHOD
|
|
{ PROOT_CURRENTM, L"Compatibility2" }, // PMAP_COMPAT2
|
|
{ PROOT_SERVICES, L"Mouclass\\Parameters" }, // PMAP_MOUCLASS_PARAMS
|
|
{ PROOT_SERVICES, L"Kbdclass\\Parameters" }, // PMAP_KBDCLASS_PARAMS
|
|
{ PROOT_CONTROL, L"ComputerName\\ComputerName" }, // PMAP_COMPUTERNAME
|
|
{ PROOT_CONTROL, L"Terminal Server" }, // PMAP_TS
|
|
{ PROOT_SYSTEM, L"WPA\\TabletPC" }, // PMAP_TABLETPC
|
|
{ PROOT_SYSTEM, L"WPA\\MediaCenter" }, // PMAP_MEDIACENTER
|
|
{ PROOT_CURRENTM, L"Windows" }, // PMAP_TS_EXCLUDE_DESKTOP_VERSION
|
|
};
|
|
|
|
WCHAR PreviousUserStringBuf[256];
|
|
UNICODE_STRING PreviousUserString = {0, sizeof PreviousUserStringBuf, PreviousUserStringBuf};
|
|
LUID luidPrevious;
|
|
|
|
CONST WCHAR wszDefaultUser[] = L"\\Registry\\User\\.Default";
|
|
UNICODE_STRING DefaultUserString = {sizeof wszDefaultUser - sizeof(WCHAR), sizeof wszDefaultUser, (WCHAR *)wszDefaultUser};
|
|
|
|
void InitPreviousUserString(void) {
|
|
UNICODE_STRING UserString;
|
|
LUID luidCaller;
|
|
|
|
CheckCritIn();
|
|
|
|
/*
|
|
* Speed hack, check if luid of this process == system or previous to
|
|
* save work.
|
|
*/
|
|
if (NT_SUCCESS(GetProcessLuid(NULL, &luidCaller))) {
|
|
|
|
if (RtlEqualLuid(&luidCaller, &luidPrevious)) {
|
|
return; // same as last time - no work.
|
|
}
|
|
luidPrevious = luidCaller;
|
|
|
|
if (RtlEqualLuid(&luidCaller, &luidSystem))
|
|
goto DefaultUser;
|
|
|
|
} else {
|
|
luidPrevious = RtlConvertLongToLuid(0);
|
|
}
|
|
|
|
/*
|
|
* Set up current user registry base string.
|
|
*/
|
|
if (!NT_SUCCESS(RtlFormatCurrentUserKeyPath(&UserString))) {
|
|
|
|
DefaultUser:
|
|
|
|
RtlCopyUnicodeString(&PreviousUserString, &DefaultUserString);
|
|
|
|
} else {
|
|
UserAssert(sizeof(PreviousUserStringBuf) >= UserString.Length + 4);
|
|
RtlCopyUnicodeString(&PreviousUserString, &UserString);
|
|
RtlFreeUnicodeString(&UserString);
|
|
}
|
|
|
|
RtlAppendUnicodeToString(&PreviousUserString, L"\\");
|
|
|
|
}
|
|
|
|
typedef struct tagPROFILEUSERNAME {
|
|
WCHAR awcName[MAXPROFILEBUF];
|
|
UNICODE_STRING NameString;
|
|
} PROFILEUSERNAME, *PPROFILEUSERNAME;
|
|
|
|
PUNICODE_STRING CreateProfileUserName(TL *ptl)
|
|
{
|
|
PPROFILEUSERNAME pMapName;
|
|
|
|
CheckCritIn();
|
|
|
|
pMapName = UserAllocPoolWithQuota(sizeof (PROFILEUSERNAME), TAG_PROFILEUSERNAME);
|
|
if (!pMapName) {
|
|
RIPMSG0(RIP_WARNING, "CreateProfileUserName: Allocation failed");
|
|
return NULL;
|
|
}
|
|
|
|
ThreadLockPool(PtiCurrent(), pMapName, ptl);
|
|
pMapName->NameString.Length = 0;
|
|
pMapName->NameString.MaximumLength = sizeof (pMapName->awcName);
|
|
pMapName->NameString.Buffer = pMapName->awcName;
|
|
|
|
InitPreviousUserString();
|
|
|
|
RtlCopyUnicodeString(&pMapName->NameString, &PreviousUserString);
|
|
return &(pMapName->NameString);
|
|
}
|
|
|
|
void FreeProfileUserName(PUNICODE_STRING pProfileUserName,TL *ptl) {
|
|
UNREFERENCED_PARAMETER(ptl);
|
|
CheckCritIn();
|
|
if (pProfileUserName) {
|
|
ThreadUnlockAndFreePool(PtiCurrent(), ptl);
|
|
}
|
|
}
|
|
|
|
|
|
/*****************************************************************************\
|
|
* OpenCacheKeyEx
|
|
*
|
|
* Attempts to open a cached key for a given section. If we are calling
|
|
* for a client thread, we must check the access rights for the key after
|
|
* opening it.
|
|
*
|
|
* Returns fSuccess.
|
|
*
|
|
* Note -- param 1 can be NULL. If the section name is a per-user registry
|
|
* section, we ill use the first parameter if available or set up
|
|
* and use the cached one if the first parameter is NULL.
|
|
*
|
|
* History:
|
|
* 03-Dec-1993 SanfordS Created.
|
|
\*****************************************************************************/
|
|
HANDLE OpenCacheKeyEx(
|
|
PUNICODE_STRING pMapName OPTIONAL,
|
|
UINT idSection,
|
|
ACCESS_MASK amRequest,
|
|
PDWORD pdwPolicyFlags
|
|
)
|
|
{
|
|
OBJECT_ATTRIBUTES OA;
|
|
WCHAR UnicodeStringBuf[256];
|
|
WCHAR pszSessionId[13];
|
|
UNICODE_STRING UnicodeString;
|
|
LONG Status;
|
|
HANDLE hKey = NULL;
|
|
PEPROCESS peCurrent = PsGetCurrentProcess();
|
|
DWORD dwPolicyFlags;
|
|
|
|
CheckCritIn();
|
|
|
|
UserAssert(idSection <= PMAP_LAST);
|
|
|
|
/*
|
|
* If we're opening the desktop or CPL\keyboard key for read access, we should be checking
|
|
* for relevant policy.
|
|
*/
|
|
if ((amRequest == KEY_READ) && (idSection == PMAP_DESKTOP)) {
|
|
UserAssert(pdwPolicyFlags);
|
|
UserAssert(!(*pdwPolicyFlags & ~POLICY_VALID));
|
|
dwPolicyFlags = *pdwPolicyFlags;
|
|
} else {
|
|
/*
|
|
* if we are here because Policy was changed and there is not POLICY_ flags set then return.
|
|
*/
|
|
if (pdwPolicyFlags && (*pdwPolicyFlags & POLICY_ONLY)) {
|
|
*pdwPolicyFlags = 0;
|
|
UserAssert(FALSE);
|
|
return NULL;
|
|
}
|
|
dwPolicyFlags = POLICY_NONE;
|
|
}
|
|
|
|
TryAgain:
|
|
|
|
UnicodeString.Length = 0;
|
|
UnicodeString.MaximumLength = sizeof(UnicodeStringBuf);
|
|
UnicodeString.Buffer = UnicodeStringBuf;
|
|
|
|
|
|
if (dwPolicyFlags & POLICY_MACHINE) {
|
|
dwPolicyFlags &= ~POLICY_MACHINE;
|
|
RtlAppendUnicodeToString(&UnicodeString,
|
|
L"\\Registry\\Machine\\");
|
|
RtlAppendUnicodeToString(&UnicodeString,
|
|
L"Software\\Policies\\Microsoft\\Windows\\");
|
|
} else {
|
|
if (aFastRegRoot[aFastRegMap[idSection].idRoot][0] == L'M') {
|
|
RtlAppendUnicodeToString(&UnicodeString, L"\\Registry\\Machine\\");
|
|
} else {
|
|
if (!pMapName) {
|
|
InitPreviousUserString();
|
|
RtlAppendUnicodeStringToString(
|
|
&UnicodeString,
|
|
&PreviousUserString);
|
|
} else {
|
|
RtlAppendUnicodeStringToString(
|
|
&UnicodeString,
|
|
pMapName);
|
|
}
|
|
}
|
|
if (dwPolicyFlags & POLICY_USER) {
|
|
dwPolicyFlags &= ~POLICY_USER;
|
|
RtlAppendUnicodeToString(&UnicodeString,
|
|
L"Software\\Policies\\Microsoft\\Windows\\");
|
|
}
|
|
else if (dwPolicyFlags & POLICY_REMOTE) {
|
|
dwPolicyFlags &= ~POLICY_REMOTE;
|
|
RtlAppendUnicodeToString(&UnicodeString,
|
|
L"Remote\\");
|
|
swprintf(pszSessionId, L"%ld\\", gSessionId);
|
|
RtlAppendUnicodeToString(&UnicodeString, pszSessionId);
|
|
} else {
|
|
/*
|
|
* if we are here because Policy was changed then do not try preferences.
|
|
*/
|
|
if (pdwPolicyFlags && (*pdwPolicyFlags & POLICY_ONLY)) {
|
|
*pdwPolicyFlags = 0;
|
|
return NULL;
|
|
}
|
|
dwPolicyFlags &= ~POLICY_NONE;
|
|
}
|
|
}
|
|
|
|
RtlAppendUnicodeToString(&UnicodeString,
|
|
(PWSTR)&aFastRegRoot[aFastRegMap[idSection].idRoot][1]);
|
|
|
|
RtlAppendUnicodeToString(&UnicodeString,
|
|
(PWSTR)aFastRegMap[idSection].szSection);
|
|
|
|
|
|
/*
|
|
* Open the key for kernel mode access
|
|
*/
|
|
InitializeObjectAttributes(&OA,
|
|
&UnicodeString,
|
|
OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
|
|
NULL,
|
|
NULL);
|
|
|
|
Status = ZwOpenKey(&hKey, amRequest, &OA);
|
|
|
|
if (
|
|
(amRequest == KEY_READ) || /*
|
|
* We must be able to read
|
|
* our registry settings.
|
|
*/
|
|
(peCurrent == gpepCSRSS) ||
|
|
(peCurrent == gpepInit)
|
|
) {
|
|
|
|
} else {
|
|
/*
|
|
* Now check if the user has access to the key
|
|
*/
|
|
|
|
if (NT_SUCCESS(Status)) {
|
|
PVOID pKey;
|
|
NTSTATUS Status2;
|
|
Status2 = ObReferenceObjectByHandle(hKey,
|
|
amRequest,
|
|
NULL,
|
|
KernelMode,
|
|
&pKey,
|
|
NULL);
|
|
|
|
if (NT_SUCCESS(Status2)) {
|
|
if (!AccessCheckObject(pKey, amRequest, UserMode, &KeyMapping)) {
|
|
ZwClose(hKey);
|
|
Status = STATUS_ACCESS_DENIED;
|
|
}
|
|
ObDereferenceObject(pKey);
|
|
} else {
|
|
ZwClose(hKey);
|
|
Status = STATUS_ACCESS_DENIED;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
#if DBG
|
|
if (!NT_SUCCESS(Status)) {
|
|
UnicodeStringBuf[UnicodeString.Length / 2] = 0;
|
|
|
|
if (PsGetCurrentProcessId() != gpidLogon) {
|
|
if (Status != STATUS_OBJECT_NAME_NOT_FOUND) {
|
|
RIPMSG1(RIP_WARNING | RIP_THERESMORE, "OpenCacheKeyEx failed with Status = %lx key:", Status);
|
|
RIPMSG1(RIP_WARNING | RIP_THERESMORE | RIP_NONAME | RIP_NONEWLINE, " %ws\\", UnicodeStringBuf);
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
|
|
/*
|
|
* If we didn't succeed and we're not down to bottom of policy chain, try again.
|
|
*/
|
|
if (!NT_SUCCESS(Status) && dwPolicyFlags) {
|
|
goto TryAgain;
|
|
}
|
|
|
|
/*
|
|
* Update policy level
|
|
*/
|
|
if (pdwPolicyFlags) {
|
|
*pdwPolicyFlags = dwPolicyFlags;
|
|
}
|
|
|
|
return (NT_SUCCESS(Status) ? hKey : NULL);
|
|
}
|
|
|
|
|
|
/*****************************************************************************\
|
|
* CheckDesktopPolicy
|
|
*
|
|
* Check if a desktop value has an associated policy.
|
|
*
|
|
* Returns TRUE if there is a policy, FALSE otherwise.
|
|
*
|
|
* History:
|
|
* 07-Feb-2000 JerrySh Created.
|
|
\*****************************************************************************/
|
|
BOOL CheckDesktopPolicy(
|
|
PUNICODE_STRING pProfileUserName OPTIONAL,
|
|
PCWSTR lpKeyName
|
|
)
|
|
{
|
|
WCHAR szKey[80];
|
|
HANDLE hKey;
|
|
DWORD cbSize;
|
|
NTSTATUS Status;
|
|
UNICODE_STRING UnicodeString;
|
|
KEY_VALUE_BASIC_INFORMATION KeyInfo;
|
|
DWORD dwPolicyFlags = gdwPolicyFlags & (POLICY_MACHINE | POLICY_USER);
|
|
|
|
/*
|
|
* If there is no policy or the caller is winlogon, let it go.
|
|
*/
|
|
if (!dwPolicyFlags || PsGetCurrentProcessId() == gpidLogon) {
|
|
return FALSE;
|
|
}
|
|
|
|
/*
|
|
* Convert the ID to a string if we need to.
|
|
*/
|
|
if (!IS_PTR(lpKeyName)) {
|
|
ServerLoadString(hModuleWin, PTR_TO_ID(lpKeyName), szKey, ARRAY_SIZE(szKey));
|
|
lpKeyName = szKey;
|
|
}
|
|
|
|
TryAgain:
|
|
|
|
/*
|
|
* Try to open a key.
|
|
*/
|
|
if ((hKey = OpenCacheKeyEx(pProfileUserName,
|
|
PMAP_DESKTOP,
|
|
KEY_READ,
|
|
&dwPolicyFlags)) == NULL) {
|
|
return FALSE;
|
|
}
|
|
|
|
/*
|
|
* See if the value exists.
|
|
*/
|
|
RtlInitUnicodeString(&UnicodeString, lpKeyName);
|
|
Status = ZwQueryValueKey(hKey,
|
|
&UnicodeString,
|
|
KeyValueBasicInformation,
|
|
&KeyInfo,
|
|
sizeof(KeyInfo),
|
|
&cbSize);
|
|
|
|
ZwClose(hKey);
|
|
|
|
if (!NT_ERROR(Status)) {
|
|
return TRUE;
|
|
} else if (dwPolicyFlags) {
|
|
goto TryAgain;
|
|
} else {
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
|
|
/*****************************************************************************\
|
|
* CheckDesktopPolicyChange
|
|
*
|
|
* Check if policy has changed since last time we checked.
|
|
*
|
|
* Returns TRUE if policy changed, FASLE otherwise.
|
|
*
|
|
* History:
|
|
* 07-Feb-2000 JerrySh Created.
|
|
\*****************************************************************************/
|
|
BOOL CheckDesktopPolicyChange(
|
|
PUNICODE_STRING pProfileUserName OPTIONAL
|
|
)
|
|
{
|
|
static LARGE_INTEGER LastMachineWriteTime;
|
|
static LARGE_INTEGER LastUserWriteTime;
|
|
KEY_BASIC_INFORMATION KeyInfo;
|
|
BOOL bPolicyChanged = FALSE;
|
|
HANDLE hKey;
|
|
DWORD cbSize;
|
|
DWORD dwPolicyFlags;
|
|
|
|
/*
|
|
* Check if machine policy has changed since last time we checked.
|
|
*/
|
|
dwPolicyFlags = POLICY_MACHINE;
|
|
KeyInfo.LastWriteTime.QuadPart = 0;
|
|
hKey = OpenCacheKeyEx(pProfileUserName,
|
|
PMAP_DESKTOP,
|
|
KEY_READ,
|
|
&dwPolicyFlags);
|
|
if (hKey) {
|
|
if (hKey) {
|
|
ZwQueryKey(hKey,
|
|
KeyValueBasicInformation,
|
|
&KeyInfo,
|
|
sizeof(KeyInfo),
|
|
&cbSize);
|
|
ZwClose(hKey);
|
|
}
|
|
gdwPolicyFlags |= POLICY_MACHINE;
|
|
} else {
|
|
gdwPolicyFlags &= ~POLICY_MACHINE;
|
|
}
|
|
if (LastMachineWriteTime.QuadPart != KeyInfo.LastWriteTime.QuadPart) {
|
|
LastMachineWriteTime.QuadPart = KeyInfo.LastWriteTime.QuadPart;
|
|
bPolicyChanged = TRUE;
|
|
}
|
|
|
|
/*
|
|
* Check if user policy has changed since last time we checked.
|
|
*/
|
|
dwPolicyFlags = POLICY_USER;
|
|
KeyInfo.LastWriteTime.QuadPart = 0;
|
|
hKey = OpenCacheKeyEx(pProfileUserName,
|
|
PMAP_DESKTOP,
|
|
KEY_READ,
|
|
&dwPolicyFlags);
|
|
if (hKey) {
|
|
ZwQueryKey(hKey,
|
|
KeyValueBasicInformation,
|
|
&KeyInfo,
|
|
sizeof(KeyInfo),
|
|
&cbSize);
|
|
ZwClose(hKey);
|
|
gdwPolicyFlags |= POLICY_USER;
|
|
} else {
|
|
gdwPolicyFlags &= ~POLICY_USER;
|
|
}
|
|
if (LastUserWriteTime.QuadPart != KeyInfo.LastWriteTime.QuadPart) {
|
|
LastUserWriteTime.QuadPart = KeyInfo.LastWriteTime.QuadPart;
|
|
bPolicyChanged = TRUE;
|
|
}
|
|
|
|
return bPolicyChanged;
|
|
}
|
|
|
|
|
|
/*****************************************************************************\
|
|
* FastGetProfileDwordW
|
|
*
|
|
* Reads a REG_DWORD type key from the registry.
|
|
*
|
|
* returns value read or default value on failure.
|
|
*
|
|
* History:
|
|
* 02-Dec-1993 SanfordS Created.
|
|
\*****************************************************************************/
|
|
BOOL FastGetProfileDwordW(PUNICODE_STRING pProfileUserName OPTIONAL,
|
|
UINT idSection,
|
|
LPCWSTR lpKeyName,
|
|
DWORD dwDefault,
|
|
PDWORD pdwReturn,
|
|
DWORD dwPolicyOnly
|
|
)
|
|
{
|
|
HANDLE hKey;
|
|
DWORD cbSize;
|
|
DWORD dwRet;
|
|
LONG Status;
|
|
UNICODE_STRING UnicodeString;
|
|
BYTE Buf[sizeof(KEY_VALUE_PARTIAL_INFORMATION) + sizeof(DWORD)];
|
|
DWORD dwPolicyFlags = gdwPolicyFlags | dwPolicyOnly;
|
|
|
|
UserAssert(idSection <= PMAP_LAST);
|
|
|
|
TryAgain:
|
|
|
|
if ((hKey = OpenCacheKeyEx(pProfileUserName,
|
|
idSection,
|
|
KEY_READ,
|
|
&dwPolicyFlags)) == NULL) {
|
|
RIPMSG1(RIP_WARNING | RIP_NONAME, "%ws", lpKeyName);
|
|
|
|
if (dwPolicyOnly & POLICY_ONLY) {
|
|
return FALSE;
|
|
}
|
|
|
|
if (pdwReturn) {
|
|
*pdwReturn = dwDefault;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
RtlInitUnicodeString(&UnicodeString, lpKeyName);
|
|
Status = ZwQueryValueKey(hKey,
|
|
&UnicodeString,
|
|
KeyValuePartialInformation,
|
|
(PKEY_VALUE_PARTIAL_INFORMATION)Buf,
|
|
sizeof(Buf),
|
|
&cbSize);
|
|
|
|
dwRet = dwDefault;
|
|
|
|
if (NT_SUCCESS(Status)) {
|
|
|
|
dwRet = *((PDWORD)((PKEY_VALUE_PARTIAL_INFORMATION)Buf)->Data);
|
|
|
|
} else if (dwPolicyFlags) {
|
|
|
|
ZwClose(hKey);
|
|
goto TryAgain;
|
|
|
|
} else if (Status != STATUS_OBJECT_NAME_NOT_FOUND) {
|
|
|
|
RIPMSG1(RIP_WARNING,
|
|
"FastGetProfileDwordW: ObjectName not found: %ws",
|
|
lpKeyName);
|
|
}
|
|
|
|
ZwClose(hKey);
|
|
|
|
if (pdwReturn) {
|
|
*pdwReturn = dwRet;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
/*****************************************************************************\
|
|
* FastGetProfileKeysW()
|
|
*
|
|
* Reads all key names in the given section.
|
|
*
|
|
* History:
|
|
* 15-Dec-1994 JimA Created.
|
|
\*****************************************************************************/
|
|
DWORD FastGetProfileKeysW(PUNICODE_STRING pProfileUserName OPTIONAL,
|
|
UINT idSection,
|
|
LPCWSTR lpDefault,
|
|
LPWSTR *lpReturnedString
|
|
)
|
|
{
|
|
HANDLE hKey;
|
|
DWORD cchSize;
|
|
DWORD cchKey;
|
|
LONG Status;
|
|
WCHAR Buffer[256 + 6];
|
|
PKEY_VALUE_BASIC_INFORMATION pKeyInfo;
|
|
ULONG iValue;
|
|
LPWSTR lpTmp;
|
|
LPWSTR lpKeys = NULL;
|
|
DWORD dwPoolSize;
|
|
|
|
UserAssert(idSection <= PMAP_LAST);
|
|
|
|
if ((hKey = OpenCacheKeyEx(pProfileUserName,
|
|
idSection,
|
|
KEY_READ,
|
|
NULL)) == NULL) {
|
|
RIPMSG0(RIP_WARNING | RIP_NONAME, "");
|
|
goto DefExit;
|
|
}
|
|
|
|
pKeyInfo = (PKEY_VALUE_BASIC_INFORMATION)Buffer;
|
|
cchSize = 0;
|
|
*lpReturnedString = NULL;
|
|
iValue = 0;
|
|
|
|
while (TRUE) {
|
|
|
|
#if DBG
|
|
wcscpy(Buffer + 256, L"DON'T");
|
|
#endif
|
|
Status = ZwEnumerateValueKey(hKey,
|
|
iValue,
|
|
KeyValueBasicInformation,
|
|
pKeyInfo,
|
|
sizeof(Buffer),
|
|
&cchKey);
|
|
|
|
UserAssert(_wcsicmp(Buffer + 256, L"DON'T") == 0);
|
|
|
|
if (Status == STATUS_NO_MORE_ENTRIES) {
|
|
|
|
break;
|
|
|
|
} else if (!NT_SUCCESS(Status)) {
|
|
|
|
if (lpKeys) {
|
|
UserFreePool(lpKeys);
|
|
lpKeys = NULL;
|
|
}
|
|
goto DefExit;
|
|
}
|
|
|
|
UserAssert(pKeyInfo->NameLength * sizeof(WCHAR) <=
|
|
sizeof(Buffer) - sizeof(KEY_VALUE_BASIC_INFORMATION));
|
|
|
|
UserAssert(cchKey <= sizeof(Buffer));
|
|
|
|
/*
|
|
* A key was found. Allocate space for it. Note that
|
|
* NameLength is in bytes.
|
|
*/
|
|
cchKey = cchSize;
|
|
cchSize += pKeyInfo->NameLength + sizeof(WCHAR);
|
|
|
|
if (lpKeys == NULL) {
|
|
|
|
dwPoolSize = cchSize + sizeof(WCHAR);
|
|
lpKeys = UserAllocPoolWithQuota(dwPoolSize, TAG_PROFILE);
|
|
|
|
} else {
|
|
|
|
lpTmp = lpKeys;
|
|
lpKeys = UserReAllocPoolWithQuota(lpTmp,
|
|
dwPoolSize,
|
|
cchSize + sizeof(WCHAR),
|
|
TAG_PROFILE);
|
|
|
|
/*
|
|
* Free the original buffer if the allocation fails
|
|
*/
|
|
if (lpKeys == NULL) {
|
|
UserFreePool(lpTmp);
|
|
}
|
|
dwPoolSize = cchSize + sizeof(WCHAR);
|
|
}
|
|
|
|
/*
|
|
* Check for out of memory.
|
|
*/
|
|
if (lpKeys == NULL)
|
|
goto DefExit;
|
|
|
|
/*
|
|
* NULL terminate the string and append it to
|
|
* the key list.
|
|
*/
|
|
UserAssert(pKeyInfo->NameLength < sizeof(Buffer) - sizeof(KEY_VALUE_BASIC_INFORMATION));
|
|
|
|
RtlCopyMemory(&lpKeys[cchKey / sizeof(WCHAR)], pKeyInfo->Name, pKeyInfo->NameLength);
|
|
lpKeys[(cchKey + pKeyInfo->NameLength) / sizeof(WCHAR)] = 0;
|
|
|
|
iValue++;
|
|
}
|
|
|
|
/*
|
|
* If no keys were found, return the default.
|
|
*/
|
|
if (iValue == 0) {
|
|
|
|
DefExit:
|
|
|
|
cchSize = wcslen(lpDefault)+1;
|
|
lpKeys = UserAllocPoolWithQuota((cchSize+1) * sizeof(WCHAR), TAG_PROFILE);
|
|
|
|
if (lpKeys)
|
|
wcscpy(lpKeys, lpDefault);
|
|
else
|
|
cchSize = 0;
|
|
|
|
} else {
|
|
|
|
/*
|
|
* Turn the byte count into a char count.
|
|
*/
|
|
cchSize /= sizeof(WCHAR);
|
|
}
|
|
|
|
/*
|
|
* Make sure hKey is closed.
|
|
*/
|
|
if (hKey)
|
|
ZwClose(hKey);
|
|
|
|
/*
|
|
* Append the ending NULL.
|
|
*/
|
|
if (lpKeys)
|
|
lpKeys[cchSize] = 0;
|
|
|
|
*lpReturnedString = lpKeys;
|
|
|
|
return cchSize;
|
|
}
|
|
|
|
/*****************************************************************************\
|
|
* FastGetProfileStringW()
|
|
*
|
|
* Implements a fast version of the standard API using predefined registry
|
|
* section indecies (PMAP_) that reference lazy-opened, cached registry
|
|
* handles. FastCloseProfileUserMapping() should be called to clean up
|
|
* cached entries when fast profile calls are completed.
|
|
*
|
|
* This api does NOT implement the NULL lpKeyName feature of the real API.
|
|
*
|
|
* History:
|
|
* 02-Dec-1993 SanfordS Created.
|
|
\*****************************************************************************/
|
|
DWORD FastGetProfileStringW(PUNICODE_STRING pProfileUserName OPTIONAL,
|
|
UINT idSection,
|
|
LPCWSTR lpKeyName,
|
|
LPCWSTR lpDefault,
|
|
LPWSTR lpReturnedString,
|
|
DWORD cchBuf,
|
|
DWORD dwPolicyOnly
|
|
)
|
|
{
|
|
HANDLE hKey = NULL;
|
|
DWORD cbSize;
|
|
LONG Status;
|
|
UNICODE_STRING UnicodeString;
|
|
PKEY_VALUE_PARTIAL_INFORMATION pKeyInfo;
|
|
DWORD dwPolicyFlags = gdwPolicyFlags | dwPolicyOnly;
|
|
|
|
|
|
UserAssert(idSection <= PMAP_LAST);
|
|
UserAssert(lpKeyName != NULL);
|
|
|
|
TryAgain:
|
|
|
|
if ((hKey = OpenCacheKeyEx(pProfileUserName,
|
|
idSection,
|
|
KEY_READ,
|
|
&dwPolicyFlags)) == NULL) {
|
|
#if DBG
|
|
if (PsGetCurrentProcessId() != gpidLogon) {
|
|
RIPMSG1(RIP_WARNING | RIP_NONAME, "%ws", lpKeyName);
|
|
}
|
|
#endif
|
|
if (dwPolicyOnly & POLICY_ONLY) {
|
|
return 0;
|
|
}
|
|
goto DefExit;
|
|
}
|
|
|
|
cbSize = (cchBuf * sizeof(WCHAR)) +
|
|
FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data);
|
|
if ((pKeyInfo = UserAllocPoolWithQuota(cbSize, TAG_PROFILE)) == NULL) {
|
|
goto DefExit;
|
|
}
|
|
|
|
RtlInitUnicodeString(&UnicodeString, lpKeyName);
|
|
Status = ZwQueryValueKey(hKey,
|
|
&UnicodeString,
|
|
KeyValuePartialInformation,
|
|
pKeyInfo,
|
|
cbSize,
|
|
&cbSize);
|
|
|
|
if (Status == STATUS_BUFFER_OVERFLOW) {
|
|
RIPMSG0(RIP_WARNING, "FastGetProfileStringW: Buffer overflow");
|
|
Status = STATUS_SUCCESS;
|
|
}
|
|
|
|
UserAssert(NT_SUCCESS(Status) || (Status == STATUS_OBJECT_NAME_NOT_FOUND));
|
|
|
|
if (NT_SUCCESS(Status)) {
|
|
|
|
if (pKeyInfo->DataLength >= sizeof(WCHAR)) {
|
|
|
|
((LPWSTR)(pKeyInfo->Data))[cchBuf - 1] = L'\0';
|
|
wcscpy(lpReturnedString, (LPWSTR)pKeyInfo->Data);
|
|
|
|
} else {
|
|
/*
|
|
* Appears to be a bug with empty strings - only first
|
|
* byte is set to NULL. (SAS)
|
|
*/
|
|
lpReturnedString[0] = TEXT('\0');
|
|
}
|
|
|
|
cchBuf = pKeyInfo->DataLength;
|
|
|
|
UserFreePool(pKeyInfo);
|
|
|
|
ZwClose(hKey);
|
|
|
|
/*
|
|
* data length includes terminating zero [bodind]
|
|
*/
|
|
return (cchBuf / sizeof(WCHAR));
|
|
|
|
} else if (dwPolicyFlags) {
|
|
UserFreePool(pKeyInfo);
|
|
ZwClose(hKey);
|
|
goto TryAgain;
|
|
}
|
|
|
|
UserFreePool(pKeyInfo);
|
|
|
|
DefExit:
|
|
|
|
/*
|
|
* Make sure the key is closed.
|
|
*/
|
|
if (hKey)
|
|
ZwClose(hKey);
|
|
|
|
/*
|
|
* wcscopy copies terminating zero, but the length returned by
|
|
* wcslen does not, so add 1 to be consistent with success
|
|
* return [bodind]
|
|
*/
|
|
if (lpDefault != NULL) {
|
|
cchBuf = wcslen(lpDefault) + 1;
|
|
RtlCopyMemory(lpReturnedString, lpDefault, cchBuf * sizeof(WCHAR));
|
|
return cchBuf;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*****************************************************************************\
|
|
* FastGetProfileIntW()
|
|
*
|
|
* Implements a fast version of the standard API using predefined registry
|
|
* section indecies (PMAP_) that reference lazy-opened, cached registry
|
|
* handles. FastCloseProfileUserMapping() should be called to clean up
|
|
* cached entries when fast profile calls are completed.
|
|
*
|
|
* History:
|
|
* 02-Dec-1993 SanfordS Created.
|
|
\*****************************************************************************/
|
|
BOOL FastGetProfileIntW(PUNICODE_STRING pProfileUserName OPTIONAL,
|
|
UINT idSection,
|
|
LPCWSTR lpKeyName,
|
|
UINT nDefault,
|
|
PUINT puiReturn,
|
|
DWORD dwPolicyOnly
|
|
)
|
|
{
|
|
WCHAR ValueBuf[40];
|
|
UNICODE_STRING Value;
|
|
UINT ReturnValue;
|
|
|
|
UserAssert(idSection <= PMAP_LAST);
|
|
UserAssert(puiReturn);
|
|
|
|
if (!FastGetProfileStringW(pProfileUserName,
|
|
idSection,
|
|
lpKeyName,
|
|
NULL,
|
|
ValueBuf,
|
|
sizeof(ValueBuf) / sizeof(WCHAR),
|
|
dwPolicyOnly
|
|
)) {
|
|
if (dwPolicyOnly & POLICY_ONLY) {
|
|
return FALSE;
|
|
}
|
|
|
|
*puiReturn = nDefault;
|
|
return TRUE;
|
|
}
|
|
|
|
/*
|
|
* Convert string to int.
|
|
*/
|
|
RtlInitUnicodeString(&Value, ValueBuf);
|
|
RtlUnicodeStringToInteger(&Value, 10, &ReturnValue);
|
|
|
|
*puiReturn = ReturnValue;
|
|
return TRUE;
|
|
}
|
|
|
|
/*****************************************************************************\
|
|
* FastWriteProfileStringW
|
|
*
|
|
* Implements a fast version of the standard API using predefined registry
|
|
* section indecies (PMAP_) that reference lazy-opened, cached registry
|
|
* handles. FastCloseProfileUserMapping() should be called to clean up
|
|
* cached entries when fast profile calls are completed.
|
|
*
|
|
* History:
|
|
* 02-Dec-1993 SanfordS Created.
|
|
\*****************************************************************************/
|
|
BOOL FastWriteProfileStringW(PUNICODE_STRING pProfileUserName OPTIONAL,
|
|
UINT idSection,
|
|
LPCWSTR lpKeyName,
|
|
LPCWSTR lpString
|
|
)
|
|
{
|
|
HANDLE hKey;
|
|
LONG Status;
|
|
UNICODE_STRING UnicodeString;
|
|
|
|
UserAssert(idSection <= PMAP_LAST);
|
|
|
|
/*
|
|
* We shouldn't be writing values that are controlled by policy.
|
|
*/
|
|
if (idSection == PMAP_DESKTOP) {
|
|
UserAssert(!CheckDesktopPolicy(pProfileUserName, lpKeyName));
|
|
}
|
|
|
|
if ((hKey = OpenCacheKeyEx(pProfileUserName,
|
|
idSection,
|
|
KEY_WRITE,
|
|
NULL)) == NULL) {
|
|
RIPMSG1(RIP_WARNING | RIP_NONAME, "%ws", lpKeyName);
|
|
return FALSE;
|
|
}
|
|
|
|
RtlInitUnicodeString(&UnicodeString, lpKeyName);
|
|
Status = ZwSetValueKey(hKey,
|
|
&UnicodeString,
|
|
0,
|
|
REG_SZ,
|
|
(PVOID)lpString,
|
|
(wcslen(lpString) + 1) * sizeof(WCHAR));
|
|
|
|
ZwClose(hKey);
|
|
|
|
return (NT_SUCCESS(Status));
|
|
}
|
|
|
|
/*****************************************************************************\
|
|
* FastGetProfileIntFromID
|
|
*
|
|
* Just like FastGetProfileIntW except it reads the USER string table for the
|
|
* key name.
|
|
*
|
|
* History:
|
|
* 02-Dec-1993 SanfordS Created.
|
|
* 25-Feb-1995 BradG Added TWIPS -> Pixel conversion.
|
|
\*****************************************************************************/
|
|
BOOL FastGetProfileIntFromID(PUNICODE_STRING pProfileUserName OPTIONAL,
|
|
UINT idSection,
|
|
UINT idKey,
|
|
int def,
|
|
PINT pResult,
|
|
DWORD dwPolicyOnly
|
|
)
|
|
{
|
|
int result;
|
|
WCHAR szKey[80];
|
|
|
|
|
|
UserAssert(idSection <= PMAP_LAST);
|
|
|
|
ServerLoadString(hModuleWin, idKey, szKey, ARRAY_SIZE(szKey));
|
|
|
|
if (FastGetProfileIntW(pProfileUserName,idSection, szKey, def, &result, dwPolicyOnly))
|
|
{
|
|
/*
|
|
* If you change the below list of STR_* make sure you make a
|
|
* corresponding change in SetWindowMetricInt (rare.c)
|
|
*/
|
|
switch (idKey) {
|
|
case STR_BORDERWIDTH:
|
|
case STR_SCROLLWIDTH:
|
|
case STR_SCROLLHEIGHT:
|
|
case STR_CAPTIONWIDTH:
|
|
case STR_CAPTIONHEIGHT:
|
|
case STR_SMCAPTIONWIDTH:
|
|
case STR_SMCAPTIONHEIGHT:
|
|
case STR_MENUWIDTH:
|
|
case STR_MENUHEIGHT:
|
|
case STR_ICONHORZSPACING:
|
|
case STR_ICONVERTSPACING:
|
|
case STR_MINWIDTH:
|
|
case STR_MINHORZGAP:
|
|
case STR_MINVERTGAP:
|
|
/*
|
|
* Convert any registry values stored in TWIPS back to pixels
|
|
*/
|
|
if (result < 0)
|
|
result = MultDiv(-result, gpsi->dmLogPixels, 72 * 20);
|
|
break;
|
|
}
|
|
|
|
if (pResult) {
|
|
*pResult = result;
|
|
}
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
/*****************************************************************************\
|
|
* FastGetProfileIntFromID
|
|
*
|
|
* Just like FastGetProfileStringW except it reads the USER string table for
|
|
* the key name.
|
|
*
|
|
* History:
|
|
* 02-Dec-1993 SanfordS Created.
|
|
\*****************************************************************************/
|
|
DWORD FastGetProfileStringFromIDW(PUNICODE_STRING pProfileUserName OPTIONAL,
|
|
UINT idSection,
|
|
UINT idKey,
|
|
LPCWSTR lpDefault,
|
|
LPWSTR lpReturnedString,
|
|
DWORD cch,
|
|
DWORD dwPolicyOnly
|
|
)
|
|
{
|
|
WCHAR szKey[80];
|
|
|
|
UserAssert(idSection <= PMAP_LAST);
|
|
|
|
ServerLoadString(hModuleWin, idKey, szKey, ARRAY_SIZE(szKey));
|
|
|
|
return FastGetProfileStringW(pProfileUserName,
|
|
idSection,
|
|
szKey,
|
|
lpDefault,
|
|
lpReturnedString,
|
|
cch,
|
|
dwPolicyOnly);
|
|
}
|
|
|
|
/*****************************************************************************\
|
|
* FastWriteProfileValue
|
|
*
|
|
* History:
|
|
* 06/10/96 GerardoB Renamed and added uType parameter
|
|
\*****************************************************************************/
|
|
BOOL FastWriteProfileValue(PUNICODE_STRING pProfileUserName OPTIONAL,
|
|
UINT idSection,
|
|
LPCWSTR lpKeyName,
|
|
UINT uType,
|
|
LPBYTE lpStruct,
|
|
UINT cbSizeStruct
|
|
)
|
|
{
|
|
HANDLE hKey;
|
|
LONG Status;
|
|
UNICODE_STRING UnicodeString;
|
|
WCHAR szKey[SERVERSTRINGMAXSIZE];
|
|
|
|
UserAssert(idSection <= PMAP_LAST);
|
|
|
|
if (!IS_PTR(lpKeyName)) {
|
|
*szKey = (WCHAR)0;
|
|
ServerLoadString(hModuleWin, PTR_TO_ID(lpKeyName), szKey, ARRAY_SIZE(szKey));
|
|
UserAssert(*szKey != (WCHAR)0);
|
|
lpKeyName = szKey;
|
|
}
|
|
|
|
/*
|
|
* We shouldn't be writing values that are controlled by policy.
|
|
*/
|
|
if (idSection == PMAP_DESKTOP) {
|
|
UserAssert(!CheckDesktopPolicy(pProfileUserName, lpKeyName));
|
|
}
|
|
|
|
if ((hKey = OpenCacheKeyEx(pProfileUserName,
|
|
idSection,
|
|
KEY_WRITE,
|
|
NULL)) == NULL) {
|
|
RIPMSG1(RIP_WARNING, "FastWriteProfileValue: Failed to open cache-key (%ws)", lpKeyName);
|
|
return FALSE;
|
|
}
|
|
|
|
RtlInitUnicodeString(&UnicodeString, lpKeyName);
|
|
|
|
Status = ZwSetValueKey(hKey,
|
|
&UnicodeString,
|
|
0,
|
|
uType,
|
|
lpStruct,
|
|
cbSizeStruct);
|
|
ZwClose(hKey);
|
|
|
|
#if DBG
|
|
if (!NT_SUCCESS(Status)) {
|
|
RIPMSG3 (RIP_WARNING, "FastWriteProfileValue: ZwSetValueKey Failed. Status:%#lx idSection:%#lx KeyName:%s",
|
|
Status, idSection, UnicodeString.Buffer);
|
|
}
|
|
#endif
|
|
|
|
return (NT_SUCCESS(Status));
|
|
}
|
|
|
|
/*****************************************************************************\
|
|
* FastGetProfileValue
|
|
*
|
|
* If cbSizeReturn is 0, just return the size of the data
|
|
*
|
|
* History:
|
|
* 06/10/96 GerardoB Renamed
|
|
\*****************************************************************************/
|
|
DWORD FastGetProfileValue(PUNICODE_STRING pProfileUserName OPTIONAL,
|
|
UINT idSection,
|
|
LPCWSTR lpKeyName,
|
|
LPBYTE lpDefault,
|
|
LPBYTE lpReturn,
|
|
UINT cbSizeReturn,
|
|
DWORD dwPolicyOnly
|
|
)
|
|
{
|
|
HANDLE hKey;
|
|
UINT cbSize;
|
|
LONG Status;
|
|
UNICODE_STRING UnicodeString;
|
|
PKEY_VALUE_PARTIAL_INFORMATION pKeyInfo;
|
|
WCHAR szKey[SERVERSTRINGMAXSIZE];
|
|
KEY_VALUE_PARTIAL_INFORMATION KeyInfo;
|
|
DWORD dwPolicyFlags = gdwPolicyFlags | dwPolicyOnly;
|
|
|
|
UserAssert(idSection <= PMAP_LAST);
|
|
|
|
if (!IS_PTR(lpKeyName)) {
|
|
*szKey = (WCHAR)0;
|
|
ServerLoadString(hModuleWin, PTR_TO_ID(lpKeyName), szKey, ARRAY_SIZE(szKey));
|
|
UserAssert(*szKey != (WCHAR)0);
|
|
lpKeyName = szKey;
|
|
}
|
|
|
|
TryAgain:
|
|
|
|
if ((hKey = OpenCacheKeyEx(pProfileUserName,
|
|
idSection,
|
|
KEY_READ,
|
|
&dwPolicyFlags)) == NULL) {
|
|
// if hi-word of lpKeName is 0, it is a resource number not a string
|
|
if (!IS_PTR(lpKeyName))
|
|
RIPMSG1(RIP_WARNING, "FastGetProfileValue: Failed to open cache-key (%08x)", lpKeyName);
|
|
else
|
|
RIPMSG1(RIP_WARNING | RIP_NONAME, "%ws", lpKeyName);
|
|
|
|
if (dwPolicyOnly & POLICY_ONLY) {
|
|
return 0;
|
|
}
|
|
goto DefExit;
|
|
}
|
|
|
|
if (cbSizeReturn == 0) {
|
|
cbSize = sizeof(KeyInfo);
|
|
pKeyInfo = &KeyInfo;
|
|
} else {
|
|
cbSize = cbSizeReturn + FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data);
|
|
if ((pKeyInfo = UserAllocPoolWithQuota(cbSize, TAG_PROFILE)) == NULL) {
|
|
goto DefExit;
|
|
}
|
|
}
|
|
|
|
RtlInitUnicodeString(&UnicodeString, lpKeyName);
|
|
|
|
Status = ZwQueryValueKey(hKey,
|
|
&UnicodeString,
|
|
KeyValuePartialInformation,
|
|
pKeyInfo,
|
|
cbSize,
|
|
&cbSize);
|
|
|
|
if (NT_SUCCESS(Status)) {
|
|
|
|
UserAssert(cbSizeReturn >= pKeyInfo->DataLength);
|
|
|
|
cbSize = pKeyInfo->DataLength;
|
|
RtlCopyMemory(lpReturn, pKeyInfo->Data, cbSize);
|
|
|
|
if (cbSizeReturn != 0) {
|
|
UserFreePool(pKeyInfo);
|
|
}
|
|
ZwClose(hKey);
|
|
|
|
return cbSize;
|
|
} else if ((Status == STATUS_BUFFER_OVERFLOW) && (cbSizeReturn == 0)) {
|
|
ZwClose(hKey);
|
|
return pKeyInfo->DataLength;
|
|
} else if (dwPolicyFlags) {
|
|
if (cbSizeReturn != 0) {
|
|
UserFreePool(pKeyInfo);
|
|
}
|
|
ZwClose(hKey);
|
|
goto TryAgain;
|
|
}
|
|
|
|
#if DBG
|
|
if (Status != STATUS_OBJECT_NAME_NOT_FOUND) {
|
|
RIPMSG3 (RIP_WARNING, "FastGetProfileValue: ZwQueryValueKey Failed. Status:%#lx idSection:%#lx KeyName:%s",
|
|
Status, idSection, UnicodeString.Buffer);
|
|
}
|
|
#endif
|
|
|
|
if (cbSizeReturn != 0) {
|
|
UserFreePool(pKeyInfo);
|
|
}
|
|
|
|
DefExit:
|
|
|
|
if (hKey)
|
|
ZwClose(hKey);
|
|
|
|
if (lpDefault) {
|
|
RtlMoveMemory(lpReturn, lpDefault, cbSizeReturn);
|
|
return cbSizeReturn;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*****************************************************************************\
|
|
* UT_FastGetProfileIntsW
|
|
*
|
|
* Repeatedly calls FastGetProfileIntW on the given table.
|
|
*
|
|
* History:
|
|
* 02-Dec-1993 SanfordS Created.
|
|
\*****************************************************************************/
|
|
BOOL FastGetProfileIntsW(PUNICODE_STRING pProfileUserName OPTIONAL,
|
|
PPROFINTINFO ppii,
|
|
DWORD dwPolicyOnly
|
|
)
|
|
{
|
|
WCHAR szKey[40];
|
|
|
|
while (ppii->idSection != 0) {
|
|
|
|
ServerLoadString(hModuleWin,
|
|
PTR_TO_ID(ppii->lpKeyName),
|
|
szKey,
|
|
ARRAY_SIZE(szKey));
|
|
|
|
FastGetProfileIntW(pProfileUserName,
|
|
ppii->idSection,
|
|
szKey,
|
|
ppii->nDefault,
|
|
ppii->puResult,
|
|
dwPolicyOnly);
|
|
ppii++;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/***************************************************************************\
|
|
* UpdateWinIni
|
|
*
|
|
* Handles impersonation stuff and writes the given value to the registry.
|
|
*
|
|
* History:
|
|
* 28-Jun-1991 MikeHar Ported.
|
|
* 03-Dec-1993 SanfordS Used FastProfile calls, moved to profile.c
|
|
\***************************************************************************/
|
|
BOOL FastUpdateWinIni(PUNICODE_STRING pProfileUserName OPTIONAL,
|
|
UINT idSection,
|
|
UINT wKeyNameId,
|
|
LPWSTR lpszValue
|
|
)
|
|
{
|
|
WCHAR szKeyName[40];
|
|
BOOL bResult = FALSE;
|
|
|
|
UserAssert(idSection <= PMAP_LAST);
|
|
|
|
ServerLoadString(hModuleWin,
|
|
wKeyNameId,
|
|
szKeyName,
|
|
ARRAY_SIZE(szKeyName));
|
|
|
|
bResult = FastWriteProfileStringW(pProfileUserName,
|
|
idSection, szKeyName, lpszValue);
|
|
|
|
return bResult;
|
|
}
|