Windows NT 4.0 source code leak
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.
 
 
 
 
 
 

1095 lines
32 KiB

/****************************** Module Header ******************************\
* Module Name: profile.c
*
* Copyright (c) 1985-1996, 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:
\***************************************************************************/
FASTREGMAP aFastRegMap[PMAP_LAST + 1] = {
{ NULL, L"U" }, // PMAP_ROOT
{ NULL, L"UControl Panel\\Colors" }, // PMAP_COLORS
{ NULL, L"UControl Panel\\Cursors" }, // PMAP_CURSORS
{ NULL, L"MSoftware\\Microsoft\\Windows NT\\CurrentVersion\\Windows" }, // PMAP_WINDOWSM
{ NULL, L"USoftware\\Microsoft\\Windows NT\\CurrentVersion\\Windows" }, // PMAP_WINDOWSU
{ NULL, L"UControl Panel\\Desktop" }, // PMAP_DESKTOP
{ NULL, L"UControl Panel\\Icons" }, // PMAP_ICONS
{ NULL, L"MSoftware\\Microsoft\\Windows NT\\CurrentVersion\\Fonts" }, // PMAP_FONTS
{ NULL, L"MSoftware\\Microsoft\\Windows NT\\CurrentVersion\\WOW\boot" }, // PMAP_BOOT
{ NULL, L"USoftware\\Microsoft\\Windows NT\\CurrentVersion\\TrueType" }, // PMAP_TRUETYPE
{ NULL, L"UKeyboard Layout" }, // PMAP_KBDLAYOUTACTIVE
{ NULL, L"MSystem\\CurrentControlSet\\Control\\Keyboard Layout" }, // PMAP_KBDLAYOUT
{ NULL, L"UControl Panel\\Sounds" }, // PMAP_SOUNDS
{ NULL, L"MSystem\\CurrentControlSet\\Services\\RIT" }, // PMAP_INPUT
{ NULL, L"MSoftware\\Microsoft\\Windows NT\\CurrentVersion\\Compatibility" }, // PMAP_COMPAT
{ NULL, L"MSystem\\CurrentControlSet\\Control\\Session Manager\\SubSystems" }, // PMAP_SUBSYSTEMS
{ NULL, L"MSoftware\\Microsoft\\Windows NT\\CurrentVersion\\FontSubstitutes" }, // PMAP_FONTSUBS
{ NULL, L"MSoftware\\Microsoft\\Windows NT\\CurrentVersion\\GRE_Initialize" }, // PMAP_GREINIT
{ NULL, L"UControl Panel\\Sound" }, // PMAP_BEEP
{ NULL, L"UControl Panel\\Mouse" }, // PMAP_MOUSE
{ NULL, L"UControl Panel\\Keyboard" }, // PMAP_KEYBOARD
{ NULL, NULL }, // UNUSED 21
{ NULL, L"MSystem\\CurrentControlSet\\Control\\Windows" }, // PMAP_HARDERRORCONTROL
{ NULL, L"UControl Panel\\Accessibility\\StickyKeys" }, // PMAP_STICKYKEYS
{ NULL, L"UControl Panel\\Accessibility\\Keyboard Response" }, // PMAP_KEYBOARDRESPONSE
{ NULL, L"UControl Panel\\Accessibility\\MouseKeys" }, // PMAP_MOUSEKEYS
{ NULL, L"UControl Panel\\Accessibility\\ToggleKeys" }, // PMAP_TOGGLEKEYS
{ NULL, L"UControl Panel\\Accessibility\\TimeOut" }, // PMAP_TIMEOUT
{ NULL, L"UControl Panel\\Accessibility\\SoundSentry" }, // PMAP_SOUNDSENTRY
{ NULL, L"UControl Panel\\Accessibility\\ShowSounds" }, // PMAP_SHOWSOUNDS
{ NULL, L"UKeyboard Layout\\Substitutes" }, // PMAP_KBDLAYOUTSUBST
{ NULL, L"MSoftware\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug" }, // PMAP_AEDEBUG
{ NULL, L"MSystem\\CurrentControlSet\\Control\\NetworkProvider" }, // PMAP_NETWORK
{ NULL, L"MSystem\\CurrentControlSet\\Control\\Lsa" }, // PMAP_LSA
{ NULL, L"MSystem\\CurrentControlSet\\Control" }, // PMAP_CONTROL
{ NULL, L"UControl Panel\\Desktop\\WindowMetrics" }, // PMAP_METRICS
{ NULL, L"UKeyboard Layout\\Toggle" }, // PMAP_KBDLAYOUTTOGGLE
#ifdef FE_SB // PMAP_WINLOGON
{ NULL, L"MSoftware\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon" }, // PMAP_WINLOGON
#endif // FE_SB
};
WCHAR CurrentUserStringBuf[256];
WCHAR wszDefault[] = L".Default";
WCHAR wszUserBase[] = L"\\Registry\\User\\";
int cReentered = 0;
/*****************************************************************************\
* OpenCacheKey
*
* Attempts to open a cached key for a given section. Do not
* use ZwOpenKey because this will open the key for kernel
* access when we really want to open for user access.
*
* Returns fSuccess.
*
* History:
* 03-Dec-1993 SanfordS Created.
\*****************************************************************************/
HANDLE OpenCacheKeyEx(
UINT idSection,
ACCESS_MASK amRequest)
{
OBJECT_ATTRIBUTES OA;
WCHAR UnicodeStringBuf[256];
UNICODE_STRING UnicodeString;
LONG Status;
HANDLE hKey;
PEPROCESS peCurrent = PsGetCurrentProcess();
CheckCritIn();
UserAssert(idSection <= PMAP_LAST);
UnicodeString.Length = 0;
UnicodeString.MaximumLength = sizeof(UnicodeStringBuf) / sizeof(WCHAR);
UnicodeString.Buffer = UnicodeStringBuf;
if (aFastRegMap[idSection].szSection[0] == L'M') {
RtlAppendUnicodeToString(&UnicodeString, L"\\Registry\\Machine\\");
} else {
RtlAppendUnicodeToString(&UnicodeString, CurrentUserStringBuf);
}
RtlAppendUnicodeToString(&UnicodeString,
&aFastRegMap[idSection].szSection[1]);
if ((peCurrent == gpepSystem) || (peCurrent == gpepCSRSS)) {
/*
* Open the key for kernel mode access
*/
InitializeObjectAttributes(&OA,
&UnicodeString,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
Status = ZwOpenKey(&hKey, amRequest, &OA);
} else {
/*
* Callback to the client to open for user mode access
*/
Status = ClientOpenKey(&hKey, amRequest, &UnicodeString);
}
return (NT_SUCCESS(Status) ? hKey : NULL);
}
/*****************************************************************************\
* FastOpenProfileUserMapping
*
* Prepares for a series of calls to FastProfile APIs by setting up
* the string needed for accessing the current user. Client impersonation
* should be done prior to calling this function. If you are just
* looking at profile entries that are not current-user specific, you
* can skip this call if desired but you should still call
* FastCloseProfileUserMapping() to clean up cached entries when your
* fast profile calls are done. Open/Close calls may be recursed with
* little cost.
*
* Returns fSuccess.
*
* History:
* 02-Dec-1993 SanfordS Created.
\*****************************************************************************/
BOOL FastOpenProfileUserMapping(VOID)
{
UNICODE_STRING UserString;
LUID luidCaller;
LUID luidSystem = SYSTEM_LUID;
static LUID luidPrevious = {0, 0};
CheckCritIn();
if (++cReentered == 1) {
/*
* 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 TRUE; // 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:
wcscpy(CurrentUserStringBuf, wszUserBase);
wcscat(CurrentUserStringBuf, wszDefault);
} else {
UserAssert(sizeof(CurrentUserStringBuf) >= UserString.Length + 4);
wcscpy(CurrentUserStringBuf, UserString.Buffer);
RtlFreeUnicodeString(&UserString);
}
wcscat(CurrentUserStringBuf, L"\\");
}
return TRUE;
}
/*****************************************************************************\
* FastCloseProfileUserMapping
*
* Cleans up cached values after a series of FastProfile calls.
* This is only actually done when cReentered == 0 so that reentrant use
* of this function runs optimally. Locked keys are never closed.
*
* returns fSuccess.
*
* History:
* 02-Dec-1993 SanfordS Created.
\*****************************************************************************/
BOOL FastCloseProfileUserMapping(VOID)
{
CheckCritIn();
UserAssert(cReentered > 0);
--cReentered;
return TRUE;
}
/*****************************************************************************\
* FastGetProfileDwordW
*
* Reads a REG_DWORD type key from the registry.
*
* returns value read or default value on failure.
*
* History:
* 02-Dec-1993 SanfordS Created.
\*****************************************************************************/
DWORD FastGetProfileDwordW(
UINT idSection,
LPCWSTR lpKeyName,
DWORD dwDefault)
{
HANDLE hKey;
DWORD cbSize;
DWORD dwRet;
LONG Status;
UNICODE_STRING UnicodeString;
BYTE Buf[sizeof(KEY_VALUE_PARTIAL_INFORMATION) + sizeof(DWORD)];
UserAssert(idSection <= PMAP_LAST);
if ((hKey = OpenCacheKeyEx(idSection, KEY_READ)) == NULL) {
RIPMSG1(RIP_WARNING, "FastGetProfileDwordW: Failed to open cache-key (%ws)", lpKeyName);
return dwDefault;
}
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 (Status != STATUS_OBJECT_NAME_NOT_FOUND) {
RIPMSG1(RIP_WARNING,
"FastGetProfileDwordW: ObjectName not found: %ws",
lpKeyName);
}
ZwClose(hKey);
return dwRet;
}
/*****************************************************************************\
* FastGetProfileKeysW()
*
* Reads all key names in the given section.
*
* History:
* 15-Dec-1994 JimA Created.
\*****************************************************************************/
DWORD FastGetProfileKeysW(
UINT idSection,
LPCWSTR lpDefault,
LPWSTR *lpReturnedString)
{
HANDLE hKey;
DWORD cchSize;
DWORD cchKey;
LONG Status;
WCHAR Buffer[256];
PKEY_VALUE_BASIC_INFORMATION pKeyInfo;
ULONG iValue;
LPWSTR lpTmp;
LPWSTR lpKeys = NULL;
DWORD dwPoolSize;
UserAssert(idSection <= PMAP_LAST);
if ((hKey = OpenCacheKeyEx(idSection, KEY_READ)) == NULL) {
RIPMSG0(RIP_WARNING, "FastGetProfileKeysW: Failed to open cache-key");
goto DefExit;
}
pKeyInfo = (PKEY_VALUE_BASIC_INFORMATION)Buffer;
cchSize = 0;
*lpReturnedString = NULL;
iValue = 0;
while (TRUE) {
Status = ZwEnumerateValueKey(hKey,
iValue,
KeyValueBasicInformation,
pKeyInfo,
sizeof(Buffer),
&cchKey);
if (Status == STATUS_NO_MORE_ENTRIES) {
break;
} else if (!NT_SUCCESS(Status)) {
if (lpKeys)
UserFreePool(lpKeys);
goto DefExit;
}
/*
* 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.
*/
pKeyInfo->Name[pKeyInfo->NameLength / sizeof(WCHAR)] = 0;
wcscpy(&lpKeys[cchKey / sizeof(WCHAR)], (LPWSTR)pKeyInfo->Name);
iValue++;
}
/*
* If no keys were found, return the default.
*/
if (iValue == 0) {
DefExit:
cchSize = wcslen(lpDefault) + 2;
lpKeys = UserAllocPoolWithQuota(cchSize * 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.
*/
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(
UINT idSection,
LPCWSTR lpKeyName,
LPCWSTR lpDefault,
LPWSTR lpReturnedString,
DWORD cchBuf)
{
HANDLE hKey;
DWORD cbSize;
LONG Status;
UNICODE_STRING UnicodeString;
PKEY_VALUE_PARTIAL_INFORMATION pKeyInfo;
UserAssert(idSection <= PMAP_LAST);
UserAssert(lpKeyName != NULL);
if ((hKey = OpenCacheKeyEx(idSection, KEY_READ)) == NULL) {
RIPMSG1(RIP_WARNING, "FastGetProfileStringW: Failed to open cache-key (%ws)", lpKeyName);
goto DefExit;
}
cbSize = (cchBuf * sizeof(WCHAR)) +
offsetof(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));
}
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) {
wcscpy(lpReturnedString, lpDefault);
return (wcslen(lpDefault) + 1);
}
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.
\*****************************************************************************/
UINT FastGetProfileIntW(
UINT idSection,
LPCWSTR lpKeyName,
UINT nDefault)
{
WCHAR ValueBuf[40];
UNICODE_STRING Value;
UINT ReturnValue;
UserAssert(idSection <= PMAP_LAST);
Value.Length = 0;
Value.MaximumLength = sizeof(ValueBuf);
Value.Buffer = ValueBuf;
RtlIntegerToUnicodeString(nDefault, 10, &Value);
if (!FastGetProfileStringW(idSection,
lpKeyName,
(LPWSTR)Value.Buffer,
Value.Buffer,
sizeof(ValueBuf) / sizeof(WCHAR))) {
return nDefault;
}
/*
* Convert string to int.
*/
Value.Length = wcslen(Value.Buffer) * sizeof(WCHAR);
RtlUnicodeStringToInteger(&Value, 10, &ReturnValue);
return ReturnValue;
}
/*****************************************************************************\
* 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(
UINT idSection,
LPCWSTR lpKeyName,
LPCWSTR lpString)
{
HANDLE hKey;
LONG Status;
UNICODE_STRING UnicodeString;
UserAssert(idSection <= PMAP_LAST);
if ((hKey = OpenCacheKeyEx(idSection, KEY_WRITE)) == NULL) {
RIPMSG1(RIP_WARNING, "FastWriteProfileStringW: Failed to open cache-key (%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.
\*****************************************************************************/
int FastGetProfileIntFromID(
UINT idSection,
UINT idKey,
int def)
{
int result;
WCHAR szKey[80];
UserAssert(idSection <= PMAP_LAST);
ServerLoadString(hModuleWin, idKey, szKey, sizeof(szKey) / sizeof(WCHAR));
result = FastGetProfileIntW(idSection, szKey, def);
/*
* 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 = UserMulDiv(-result, oemInfo.cyPixelsPerInch, 72 * 20);
break;
}
return result;
}
/*****************************************************************************\
* FastGetProfileIntFromID
*
* Just like FastGetProfileStringW except it reads the USER string table for
* the key name.
*
* History:
* 02-Dec-1993 SanfordS Created.
\*****************************************************************************/
DWORD FastGetProfileStringFromIDW(
UINT idSection,
UINT idKey,
LPCWSTR lpDefault,
LPWSTR lpReturnedString,
DWORD cch)
{
WCHAR szKey[80];
UserAssert(idSection <= PMAP_LAST);
ServerLoadString(hModuleWin, idKey, szKey, sizeof(szKey) / sizeof(WCHAR));
return FastGetProfileStringW(idSection,
szKey,
lpDefault,
lpReturnedString,
cch);
}
/*****************************************************************************\
* FastWriteProfileValue
*
* History:
* 06/10/96 GerardoB Renamed and added uType parameter
\*****************************************************************************/
BOOL FastWriteProfileValue(
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 ((hKey = OpenCacheKeyEx(idSection, KEY_WRITE)) == NULL) {
RIPMSG1(RIP_WARNING, "FastWriteProfileValue: Failed to open cache-key (%ws)", lpKeyName);
return FALSE;
}
if (HIWORD(lpKeyName) == 0) {
ServerLoadString(hModuleWin, (UINT)lpKeyName, szKey, sizeof(szKey));
UserAssert(*szKey != (WCHAR)0);
lpKeyName = szKey;
}
RtlInitUnicodeString(&UnicodeString, lpKeyName);
Status = ZwSetValueKey(hKey,
&UnicodeString,
0,
uType,
lpStruct,
cbSizeStruct);
ZwClose(hKey);
#ifdef DEBUG
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(
UINT idSection,
LPCWSTR lpKeyName,
LPBYTE lpDefault,
LPBYTE lpReturn,
UINT cbSizeReturn)
{
HANDLE hKey;
UINT cbSize;
LONG Status;
UNICODE_STRING UnicodeString;
PKEY_VALUE_PARTIAL_INFORMATION pKeyInfo;
WCHAR szKey[SERVERSTRINGMAXSIZE];
KEY_VALUE_PARTIAL_INFORMATION KeyInfo;
UserAssert(idSection <= PMAP_LAST);
if ((hKey = OpenCacheKeyEx(idSection, KEY_READ)) == NULL) {
RIPMSG1(RIP_WARNING, "FastGetProfileValue: Failed to open cache-key (%ws)", lpKeyName);
goto DefExit;
}
if (cbSizeReturn == 0) {
cbSize = sizeof(KeyInfo);
pKeyInfo = &KeyInfo;
} else {
cbSize = cbSizeReturn + offsetof(KEY_VALUE_PARTIAL_INFORMATION, Data);
if ((pKeyInfo = UserAllocPoolWithQuota(cbSize, TAG_PROFILE)) == NULL) {
goto DefExit;
}
}
if (HIWORD(lpKeyName) == 0) {
ServerLoadString(hModuleWin, (UINT)lpKeyName, szKey, sizeof(szKey));
UserAssert(*szKey != (WCHAR)0);
lpKeyName = szKey;
}
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)) {
return pKeyInfo->DataLength;
}
#ifdef DEBUG
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_FastGetProfileStringW(
*
* Just like FastGetProfileStringW except it handles impersonation chores
* for you.
*
* History:
* 02-Dec-1993 SanfordS Created.
\*****************************************************************************/
UINT UT_FastGetProfileStringW(
UINT idSection,
LPCWSTR pwszKey,
LPCWSTR pwszDefault,
LPWSTR pwszReturn,
DWORD cch)
{
UINT uResult = 0;
UserAssert(idSection <= PMAP_LAST);
if (!FastOpenProfileUserMapping())
return FALSE;
try {
uResult = FastGetProfileStringW(idSection,
pwszKey,
pwszDefault,
pwszReturn,
cch);
} finally {
FastCloseProfileUserMapping();
}
return uResult;
}
/*****************************************************************************\
* UT_FastWriteProfileStringW
*
* Just like FastWriteProfileStringW except it handles impersonation chores
* for you.
*
* History:
* 02-Dec-1993 SanfordS Created.
\*****************************************************************************/
UINT UT_FastWriteProfileStringW(
UINT idSection,
LPCWSTR pwszKey,
LPCWSTR pwszString)
{
UINT uResult = 0;
UserAssert(idSection <= PMAP_LAST);
if (!FastOpenProfileUserMapping())
return FALSE;
try {
uResult = FastWriteProfileStringW(idSection, pwszKey, pwszString);
} finally {
FastCloseProfileUserMapping();
}
return uResult;
}
/*****************************************************************************\
* UT_FastGetProfileIntW
*
* Just like FastGetProfileIntW except it handles impersonation chores
* for you.
*
* History:
* 02-Dec-1993 SanfordS Created.
\*****************************************************************************/
UINT UT_FastGetProfileIntW(
UINT idSection,
LPCWSTR lpKeyName,
DWORD nDefault)
{
UINT uResult = 0;
UserAssert(idSection <= PMAP_LAST);
if (!FastOpenProfileUserMapping())
return FALSE;
try {
uResult = FastGetProfileIntW(idSection, lpKeyName, nDefault);
} finally {
FastCloseProfileUserMapping();
}
return uResult;
}
/*****************************************************************************\
* UT_FastGetProfileIntsW
*
* Repeatedly calls FastGetProfileIntW on the given table.
*
* History:
* 02-Dec-1993 SanfordS Created.
\*****************************************************************************/
BOOL UT_FastGetProfileIntsW(
PPROFINTINFO ppii)
{
WCHAR szKey[40];
if (!FastOpenProfileUserMapping())
return FALSE;
try {
while (ppii->idSection != 0) {
ServerLoadString(hModuleWin,
(UINT)ppii->lpKeyName,
szKey,
sizeof(szKey) / sizeof(WCHAR));
*ppii->puResult = FastGetProfileIntW(ppii->idSection,
szKey,
ppii->nDefault);
ppii++;
}
} finally {
FastCloseProfileUserMapping();
}
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 UT_FastUpdateWinIni(
UINT idSection,
UINT wKeyNameId,
LPWSTR lpszValue)
{
WCHAR szKeyName[40];
BOOL bResult = FALSE;
UserAssert(idSection <= PMAP_LAST);
if (!FastOpenProfileUserMapping())
return FALSE;
try {
ServerLoadString(hModuleWin,
wKeyNameId,
szKeyName,
sizeof(szKeyName) / sizeof(WCHAR));
bResult = FastWriteProfileStringW(idSection, szKeyName, lpszValue);
} finally {
FastCloseProfileUserMapping();
}
return bResult;
}
/*****************************************************************************\
* UT_FastWriteProfileStrcut
*
* History:
* 06/10/96 GerardoB Renamed and added uType parameter
\*****************************************************************************/
BOOL UT_FastWriteProfileValue(
UINT idSection,
LPCWSTR pwszKey,
UINT uType,
LPBYTE lpStruct,
UINT cbSizeStruct)
{
BOOL fResult = FALSE;
UserAssert(idSection <= PMAP_LAST);
if (!FastOpenProfileUserMapping())
return FALSE;
try {
fResult = FastWriteProfileValue(idSection,
pwszKey,
uType,
lpStruct,
cbSizeStruct);
} finally {
FastCloseProfileUserMapping();
}
return fResult;
}
/*****************************************************************************\
* UT_FastGetProfileValue
*
* History:
* 06/10/96 GerardoB Renamed.
\*****************************************************************************/
DWORD UT_FastGetProfileValue(
UINT idSection,
LPCWSTR pwszKey,
LPBYTE lpDefault,
LPBYTE lpReturn,
UINT cbSizeReturn)
{
DWORD dwResult = 0;
UserAssert(idSection <= PMAP_LAST);
if (!FastOpenProfileUserMapping())
return FALSE;
try {
dwResult = FastGetProfileValue(idSection,
pwszKey,
lpDefault,
lpReturn,
cbSizeReturn);
} finally {
FastCloseProfileUserMapping();
}
return dwResult;
}