test: profile.c Source File

Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

# profile.c

Go to the documentation of this file.

    00001 /****************************** Module Header ******************************\
    00002 * Module Name: profile.c
    00003 *
    00004 * Copyright (c) 1985 - 1999, Microsoft Corporation
    00005 *
    00006 * This module contains code to emulate ini file mapping.
    00007 *
    00008 * History:
    00009 * 30-Nov-1993 SanfordS  Created.
    00010 \***************************************************************************/
    00011 #include "precomp.h"
    00012 #pragma hdrstop
    00013
    00014 /***************************************************************************\
    00015 * aFastRegMap[]
    00016 *
    00017 * This array maps section ids (PMAP_) to cached registry keys and section
    00018 * addresses within the registry.  IF INI FILE MAPPING CHANGES ARE MADE,
    00019 * THIS TABLE MUST BE UPDATED.
    00020 *
    00021 * The first character of the szSection field indicates what root the
    00022 * section is in. (or locked open status)
    00023 *      M = LocalMachine
    00024 *      U = CurrentUser
    00025 *      L = Locked open - used only on M mappings.
    00026 *
    00027 * History:
    00028 \***************************************************************************/
    00029 #define PROOT_CPANEL     0
    00030 #define PROOT_ACCESS     1
    00031 #define PROOT_CURRENTM   2
    00032 #define PROOT_CURRENTU   3
    00033 #define PROOT_CONTROL    4
    00034 #define PROOT_SERVICES   5
    00035 #define PROOT_KEYBOARD   6
    00036
    00037 typedef struct tagFASTREGMAP {
    00038     UINT idRoot;
    00039     PCWSTR szSection;
    00040 } FASTREGMAP, *PFASTREGMAP;
    00041
    00042 CONST PCWSTR aFastRegRoot[] = {
    00043     L"UControl Panel\\",                                    // PROOT_CPANEL
    00044     L"UControl Panel\\Accessibility\\",                     // PROOT_ACCESS
    00045     L"MSoftware\\Microsoft\\Windows NT\\CurrentVersion\\",  // PROOT_CURRENTM
    00046     L"USoftware\\Microsoft\\Windows NT\\CurrentVersion\\",  // PROOT_CURRENTU
    00047     L"MSystem\\CurrentControlSet\\Control\\",               // PROOT_CONTROL
    00048     L"MSystem\\CurrentControlSet\\Services\\",              // PROOT_SERVICES
    00049     L"UKeyboard Layout\\",                                  // PROOT_KEYBOARD
    00050 };
    00051
    00052 CONST FASTREGMAP aFastRegMap[PMAP_LAST + 1] = {
    00053     { PROOT_CPANEL,   L"Colors" },                          // PMAP_COLORS
    00054     { PROOT_CPANEL,   L"Cursors" },                         // PMAP_CURSORS
    00055     { PROOT_CURRENTM, L"Windows" },                         // PMAP_WINDOWSM
    00056     { PROOT_CURRENTU, L"Windows" },                         // PMAP_WINDOWSU
    00057     { PROOT_CPANEL,   L"Desktop" },                         // PMAP_DESKTOP
    00058     { PROOT_CPANEL,   L"Icons" },                           // PMAP_ICONS
    00059     { PROOT_CURRENTM, L"Fonts" },                           // PMAP_FONTS
    00060     { PROOT_CURRENTU, L"TrueType" },                        // PMAP_TRUETYPE
    00061     { PROOT_CONTROL,  L"Keyboard Layout" },                 // PMAP_KBDLAYOUT
    00062     { PROOT_SERVICES, L"RIT" },                             // PMAP_INPUT
    00063     { PROOT_CURRENTM, L"Compatibility" },                   // PMAP_COMPAT
    00064     { PROOT_CONTROL,  L"Session Manager\\SubSystems" },     // PMAP_SUBSYSTEMS
    00065     { PROOT_CPANEL,   L"Sound" },                           // PMAP_BEEP
    00066     { PROOT_CPANEL,   L"Mouse" },                           // PMAP_MOUSE
    00067     { PROOT_CPANEL,   L"Keyboard" },                        // PMAP_KEYBOARD
    00068     { PROOT_ACCESS,   L"StickyKeys" },                      // PMAP_STICKYKEYS
    00069     { PROOT_ACCESS,   L"Keyboard Response" },               // PMAP_KEYBOARDRESPONSE
    00070     { PROOT_ACCESS,   L"MouseKeys" },                       // PMAP_MOUSEKEYS
    00071     { PROOT_ACCESS,   L"ToggleKeys" },                      // PMAP_TOGGLEKEYS
    00072     { PROOT_ACCESS,   L"TimeOut" },                         // PMAP_TIMEOUT
    00073     { PROOT_ACCESS,   L"SoundSentry" },                     // PMAP_SOUNDSENTRY
    00074     { PROOT_ACCESS,   L"ShowSounds" },                      // PMAP_SHOWSOUNDS
    00075     { PROOT_CURRENTM, L"AeDebug" },                         // PMAP_AEDEBUG
    00076     { PROOT_CONTROL,  L"NetworkProvider" },                 // PMAP_NETWORK
    00077     { PROOT_CPANEL,   L"Desktop\\WindowMetrics" },          // PMAP_METRICS
    00078     { PROOT_KEYBOARD, L"" },                                // PMAP_UKBDLAYOUT
    00079     { PROOT_KEYBOARD, L"Toggle" },                          // PMAP_UKBDLAYOUTTOGGLE
    00080     { PROOT_CURRENTM, L"Winlogon" },                        // PMAP_WINLOGON
    00081     { PROOT_ACCESS,   L"Keyboard Preference" },             // PMAP_KEYBOARDPREF
    00082     { PROOT_ACCESS,   L"Blind Access" },                    // PMAP_SCREENREADER
    00083     { PROOT_ACCESS,   L"HighContrast" },                    // PMAP_HIGHCONTRAST
    00084     { PROOT_CURRENTM, L"IME Compatibility" },               // PMAP_IMECOMPAT
    00085     { PROOT_CURRENTM, L"IMM" },                             // PMAP_IMM
    00086     { PROOT_CONTROL,  L"Session Manager\\SubSystems\\Pool" },// PMAP_POOLLIMITS
    00087     { PROOT_CURRENTM, L"Compatibility32" },                  // PMAP_COMPAT32
    00088     { PROOT_CURRENTM, L"WOW\\SetupPrograms" },               // PMAP_SETUPPROGRAMNAMES
    00089     { PROOT_CPANEL,   L"Input Method" },                     // PMAP_INPUTMETHOD
    00090     { PROOT_CURRENTM, L"Compatibility2" },                   // PMAP_COMPAT2
    00091     { PROOT_SERVICES, L"Mouclass\\Parameters" },             // PMAP_MOUCLASS_PARAMS
    00092     { PROOT_SERVICES, L"Kbdclass\\Parameters" },             // PMAP_KBDCLASS_PARAMS
    00093 };
    00094
    00095 DWORD gdwPolicyFlags = POLICY_ALL;
    00096 WCHAR PreviousUserStringBuf[256];
    00097 UNICODE_STRING PreviousUserString = {0, sizeof PreviousUserStringBuf, PreviousUserStringBuf};
    00098 LUID luidPrevious;
    00099
    00100 CONST WCHAR wszDefaultUser[] = L"\\Registry\\User\\.Default";
    00101 UNICODE_STRING DefaultUserString = {sizeof wszDefaultUser - sizeof(WCHAR), sizeof wszDefaultUser, (WCHAR *)wszDefaultUser};
    00102
    00103 void InitPreviousUserString(void) {
    00104     UNICODE_STRING UserString;
    00105     LUID           luidCaller;
    00106
    00107     CheckCritIn();
    00108
    00109     /*
    00110      * Speed hack, check if luid of this process == system or previous to
    00111      * save work.
    00112      */
    00113     if (NT_SUCCESS(GetProcessLuid(NULL, &luidCaller))) {
    00114
    00115         if (RtlEqualLuid(&luidCaller, &luidPrevious)) {
    00116             return;   // same as last time - no work.
    00117         }
    00118         luidPrevious = luidCaller;
    00119
    00120         if (RtlEqualLuid(&luidCaller, &luidSystem))
    00121             goto DefaultUser;
    00122
    00123     } else {
    00124         luidPrevious = RtlConvertLongToLuid(0);
    00125     }
    00126
    00127     /*
    00128      * Set up current user registry base string.
    00129      */
    00130     if (!NT_SUCCESS(RtlFormatCurrentUserKeyPath(&UserString))) {
    00131
    00132 DefaultUser:
    00133
    00134         RtlCopyUnicodeString(&PreviousUserString, &DefaultUserString);
    00135
    00136     } else {
    00137         UserAssert(sizeof(PreviousUserStringBuf) >= UserString.Length + 4);
    00138         RtlCopyUnicodeString(&PreviousUserString, &UserString);
    00139         RtlFreeUnicodeString(&UserString);
    00140     }
    00141
    00142     RtlAppendUnicodeToString(&PreviousUserString, L"\\");
    00143
    00144 }
    00145
    00146 typedef struct tagPROFILEUSERNAME {
    00147     WCHAR awcName[MAXPROFILEBUF];
    00148     UNICODE_STRING NameString;
    00149 } PROFILEUSERNAME, *PPROFILEUSERNAME;
    00150
    00151 PUNICODE_STRING CreateProfileUserName(TL *ptl)
    00152 {
    00153     PPROFILEUSERNAME pMapName;
    00154
    00155     CheckCritIn();
    00156
    00157     pMapName = UserAllocPoolWithQuota(sizeof (PROFILEUSERNAME), TAG_PROFILEUSERNAME);
    00158     if (!pMapName) {
    00159         RIPMSG0(RIP_WARNING, "CreateProfileUserName: Allocation failed");
    00160         return NULL;
    00161     }
    00162
    00163     ThreadLockPool(PtiCurrent(), pMapName, ptl);
    00164     pMapName->NameString.Length = 0;
    00165     pMapName->NameString.MaximumLength = sizeof (pMapName->awcName);
    00166     pMapName->NameString.Buffer = pMapName->awcName;
    00167
    00168     InitPreviousUserString();
    00169
    00170     RtlCopyUnicodeString(&pMapName->NameString, &PreviousUserString);
    00171     return &(pMapName->NameString);
    00172 }
    00173
    00174 void FreeProfileUserName(PUNICODE_STRING pProfileUserName,TL *ptl) {
    00175     UNREFERENCED_PARAMETER(ptl);
    00176     CheckCritIn();
    00177     if (pProfileUserName) {
    00178         ThreadUnlockAndFreePool(PtiCurrent(), ptl);
    00179     }
    00180 }
    00181
    00182 /*****************************************************************************\
    00183 * RemoteOpenCacheKeyEx
    00184 *
    00185 * History:
    00186 * 21-Jan-1998 CLupu  Ported from Citrix.
    00187 \*****************************************************************************/
    00188 HANDLE RemoteOpenCacheKeyEx(
    00189     UINT        idSection,
    00190     ACCESS_MASK amRequest)
    00191 {
    00192     OBJECT_ATTRIBUTES OA;
    00193     WCHAR             UnicodeStringBuf[512];
    00194     UNICODE_STRING    UnicodeString;
    00195     LONG              Status;
    00196     HANDLE            hKey;
    00197
    00198     CheckCritIn();
    00199
    00200     UserAssert(gbRemoteSession == TRUE);
    00201
    00202     if (aFastRegRoot[aFastRegMap[idSection].idRoot][0] == L'M')
    00203         return NULL;
    00204
    00205     if (gstrBaseWinStationName[0] == 0)
    00206         return NULL;
    00207
    00208     if (amRequest != KEY_READ)
    00209         return NULL;
    00210
    00211     UserAssert(idSection <= PMAP_LAST);
    00212     UnicodeString.Length        = 0;
    00213     UnicodeString.MaximumLength = sizeof(UnicodeStringBuf);
    00214     UnicodeString.Buffer        = UnicodeStringBuf;
    00215
    00216     RtlAppendUnicodeToString(&UnicodeString, L"\\Registry\\Machine\\");
    00217     RtlAppendUnicodeToString(&UnicodeString, WINSTATION_REG_NAME);
    00218
    00219     RtlAppendUnicodeToString(&UnicodeString, L"\\");
    00220     RtlAppendUnicodeToString(&UnicodeString, gstrBaseWinStationName);
    00221     RtlAppendUnicodeToString(&UnicodeString, L"\\");
    00222     RtlAppendUnicodeToString(&UnicodeString, WIN_USEROVERRIDE);
    00223     RtlAppendUnicodeToString(&UnicodeString, L"\\");
    00224
    00225     Status = RtlAppendUnicodeToString(&UnicodeString,
    00226                                       (PWSTR)(&aFastRegRoot[aFastRegMap[idSection].idRoot][1]));
    00227     UserAssert(NT_SUCCESS(Status));
    00228
    00229     Status = RtlAppendUnicodeToString(&UnicodeString,
    00230                                       (PWSTR)(aFastRegMap[idSection].szSection));
    00231     UserAssert(NT_SUCCESS(Status));
    00232
    00233     /*
    00234      * Open the key for kernel mode access
    00235      */
    00236     InitializeObjectAttributes(&OA,
    00237                                &UnicodeString,
    00238                                OBJ_CASE_INSENSITIVE,
    00239                                NULL,
    00240                                NULL);
    00241
    00242     Status = ZwOpenKey(&hKey, amRequest, &OA);
    00243
    00244     return (NT_SUCCESS(Status) ? hKey : NULL);
    00245 }
    00246
    00247 /*****************************************************************************\
    00248 * OpenCacheKeyEx
    00249 *
    00250 * Attempts to open a cached key for a given section.  If we are calling
    00251 * for a client thread, we must check the access rights for the key after
    00252 * opening it.
    00253 *
    00254 * Returns fSuccess.
    00255 *
    00256 * Note -- param 1 can be NULL.  If the section name is a per-user registry
    00257 *         section, we ill use the first parameter if available or set up
    00258 *         and use the cached one if the first parameter is NULL.
    00259 *
    00260 * History:
    00261 * 03-Dec-1993 SanfordS  Created.
    00262 \*****************************************************************************/
    00263 HANDLE OpenCacheKeyEx(
    00264     PUNICODE_STRING pMapName OPTIONAL,
    00265     UINT        idSection,
    00266     ACCESS_MASK amRequest,
    00267     PDWORD      pdwPolicyFlags
    00268     )
    00269 {
    00270     OBJECT_ATTRIBUTES OA;
    00271     WCHAR             UnicodeStringBuf[256];
    00272     UNICODE_STRING    UnicodeString;
    00273     LONG              Status;
    00274     HANDLE            hKey = NULL;
    00275     PEPROCESS         peCurrent = PsGetCurrentProcess();
    00276     DWORD             dwPolicyFlags;
    00277
    00278     CheckCritIn();
    00279
    00280     UserAssert(idSection <= PMAP_LAST);
    00281
    00282     /*
    00283      * If we're opening the desktop key for read access, we should be checking
    00284      * for relevant policy.
    00285      */
    00286     if (idSection == PMAP_DESKTOP && amRequest == KEY_READ && pdwPolicyFlags) {
    00287         UserAssert(!(*pdwPolicyFlags & ~POLICY_ALL));
    00288         dwPolicyFlags = *pdwPolicyFlags;
    00289     } else {
    00290         dwPolicyFlags = POLICY_NONE;
    00291     }
    00292
    00293 TryAgain:
    00294
    00295     UnicodeString.Length        = 0;
    00296     UnicodeString.MaximumLength = sizeof(UnicodeStringBuf);
    00297     UnicodeString.Buffer        = UnicodeStringBuf;
    00298
    00299
    00300     if (dwPolicyFlags & POLICY_MACHINE) {
    00301         dwPolicyFlags &= ~POLICY_MACHINE;
    00302         RtlAppendUnicodeToString(&UnicodeString,
    00303                                  L"\\Registry\\Machine\\");
    00304         RtlAppendUnicodeToString(&UnicodeString,
    00305                                  L"Software\\Policies\\Microsoft\\Windows\\");
    00306     } else {
    00307         if (aFastRegRoot[aFastRegMap[idSection].idRoot][0] == L'M') {
    00308             RtlAppendUnicodeToString(&UnicodeString, L"\\Registry\\Machine\\");
    00309         } else {
    00310             if (!pMapName) {
    00311                 InitPreviousUserString();
    00312                 RtlAppendUnicodeStringToString(
    00313                     &UnicodeString,
    00314                     &PreviousUserString);
    00315             } else {
    00316                 RtlAppendUnicodeStringToString(
    00317                     &UnicodeString,
    00318                     pMapName);
    00319             }
    00320         }
    00321         if (dwPolicyFlags & POLICY_USER) {
    00322             dwPolicyFlags &= ~POLICY_USER;
    00323             RtlAppendUnicodeToString(&UnicodeString,
    00324                                      L"Software\\Policies\\Microsoft\\Windows\\");
    00325         } else {
    00326             dwPolicyFlags &= ~POLICY_NONE;
    00327         }
    00328
    00329     }
    00330
    00331     RtlAppendUnicodeToString(&UnicodeString,
    00332                              (PWSTR)&aFastRegRoot[aFastRegMap[idSection].idRoot][1]);
    00333
    00334     RtlAppendUnicodeToString(&UnicodeString,
    00335                              (PWSTR)aFastRegMap[idSection].szSection);
    00336
    00337
    00338     /*
    00339      * Open the key for kernel mode access
    00340      */
    00341     InitializeObjectAttributes(&OA,
    00342                                &UnicodeString,
    00343                                OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
    00344                                NULL,
    00345                                NULL);
    00346
    00347     Status = ZwOpenKey(&hKey, amRequest, &OA);
    00348
    00349     if (
    00350         (amRequest == KEY_READ)   ||     /*
    00351                                           * We must be able to read
    00352                                           * our registry settings.
    00353                                           */
    00354         (peCurrent == gpepCSRSS)  ||
    00355         (peCurrent == gpepInit)
    00356              ) {
    00357
    00358     } else {
    00359         /*
    00360          * Now check if the user has access to the key
    00361          */
    00362
    00363         if (NT_SUCCESS(Status)) {
    00364             PVOID pKey;
    00365             NTSTATUS Status2;
    00366             Status2 = ObReferenceObjectByHandle(hKey,
    00367                                         amRequest,
    00368                                         NULL,
    00369                                         KernelMode,
    00370                                         &pKey,
    00371                                         NULL);
    00372
    00373             if (NT_SUCCESS(Status2)) {
    00374                 if (!AccessCheckObject(pKey, amRequest, UserMode, &KeyMapping)) {
    00375                     ZwClose(hKey);
    00376                     Status = STATUS_ACCESS_DENIED;
    00377                 }
    00378                 ObDereferenceObject(pKey);
    00379             } else {
    00380                 ZwClose(hKey);
    00381                 Status = STATUS_ACCESS_DENIED;
    00382             }
    00383         }
    00384
    00385     }
    00386
    00387 #if DBG
    00388     if (!NT_SUCCESS(Status)) {
    00389         UnicodeStringBuf[UnicodeString.Length / 2] = 0;
    00390
    00391         if (PsGetCurrentProcess()->UniqueProcessId != gpidLogon) {
    00392             RIPMSG1(RIP_WARNING | RIP_THERESMORE, "OpenCacheKeyEx failed with Status = %lx key:", Status);
    00393             RIPMSG1(RIP_WARNING | RIP_THERESMORE | RIP_NONAME | RIP_NONEWLINE, " %ws\\", UnicodeStringBuf);
    00394         }
    00395     }
    00396 #endif DBG
    00397
    00398     /*
    00399      * If we didn't succeed and we're not down to bottom of policy chain, try again.
    00400      */
    00401     if (!NT_SUCCESS(Status) && dwPolicyFlags) {
    00402         goto TryAgain;
    00403     }
    00404
    00405     /*
    00406      * Update policy level
    00407      */
    00408     if (pdwPolicyFlags) {
    00409         *pdwPolicyFlags = dwPolicyFlags;
    00410     }
    00411
    00412     return (NT_SUCCESS(Status) ? hKey : NULL);
    00413 }
    00414
    00415
    00416 /*****************************************************************************\
    00417 * CheckDesktopPolicy
    00418 *
    00419 * Check if a desktop value has an associated policy.
    00420 *
    00421 * Returns TRUE if there is a policy, FALSE otherwise.
    00422 *
    00423 * History:
    00424 * 07-Feb-2000 JerrySh   Created.
    00425 \*****************************************************************************/
    00426 BOOL CheckDesktopPolicy(
    00427     PUNICODE_STRING pProfileUserName OPTIONAL,
    00428     PCWSTR      lpKeyName
    00429     )
    00430 {
    00431     WCHAR          szKey[80];
    00432     HANDLE         hKey;
    00433     DWORD          cbSize;
    00434     NTSTATUS       Status;
    00435     UNICODE_STRING UnicodeString;
    00436     KEY_VALUE_BASIC_INFORMATION  KeyInfo;
    00437     DWORD          dwPolicyFlags = gdwPolicyFlags & (POLICY_MACHINE | POLICY_USER);
    00438
    00439     /*
    00440      * If there is no policy or the caller is winlogon, let it go.
    00441      */
    00442     if (!dwPolicyFlags || GetCurrentProcessId() == gpidLogon) {
    00443         return FALSE;
    00444     }
    00445
    00446     /*
    00447      * Convert the ID to a string if we need to.
    00448      */
    00449     if (!IS_PTR(lpKeyName)) {
    00450         ServerLoadString(hModuleWin, PTR_TO_ID(lpKeyName), szKey, ARRAY_SIZE(szKey));
    00451         lpKeyName = szKey;
    00452     }
    00453
    00454 TryAgain:
    00455
    00456     /*
    00457      * Try to open a key.
    00458      */
    00459     if ((hKey = OpenCacheKeyEx(pProfileUserName,
    00460                                PMAP_DESKTOP,
    00461                                KEY_READ,
    00462                                &dwPolicyFlags)) == NULL) {
    00463         return FALSE;
    00464     }
    00465
    00466     /*
    00467      * See if the value exists.
    00468      */
    00469     RtlInitUnicodeString(&UnicodeString, lpKeyName);
    00470     Status = ZwQueryValueKey(hKey,
    00471                              &UnicodeString,
    00472                              KeyValueBasicInformation,
    00473                              &KeyInfo,
    00474                              sizeof(KeyInfo),
    00475                              &cbSize);
    00476
    00477     ZwClose(hKey);
    00478
    00479     if (!NT_ERROR(Status)) {
    00480         return TRUE;
    00481     } else if (dwPolicyFlags) {
    00482         goto TryAgain;
    00483     } else {
    00484         return FALSE;
    00485     }
    00486 }
    00487
    00488
    00489 /*****************************************************************************\
    00490 * CheckDesktopPolicyChange
    00491 *
    00492 * Check if policy has changed since last time we checked.
    00493 *
    00494 * Returns TRUE if policy changed, FASLE otherwise.
    00495 *
    00496 * History:
    00497 * 07-Feb-2000 JerrySh   Created.
    00498 \*****************************************************************************/
    00499 BOOL CheckDesktopPolicyChange(
    00500     PUNICODE_STRING pProfileUserName OPTIONAL
    00501     )
    00502 {
    00503     static LARGE_INTEGER  LastMachineWriteTime;
    00504     static LARGE_INTEGER  LastUserWriteTime;
    00505     KEY_BASIC_INFORMATION KeyInfo;
    00506     BOOL                  bPolicyChanged = FALSE;
    00507     HANDLE                hKey;
    00508     DWORD                 cbSize;
    00509     DWORD                 dwPolicyFlags;
    00510
    00511     /*
    00512      * Check if machine policy has changed since last time we checked.
    00513      */
    00514     dwPolicyFlags = POLICY_MACHINE;
    00515     KeyInfo.LastWriteTime.QuadPart = 0;
    00516     hKey = OpenCacheKeyEx(pProfileUserName,
    00517                           PMAP_DESKTOP,
    00518                           KEY_READ,
    00519                           &dwPolicyFlags);
    00520     if (hKey) {
    00521         ZwQueryKey(hKey,
    00522                    KeyValueBasicInformation,
    00523                    &KeyInfo,
    00524                    sizeof(KeyInfo),
    00525                    &cbSize);
    00526         ZwClose(hKey);
    00527         gdwPolicyFlags |= POLICY_MACHINE;
    00528     } else {
    00529         gdwPolicyFlags &= ~POLICY_MACHINE;
    00530     }
    00531     if (LastMachineWriteTime.QuadPart != KeyInfo.LastWriteTime.QuadPart) {
    00532         LastMachineWriteTime.QuadPart = KeyInfo.LastWriteTime.QuadPart;
    00533         bPolicyChanged = TRUE;
    00534     }
    00535
    00536     /*
    00537      * Check if user policy has changed since last time we checked.
    00538      */
    00539     dwPolicyFlags = POLICY_USER;
    00540     KeyInfo.LastWriteTime.QuadPart = 0;
    00541     hKey = OpenCacheKeyEx(pProfileUserName,
    00542                           PMAP_DESKTOP,
    00543                           KEY_READ,
    00544                           &dwPolicyFlags);
    00545     if (hKey) {
    00546         ZwQueryKey(hKey,
    00547                    KeyValueBasicInformation,
    00548                    &KeyInfo,
    00549                    sizeof(KeyInfo),
    00550                    &cbSize);
    00551         ZwClose(hKey);
    00552         gdwPolicyFlags |= POLICY_USER;
    00553     } else {
    00554         gdwPolicyFlags &= ~POLICY_USER;
    00555     }
    00556     if (LastUserWriteTime.QuadPart != KeyInfo.LastWriteTime.QuadPart) {
    00557         LastUserWriteTime.QuadPart = KeyInfo.LastWriteTime.QuadPart;
    00558         bPolicyChanged = TRUE;
    00559     }
    00560
    00561     return bPolicyChanged;
    00562 }
    00563
    00564
    00565 /*****************************************************************************\
    00566 * FastGetProfileDwordW
    00567 *
    00568 * Reads a REG_DWORD type key from the registry.
    00569 *
    00570 * returns value read or default value on failure.
    00571 *
    00572 * History:
    00573 * 02-Dec-1993 SanfordS  Created.
    00574 \*****************************************************************************/
    00575 DWORD FastGetProfileDwordW(PUNICODE_STRING pProfileUserName OPTIONAL,
    00576     UINT    idSection,
    00577     LPCWSTR lpKeyName,
    00578     DWORD   dwDefault
    00579     )
    00580 {
    00581     HANDLE         hKey;
    00582     DWORD          cbSize;
    00583     DWORD          dwRet;
    00584     LONG           Status;
    00585     UNICODE_STRING UnicodeString;
    00586     BYTE           Buf[sizeof(KEY_VALUE_PARTIAL_INFORMATION) + sizeof(DWORD)];
    00587
    00588     UserAssert(idSection <= PMAP_LAST);
    00589
    00590     if (gbRemoteSession) {
    00591
    00592         hKey = RemoteOpenCacheKeyEx(idSection, KEY_READ);
    00593         if (hKey != NULL) {
    00594             goto Override;
    00595         }
    00596     }
    00597
    00598     if ((hKey = OpenCacheKeyEx(pProfileUserName,
    00599                                idSection,
    00600                                KEY_READ,
    00601                                NULL)) == NULL) {
    00602         RIPMSG1(RIP_WARNING | RIP_NONAME, "%ws", lpKeyName);
    00603         return dwDefault;
    00604     }
    00605
    00606 Override:
    00607
    00608     RtlInitUnicodeString(&UnicodeString, lpKeyName);
    00609     Status = ZwQueryValueKey(hKey,
    00610                              &UnicodeString,
    00611                              KeyValuePartialInformation,
    00612                              (PKEY_VALUE_PARTIAL_INFORMATION)Buf,
    00613                              sizeof(Buf),
    00614                              &cbSize);
    00615
    00616     dwRet = dwDefault;
    00617
    00618     if (NT_SUCCESS(Status)) {
    00619
    00620         dwRet = *((PDWORD)((PKEY_VALUE_PARTIAL_INFORMATION)Buf)->Data);
    00621
    00622     } else if (Status != STATUS_OBJECT_NAME_NOT_FOUND) {
    00623
    00624         RIPMSG1(RIP_WARNING,
    00625                 "FastGetProfileDwordW: ObjectName not found: %ws",
    00626                 lpKeyName);
    00627     }
    00628
    00629     ZwClose(hKey);
    00630
    00631     return dwRet;
    00632 }
    00633
    00634 /*****************************************************************************\
    00635 * FastGetProfileKeysW()
    00636 *
    00637 * Reads all key names in the given section.
    00638 *
    00639 * History:
    00640 * 15-Dec-1994 JimA      Created.
    00641 \*****************************************************************************/
    00642 DWORD FastGetProfileKeysW(PUNICODE_STRING pProfileUserName OPTIONAL,
    00643     UINT    idSection,
    00644     LPCWSTR lpDefault,
    00645     LPWSTR  *lpReturnedString
    00646     )
    00647 {
    00648     HANDLE                       hKey;
    00649     DWORD                        cchSize;
    00650     DWORD                        cchKey;
    00651     LONG                         Status;
    00652     WCHAR                        Buffer[256 + 6];
    00653     PKEY_VALUE_BASIC_INFORMATION pKeyInfo;
    00654     ULONG                        iValue;
    00655     LPWSTR                       lpTmp;
    00656     LPWSTR                       lpKeys = NULL;
    00657     DWORD                        dwPoolSize;
    00658
    00659     UserAssert(idSection <= PMAP_LAST);
    00660
    00661     if ((hKey = OpenCacheKeyEx(pProfileUserName,
    00662                                idSection,
    00663                                KEY_READ,
    00664                                NULL)) == NULL) {
    00665         RIPMSG0(RIP_WARNING | RIP_NONAME, "");
    00666         goto DefExit;
    00667     }
    00668
    00669     pKeyInfo          = (PKEY_VALUE_BASIC_INFORMATION)Buffer;
    00670     cchSize           = 0;
    00671     *lpReturnedString = NULL;
    00672     iValue            = 0;
    00673
    00674     while (TRUE) {
    00675
    00676 #if DBG
    00677         wcscpy(Buffer + 256, L"DON'T");
    00678 #endif
    00679         Status = ZwEnumerateValueKey(hKey,
    00680                                      iValue,
    00681                                      KeyValueBasicInformation,
    00682                                      pKeyInfo,
    00683                                      sizeof(Buffer),
    00684                                      &cchKey);
    00685
    00686         UserAssert(_wcsicmp(Buffer + 256, L"DON'T") == 0);
    00687
    00688         if (Status == STATUS_NO_MORE_ENTRIES) {
    00689
    00690             break;
    00691
    00692         } else if (!NT_SUCCESS(Status)) {
    00693
    00694             if (lpKeys) {
    00695                 UserFreePool(lpKeys);
    00696                 lpKeys = NULL;
    00697             }
    00698             goto DefExit;
    00699         }
    00700
    00701         UserAssert(pKeyInfo->NameLength * sizeof(WCHAR) <=
    00702                    sizeof(Buffer) - sizeof(KEY_VALUE_BASIC_INFORMATION));
    00703
    00704         UserAssert(cchKey <= sizeof(Buffer));
    00705
    00706         /*
    00707          * A key was found.  Allocate space for it.  Note that
    00708          * NameLength is in bytes.
    00709          */
    00710         cchKey   = cchSize;
    00711         cchSize += pKeyInfo->NameLength + sizeof(WCHAR);
    00712
    00713         if (lpKeys == NULL) {
    00714
    00715             dwPoolSize = cchSize + sizeof(WCHAR);
    00716             lpKeys = UserAllocPoolWithQuota(dwPoolSize, TAG_PROFILE);
    00717
    00718         } else {
    00719
    00720             lpTmp = lpKeys;
    00721             lpKeys = UserReAllocPoolWithQuota(lpTmp,
    00722                                               dwPoolSize,
    00723                                               cchSize + sizeof(WCHAR),
    00724                                               TAG_PROFILE);
    00725
    00726             /*
    00727              * Free the original buffer if the allocation fails
    00728              */
    00729             if (lpKeys == NULL) {
    00730                 UserFreePool(lpTmp);
    00731             }
    00732             dwPoolSize = cchSize + sizeof(WCHAR);
    00733         }
    00734
    00735         /*
    00736          * Check for out of memory.
    00737          */
    00738         if (lpKeys == NULL)
    00739             goto DefExit;
    00740
    00741         /*
    00742          * NULL terminate the string and append it to
    00743          * the key list.
    00744          */
    00745         UserAssert(pKeyInfo->NameLength < sizeof(Buffer) - sizeof(KEY_VALUE_BASIC_INFORMATION));
    00746
    00747         RtlCopyMemory(&lpKeys[cchKey / sizeof(WCHAR)], pKeyInfo->Name, pKeyInfo->NameLength);
    00748         lpKeys[(cchKey + pKeyInfo->NameLength) / sizeof(WCHAR)] = 0;
    00749
    00750         iValue++;
    00751     }
    00752
    00753     /*
    00754      * If no keys were found, return the default.
    00755      */
    00756     if (iValue == 0) {
    00757
    00758 DefExit:
    00759
    00760         cchSize = wcslen(lpDefault)+1;
    00761         lpKeys  = UserAllocPoolWithQuota((cchSize+1) * sizeof(WCHAR), TAG_PROFILE);
    00762
    00763         if (lpKeys)
    00764             wcscpy(lpKeys, lpDefault);
    00765         else
    00766             cchSize = 0;
    00767
    00768     } else {
    00769
    00770         /*
    00771          * Turn the byte count into a char count.
    00772          */
    00773         cchSize /= sizeof(WCHAR);
    00774     }
    00775
    00776     /*
    00777      * Make sure hKey is closed.
    00778      */
    00779     if (hKey)
    00780         ZwClose(hKey);
    00781
    00782     /*
    00783      * Append the ending NULL.
    00784      */
    00785     if (lpKeys)
    00786         lpKeys[cchSize] = 0;
    00787
    00788     *lpReturnedString = lpKeys;
    00789
    00790     return cchSize;
    00791 }
    00792
    00793 /*****************************************************************************\
    00794 * FastGetProfileStringW()
    00795 *
    00796 * Implements a fast version of the standard API using predefined registry
    00797 * section indecies (PMAP_) that reference lazy-opened, cached registry
    00798 * handles.  FastCloseProfileUserMapping() should be called to clean up
    00799 * cached entries when fast profile calls are completed.
    00800 *
    00801 * This api does NOT implement the NULL lpKeyName feature of the real API.
    00802 *
    00803 * History:
    00804 * 02-Dec-1993 SanfordS  Created.
    00805 \*****************************************************************************/
    00806 DWORD FastGetProfileStringW(PUNICODE_STRING pProfileUserName OPTIONAL,
    00807     UINT    idSection,
    00808     LPCWSTR lpKeyName,
    00809     LPCWSTR lpDefault,
    00810     LPWSTR  lpReturnedString,
    00811     DWORD   cchBuf
    00812     )
    00813 {
    00814     HANDLE                         hKey = NULL;
    00815     DWORD                          cbSize;
    00816     LONG                           Status;
    00817     UNICODE_STRING                 UnicodeString;
    00818     PKEY_VALUE_PARTIAL_INFORMATION pKeyInfo;
    00819     BOOL                           bRemoteOverride = FALSE;
    00820     DWORD                          dwPolicyFlags = gdwPolicyFlags;
    00821
    00822
    00823     UserAssert(idSection <= PMAP_LAST);
    00824     UserAssert(lpKeyName != NULL);
    00825
    00826     if (gbRemoteSession) {
    00827         hKey = RemoteOpenCacheKeyEx(idSection, KEY_READ);
    00828         if (hKey != NULL) {
    00829             bRemoteOverride = TRUE;
    00830             goto Override;
    00831         }
    00832     }
    00833
    00834 TryAgain:
    00835     if ((hKey = OpenCacheKeyEx(pProfileUserName,
    00836                                idSection,
    00837                                KEY_READ,
    00838                                &dwPolicyFlags)) == NULL) {
    00839
    00840 #if DBG
    00841         if (PsGetCurrentProcess()->UniqueProcessId != gpidLogon) {
    00842             RIPMSG1(RIP_WARNING | RIP_NONAME, "%ws", lpKeyName);
    00843         }
    00844 #endif
    00845         goto DefExit;
    00846     }
    00847
    00848 Override:
    00849
    00850     cbSize = (cchBuf * sizeof(WCHAR)) +
    00851             FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data);
    00852
    00853     if ((pKeyInfo = UserAllocPoolWithQuota(cbSize, TAG_PROFILE)) == NULL)
    00854         goto DefExit;
    00855
    00856     RtlInitUnicodeString(&UnicodeString, lpKeyName);
    00857     Status = ZwQueryValueKey(hKey,
    00858                              &UnicodeString,
    00859                              KeyValuePartialInformation,
    00860                              pKeyInfo,
    00861                              cbSize,
    00862                              &cbSize);
    00863
    00864     if (Status == STATUS_BUFFER_OVERFLOW) {
    00865         RIPMSG0(RIP_WARNING, "FastGetProfileStringW: Buffer overflow");
    00866         Status = STATUS_SUCCESS;
    00867     }
    00868
    00869     UserAssert(NT_SUCCESS(Status) || (Status == STATUS_OBJECT_NAME_NOT_FOUND));
    00870
    00871     if (NT_SUCCESS(Status)) {
    00872
    00873         if (pKeyInfo->DataLength >= sizeof(WCHAR)) {
    00874
    00875             ((LPWSTR)(pKeyInfo->Data))[cchBuf - 1] = L'\0';
    00876             wcscpy(lpReturnedString, (LPWSTR)pKeyInfo->Data);
    00877
    00878         } else {
    00879             /*
    00880              * Appears to be a bug with empty strings - only first
    00881              * byte is set to NULL. (SAS)
    00882              */
    00883             lpReturnedString[0] = TEXT('\0');
    00884         }
    00885
    00886         cchBuf = pKeyInfo->DataLength;
    00887
    00888         UserFreePool(pKeyInfo);
    00889
    00890         ZwClose(hKey);
    00891
    00892         /*
    00893          * data length includes terminating zero [bodind]
    00894          */
    00895         return (cchBuf / sizeof(WCHAR));
    00896
    00897     } else if (bRemoteOverride) {
    00898         bRemoteOverride = FALSE;
    00899         UserFreePool(pKeyInfo);
    00900         ZwClose(hKey);
    00901         hKey = NULL;
    00902         goto TryAgain;
    00903
    00904     } else if (dwPolicyFlags) {
    00905         UserFreePool(pKeyInfo);
    00906         ZwClose(hKey);
    00907         goto TryAgain;
    00908     }
    00909
    00910     UserFreePool(pKeyInfo);
    00911
    00912 DefExit:
    00913
    00914     /*
    00915      * Make sure the key is closed.
    00916      */
    00917     if (hKey)
    00918         ZwClose(hKey);
    00919
    00920     /*
    00921      * wcscopy copies terminating zero, but the length returned by
    00922      * wcslen does not, so add 1 to be consistent with success
    00923      * return [bodind]
    00924      */
    00925     if (lpDefault != NULL) {
    00926         cchBuf = wcslen(lpDefault) + 1;
    00927         RtlCopyMemory(lpReturnedString, lpDefault, cchBuf * sizeof(WCHAR));
    00928         return cchBuf;
    00929     }
    00930
    00931     return 0;
    00932 }
    00933
    00934 /*****************************************************************************\
    00935 * FastGetProfileIntW()
    00936 *
    00937 * Implements a fast version of the standard API using predefined registry
    00938 * section indecies (PMAP_) that reference lazy-opened, cached registry
    00939 * handles.  FastCloseProfileUserMapping() should be called to clean up
    00940 * cached entries when fast profile calls are completed.
    00941 *
    00942 * History:
    00943 * 02-Dec-1993 SanfordS  Created.
    00944 \*****************************************************************************/
    00945 UINT FastGetProfileIntW(PUNICODE_STRING pProfileUserName OPTIONAL,
    00946     UINT    idSection,
    00947     LPCWSTR lpKeyName,
    00948     UINT    nDefault
    00949     )
    00950 {
    00951     WCHAR          ValueBuf[40];
    00952     UNICODE_STRING Value;
    00953     UINT           ReturnValue;
    00954
    00955     UserAssert(idSection <= PMAP_LAST);
    00956
    00957     if (!FastGetProfileStringW(pProfileUserName,
    00958                                idSection,
    00959                                lpKeyName,
    00960                                NULL,
    00961                                ValueBuf,
    00962                                sizeof(ValueBuf) / sizeof(WCHAR)
    00963                                )) {
    00964
    00965         return nDefault;
    00966     }
    00967
    00968     /*
    00969      * Convert string to int.
    00970      */
    00971     RtlInitUnicodeString(&Value, ValueBuf);
    00972     RtlUnicodeStringToInteger(&Value, 10, &ReturnValue);
    00973
    00974     return ReturnValue;
    00975 }
    00976
    00977 /*****************************************************************************\
    00978 * FastWriteProfileStringW
    00979 *
    00980 * Implements a fast version of the standard API using predefined registry
    00981 * section indecies (PMAP_) that reference lazy-opened, cached registry
    00982 * handles.  FastCloseProfileUserMapping() should be called to clean up
    00983 * cached entries when fast profile calls are completed.
    00984 *
    00985 * History:
    00986 * 02-Dec-1993 SanfordS  Created.
    00987 \*****************************************************************************/
    00988 BOOL FastWriteProfileStringW(PUNICODE_STRING pProfileUserName OPTIONAL,
    00989     UINT    idSection,
    00990     LPCWSTR lpKeyName,
    00991     LPCWSTR lpString
    00992     )
    00993 {
    00994     HANDLE         hKey;
    00995     LONG           Status;
    00996     UNICODE_STRING UnicodeString;
    00997
    00998     UserAssert(idSection <= PMAP_LAST);
    00999
    01000     if ((hKey = OpenCacheKeyEx(pProfileUserName,
    01001                                idSection,
    01002                                KEY_WRITE,
    01003                                NULL)) == NULL) {
    01004         RIPMSG1(RIP_WARNING | RIP_NONAME, "%ws", lpKeyName);
    01005         return FALSE;
    01006     }
    01007
    01008     RtlInitUnicodeString(&UnicodeString, lpKeyName);
    01009     Status = ZwSetValueKey(hKey,
    01010                            &UnicodeString,
    01011                            0,
    01012                            REG_SZ,
    01013                            (PVOID)lpString,
    01014                            (wcslen(lpString) + 1) * sizeof(WCHAR));
    01015
    01016     ZwClose(hKey);
    01017
    01018     return (NT_SUCCESS(Status));
    01019 }
    01020
    01021 /*****************************************************************************\
    01022 * FastGetProfileIntFromID
    01023 *
    01024 * Just like FastGetProfileIntW except it reads the USER string table for the
    01025 * key name.
    01026 *
    01027 * History:
    01028 * 02-Dec-1993 SanfordS  Created.
    01029 * 25-Feb-1995 BradG     Added TWIPS -> Pixel conversion.
    01030 \*****************************************************************************/
    01031 int FastGetProfileIntFromID(PUNICODE_STRING pProfileUserName OPTIONAL,
    01032     UINT idSection,
    01033     UINT idKey,
    01034     int  def
    01035     )
    01036 {
    01037     int   result;
    01038     WCHAR szKey[80];
    01039
    01040
    01041     UserAssert(idSection <= PMAP_LAST);
    01042
    01043     ServerLoadString(hModuleWin, idKey, szKey, ARRAY_SIZE(szKey));
    01044
    01045     result = FastGetProfileIntW(pProfileUserName,idSection, szKey, def);
    01046
    01047     /*
    01048      * If you change the below list of STR_* make sure you make a
    01049      * corresponding change in SetWindowMetricInt (rare.c)
    01050      */
    01051     switch (idKey) {
    01052     case STR_BORDERWIDTH:
    01053     case STR_SCROLLWIDTH:
    01054     case STR_SCROLLHEIGHT:
    01055     case STR_CAPTIONWIDTH:
    01056     case STR_CAPTIONHEIGHT:
    01057     case STR_SMCAPTIONWIDTH:
    01058     case STR_SMCAPTIONHEIGHT:
    01059     case STR_MENUWIDTH:
    01060     case STR_MENUHEIGHT:
    01061     case STR_ICONHORZSPACING:
    01062     case STR_ICONVERTSPACING:
    01063     case STR_MINWIDTH:
    01064     case STR_MINHORZGAP:
    01065     case STR_MINVERTGAP:
    01066         /*
    01067          * Convert any registry values stored in TWIPS back to pixels
    01068          */
    01069         if (result < 0)
    01070             result = MultDiv(-result, gpsi->dmLogPixels, 72 * 20);
    01071         break;
    01072     }
    01073
    01074     return result;
    01075 }
    01076
    01077 /*****************************************************************************\
    01078 * FastGetProfileIntFromID
    01079 *
    01080 * Just like FastGetProfileStringW except it reads the USER string table for
    01081 * the key name.
    01082 *
    01083 * History:
    01084 * 02-Dec-1993 SanfordS  Created.
    01085 \*****************************************************************************/
    01086 DWORD FastGetProfileStringFromIDW(PUNICODE_STRING pProfileUserName OPTIONAL,
    01087     UINT    idSection,
    01088     UINT    idKey,
    01089     LPCWSTR lpDefault,
    01090     LPWSTR  lpReturnedString,
    01091     DWORD   cch
    01092     )
    01093 {
    01094     WCHAR szKey[80];
    01095
    01096     UserAssert(idSection <= PMAP_LAST);
    01097
    01098     ServerLoadString(hModuleWin, idKey, szKey, ARRAY_SIZE(szKey));
    01099
    01100     return FastGetProfileStringW(pProfileUserName,
    01101                                  idSection,
    01102                                  szKey,
    01103                                  lpDefault,
    01104                                  lpReturnedString,
    01105                                  cch
    01106                                  );
    01107 }
    01108
    01109 /*****************************************************************************\
    01110 * FastWriteProfileValue
    01111 *
    01112 * History:
    01113 * 06/10/96 GerardoB Renamed and added uType parameter
    01114 \*****************************************************************************/
    01115 BOOL FastWriteProfileValue(PUNICODE_STRING pProfileUserName OPTIONAL,
    01116     UINT    idSection,
    01117     LPCWSTR lpKeyName,
    01118     UINT    uType,
    01119     LPBYTE  lpStruct,
    01120     UINT    cbSizeStruct
    01121     )
    01122 {
    01123     HANDLE         hKey;
    01124     LONG           Status;
    01125     UNICODE_STRING UnicodeString;
    01126     WCHAR          szKey[SERVERSTRINGMAXSIZE];
    01127
    01128     UserAssert(idSection <= PMAP_LAST);
    01129
    01130     if (!IS_PTR(lpKeyName)) {
    01131         *szKey = (WCHAR)0;
    01132         ServerLoadString(hModuleWin, PTR_TO_ID(lpKeyName), szKey, ARRAY_SIZE(szKey));
    01133         UserAssert(*szKey != (WCHAR)0);
    01134         lpKeyName = szKey;
    01135     }
    01136
    01137     if ((hKey = OpenCacheKeyEx(pProfileUserName,
    01138                                idSection,
    01139                                KEY_WRITE,
    01140                                NULL)) == NULL) {
    01141         RIPMSG1(RIP_WARNING, "FastWriteProfileValue: Failed to open cache-key (%ws)", lpKeyName);
    01142         return FALSE;
    01143     }
    01144
    01145     RtlInitUnicodeString(&UnicodeString, lpKeyName);
    01146
    01147     Status = ZwSetValueKey(hKey,
    01148                            &UnicodeString,
    01149                            0,
    01150                            uType,
    01151                            lpStruct,
    01152                            cbSizeStruct);
    01153     ZwClose(hKey);
    01154
    01155 #if DBG
    01156     if (!NT_SUCCESS(Status)) {
    01157         RIPMSG3 (RIP_WARNING, "FastWriteProfileValue: ZwSetValueKey Failed. Status:%#lx idSection:%#lx KeyName:%s",
    01158                  Status, idSection, UnicodeString.Buffer);
    01159     }
    01160 #endif
    01161
    01162     return (NT_SUCCESS(Status));
    01163 }
    01164
    01165 /*****************************************************************************\
    01166 * FastGetProfileValue
    01167 *
    01168 * If cbSizeReturn is 0, just return the size of the data
    01169 *
    01170 * History:
    01171 * 06/10/96 GerardoB Renamed
    01172 \*****************************************************************************/
    01173 DWORD FastGetProfileValue(PUNICODE_STRING pProfileUserName OPTIONAL,
    01174     UINT    idSection,
    01175     LPCWSTR lpKeyName,
    01176     LPBYTE  lpDefault,
    01177     LPBYTE  lpReturn,
    01178     UINT    cbSizeReturn
    01179     )
    01180 {
    01181     HANDLE                         hKey;
    01182     UINT                           cbSize;
    01183     LONG                           Status;
    01184     UNICODE_STRING                 UnicodeString;
    01185     PKEY_VALUE_PARTIAL_INFORMATION pKeyInfo;
    01186     WCHAR                          szKey[SERVERSTRINGMAXSIZE];
    01187     KEY_VALUE_PARTIAL_INFORMATION  KeyInfo;
    01188
    01189     UserAssert(idSection <= PMAP_LAST);
    01190
    01191     if (!IS_PTR(lpKeyName)) {
    01192         *szKey = (WCHAR)0;
    01193         ServerLoadString(hModuleWin, PTR_TO_ID(lpKeyName), szKey, ARRAY_SIZE(szKey));
    01194         UserAssert(*szKey != (WCHAR)0);
    01195         lpKeyName = szKey;
    01196     }
    01197
    01198     if (gbRemoteSession) {
    01199         hKey = RemoteOpenCacheKeyEx(idSection, KEY_READ);
    01200         if (hKey != NULL) {
    01201             goto Override;
    01202         }
    01203     }
    01204
    01205     if ((hKey = OpenCacheKeyEx(pProfileUserName,
    01206                                idSection,
    01207                                KEY_READ,
    01208                                NULL)) == NULL) {
    01209         // if hi-word of lpKeName is 0, it is a resource number not a string
    01210
    01211         if (!IS_PTR(lpKeyName))
    01212             RIPMSG1(RIP_WARNING, "FastGetProfileValue: Failed to open cache-key (%08x)", lpKeyName);
    01213         else
    01214             RIPMSG1(RIP_WARNING | RIP_NONAME, "%ws", lpKeyName);
    01215
    01216         goto DefExit;
    01217     }
    01218
    01219 Override:
    01220
    01221     if (cbSizeReturn == 0) {
    01222         cbSize = sizeof(KeyInfo);
    01223         pKeyInfo = &KeyInfo;
    01224     } else {
    01225         cbSize = cbSizeReturn + FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data);
    01226         if ((pKeyInfo = UserAllocPoolWithQuota(cbSize, TAG_PROFILE)) == NULL) {
    01227             goto DefExit;
    01228         }
    01229     }
    01230
    01231     RtlInitUnicodeString(&UnicodeString, lpKeyName);
    01232
    01233     Status = ZwQueryValueKey(hKey,
    01234                              &UnicodeString,
    01235                              KeyValuePartialInformation,
    01236                              pKeyInfo,
    01237                              cbSize,
    01238                              &cbSize);
    01239
    01240     if (NT_SUCCESS(Status)) {
    01241
    01242         UserAssert(cbSizeReturn >= pKeyInfo->DataLength);
    01243
    01244         cbSize = pKeyInfo->DataLength;
    01245         RtlCopyMemory(lpReturn, pKeyInfo->Data, cbSize);
    01246
    01247         if (cbSizeReturn != 0) {
    01248             UserFreePool(pKeyInfo);
    01249         }
    01250         ZwClose(hKey);
    01251
    01252         return cbSize;
    01253     } else if ((Status == STATUS_BUFFER_OVERFLOW) && (cbSizeReturn == 0)) {
    01254         ZwClose(hKey);
    01255         return pKeyInfo->DataLength;
    01256     }
    01257
    01258 #if DBG
    01259     if (Status != STATUS_OBJECT_NAME_NOT_FOUND) {
    01260         RIPMSG3 (RIP_WARNING, "FastGetProfileValue: ZwQueryValueKey Failed. Status:%#lx idSection:%#lx KeyName:%s",
    01261                 Status, idSection, UnicodeString.Buffer);
    01262     }
    01263 #endif
    01264
    01265     if (cbSizeReturn != 0) {
    01266         UserFreePool(pKeyInfo);
    01267     }
    01268
    01269 DefExit:
    01270
    01271     if (hKey)
    01272         ZwClose(hKey);
    01273
    01274     if (lpDefault) {
    01275         RtlMoveMemory(lpReturn, lpDefault, cbSizeReturn);
    01276         return cbSizeReturn;
    01277     }
    01278
    01279     return 0;
    01280 }
    01281
    01282 /*****************************************************************************\
    01283 * UT_FastGetProfileIntsW
    01284 *
    01285 * Repeatedly calls FastGetProfileIntW on the given table.
    01286 *
    01287 * History:
    01288 * 02-Dec-1993 SanfordS  Created.
    01289 \*****************************************************************************/
    01290 BOOL FastGetProfileIntsW(PUNICODE_STRING pProfileUserName OPTIONAL,
    01291     PPROFINTINFO ppii
    01292     )
    01293 {
    01294     WCHAR szKey[40];
    01295
    01296     while (ppii->idSection != 0) {
    01297
    01298         ServerLoadString(hModuleWin,
    01299                              PTR_TO_ID(ppii->lpKeyName),
    01300                              szKey,
    01301                              ARRAY_SIZE(szKey));
    01302
    01303         *ppii->puResult = FastGetProfileIntW(pProfileUserName,
    01304                                                  ppii->idSection,
    01305                                                  szKey,
    01306                                                  ppii->nDefault
    01307                                                  );
    01308         ppii++;
    01309     }
    01310
    01311     return TRUE;
    01312 }
    01313
    01314 /***************************************************************************\
    01315 * UpdateWinIni
    01316 *
    01317 * Handles impersonation stuff and writes the given value to the registry.
    01318 *
    01319 * History:
    01320 * 28-Jun-1991 MikeHar       Ported.
    01321 * 03-Dec-1993 SanfordS      Used FastProfile calls, moved to profile.c
    01322 \***************************************************************************/
    01323 BOOL FastUpdateWinIni(PUNICODE_STRING pProfileUserName OPTIONAL,
    01324     UINT         idSection,
    01325     UINT         wKeyNameId,
    01326     LPWSTR       lpszValue
    01327     )
    01328 {
    01329     WCHAR            szKeyName[40];
    01330     BOOL             bResult = FALSE;
    01331
    01332     UserAssert(idSection <= PMAP_LAST);
    01333
    01334     ServerLoadString(hModuleWin,
    01335                          wKeyNameId,
    01336                          szKeyName,
    01337                          ARRAY_SIZE(szKeyName));
    01338
    01339     bResult = FastWriteProfileStringW(pProfileUserName,
    01340                                           idSection, szKeyName, lpszValue);
    01341
    01342     return bResult;
    01343 }