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

init.c

Go to the documentation of this file.
00001 /****************************** Module Header ******************************\ 00002 * Module Name: init.c 00003 * 00004 * Copyright (c) 1985 - 1999, Microsoft Corporation 00005 * 00006 * This module contains all the init code for the USERSRV.DLL. When 00007 * the DLL is dynlinked by the SERVER EXE its initialization procedure 00008 * (xxxUserServerDllInitialize) is called by the loader. 00009 * 00010 * History: 00011 * 18-Sep-1990 DarrinM Created. 00012 \***************************************************************************/ 00013 00014 #define OEMRESOURCE 1 00015 00016 #include "precomp.h" 00017 #pragma hdrstop 00018 00019 #if DBG 00020 LIST_ENTRY gDesktopList; 00021 #endif 00022 00023 // 00024 // External references 00025 // 00026 extern PVOID *apObjects; 00027 extern PKWAIT_BLOCK gWaitBlockArray; 00028 extern PVOID UserAtomTableHandle; 00029 extern PKTIMER gptmrWD; 00030 00031 extern UNICODE_STRING* gpastrSetupExe; 00032 extern WCHAR* glpSetupPrograms; 00033 00034 extern PHANDLEPAGE gpHandlePages; 00035 00036 extern PBWL pbwlCache; 00037 00038 // 00039 // Forward references 00040 // 00041 BOOL 00042 Win32kNtUserCleanup(); 00043 00044 #if DBG 00045 void InitGlobalThreadLockArray(DWORD dwIndex); 00046 #endif // DBG 00047 00048 /* 00049 * Local Constants. 00050 */ 00051 #define GRAY_STRLEN 40 00052 00053 /* 00054 * Globals local to this file only. 00055 */ 00056 BOOL bPermanentFontsLoaded = FALSE; 00057 int LastFontLoaded = -1; 00058 00059 /* 00060 * Globals shared with W32 00061 */ 00062 ULONG W32ProcessSize = sizeof(PROCESSINFO); 00063 ULONG W32ProcessTag = TAG_PROCESSINFO; 00064 ULONG W32ThreadSize = sizeof(THREADINFO); 00065 ULONG W32ThreadTag = TAG_THREADINFO; 00066 PFAST_MUTEX gpW32FastMutex; 00067 00068 NTSTATUS 00069 DriverEntry( 00070 IN PDRIVER_OBJECT DriverObject, 00071 IN PUNICODE_STRING RegistryPath); 00072 00073 #pragma alloc_text(INIT, DriverEntry) 00074 #pragma alloc_text(INIT, LW_LoadSomeStrings) 00075 00076 NTSTATUS Win32UserInitialize(VOID); 00077 00078 #if defined(_X86_) 00079 ULONG Win32UserProbeAddress; 00080 #endif 00081 00082 void FreeSMS(PSMS psms); 00083 VOID FreeImeHotKeys(VOID); 00084 00085 /***************************************************************************\ 00086 * Win32kNtUserCleanup 00087 * 00088 * History: 00089 * 5-Jan-1997 CLupu Created. 00090 \***************************************************************************/ 00091 extern PPAGED_LOOKASIDE_LIST SMSLookaside; 00092 extern PPAGED_LOOKASIDE_LIST QEntryLookaside; 00093 00094 // Max time is 10 minutes, and the count is 10 min * 60 sec * 4 for 250 mili seconds 00095 #define MAX_TIME_OUT (10*60*4) 00096 00097 BOOL Win32kNtUserCleanup( 00098 VOID) 00099 { 00100 int i; 00101 00102 TRACE_HYDAPI(("Win32kNtUserCleanup: Cleanup Resources\n")); 00103 00104 EnterCrit(); 00105 00106 DbgDumpTrackedDesktops(TRUE); 00107 00108 /* 00109 * Anything in this list must be cleaned up when threads go away. 00110 */ 00111 UserAssert(gpbwlList == NULL); 00112 00113 UserAssert(gpWinEventHooks == NULL); 00114 00115 UserAssert(gpScancodeMap == NULL); 00116 00117 /* 00118 * Free IME hotkeys 00119 */ 00120 FreeImeHotKeys(); 00121 00122 /* 00123 * Free the wallpaper name string 00124 */ 00125 if (gpszWall != NULL) { 00126 UserFreePool(gpszWall); 00127 gpszWall = NULL; 00128 } 00129 /* 00130 * Free the hung redraw stuff 00131 */ 00132 if (gpvwplHungRedraw != NULL) { 00133 UserFreePool(gpvwplHungRedraw); 00134 gpvwplHungRedraw = NULL; 00135 } 00136 00137 /* 00138 * Free the arrary of setup app names 00139 */ 00140 if (gpastrSetupExe) { 00141 UserFreePool(gpastrSetupExe); 00142 gpastrSetupExe = NULL; 00143 } 00144 00145 if (glpSetupPrograms) { 00146 UserFreePool(glpSetupPrograms); 00147 glpSetupPrograms = NULL; 00148 } 00149 00150 /* 00151 * Free the cached window list 00152 */ 00153 if (pbwlCache != NULL) { 00154 UserFreePool(pbwlCache); 00155 pbwlCache = NULL; 00156 } 00157 00158 /* 00159 * Free outstanding timers 00160 */ 00161 while (gptmrFirst != NULL) { 00162 FreeTimer(gptmrFirst); 00163 } 00164 00165 if (gptmrWD) { 00166 KeCancelTimer(gptmrWD); 00167 UserFreePool(gptmrWD); 00168 gptmrWD = NULL; 00169 } 00170 00171 if (gptmrMaster) { 00172 KeCancelTimer(gptmrMaster); 00173 UserFreePool(gptmrMaster); 00174 gptmrMaster = NULL; 00175 } 00176 00177 /* 00178 * Cleanup mouse & kbd change events 00179 */ 00180 for (i = 0; i <= DEVICE_TYPE_MAX; i++) { 00181 UserAssert(gptiRit == NULL); 00182 if (aDeviceTemplate[i].pkeHidChange) { 00183 FreeKernelEvent(&aDeviceTemplate[i].pkeHidChange); 00184 } 00185 } 00186 00187 EnterDeviceInfoListCrit(); 00188 while (gpDeviceInfoList) { 00189 /* 00190 * Assert that there is no outstanding read or PnP thread waiting 00191 * in RequestDeviceChanges() for this device. 00192 * Clear these flags anyway, to force the free. 00193 */ 00194 UserAssert((gpDeviceInfoList->bFlags & GDIF_READING) == 0); 00195 UserAssert((gpDeviceInfoList->usActions & GDIAF_PNPWAITING) == 0); 00196 gpDeviceInfoList->bFlags &= ~GDIF_READING; 00197 gpDeviceInfoList->usActions &= ~GDIAF_PNPWAITING; 00198 FreeDeviceInfo(gpDeviceInfoList); 00199 } 00200 LeaveDeviceInfoListCrit(); 00201 00202 /* 00203 * Cleanup object references 00204 */ 00205 if (gThinwireFileObject) 00206 ObDereferenceObject(gThinwireFileObject); 00207 00208 if (gVideoFileObject) 00209 ObDereferenceObject(gVideoFileObject); 00210 00211 if (gpRemoteBeepDevice) 00212 ObDereferenceObject(gpRemoteBeepDevice); 00213 00214 /* 00215 * Cleanup our resources. There should be no threads in here 00216 * when we get called. 00217 */ 00218 if (gpresMouseEventQueue) { 00219 ExDeleteResource(gpresMouseEventQueue); 00220 ExFreePool(gpresMouseEventQueue); 00221 gpresMouseEventQueue = NULL; 00222 } 00223 00224 if (gpresDeviceInfoList) { 00225 ExDeleteResource(gpresDeviceInfoList); 00226 ExFreePool(gpresDeviceInfoList); 00227 gpresDeviceInfoList = NULL; 00228 } 00229 00230 if (gpkeMouseData != NULL) { 00231 FreeKernelEvent(&gpkeMouseData); 00232 } 00233 00234 if (apObjects) { 00235 UserFreePool(apObjects); 00236 apObjects = NULL; 00237 } 00238 00239 if (gWaitBlockArray) { 00240 UserFreePool(gWaitBlockArray); 00241 gWaitBlockArray = NULL; 00242 } 00243 00244 if (gpEventDiconnectDesktop != NULL) { 00245 FreeKernelEvent(&gpEventDiconnectDesktop); 00246 } 00247 00248 if (gpevtDesktopDestroyed != NULL) { 00249 FreeKernelEvent(&gpevtDesktopDestroyed); 00250 } 00251 00252 if (UserAtomTableHandle != NULL) { 00253 RtlDestroyAtomTable(UserAtomTableHandle); 00254 UserAtomTableHandle = NULL; 00255 } 00256 00257 /* 00258 * cleanup the SMS lookaside buffer 00259 */ 00260 { 00261 PSMS psmsNext; 00262 00263 while (gpsmsList != NULL) { 00264 psmsNext = gpsmsList->psmsNext; 00265 UserAssert(gpsmsList->spwnd == NULL); 00266 FreeSMS(gpsmsList); 00267 gpsmsList = psmsNext; 00268 } 00269 00270 if (SMSLookaside != NULL) { 00271 ExDeletePagedLookasideList(SMSLookaside); 00272 UserFreePool(SMSLookaside); 00273 SMSLookaside = NULL; 00274 } 00275 } 00276 00277 /* 00278 * Let go of the attached queue for hard error handling. 00279 * Do this before we free the Qlookaside ! 00280 */ 00281 if (gHardErrorHandler.pqAttach != NULL) { 00282 00283 UserAssert(gHardErrorHandler.pqAttach > 0); 00284 UserAssert(gHardErrorHandler.pqAttach->QF_flags & QF_INDESTROY); 00285 00286 FreeQueue(gHardErrorHandler.pqAttach); 00287 gHardErrorHandler.pqAttach = NULL; 00288 } 00289 00290 /* 00291 * Free the cached array of queues 00292 */ 00293 FreeCachedQueues(); 00294 00295 /* 00296 * cleanup the QEntry lookaside buffer 00297 */ 00298 if (QEntryLookaside != NULL) { 00299 ExDeletePagedLookasideList(QEntryLookaside); 00300 UserFreePool(QEntryLookaside); 00301 QEntryLookaside = NULL; 00302 } 00303 00304 /* 00305 * Unlock the keyboard layouts 00306 */ 00307 if (gspklBaseLayout != NULL) { 00308 00309 PKL pkl; 00310 PKL pklNext; 00311 00312 pkl = gspklBaseLayout->pklNext; 00313 00314 while (pkl->pklNext != pkl) { 00315 pklNext = pkl->pklNext; 00316 00317 DestroyKL(pkl); 00318 00319 pkl = pklNext; 00320 } 00321 00322 UserAssert(pkl == gspklBaseLayout); 00323 00324 if (!HMIsMarkDestroy(gspklBaseLayout)) { 00325 HMMarkObjectDestroy(gspklBaseLayout); 00326 } 00327 00328 HYDRA_HINT(HH_KBDLYOUTGLOBALCLEANUP); 00329 00330 if (Unlock(&gspklBaseLayout)) { 00331 DestroyKL(pkl); 00332 } 00333 } 00334 00335 UserAssert(gpkfList == NULL); 00336 00337 { 00338 PWOWTHREADINFO pwti; 00339 00340 /* 00341 * Cleanup gpwtiFirst list. This list is supposed to be empty 00342 * at this point. In one case during stress we hit the case where 00343 * it was not empty. The assert is to catch that case in 00344 * checked builds. 00345 */ 00346 00347 while (gpwtiFirst != NULL) { 00348 pwti = gpwtiFirst; 00349 gpwtiFirst = pwti->pwtiNext; 00350 UserFreePool(pwti); 00351 } 00352 } 00353 00354 /* 00355 * Cleanup cached SMWP array 00356 */ 00357 if (gSMWP.acvr != NULL) { 00358 UserFreePool(gSMWP.acvr); 00359 } 00360 00361 /* 00362 * Free gpsdInitWinSta. This is != NULL only if the session didn't 00363 * make it to UserInitialize. 00364 */ 00365 if (gpsdInitWinSta != NULL) { 00366 UserFreePool(gpsdInitWinSta); 00367 gpsdInitWinSta = NULL; 00368 } 00369 00370 if (gpHandleFlagsMutex != NULL) { 00371 ExFreePool(gpHandleFlagsMutex); 00372 gpHandleFlagsMutex = NULL; 00373 } 00374 00375 /* 00376 * Delete the power request structures. 00377 */ 00378 DeletePowerRequestList(); 00379 00380 LeaveCrit(); 00381 00382 if (gpresUser != NULL) { 00383 ExDeleteResource(gpresUser); 00384 ExFreePool(gpresUser); 00385 gpresUser = NULL; 00386 } 00387 #if DBG 00388 /* 00389 * Cleanup the global thread lock structures 00390 */ 00391 for (i = 0; i < gcThreadLocksArraysAllocated; i++) { 00392 UserFreePool(gpaThreadLocksArrays[i]); 00393 gpaThreadLocksArrays[i] = NULL; 00394 } 00395 #endif // DBG 00396 00397 return TRUE; 00398 } 00399 00400 #if DBG 00401 00402 /***************************************************************************\ 00403 * TrackAddDesktop 00404 * 00405 * Track desktops for cleanup purposes 00406 * 00407 * History: 00408 * 04-Dec-1997 clupu Created. 00409 \***************************************************************************/ 00410 VOID TrackAddDesktop( 00411 PVOID pDesktop) 00412 { 00413 PLIST_ENTRY Entry; 00414 PVOID Atom; 00415 00416 TRACE_HYDAPI(("TrackAddDesktop %#p\n", pDesktop)); 00417 00418 Atom = (PVOID)UserAllocPool(sizeof(PVOID) + sizeof(LIST_ENTRY), 00419 TAG_TRACKDESKTOP); 00420 if (Atom) { 00421 00422 *(PVOID*)Atom = pDesktop; 00423 00424 Entry = (PLIST_ENTRY)(((PCHAR)Atom) + sizeof(PVOID)); 00425 00426 InsertTailList(&gDesktopList, Entry); 00427 } 00428 } 00429 00430 /***************************************************************************\ 00431 * TrackRemoveDesktop 00432 * 00433 * Track desktops for cleanup purposes 00434 * 00435 * History: 00436 * 04-Dec-1997 clupu Created. 00437 \***************************************************************************/ 00438 VOID TrackRemoveDesktop( 00439 PVOID pDesktop) 00440 { 00441 PLIST_ENTRY NextEntry; 00442 PVOID Atom; 00443 00444 TRACE_HYDAPI(("TrackRemoveDesktop %#p\n", pDesktop)); 00445 00446 NextEntry = gDesktopList.Flink; 00447 00448 while (NextEntry != &gDesktopList) { 00449 00450 Atom = (PVOID)(((PCHAR)NextEntry) - sizeof(PVOID)); 00451 00452 if (pDesktop == *(PVOID*)Atom) { 00453 00454 RemoveEntryList(NextEntry); 00455 00456 UserFreePool(Atom); 00457 00458 break; 00459 } 00460 00461 NextEntry = NextEntry->Flink; 00462 } 00463 } 00464 00465 /***************************************************************************\ 00466 * DumpTrackedDesktops 00467 * 00468 * Dumps the tracked desktops 00469 * 00470 * History: 00471 * 04-Dec-1997 clupu Created. 00472 \***************************************************************************/ 00473 VOID DumpTrackedDesktops( 00474 BOOL bBreak) 00475 { 00476 PLIST_ENTRY NextEntry; 00477 PVOID pdesk; 00478 PVOID Atom; 00479 int nAlive = 0; 00480 00481 TRACE_HYDAPI(("DumpTrackedDesktops\n")); 00482 00483 NextEntry = gDesktopList.Flink; 00484 00485 while (NextEntry != &gDesktopList) { 00486 00487 Atom = (PVOID)(((PCHAR)NextEntry) - sizeof(PVOID)); 00488 00489 pdesk = *(PVOID*)Atom; 00490 00491 KdPrint(("pdesk %#p\n", pdesk)); 00492 00493 /* 00494 * Restart at the begining of the list since our 00495 * entry got deleted 00496 */ 00497 NextEntry = NextEntry->Flink; 00498 00499 nAlive++; 00500 } 00501 if (bBreak && nAlive > 0) { 00502 RIPMSG0(RIP_ERROR, "Desktop objects still around\n"); 00503 } 00504 } 00505 00506 #endif // DBG 00507 00508 VOID DestroyRegion( 00509 HRGN* prgn) 00510 { 00511 if (*prgn != NULL) { 00512 GreSetRegionOwner(*prgn, OBJECT_OWNER_CURRENT); 00513 GreDeleteObject(*prgn); 00514 *prgn = NULL; 00515 } 00516 } 00517 00518 VOID DestroyBrush( 00519 HBRUSH* pbr) 00520 { 00521 if (*pbr != NULL) { 00522 //GreSetBrushOwner(*pbr, OBJECT_OWNER_CURRENT); 00523 GreDeleteObject(*pbr); 00524 *pbr = NULL; 00525 } 00526 } 00527 00528 VOID DestroyBitmap( 00529 HBITMAP* pbm) 00530 { 00531 if (*pbm != NULL) { 00532 GreSetBitmapOwner(*pbm, OBJECT_OWNER_CURRENT); 00533 GreDeleteObject(*pbm); 00534 *pbm = NULL; 00535 } 00536 } 00537 00538 VOID DestroyDC( 00539 HDC* phdc) 00540 { 00541 if (*phdc != NULL) { 00542 GreSetDCOwner(*phdc, OBJECT_OWNER_CURRENT); 00543 GreDeleteDC(*phdc); 00544 *phdc = NULL; 00545 } 00546 } 00547 00548 VOID DestroyFont( 00549 HFONT* pfnt) 00550 { 00551 if (*pfnt != NULL) { 00552 GreDeleteObject(*pfnt); 00553 *pfnt = NULL; 00554 } 00555 } 00556 00557 /***************************************************************************\ 00558 * CleanupGDI 00559 * 00560 * Cleanup all the GDI global objects used in USERK 00561 * 00562 * History: 00563 * 29-Jan-1998 clupu Created. 00564 \***************************************************************************/ 00565 VOID CleanupGDI( 00566 VOID) 00567 { 00568 int i; 00569 00570 /* 00571 * Free gpDispInfo stuff 00572 */ 00573 DestroyDC(&gpDispInfo->hdcScreen); 00574 DestroyDC(&gpDispInfo->hdcBits); 00575 DestroyDC(&gpDispInfo->hdcGray); 00576 DestroyDC(&ghdcMem); 00577 DestroyDC(&ghdcMem2); 00578 DestroyDC(&gfade.hdc); 00579 00580 /* 00581 * Free the cache DC stuff before the GRE cleanup. 00582 * Also notice that we call DelayedDestroyCacheDC which 00583 * we usualy call from DestroyProcessInfo. We do it 00584 * here because this is the last WIN32 thread. 00585 */ 00586 DestroyCacheDCEntries(PtiCurrent()); 00587 DestroyCacheDCEntries(NULL); 00588 DelayedDestroyCacheDC(); 00589 00590 UserAssert(gpDispInfo->pdceFirst == NULL); 00591 00592 /* 00593 * Free bitmaps 00594 */ 00595 DestroyBitmap(&gpDispInfo->hbmGray); 00596 DestroyBitmap(&ghbmBits); 00597 DestroyBitmap(&ghbmCaption); 00598 00599 /* 00600 * Cleanup brushes 00601 */ 00602 DestroyBrush(&ghbrHungApp); 00603 DestroyBrush(&gpsi->hbrGray); 00604 DestroyBrush(&ghbrWhite); 00605 DestroyBrush(&ghbrBlack); 00606 00607 for (i = 0; i < COLOR_MAX; i++) { 00608 DestroyBrush(&(SYSHBRUSH(i))); 00609 } 00610 00611 /* 00612 * Cleanup regions 00613 */ 00614 DestroyRegion(&gpDispInfo->hrgnScreen); 00615 DestroyRegion(&ghrgnInvalidSum); 00616 DestroyRegion(&ghrgnVisNew); 00617 DestroyRegion(&ghrgnSWP1); 00618 DestroyRegion(&ghrgnValid); 00619 DestroyRegion(&ghrgnValidSum); 00620 DestroyRegion(&ghrgnInvalid); 00621 DestroyRegion(&ghrgnInv0); 00622 DestroyRegion(&ghrgnInv1); 00623 DestroyRegion(&ghrgnInv2); 00624 DestroyRegion(&ghrgnGDC); 00625 DestroyRegion(&ghrgnSCR); 00626 DestroyRegion(&ghrgnSPB1); 00627 DestroyRegion(&ghrgnSPB2); 00628 DestroyRegion(&ghrgnSW); 00629 DestroyRegion(&ghrgnScrl1); 00630 DestroyRegion(&ghrgnScrl2); 00631 DestroyRegion(&ghrgnScrlVis); 00632 DestroyRegion(&ghrgnScrlSrc); 00633 DestroyRegion(&ghrgnScrlDst); 00634 DestroyRegion(&ghrgnScrlValid); 00635 00636 /* 00637 * Cleanup fonts 00638 */ 00639 DestroyFont(&ghSmCaptionFont); 00640 DestroyFont(&ghMenuFont); 00641 DestroyFont(&ghMenuFontDef); 00642 DestroyFont(&ghStatusFont); 00643 DestroyFont(&ghIconFont); 00644 DestroyFont(&ghFontSys); 00645 00646 /* 00647 * wallpaper stuff. 00648 */ 00649 if (ghpalWallpaper != NULL) { 00650 GreSetPaletteOwner(ghpalWallpaper, OBJECT_OWNER_CURRENT); 00651 GreDeleteObject(ghpalWallpaper); 00652 ghpalWallpaper = NULL; 00653 } 00654 DestroyBitmap(&ghbmWallpaper); 00655 00656 /* 00657 * Unload the video driver 00658 */ 00659 if (gpDispInfo->pmdev) { 00660 DrvDestroyMDEV(gpDispInfo->pmdev); 00661 GreFreePool(gpDispInfo->pmdev); 00662 gpDispInfo->pmdev = NULL; 00663 gpDispInfo->hDev = NULL; 00664 } 00665 00666 /* 00667 * Free the monitor stuff 00668 */ 00669 { 00670 PMONITOR pMonitor; 00671 PMONITOR pMonitorNext; 00672 00673 pMonitor = gpDispInfo->pMonitorFirst; 00674 00675 while (pMonitor != NULL) { 00676 pMonitorNext = pMonitor->pMonitorNext; 00677 DestroyMonitor(pMonitor); 00678 pMonitor = pMonitorNext; 00679 } 00680 00681 UserAssert(gpDispInfo->pMonitorFirst == NULL); 00682 00683 if (gpMonitorCached != NULL) { 00684 DestroyMonitor(gpMonitorCached); 00685 } 00686 } 00687 } 00688 00689 00690 /***************************************************************************\ 00691 * DestroyHandleTableObjects 00692 * 00693 * Destroy any object still in the handle table. 00694 * 00695 \***************************************************************************/ 00696 VOID DestroyHandleTableObjects(VOID) 00697 { 00698 HANDLEENTRY volatile * (*pphe); 00699 PHE pheT; 00700 DWORD i; 00701 00702 /* 00703 * Make sure the handle table was created ! 00704 */ 00705 if (gSharedInfo.aheList == NULL) { 00706 return; 00707 } 00708 00709 /* 00710 * Loop through the table destroying all remaining objects. 00711 */ 00712 pphe = &gSharedInfo.aheList; 00713 00714 for (i = 0; i <= giheLast; i++) { 00715 00716 pheT = (PHE)((*pphe) + i); 00717 00718 if (pheT->bType == TYPE_FREE) 00719 continue; 00720 00721 UserAssert(!(gahti[pheT->bType].bObjectCreateFlags & OCF_PROCESSOWNED) && 00722 !(gahti[pheT->bType].bObjectCreateFlags & OCF_THREADOWNED)); 00723 00724 UserAssert(!(pheT->bFlags & HANDLEF_DESTROY)); 00725 00726 /* 00727 * Destroy the object. 00728 */ 00729 if (pheT->phead->cLockObj > 0) { 00730 00731 RIPMSG1(RIP_ERROR, "pheT %#p still locked !", pheT); 00732 00733 /* 00734 * We're going to die, why bothered by the lock count? 00735 * We're forcing the lockcount to 0, and call the destroy routine. 00736 */ 00737 pheT->phead->cLockObj = 0; 00738 } 00739 HMDestroyUnlockedObject(pheT); 00740 UserAssert(pheT->bType == TYPE_FREE); 00741 } 00742 } 00743 00744 /***************************************************************************\ 00745 * Win32KDriverUnload 00746 * 00747 * Exit point for win32k.sys 00748 * 00749 \***************************************************************************/ 00750 #ifdef TRACE_MAP_VIEWS 00751 extern PWin32Section gpSections; 00752 #endif // TRACE_MAP_VIEWS; 00753 00754 #if DBG 00755 ULONG DriverUnloadExceptionHandler(PEXCEPTION_POINTERS pexi) 00756 { 00757 KdPrint(("\nEXCEPTION IN Win32kDriverUnload !!!\n\n" 00758 "Exception: %#x\n" 00759 "at address: %#p\n" 00760 "flags: %#x\n\n" 00761 "!exr %#p\n" 00762 "!cxr %#p\n\n", 00763 pexi->ExceptionRecord->ExceptionCode, 00764 CONTEXT_TO_PROGRAM_COUNTER(pexi->ContextRecord), 00765 pexi->ExceptionRecord->ExceptionFlags, 00766 pexi->ExceptionRecord, 00767 pexi->ContextRecord)); 00768 00769 return EXCEPTION_EXECUTE_HANDLER; 00770 } 00771 #endif // DBG 00772 00773 VOID Win32KDriverUnload( 00774 IN PDRIVER_OBJECT DriverObject) 00775 { 00776 TRACE_HYDAPI(("Win32KDriverUnload\n")); 00777 00778 #if DBG 00779 /* 00780 * Have a try/except around the driver unload code to catch 00781 * bugs. We need to do this because NtSetSystemInformation which 00782 * smss calls has a try/except when calling the driver entry and 00783 * the driver unload routines which does nothing but returns the 00784 * status code to the caller and doesn't break in the debugger! 00785 * So w/o this try/except here we wouldn't even know we hit 00786 * an AV !!! 00787 */ 00788 try { 00789 #endif // DBG 00790 00791 HYDRA_HINT(HH_DRIVERUNLOAD); 00792 00793 /* 00794 * Cleanup all resources in GRE 00795 */ 00796 MultiUserNtGreCleanup(); 00797 00798 HYDRA_HINT(HH_GRECLEANUP); 00799 00800 /* 00801 * BUG 305965. There might be cases when we end up with DCEs still 00802 * in the list. Go ahead and clean it up here. 00803 */ 00804 if (gpDispInfo != NULL && gpDispInfo->pdceFirst != NULL) { 00805 00806 PDCE pdce; 00807 PDCE pdceNext; 00808 00809 RIPMSG0(RIP_ERROR, "Win32KDriverUnload: the DCE list is not empty !"); 00810 00811 pdce = gpDispInfo->pdceFirst; 00812 00813 while (pdce != NULL) { 00814 pdceNext = pdce->pdceNext; 00815 00816 UserFreePool(pdce); 00817 00818 pdce = pdceNext; 00819 } 00820 gpDispInfo->pdceFirst = NULL; 00821 } 00822 00823 /* 00824 * Cleanup all resources in ntuser 00825 */ 00826 Win32kNtUserCleanup(); 00827 00828 /* 00829 * Cleanup the handle table for any object that is neither process 00830 * owned nor thread owned 00831 */ 00832 DestroyHandleTableObjects(); 00833 00834 00835 HYDRA_HINT(HH_USERKCLEANUP); 00836 00837 #if DBG 00838 HMCleanUpHandleTable(); 00839 #endif 00840 00841 /* 00842 * Free the handle page array 00843 */ 00844 00845 if (gpHandlePages != NULL) { 00846 UserFreePool(gpHandlePages); 00847 gpHandlePages = NULL; 00848 } 00849 00850 if (CsrApiPort != NULL) { 00851 ObDereferenceObject(CsrApiPort); 00852 CsrApiPort = NULL; 00853 } 00854 00855 /* 00856 * destroy the shared memory 00857 */ 00858 if (ghSectionShared != NULL) { 00859 00860 NTSTATUS Status; 00861 00862 /* 00863 * Set gpsi to NULL 00864 */ 00865 gpsi = NULL; 00866 00867 if (gpvSharedBase != NULL) { 00868 Win32HeapDestroy(gpvSharedAlloc); 00869 Status = Win32UnmapViewInSessionSpace(gpvSharedBase); 00870 UserAssert(NT_SUCCESS(Status)); 00871 } 00872 Win32DestroySection(ghSectionShared); 00873 } 00874 00875 CleanupWin32HeapStubs(); 00876 00877 #ifdef TRACE_MAP_VIEWS 00878 #if DBG 00879 UserAssert(gpSections == NULL); 00880 #else 00881 if (gpSections != NULL) { 00882 DbgBreakPoint(); 00883 } 00884 #endif // DBG 00885 #endif // TRACE_MAP_VIEWS 00886 00887 /* 00888 * Cleanup all the user pool allocations by hand 00889 */ 00890 CleanupPoolAllocations(); 00891 00892 CleanUpPoolLimitations(); 00893 CleanUpSections(); 00894 00895 /* 00896 * Cleanup W32 structures. 00897 */ 00898 if (gpW32FastMutex != NULL) { 00899 ExFreePool(gpW32FastMutex); 00900 gpW32FastMutex = NULL; 00901 } 00902 00903 #if DBG 00904 } except (DriverUnloadExceptionHandler(GetExceptionInformation())) { 00905 DbgBreakPoint(); 00906 } 00907 #endif // DBG 00908 00909 return; 00910 UNREFERENCED_PARAMETER(DriverObject); 00911 } 00912 00913 /***************************************************************************\ 00914 * DriverEntry 00915 * 00916 * Entry point needed to initialize win32k.sys 00917 * 00918 \***************************************************************************/ 00919 NTSTATUS DriverEntry( 00920 IN PDRIVER_OBJECT DriverObject, 00921 IN PUNICODE_STRING RegistryPath) 00922 { 00923 PVOID countTable; 00924 NTSTATUS Status = STATUS_SUCCESS; 00925 OBJECT_ATTRIBUTES obja; 00926 UNICODE_STRING strName; 00927 HANDLE hEventFirstSession; 00928 00929 HYDRA_HINT(HH_DRIVERENTRY); 00930 00931 /* 00932 * Find out if this is a remote session 00933 */ 00934 RtlInitUnicodeString(&strName, L"\\UniqueSessionIdEvent"); 00935 00936 InitializeObjectAttributes(&obja, 00937 &strName, 00938 OBJ_CASE_INSENSITIVE, 00939 NULL, 00940 NULL); 00941 00942 Status = ZwCreateEvent(&hEventFirstSession, 00943 EVENT_ALL_ACCESS, 00944 &obja, 00945 SynchronizationEvent, 00946 FALSE); 00947 00948 if (Status == STATUS_OBJECT_NAME_EXISTS || 00949 Status == STATUS_OBJECT_NAME_COLLISION) { 00950 00951 gbRemoteSession = TRUE; 00952 } else { 00953 UserAssert(NT_SUCCESS(Status)); 00954 gbRemoteSession = FALSE; 00955 } 00956 00957 /* 00958 * Set the unload address 00959 */ 00960 DriverObject->DriverUnload = Win32KDriverUnload; 00961 00962 /* 00963 * Initialize data used for the timers. We want to do this really early, 00964 * before any Win32 Timer will be created. We need to be very careful to 00965 * not do anything that will need Win32 initialized yet. 00966 */ 00967 00968 gcmsLastTimer = NtGetTickCount(); 00969 00970 /* 00971 * Initialize the Win32 structures. We need to do this before we create 00972 * any threads. 00973 */ 00974 gpW32FastMutex = ExAllocatePoolWithTag(NonPagedPool, 00975 sizeof(FAST_MUTEX), 00976 TAG_SYSTEM); 00977 if (gpW32FastMutex == NULL) { 00978 Status = STATUS_NO_MEMORY; 00979 goto Failure; 00980 } 00981 ExInitializeFastMutex(gpW32FastMutex); 00982 00983 if (gbRemoteSession) 00984 goto executeAlsoForRemote; 00985 00986 #if !DBG 00987 countTable = NULL; 00988 #else 00989 00990 /* 00991 * Allocate and zero the system service count table. 00992 * Do not use UserAllocPool for this one ! 00993 */ 00994 countTable = (PULONG)ExAllocatePoolWithTag(NonPagedPool, 00995 W32pServiceLimit * sizeof(ULONG), 00996 'llac'); 00997 if (countTable == NULL ) { 00998 Status = STATUS_NO_MEMORY; 00999 goto Failure; 01000 } 01001 01002 RtlZeroMemory(countTable, W32pServiceLimit * sizeof(ULONG)); 01003 #endif // #else DBG 01004 01005 /* 01006 * We only establish the system entry table once for the 01007 * whole system, even though WIN32K.SYS is instanced on a winstation 01008 * basis. This is because the VM changes assure that all loads of 01009 * WIN32K.SYS are at the exact same address, even if a fixup had 01010 * to occur. 01011 */ 01012 UserVerify(KeAddSystemServiceTable(W32pServiceTable, 01013 countTable, 01014 W32pServiceLimit, 01015 W32pArgumentTable, 01016 W32_SERVICE_NUMBER)); 01017 01018 /* 01019 * Initialize the critical section before establishing the callouts so 01020 * we can assume that it's always valid 01021 */ 01022 if (!InitCreateUserCrit()) { 01023 Status = STATUS_NO_MEMORY; 01024 goto Failure; 01025 } 01026 01027 PsEstablishWin32Callouts(W32pProcessCallout, 01028 W32pThreadCallout, 01029 UserGlobalAtomTableCallout, 01030 UserPowerEventCallout, 01031 UserPowerStateCallout, 01032 UserJobCallout, 01033 (PVOID)NtGdiFlushUserBatch); 01034 01035 executeAlsoForRemote: 01036 01037 if (gbRemoteSession) { 01038 01039 if (!InitCreateUserCrit()) { 01040 Status = STATUS_NO_MEMORY; 01041 goto Failure; 01042 } 01043 } 01044 01045 InitSectionTrace(); 01046 01047 InitWin32HeapStubs(); 01048 01049 /* 01050 * Initialize pool limitation array. 01051 */ 01052 InitPoolLimitations(); 01053 01054 #if defined(_X86_) 01055 /* 01056 * Keep our own copy of this to avoid double indirections on probing 01057 */ 01058 Win32UserProbeAddress = *MmUserProbeAddress; 01059 #endif 01060 01061 if ((hModuleWin = MmPageEntireDriver(DriverEntry)) == NULL) { 01062 RIPMSG0(RIP_WARNING, "MmPageEntireDriver failed"); 01063 Status = STATUS_NO_MEMORY; 01064 goto Failure; 01065 } 01066 01067 #if DBG 01068 /* 01069 * Initialize the desktop tracking list 01070 */ 01071 InitializeListHead(&gDesktopList); 01072 /* 01073 * Initialize the gpaThreadLocksArray mechanism 01074 */ 01075 gFreeTLList = gpaThreadLocksArrays[gcThreadLocksArraysAllocated] = 01076 UserAllocPoolZInit(sizeof(TL)*MAX_THREAD_LOCKS, TAG_GLOBALTHREADLOCK); 01077 if (gFreeTLList == NULL) { 01078 Status = STATUS_NO_MEMORY; 01079 goto Failure; 01080 } 01081 InitGlobalThreadLockArray(0); 01082 gcThreadLocksArraysAllocated = 1; 01083 #endif // DBG 01084 01085 if (!InitializeGre()) { 01086 RIPMSG0(RIP_WARNING, "InitializeGre failed"); 01087 Status = STATUS_NO_MEMORY; 01088 goto Failure; 01089 } 01090 01091 Status = Win32UserInitialize(); 01092 01093 if (!NT_SUCCESS(Status)) { 01094 RIPMSG1(RIP_WARNING, "Win32UserInitialize failed with Status %x", 01095 Status); 01096 goto Failure; 01097 } 01098 01099 return STATUS_SUCCESS; 01100 01101 Failure: 01102 01103 RIPMSG1(RIP_WARNING, "Initialization of WIN32K.SYS failed with Status = 0x%x!!!", 01104 Status); 01105 01106 Win32KDriverUnload(NULL); 01107 return Status; 01108 01109 UNREFERENCED_PARAMETER(RegistryPath); 01110 } 01111 01112 /***************************************************************************\ 01113 * xxxAddFontResourceW 01114 * 01115 * 01116 * History: 01117 \***************************************************************************/ 01118 01119 int xxxAddFontResourceW( 01120 LPWSTR lpFile, 01121 FLONG flags, 01122 DESIGNVECTOR *pdv) 01123 { 01124 UNICODE_STRING strFile; 01125 01126 RtlInitUnicodeString(&strFile, lpFile); 01127 01128 /* 01129 * Callbacks leave the critsec, so make sure that we're in it. 01130 */ 01131 01132 return xxxClientAddFontResourceW(&strFile, flags, pdv); 01133 } 01134 01135 /***************************************************************************\ 01136 * LW_DriversInit 01137 * 01138 * 01139 * History: 01140 \***************************************************************************/ 01141 01142 VOID LW_DriversInit(VOID) 01143 { 01144 /* 01145 * Initialize the keyboard typematic rate. 01146 */ 01147 SetKeyboardRate((UINT)gnKeyboardSpeed); 01148 01149 /* 01150 * Adjust VK modification table if not default (type 4) kbd. 01151 */ 01152 if (gKeyboardInfo.KeyboardIdentifier.Type == 3) 01153 gapulCvt_VK = gapulCvt_VK_84; 01154 01155 /* 01156 * Adjust VK modification table for IBM 5576 002/003 keyboard. 01157 */ 01158 if (JAPANESE_KEYBOARD(gKeyboardInfo.KeyboardIdentifier) && 01159 (gKeyboardInfo.KeyboardIdentifier.Subtype == 3)) 01160 gapulCvt_VK = gapulCvt_VK_IBM02; 01161 01162 /* 01163 * Initialize NLS keyboard globals. 01164 */ 01165 NlsKbdInitializePerSystem(); 01166 } 01167 01168 /***************************************************************************\ 01169 * LoadCPUserPreferences 01170 * 01171 * 06/07/96 GerardoB Created 01172 \***************************************************************************/ 01173 BOOL LoadCPUserPreferences(PUNICODE_STRING pProfileUserName) 01174 { 01175 DWORD pdwValue [SPI_BOOLMASKDWORDSIZE]; 01176 DWORD dw; 01177 PPROFILEVALUEINFO ppvi = gpviCPUserPreferences; 01178 01179 UserAssert(1 + SPI_DWORDRANGECOUNT == sizeof(gpviCPUserPreferences) / sizeof(*gpviCPUserPreferences)); 01180 01181 /* 01182 * The first value in gpviCPUserPreferences corresponds to the bit mask 01183 */ 01184 dw = FastGetProfileValue(pProfileUserName, 01185 ppvi->uSection, 01186 ppvi->pwszKeyName, 01187 NULL, 01188 (LPBYTE)pdwValue, 01189 sizeof(*pdwValue) 01190 ); 01191 01192 /* 01193 * Copy only the amount of data read and no more than what we expect 01194 */ 01195 if (dw != 0) { 01196 if (dw > sizeof(gpdwCPUserPreferencesMask)) { 01197 dw = sizeof(gpdwCPUserPreferencesMask); 01198 } 01199 RtlCopyMemory(gpdwCPUserPreferencesMask, pdwValue, dw); 01200 } 01201 01202 ppvi++; 01203 01204 /* 01205 * DWORD values 01206 */ 01207 for (dw = 1; dw < 1 + SPI_DWORDRANGECOUNT; dw++, ppvi++) { 01208 if (FastGetProfileValue(pProfileUserName, 01209 ppvi->uSection, 01210 ppvi->pwszKeyName, 01211 NULL, 01212 (LPBYTE)pdwValue, 01213 sizeof(DWORD) 01214 )) { 01215 01216 ppvi->dwValue = *pdwValue; 01217 } 01218 } 01219 01220 if (gbRemoteSession) { 01221 01222 /* 01223 * Default is w/o UIEFFECTS for remote connections 01224 */ 01225 gpdwCPUserPreferencesMask[0] &= ~0x80000000; 01226 } 01227 01228 /* 01229 * Propagate gpsi flags 01230 */ 01231 PropagetUPBOOLTogpsi(COMBOBOXANIMATION); 01232 PropagetUPBOOLTogpsi(LISTBOXSMOOTHSCROLLING); 01233 PropagetUPBOOLTogpsi(KEYBOARDCUES); 01234 gpsi->bKeyboardPref = TEST_BOOL_ACCF(ACCF_KEYBOARDPREF); 01235 01236 gpsi->uCaretWidth = UP(CARETWIDTH); 01237 01238 PropagetUPBOOLTogpsi(UIEFFECTS); 01239 01240 EnforceColorDependentSettings(); 01241 01242 return TRUE; 01243 } 01244 01245 /***************************************************************************\ 01246 * LW_LoadProfileInitData 01247 * 01248 * Only stuff that gets initialized at boot should go here. Per user settings 01249 * should be initialized in xxxUpdatePerUserSystemParameters. 01250 * 01251 * History: 01252 \***************************************************************************/ 01253 VOID LW_LoadProfileInitData(PUNICODE_STRING pProfileUserName) 01254 { 01255 guDdeSendTimeout = FastGetProfileIntFromID(pProfileUserName, 01256 PMAP_WINDOWSM, 01257 STR_DDESENDTIMEOUT, 01258 0); 01259 } 01260 01261 /***************************************************************************\ 01262 * LW_LoadResources 01263 * 01264 * 01265 * History: 01266 \***************************************************************************/ 01267 01268 VOID LW_LoadResources(PUNICODE_STRING pProfileUserName) 01269 { 01270 WCHAR rgch[4]; 01271 01272 /* 01273 * See if the Mouse buttons need swapping. 01274 */ 01275 FastGetProfileStringFromIDW(pProfileUserName, 01276 PMAP_MOUSE, 01277 STR_SWAPBUTTONS, 01278 szN, 01279 rgch, 01280 sizeof(rgch) / sizeof(WCHAR)); 01281 SYSMET(SWAPBUTTON) = (*rgch == '1' || *rgch == *szY || *rgch == *szy); 01282 01283 /* 01284 * See if we should beep. 01285 */ 01286 FastGetProfileStringFromIDW(pProfileUserName, 01287 PMAP_BEEP, 01288 STR_BEEP, 01289 szY, 01290 rgch, 01291 sizeof(rgch) / sizeof(WCHAR) 01292 ); 01293 01294 SET_OR_CLEAR_PUDF(PUDF_BEEP, (rgch[0] == *szY) || (rgch[0] == *szy)); 01295 01296 /* 01297 * See if we should have extended sounds. 01298 */ 01299 FastGetProfileStringFromIDW(pProfileUserName, 01300 PMAP_BEEP, 01301 STR_EXTENDEDSOUNDS, 01302 szN, 01303 rgch, 01304 sizeof(rgch) / sizeof(WCHAR) 01305 ); 01306 01307 SET_OR_CLEAR_PUDF(PUDF_EXTENDEDSOUNDS, (rgch[0] == *szY || rgch[0] == *szy)); 01308 01309 } 01310 /***************************************************************************\ 01311 * xxxInitWindowStation 01312 * 01313 * History: 01314 * 6-Sep-1996 CLupu Created. 01315 * 21-Jan-98 SamerA Renamed to xxxInitWindowStation since it may leave the 01316 * critical section. 01317 \***************************************************************************/ 01318 01319 BOOL xxxInitWindowStation( 01320 PWINDOWSTATION pwinsta) 01321 { 01322 TL tlName; 01323 PUNICODE_STRING pProfileUserName = CreateProfileUserName(&tlName); 01324 BOOL fRet; 01325 01326 /* 01327 * Load all profile data first 01328 */ 01329 LW_LoadProfileInitData(pProfileUserName); 01330 01331 /* 01332 * Initialize User in a specific order. 01333 */ 01334 LW_DriversInit(); 01335 01336 /* 01337 * This is the initialization from Chicago 01338 */ 01339 if (!(fRet = xxxSetWindowNCMetrics(pProfileUserName, NULL, TRUE, -1))) { 01340 RIPMSG0(RIP_WARNING, "xxxInitWindowStation failed in xxxSetWindowNCMetrics"); 01341 goto Exit; 01342 } 01343 01344 SetMinMetrics(pProfileUserName, NULL); 01345 01346 if (!(fRet = SetIconMetrics(pProfileUserName, NULL))) { 01347 RIPMSG0(RIP_WARNING, "xxxInitWindowStation failed in SetIconMetrics"); 01348 goto Exit; 01349 } 01350 01351 if (!(fRet = FinalUserInit())) { 01352 RIPMSG0(RIP_WARNING, "xxxInitWindowStation failed in FinalUserInit"); 01353 goto Exit; 01354 } 01355 01356 /* 01357 * Initialize the key cache index. 01358 */ 01359 gpsi->dwKeyCache = 1; 01360 01361 Exit: 01362 FreeProfileUserName(pProfileUserName, &tlName); 01363 01364 return fRet; 01365 UNREFERENCED_PARAMETER(pwinsta); 01366 } 01367 01368 /***************************************************************************\ 01369 * CreateTerminalInput 01370 * 01371 * 01372 * History: 01373 * 6-Sep-1996 CLupu Created. 01374 \***************************************************************************/ 01375 01376 BOOL CreateTerminalInput( 01377 PTERMINAL pTerm) 01378 { 01379 UserAssert(pTerm != NULL); 01380 01381 /* 01382 * call to the client side to clean up the [Fonts] section 01383 * of the registry. This will only take significant chunk of time 01384 * if the [Fonts] key changed during since the last boot and if 01385 * there are lots of fonts loaded 01386 */ 01387 ClientFontSweep(); 01388 01389 /* 01390 * Load the standard fonts before we create any DCs. 01391 * At this time we can only add the fonts that do not 01392 * reside on the net. They may be needed by winlogon. 01393 * Our winlogon needs only ms sans serif, but private 01394 * winlogon's may need some other fonts as well. 01395 * The fonts on the net will be added later, right 01396 * after all the net connections have been restored. 01397 */ 01398 /* 01399 * This call should be made in UserInitialize. 01400 */ 01401 xxxLW_LoadFonts(FALSE); 01402 01403 /* 01404 * Initialize the input system. 01405 */ 01406 if (!xxxInitInput(pTerm)) 01407 return FALSE; 01408 01409 return TRUE; 01410 } 01411 01412 /***************************************************************************\ 01413 * LW_LoadSomeStrings 01414 * 01415 * This function loads a bunch of strings from the string table 01416 * into DS or INTDS. This is done to keep all localizable strings 01417 * in the .RC file. 01418 * 01419 * History: 01420 \***************************************************************************/ 01421 01422 VOID LW_LoadSomeStrings(VOID) 01423 { 01424 int i, str, id; 01425 01426 /* 01427 * MessageBox strings 01428 */ 01429 for (i = 0, str = STR_OK, id = IDOK; i<MAX_MB_STRINGS; i++, str++, id++) { 01430 gpsi->MBStrings[i].uStr = str; 01431 gpsi->MBStrings[i].uID = id; 01432 ServerLoadString(hModuleWin, str, gpsi->MBStrings[i].szName, sizeof(gpsi->MBStrings[i].szName) / sizeof(WCHAR)); 01433 } 01434 01435 /* 01436 * Tooltips strings 01437 */ 01438 ServerLoadString(hModuleWin, STR_MIN, gszMIN, sizeof(gszMIN) / sizeof(WCHAR)); 01439 ServerLoadString(hModuleWin, STR_MAX, gszMAX, sizeof(gszMAX) / sizeof(WCHAR)); 01440 ServerLoadString(hModuleWin, STR_RESUP, gszRESUP, sizeof(gszRESUP) / sizeof(WCHAR)); 01441 ServerLoadString(hModuleWin, STR_RESDOWN,gszRESDOWN,sizeof(gszRESDOWN)/ sizeof(WCHAR)); 01442 /* Commented out due to TandyT ... 01443 * ServerLoadString(hModuleWin, STR_SMENU, gszSMENU, sizeof(gszSMENU) / sizeof(WCHAR)); 01444 */ 01445 ServerLoadString(hModuleWin, STR_SCLOSE, gszSCLOSE, sizeof(gszSCLOSE) / sizeof(WCHAR)); 01446 } 01447 01448 /***************************************************************************\ 01449 * CI_GetClrVal 01450 * 01451 * Returns the RGB value of a color string from WIN.INI. 01452 * 01453 * History: 01454 \***************************************************************************/ 01455 01456 DWORD CI_GetClrVal( 01457 LPWSTR p) 01458 { 01459 LPBYTE pl; 01460 BYTE val; 01461 int i; 01462 DWORD clrval; 01463 01464 /* 01465 * Initialize the pointer to the LONG return value. Set to MSB. 01466 */ 01467 pl = (LPBYTE)&clrval; 01468 01469 /* 01470 * Get three goups of numbers seprated by non-numeric characters. 01471 */ 01472 for (i = 0; i < 3; i++) { 01473 01474 /* 01475 * Skip over any non-numeric characters. 01476 */ 01477 while (!(*p >= TEXT('0') && *p <= TEXT('9'))) 01478 p++; 01479 01480 /* 01481 * Get the next series of digits. 01482 */ 01483 val = 0; 01484 while (*p >= TEXT('0') && *p <= TEXT('9')) 01485 val = (BYTE)((int)val*10 + (int)*p++ - '0'); 01486 01487 /* 01488 * HACK! Store the group in the LONG return value. 01489 */ 01490 *pl++ = val; 01491 } 01492 01493 /* 01494 * Force the MSB to zero for GDI. 01495 */ 01496 *pl = 0; 01497 01498 return clrval; 01499 } 01500 01501 /***************************************************************************\ 01502 * xxxODI_ColorInit 01503 * 01504 * 01505 * History: 01506 \***************************************************************************/ 01507 01508 VOID xxxODI_ColorInit(PUNICODE_STRING pProfileUserName) 01509 { 01510 int i; 01511 COLORREF colorVals[STR_COLOREND - STR_COLORSTART + 1]; 01512 INT colorIndex[STR_COLOREND - STR_COLORSTART + 1]; 01513 WCHAR rgchValue[25]; 01514 01515 #if COLOR_MAX - (STR_COLOREND - STR_COLORSTART + 1) 01516 #error "COLOR_MAX value conflicts with STR_COLOREND - STR_COLORSTART" 01517 #endif 01518 01519 /* 01520 * Now set up default color values. 01521 * These are not in display drivers anymore since we just want default. 01522 * The real values are stored in the profile. 01523 */ 01524 RtlCopyMemory(gpsi->argbSystem, gargbInitial, sizeof(COLORREF) * COLOR_MAX); 01525 01526 for (i = 0; i < COLOR_MAX; i++) { 01527 01528 /* 01529 * Try to find a WIN.INI entry for this object. 01530 */ 01531 *rgchValue = 0; 01532 FastGetProfileStringFromIDW(pProfileUserName, 01533 PMAP_COLORS, 01534 STR_COLORSTART + i, 01535 szNull, 01536 rgchValue, 01537 sizeof(rgchValue) / sizeof(WCHAR) 01538 ); 01539 01540 /* 01541 * Convert the string into an RGB value and store. Use the 01542 * default RGB value if the profile value is missing. 01543 */ 01544 colorVals[i] = *rgchValue ? CI_GetClrVal(rgchValue) : gpsi->argbSystem[i]; 01545 colorIndex[i] = i; 01546 } 01547 01548 xxxSetSysColors(pProfileUserName, 01549 i, 01550 colorIndex, 01551 colorVals, 01552 SSCF_FORCESOLIDCOLOR | SSCF_SETMAGICCOLORS); 01553 } 01554 01555 01556 /***********************************************************************\ 01557 * _LoadIconsAndCursors 01558 * 01559 * Used in parallel with the client side - LoadIconsAndCursors. This 01560 * assumes that only the default configurable cursors and icons have 01561 * been loaded and searches the global icon cache for them to fixup 01562 * the default resource ids to standard ids. Also initializes the 01563 * rgsys arrays allowing SYSCUR and SYSICO macros to work. 01564 * 01565 * 14-Oct-1995 SanfordS created. 01566 \***********************************************************************/ 01567 01568 VOID _LoadCursorsAndIcons(VOID) 01569 { 01570 PCURSOR pcur; 01571 int i; 01572 01573 pcur = gpcurFirst; 01574 01575 /* 01576 * Only CSR can call this (and only once). 01577 */ 01578 if (PsGetCurrentProcess() != gpepCSRSS) { 01579 return; 01580 } 01581 01582 HYDRA_HINT(HH_LOADCURSORS); 01583 01584 while (pcur) { 01585 01586 UserAssert(!IS_PTR(pcur->strName.Buffer)); 01587 01588 switch (pcur->rt) { 01589 case RT_ICON: 01590 UserAssert((LONG_PTR)pcur->strName.Buffer >= OIC_FIRST_DEFAULT); 01591 01592 UserAssert((LONG_PTR)pcur->strName.Buffer < 01593 OIC_FIRST_DEFAULT + COIC_CONFIGURABLE); 01594 01595 i = PTR_TO_ID(pcur->strName.Buffer) - OIC_FIRST_DEFAULT; 01596 pcur->strName.Buffer = (LPWSTR)gasysico[i].Id; 01597 01598 if (pcur->CURSORF_flags & CURSORF_LRSHARED) { 01599 UserAssert(gasysico[i].spcur == NULL); 01600 Lock(&gasysico[i].spcur, pcur); 01601 } else { 01602 UserAssert(gpsi->hIconSmWindows == NULL); 01603 UserAssert((int)pcur->cx == SYSMET(CXSMICON)); 01604 /* 01605 * The special small winlogo icon is not shared. 01606 */ 01607 gpsi->hIconSmWindows = PtoH(pcur); 01608 } 01609 break; 01610 01611 case RT_CURSOR: 01612 UserAssert((LONG_PTR)pcur->strName.Buffer >= OCR_FIRST_DEFAULT); 01613 01614 UserAssert((LONG_PTR)pcur->strName.Buffer < 01615 OCR_FIRST_DEFAULT + COCR_CONFIGURABLE); 01616 01617 i = PTR_TO_ID(pcur->strName.Buffer) - OCR_FIRST_DEFAULT; 01618 pcur->strName.Buffer = (LPWSTR)gasyscur[i].Id; 01619 Lock(&gasyscur[i].spcur ,pcur); 01620 break; 01621 01622 default: 01623 UserAssert(FALSE); // should be nothing in the cache but these! 01624 } 01625 01626 pcur = pcur->pcurNext; 01627 } 01628 01629 /* 01630 * copy special icon handles to global spots for later use. 01631 */ 01632 gpsi->hIcoWindows = PtoH(SYSICO(WINLOGO)); 01633 } 01634 01635 /***********************************************************************\ 01636 * UnloadCursorsAndIcons 01637 * 01638 * used for cleanup of win32k 01639 * 01640 * Dec-10-1997 clupu created. 01641 \***********************************************************************/ 01642 VOID UnloadCursorsAndIcons( 01643 VOID) 01644 { 01645 PCURSOR pcur; 01646 int ind; 01647 01648 TRACE_HYDAPI(("UnloadCursorsAndIcons\n")); 01649 01650 /* 01651 * unlock the icons 01652 */ 01653 for (ind = 0; ind < COIC_CONFIGURABLE; ind++) { 01654 pcur = gasysico[ind].spcur; 01655 01656 if (pcur == NULL) 01657 continue; 01658 01659 pcur->head.ppi = PpiCurrent(); 01660 Unlock(&gasysico[ind].spcur); 01661 } 01662 01663 /* 01664 * unlock the cursors 01665 */ 01666 for (ind = 0; ind < COCR_CONFIGURABLE; ind++) { 01667 pcur = gasyscur[ind].spcur; 01668 01669 if (pcur == NULL) 01670 continue; 01671 01672 pcur->head.ppi = PpiCurrent(); 01673 Unlock(&gasyscur[ind].spcur); 01674 } 01675 } 01676 01677 /***********************************************************************\ 01678 * xxxUpdateSystemCursorsFromRegistry 01679 * 01680 * Reloads all customizable cursors from the registry. 01681 * 01682 * 09-Oct-1995 SanfordS created. 01683 \***********************************************************************/ 01684 01685 VOID xxxUpdateSystemCursorsFromRegistry(PUNICODE_STRING pProfileUserName) 01686 { 01687 int i; 01688 UNICODE_STRING strName; 01689 TCHAR szFilename[MAX_PATH]; 01690 PCURSOR pCursor; 01691 UINT LR_flags; 01692 01693 for (i = 0; i < COCR_CONFIGURABLE; i++) { 01694 01695 FastGetProfileStringFromIDW(pProfileUserName, 01696 PMAP_CURSORS, 01697 gasyscur[i].StrId, 01698 TEXT(""), 01699 szFilename, 01700 sizeof(szFilename) / sizeof(TCHAR)); 01701 01702 if (*szFilename) { 01703 RtlInitUnicodeString(&strName, szFilename); 01704 LR_flags = LR_LOADFROMFILE | LR_ENVSUBST; 01705 } else { 01706 RtlInitUnicodeStringOrId(&strName, 01707 MAKEINTRESOURCE(i + OCR_FIRST_DEFAULT)); 01708 LR_flags = LR_ENVSUBST; 01709 } 01710 01711 pCursor = xxxClientLoadImage(&strName, 01712 0, 01713 IMAGE_CURSOR, 01714 0, 01715 0, 01716 LR_flags, 01717 FALSE); 01718 01719 if (pCursor) { 01720 zzzSetSystemImage(pCursor, gasyscur[i].spcur); 01721 } else { 01722 RIPMSG1(RIP_WARNING, "Unable to update cursor. id=%x.", i + OCR_FIRST_DEFAULT); 01723 01724 } 01725 } 01726 } 01727 01728 /***********************************************************************\ 01729 * xxxUpdateSystemIconsFromRegistry 01730 * 01731 * Reloads all customizable icons from the registry. 01732 * 01733 * 09-Oct-1995 SanfordS created. 01734 \***********************************************************************/ 01735 VOID xxxUpdateSystemIconsFromRegistry(PUNICODE_STRING pProfileUserName) 01736 { 01737 int i; 01738 UNICODE_STRING strName; 01739 TCHAR szFilename[MAX_PATH]; 01740 PCURSOR pCursor; 01741 UINT LR_flags; 01742 01743 for (i = 0; i < COIC_CONFIGURABLE; i++) { 01744 01745 FastGetProfileStringFromIDW(pProfileUserName, 01746 PMAP_ICONS, 01747 gasysico[i].StrId, 01748 TEXT(""), 01749 szFilename, 01750 sizeof(szFilename) / sizeof(TCHAR)); 01751 01752 if (*szFilename) { 01753 RtlInitUnicodeString(&strName, szFilename); 01754 LR_flags = LR_LOADFROMFILE | LR_ENVSUBST; 01755 } else { 01756 RtlInitUnicodeStringOrId(&strName, 01757 MAKEINTRESOURCE(i + OIC_FIRST_DEFAULT)); 01758 LR_flags = LR_ENVSUBST; 01759 } 01760 01761 pCursor = xxxClientLoadImage(&strName, 01762 0, 01763 IMAGE_ICON, 01764 0, 01765 0, 01766 LR_flags, 01767 FALSE); 01768 01769 RIPMSG3(RIP_VERBOSE, 01770 (!IS_PTR(strName.Buffer)) ? 01771 "%#.8lx = Loaded id %ld" : 01772 "%#.8lx = Loaded file %ws for id %ld", 01773 PtoH(pCursor), 01774 strName.Buffer, 01775 i + OIC_FIRST_DEFAULT); 01776 01777 if (pCursor) { 01778 zzzSetSystemImage(pCursor, gasysico[i].spcur); 01779 } else { 01780 RIPMSG1(RIP_WARNING, "Unable to update icon. id=%ld", i + OIC_FIRST_DEFAULT); 01781 } 01782 01783 /* 01784 * update the small winlogo icon which is referenced by gpsi. 01785 * Seems like we should load the small version for all configurable 01786 * icons anyway. What is needed is for CopyImage to support 01787 * copying of images loaded from files with LR_COPYFROMRESOURCE 01788 * allowing a reaload of the bits. (SAS) 01789 */ 01790 if (i == OIC_WINLOGO_DEFAULT - OIC_FIRST_DEFAULT) { 01791 01792 PCURSOR pCurSys = HtoP(gpsi->hIconSmWindows); 01793 01794 if (pCurSys != NULL) { 01795 pCursor = xxxClientLoadImage(&strName, 01796 0, 01797 IMAGE_ICON, 01798 SYSMET(CXSMICON), 01799 SYSMET(CYSMICON), 01800 LR_flags, 01801 FALSE); 01802 01803 if (pCursor) { 01804 zzzSetSystemImage(pCursor, pCurSys); 01805 } else { 01806 RIPMSG0(RIP_WARNING, "Unable to update small winlogo icon."); 01807 } 01808 } 01809 } 01810 } 01811 } 01812 01813 /***************************************************************************\ 01814 * LW_BrushInit 01815 * 01816 * 01817 * History: 01818 \***************************************************************************/ 01819 01820 BOOL LW_BrushInit(VOID) 01821 { 01822 HBITMAP hbmGray; 01823 CONST static WORD patGray[8] = {0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa}; 01824 01825 /* 01826 * Create a gray brush to be used with GrayString 01827 */ 01828 hbmGray = GreCreateBitmap(8, 8, 1, 1, (LPBYTE)patGray); 01829 01830 if (hbmGray == NULL) { 01831 return FALSE; 01832 } 01833 01834 gpsi->hbrGray = GreCreatePatternBrush(hbmGray); 01835 ghbrWhite = GreGetStockObject(WHITE_BRUSH); 01836 ghbrBlack = GreGetStockObject(BLACK_BRUSH); 01837 01838 UserAssert(ghbrWhite != NULL && ghbrBlack != NULL); 01839 01840 if (gpsi->hbrGray == NULL) { 01841 return FALSE; 01842 } 01843 01844 GreDeleteObject(hbmGray); 01845 GreSetBrushOwnerPublic(gpsi->hbrGray); 01846 ghbrHungApp = GreCreateSolidBrush(0); 01847 01848 if (ghbrHungApp == NULL) { 01849 return FALSE; 01850 } 01851 01852 GreSetBrushOwnerPublic(ghbrHungApp); 01853 01854 return TRUE; 01855 } 01856 01857 /***************************************************************************\ 01858 * LW_RegisterWindows 01859 * 01860 * 01861 * History: 01862 \***************************************************************************/ 01863 BOOL LW_RegisterWindows( 01864 BOOL fSystem) 01865 { 01866 #ifdef HUNGAPP_GHOSTING 01867 #define CCLASSES 9 01868 #else // HUNGAPP_GHOSTING 01869 #define CCLASSES 8 01870 #endif // HUNGAPP_GHOSTING 01871 01872 int i; 01873 WNDCLASSEX wndcls; 01874 01875 CONST static struct { 01876 BOOLEAN fSystem; 01877 BOOLEAN fGlobalClass; 01878 WORD fnid; 01879 UINT style; 01880 WNDPROC lpfnWndProc; 01881 int cbWndExtra; 01882 BOOL fNormalCursor : 1; 01883 HBRUSH hbrBackground; 01884 LPCTSTR lpszClassName; 01885 } rc[CCLASSES] = { 01886 { TRUE, TRUE, FNID_DESKTOP, 01887 CS_DBLCLKS, 01888 (WNDPROC)xxxDesktopWndProc, 01889 sizeof(DESKWND) - sizeof(WND), 01890 TRUE, 01891 (HBRUSH)(COLOR_BACKGROUND + 1), 01892 DESKTOPCLASS}, 01893 { TRUE, FALSE, FNID_SWITCH, 01894 CS_VREDRAW | CS_HREDRAW | CS_SAVEBITS, 01895 (WNDPROC)xxxSwitchWndProc, 01896 sizeof(SWITCHWND) - sizeof(WND), 01897 TRUE, 01898 NULL, 01899 SWITCHWNDCLASS}, 01900 { TRUE, FALSE, FNID_MENU, 01901 CS_DBLCLKS | CS_SAVEBITS, 01902 (WNDPROC)xxxMenuWindowProc, 01903 sizeof(PPOPUPMENU), 01904 FALSE, 01905 (HBRUSH)(COLOR_MENU + 1), 01906 MENUCLASS}, 01907 { FALSE, FALSE, FNID_SCROLLBAR, 01908 CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS | CS_PARENTDC, 01909 (WNDPROC)xxxSBWndProc, 01910 sizeof(SBWND) - sizeof(WND), 01911 TRUE, 01912 NULL, 01913 L"ScrollBar"}, 01914 { TRUE, FALSE, FNID_TOOLTIP, 01915 CS_DBLCLKS | CS_SAVEBITS, 01916 (WNDPROC)xxxTooltipWndProc, 01917 sizeof(TOOLTIPWND) - sizeof(WND), 01918 TRUE, 01919 NULL, 01920 TOOLTIPCLASS}, 01921 { TRUE, TRUE, FNID_ICONTITLE, 01922 0, 01923 (WNDPROC)xxxDefWindowProc, 01924 0, 01925 TRUE, 01926 NULL, 01927 ICONTITLECLASS}, 01928 { FALSE, FALSE, 0, 01929 0, 01930 (WNDPROC)xxxEventWndProc, 01931 sizeof(PSVR_INSTANCE_INFO), 01932 FALSE, 01933 NULL, 01934 L"DDEMLEvent"}, 01935 #ifdef HUNGAPP_GHOSTING 01936 { TRUE, TRUE, 0, 01937 0, 01938 (WNDPROC)xxxGhostWndProc, 01939 0, 01940 TRUE, 01941 NULL, 01942 L"Ghost"}, 01943 #endif // HUNGAPP_GHOSTING 01944 { TRUE, TRUE, 0, 01945 0, 01946 (WNDPROC)xxxDefWindowProc, 01947 4, 01948 TRUE, 01949 NULL, 01950 L"Message"} 01951 }; 01952 01953 01954 /* 01955 * All other classes are registered via the table. 01956 */ 01957 wndcls.cbClsExtra = 0; 01958 wndcls.hInstance = hModuleWin; 01959 wndcls.hIcon = NULL; 01960 wndcls.hIconSm = NULL; 01961 wndcls.lpszMenuName = NULL; 01962 01963 for (i = 0; i < CCLASSES; i++) { 01964 if (fSystem && !rc[i].fSystem) { 01965 continue; 01966 } 01967 wndcls.style = rc[i].style; 01968 wndcls.lpfnWndProc = rc[i].lpfnWndProc; 01969 wndcls.cbWndExtra = rc[i].cbWndExtra; 01970 wndcls.hCursor = rc[i].fNormalCursor ? PtoH(SYSCUR(ARROW)) : NULL; 01971 wndcls.hbrBackground= rc[i].hbrBackground; 01972 wndcls.lpszClassName= rc[i].lpszClassName; 01973 01974 if (InternalRegisterClassEx(&wndcls, 01975 rc[i].fnid, 01976 CSF_SERVERSIDEPROC | CSF_WIN40COMPAT) == NULL) { 01977 RIPMSG0(RIP_WARNING, "LW_RegisterWindows: InternalRegisterClassEx failed"); 01978 return FALSE; 01979 } 01980 01981 if (fSystem && rc[i].fGlobalClass) { 01982 if (InternalRegisterClassEx(&wndcls, 01983 rc[i].fnid, 01984 CSF_SERVERSIDEPROC | CSF_SYSTEMCLASS | CSF_WIN40COMPAT) == NULL) { 01985 01986 RIPMSG0(RIP_WARNING, "LW_RegisterWindows: InternalRegisterClassEx failed"); 01987 return FALSE; 01988 } 01989 } 01990 } 01991 return TRUE; 01992 } 01993 01994 /**********************************************************\ 01995 * VOID vCheckMMInstance 01996 * 01997 * History: 01998 * Feb-06-98 Xudong Wu [TessieW] 01999 * Wrote it. 02000 \**********************************************************/ 02001 VOID vCheckMMInstance( 02002 LPWSTR pchSrch, 02003 DESIGNVECTOR *pdv) 02004 { 02005 LPWSTR pKeyName; 02006 WCHAR szName[MAX_PATH], *pszName = szName; 02007 WCHAR szCannonicalName[MAX_PATH]; 02008 ULONG NumAxes; 02009 02010 pdv->dvNumAxes = 0; 02011 pKeyName = pchSrch; 02012 while (*pKeyName && (*pKeyName++ != TEXT('('))) 02013 ; 02014 02015 if (*pKeyName){ 02016 if (!_wcsicmp(pKeyName, L"OpenType)")) 02017 { 02018 pKeyName = pchSrch; 02019 while(*pKeyName != TEXT('(')) 02020 *pszName++ = *pKeyName++; 02021 *pszName = 0; 02022 02023 GreGetCannonicalName(szName, szCannonicalName, &NumAxes, pdv); 02024 } 02025 } 02026 } 02027 02028 02029 /***************************************************************************\ 02030 * LW_LoadFonts 02031 * 02032 * 02033 * History: 02034 \***************************************************************************/ 02035 02036 BOOL bEnumerateRegistryFonts( 02037 BOOL bPermanent) 02038 { 02039 LPWSTR pchKeys; 02040 LPWSTR pchSrch; 02041 LPWSTR lpchT; 02042 int cchReal; 02043 int cFont; 02044 WCHAR szFontFile[MAX_PATH]; 02045 FLONG flAFRW; 02046 TL tlPool; 02047 DESIGNVECTOR dv; 02048 02049 WCHAR szPreloadFontFile[MAX_PATH]; 02050 02051 /* 02052 * if we are not just checking whether this is a registry font 02053 */ 02054 flAFRW = (bPermanent ? AFRW_ADD_LOCAL_FONT : AFRW_ADD_REMOTE_FONT); 02055 02056 cchReal = (int)FastGetProfileKeysW(NULL, 02057 PMAP_FONTS, 02058 TEXT("vgasys.fnt"), 02059 &pchKeys 02060 ); 02061 02062 #if DBG 02063 if (cchReal == 0) { 02064 RIPMSG0(RIP_WARNING, "bEnumerateRegistryFonts: cchReal is 0"); 02065 } 02066 #endif 02067 02068 if (!pchKeys) 02069 return FALSE; 02070 02071 ThreadLockPool(PtiCurrent(), pchKeys, &tlPool); 02072 02073 /* 02074 * If we got here first, we load the fonts until this preload font. 02075 * Preload fonts will be used by Winlogon UI, then we need to make sure 02076 * the font is available when Winlogon UI comes up. 02077 */ 02078 if (LastFontLoaded == -1) { 02079 FastGetProfileStringW(NULL, PMAP_WINLOGON, 02080 TEXT("PreloadFontFile"), 02081 TEXT("Micross.ttf"), 02082 szPreloadFontFile, 02083 MAX_PATH 02084 ); 02085 RIPMSG1(RIP_VERBOSE, "Winlogon preload font = %ws\n",szPreloadFontFile); 02086 } 02087 02088 /* 02089 * Now we have all the key names in pchKeys. 02090 */ 02091 if (cchReal != 0) { 02092 02093 cFont = 0; 02094 pchSrch = pchKeys; 02095 02096 do { 02097 // check to see whether this is MM(OpenType) instance 02098 vCheckMMInstance(pchSrch, &dv); 02099 02100 if (FastGetProfileStringW(NULL, 02101 PMAP_FONTS, 02102 pchSrch, 02103 TEXT("vgasys.fon"), 02104 szFontFile, 02105 (MAX_PATH - 5) 02106 )) { 02107 02108 /* 02109 * If no extension, append ".FON" 02110 */ 02111 for (lpchT = szFontFile; *lpchT != TEXT('.'); lpchT++) { 02112 02113 if (*lpchT == 0) { 02114 wcscat(szFontFile, TEXT(".FON")); 02115 break; 02116 } 02117 } 02118 02119 if ((cFont > LastFontLoaded) && bPermanent) { 02120 02121 /* 02122 * skip if we've already loaded this local font. 02123 */ 02124 xxxAddFontResourceW(szFontFile, flAFRW, dv.dvNumAxes ? &dv : NULL); 02125 } 02126 02127 if (!bPermanent) 02128 xxxAddFontResourceW(szFontFile, flAFRW, dv.dvNumAxes ? &dv : NULL); 02129 02130 if ((LastFontLoaded == -1) && 02131 /* 02132 * Compare with the font file name from Registry. 02133 */ 02134 (!_wcsnicmp(szFontFile, szPreloadFontFile, wcslen(szPreloadFontFile))) && 02135 (bPermanent)) { 02136 02137 /* 02138 * On the first time through only load up until 02139 * ms sans serif for winlogon to use. Later we 02140 * will spawn off a thread which loads the remaining 02141 * fonts in the background. 02142 */ 02143 LastFontLoaded = cFont; 02144 02145 ThreadUnlockAndFreePool(PtiCurrent(), &tlPool); 02146 return TRUE; 02147 } 02148 } 02149 02150 /* 02151 * Skip to the next key. 02152 */ 02153 while (*pchSrch++); 02154 02155 cFont += 1; 02156 02157 } while (pchSrch < ((LPWSTR)pchKeys + cchReal)); 02158 } 02159 02160 /* 02161 * signal that all the permanent fonts have been loaded 02162 */ 02163 bPermanentFontsLoaded = TRUE; 02164 02165 ThreadUnlockAndFreePool(PtiCurrent(), &tlPool); 02166 02167 if (!bPermanent) 02168 SET_PUDF(PUDF_FONTSARELOADED); 02169 02170 return TRUE; 02171 02172 } 02173 02174 extern VOID CloseFNTCache(VOID); 02175 02176 /***************************************************************************\ 02177 * xxxLW_LoadFonts 02178 * 02179 * 02180 * History: 02181 \***************************************************************************/ 02182 02183 02184 VOID xxxLW_LoadFonts( 02185 BOOL bRemote) 02186 { 02187 BOOL bTimeOut = FALSE; 02188 02189 if(bRemote) { 02190 02191 LARGE_INTEGER li; 02192 ULONG ulWaitCount = 0; 02193 02194 /* 02195 * Before we can proceed we must make sure that all the permanent 02196 * fonts have been loaded. 02197 */ 02198 02199 while (!bPermanentFontsLoaded) { 02200 02201 if (!gbRemoteSession || (ulWaitCount < MAX_TIME_OUT)) 02202 { 02203 LeaveCrit(); 02204 li.QuadPart = (LONGLONG)-10000 * CMSSLEEP; 02205 KeDelayExecutionThread(KernelMode, FALSE, &li); 02206 EnterCrit(); 02207 } 02208 else 02209 { 02210 bTimeOut = TRUE; 02211 break; 02212 } 02213 02214 ulWaitCount++; 02215 } 02216 02217 if (!bTimeOut) 02218 { 02219 if (!bEnumerateRegistryFonts(FALSE)) 02220 return; // nothing you can do 02221 02222 // add remote type 1 fonts. 02223 02224 ClientLoadRemoteT1Fonts(); 02225 } 02226 02227 } else { 02228 02229 xxxAddFontResourceW(L"marlett.ttf", AFRW_ADD_LOCAL_FONT,NULL); 02230 if (!bEnumerateRegistryFonts(TRUE)) 02231 return; // nothing you can do 02232 02233 // add local type 1 fonts. 02234 02235 // only want to be called once, the second time after ms sans serif was installed 02236 02237 if (bPermanentFontsLoaded) 02238 { 02239 ClientLoadLocalT1Fonts(); 02240 02241 // All the fonts loaded, we can close the FNTCache 02242 02243 CloseFNTCache(); 02244 } 02245 02246 } 02247 } 02248 02249 /***************************************************************************\ 02250 * FinalUserInit 02251 * 02252 * History: 02253 \***************************************************************************/ 02254 BOOL FinalUserInit(VOID) 02255 { 02256 HBITMAP hbm; 02257 PPCLS ppcls; 02258 02259 gpDispInfo->hdcGray = GreCreateCompatibleDC(gpDispInfo->hdcScreen); 02260 02261 if (gpDispInfo->hdcGray == NULL) { 02262 return FALSE; 02263 } 02264 02265 GreSelectFont(gpDispInfo->hdcGray, ghFontSys); 02266 GreSetDCOwner(gpDispInfo->hdcGray, OBJECT_OWNER_PUBLIC); 02267 02268 gpDispInfo->cxGray = gpsi->cxSysFontChar * GRAY_STRLEN; 02269 gpDispInfo->cyGray = gpsi->cySysFontChar + 2; 02270 gpDispInfo->hbmGray = GreCreateBitmap(gpDispInfo->cxGray, gpDispInfo->cyGray, 1, 1, 0L); 02271 02272 if (gpDispInfo->hbmGray == NULL) { 02273 return FALSE; 02274 } 02275 02276 GreSetBitmapOwner(gpDispInfo->hbmGray, OBJECT_OWNER_PUBLIC); 02277 02278 hbm = GreSelectBitmap(gpDispInfo->hdcGray, gpDispInfo->hbmGray); 02279 GreSetTextColor(gpDispInfo->hdcGray, 0x00000000L); 02280 GreSelectBrush(gpDispInfo->hdcGray, gpsi->hbrGray); 02281 GreSetBkMode(gpDispInfo->hdcGray, OPAQUE); 02282 GreSetBkColor(gpDispInfo->hdcGray, 0x00FFFFFFL); 02283 02284 /* 02285 * Setup menu animation dc for global menu state 02286 */ 02287 if (MNSetupAnimationDC(&gMenuState)) { 02288 GreSetDCOwner(gMenuState.hdcAni, OBJECT_OWNER_PUBLIC); 02289 } else { 02290 RIPMSG0(RIP_WARNING, "FinalUserInit: MNSetupAnimationDC failed"); 02291 } 02292 02293 /* 02294 * Creation of the queue registers some bogus classes. Get rid 02295 * of them and register the real ones. 02296 */ 02297 ppcls = &PpiCurrent()->pclsPublicList; 02298 while ((*ppcls != NULL) && !((*ppcls)->style & CS_GLOBALCLASS)) 02299 DestroyClass(ppcls); 02300 02301 return TRUE; 02302 } 02303 02304 /***************************************************************************\ 02305 * InitializeClientPfnArrays 02306 * 02307 * This routine gets called by the client to tell the kernel where 02308 * its important functions can be located. 02309 * 02310 * 18-Apr-1995 JimA Created. 02311 \***************************************************************************/ 02312 02313 NTSTATUS InitializeClientPfnArrays( 02314 CONST PFNCLIENT *ppfnClientA, 02315 CONST PFNCLIENT *ppfnClientW, 02316 CONST PFNCLIENTWORKER *ppfnClientWorker, 02317 HANDLE hModUser) 02318 { 02319 static BOOL fHaveClientPfns = FALSE; 02320 /* 02321 * Remember client side addresses in this global structure. These are 02322 * always constant, so this is ok. Note that if either of the 02323 * pointers are invalid, the exception will be handled in 02324 * the thunk and fHaveClientPfns will not be set. 02325 */ 02326 if (!fHaveClientPfns && ppfnClientA != NULL) { 02327 if (!ISCSRSS()) { 02328 RIPMSG0(RIP_WARNING, "InitializeClientPfnArrays failed !csrss"); 02329 return STATUS_UNSUCCESSFUL; 02330 } 02331 gpsi->apfnClientA = *ppfnClientA; 02332 gpsi->apfnClientW = *ppfnClientW; 02333 gpsi->apfnClientWorker = *ppfnClientWorker; 02334 02335 gpfnwp[ICLS_BUTTON] = gpsi->apfnClientW.pfnButtonWndProc; 02336 gpfnwp[ICLS_EDIT] = gpsi->apfnClientW.pfnDefWindowProc; 02337 gpfnwp[ICLS_STATIC] = gpsi->apfnClientW.pfnStaticWndProc; 02338 gpfnwp[ICLS_LISTBOX] = gpsi->apfnClientW.pfnListBoxWndProc; 02339 gpfnwp[ICLS_SCROLLBAR] = (PROC)xxxSBWndProc; 02340 gpfnwp[ICLS_COMBOBOX] = gpsi->apfnClientW.pfnComboBoxWndProc; 02341 gpfnwp[ICLS_DESKTOP] = (PROC)xxxDesktopWndProc; 02342 gpfnwp[ICLS_DIALOG] = gpsi->apfnClientW.pfnDialogWndProc; 02343 gpfnwp[ICLS_MENU] = (PROC)xxxMenuWindowProc; 02344 gpfnwp[ICLS_SWITCH] = (PROC)xxxSwitchWndProc; 02345 gpfnwp[ICLS_ICONTITLE] = gpsi->apfnClientW.pfnTitleWndProc; 02346 gpfnwp[ICLS_MDICLIENT] = gpsi->apfnClientW.pfnMDIClientWndProc; 02347 gpfnwp[ICLS_COMBOLISTBOX] = gpsi->apfnClientW.pfnComboListBoxProc; 02348 gpfnwp[ICLS_DDEMLEVENT] = NULL; 02349 gpfnwp[ICLS_DDEMLMOTHER] = NULL; 02350 gpfnwp[ICLS_DDEML16BIT] = NULL; 02351 gpfnwp[ICLS_DDEMLCLIENTA] = NULL; 02352 gpfnwp[ICLS_DDEMLCLIENTW] = NULL; 02353 gpfnwp[ICLS_DDEMLSERVERA] = NULL; 02354 gpfnwp[ICLS_DDEMLSERVERW] = NULL; 02355 gpfnwp[ICLS_IME] = NULL; 02356 gpfnwp[ICLS_TOOLTIP] = (PROC)xxxTooltipWndProc; 02357 02358 /* 02359 * Change this assert when new classes are added. 02360 */ 02361 UserAssert(ICLS_MAX == ICLS_TOOLTIP+1); 02362 02363 hModClient = hModUser; 02364 fHaveClientPfns = TRUE; 02365 } 02366 #if DBG 02367 /* 02368 * BradG - Verify that user32.dll on the client side has loaded 02369 * at the correct address. If not, do an RIPMSG. 02370 */ 02371 02372 if((ppfnClientA != NULL) && 02373 (gpsi->apfnClientA.pfnButtonWndProc != ppfnClientA->pfnButtonWndProc)) 02374 RIPMSG0(RIP_ERROR, "Client side user32.dll not loaded at same address."); 02375 #endif 02376 02377 return STATUS_SUCCESS; 02378 } 02379 02380 /***************************************************************************\ 02381 * GetKbdLangSwitch 02382 * 02383 * read the kbd language hotkey setting - if any - from the registry and set 02384 * LangToggle[] appropriately. 02385 * 02386 * values are: 02387 * 1 : VK_MENU (this is the default) 02388 * 2 : VK_CONTROL 02389 * 3 : none 02390 * History: 02391 \***************************************************************************/ 02392 02393 BOOL GetKbdLangSwitch(PUNICODE_STRING pProfileUserName) 02394 { 02395 DWORD dwToggle; 02396 BOOL bStatus = TRUE; 02397 LCID lcid; 02398 02399 dwToggle = FastGetProfileIntW(pProfileUserName, 02400 PMAP_UKBDLAYOUTTOGGLE, 02401 TEXT("Hotkey"), 02402 1); 02403 02404 gbGraveKeyToggle = FALSE; 02405 02406 switch (dwToggle) { 02407 case 4: 02408 /* 02409 * Grave accent keyboard switch for thai locales 02410 */ 02411 ZwQueryDefaultLocale(FALSE, &lcid); 02412 gbGraveKeyToggle = (PRIMARYLANGID(lcid) == LANG_THAI) ? TRUE : FALSE; 02413 /* 02414 * fall through (intentional) and disable the ctrl/alt toggle mechanism 02415 */ 02416 case 3: 02417 gLangToggle[0].bVkey = 0; 02418 gLangToggle[0].bScan = 0; 02419 break; 02420 02421 case 2: 02422 gLangToggle[0].bVkey = VK_CONTROL; 02423 break; 02424 02425 default: 02426 gLangToggle[0].bVkey = VK_MENU; 02427 break; 02428 } 02429 02430 return bStatus; 02431 } 02432 02433 /***************************************************************************\ 02434 * xxxUpdatePerUserSystemParameters 02435 * 02436 * Called by winlogon to set Window system parameters to the current user's 02437 * profile. 02438 * 02439 * != 0 is failure. 02440 * 02441 * 18-Sep-1992 IanJa Created. 02442 * 18-Nov-1993 SanfordS Moved more winlogon init code to here for speed. 02443 \***************************************************************************/ 02444 02445 BOOL xxxUpdatePerUserSystemParameters( 02446 HANDLE hToken, 02447 BOOL bUserLoggedOn) 02448 { 02449 int i; 02450 HANDLE hKey; 02451 DWORD dwFontSmoothing; 02452 BOOL fDragFullWindows; 02453 TL tlName; 02454 PUNICODE_STRING pProfileUserName = NULL; 02455 02456 02457 static struct { 02458 UINT idSection; 02459 UINT id; 02460 UINT idRes; 02461 UINT def; 02462 } spi[] = { 02463 { PMAP_DESKTOP, SPI_SETSCREENSAVETIMEOUT, STR_SCREENSAVETIMEOUT, 0 }, 02464 { PMAP_DESKTOP, SPI_SETSCREENSAVEACTIVE, STR_SCREENSAVEACTIVE, 0 }, 02465 { PMAP_DESKTOP, SPI_SETDRAGHEIGHT, STR_DRAGHEIGHT, 4 }, 02466 { PMAP_DESKTOP, SPI_SETDRAGWIDTH, STR_DRAGWIDTH, 4 }, 02467 { PMAP_DESKTOP, SPI_SETWHEELSCROLLLINES, STR_WHEELSCROLLLINES, 3 }, 02468 { PMAP_KEYBOARD, SPI_SETKEYBOARDDELAY, STR_KEYDELAY, 0 }, 02469 { PMAP_KEYBOARD, SPI_SETKEYBOARDSPEED, STR_KEYSPEED, 15 }, 02470 { PMAP_MOUSE, SPI_SETDOUBLECLICKTIME, STR_DBLCLKSPEED, 500 }, 02471 { PMAP_MOUSE, SPI_SETDOUBLECLKWIDTH, STR_DOUBLECLICKWIDTH, 4 }, 02472 { PMAP_MOUSE, SPI_SETDOUBLECLKHEIGHT, STR_DOUBLECLICKHEIGHT, 4 }, 02473 { PMAP_MOUSE, SPI_SETSNAPTODEFBUTTON, STR_SNAPTO, 0 }, 02474 { PMAP_WINDOWSU, SPI_SETMENUDROPALIGNMENT, STR_MENUDROPALIGNMENT, 0 }, 02475 { PMAP_INPUTMETHOD, SPI_SETSHOWIMEUI, STR_SHOWIMESTATUS, 1 }, 02476 }; 02477 02478 PROFINTINFO apii[] = { 02479 { PMAP_MOUSE, (LPWSTR)STR_MOUSETHRESH1, 6, &gMouseThresh1 }, 02480 { PMAP_MOUSE, (LPWSTR)STR_MOUSETHRESH2, 10, &gMouseThresh2 }, 02481 { PMAP_MOUSE, (LPWSTR)STR_MOUSESPEED, 1, &gMouseSpeed }, 02482 { PMAP_DESKTOP, (LPWSTR)STR_MENUSHOWDELAY, 400, &gdtMNDropDown }, 02483 { PMAP_DESKTOP, (LPWSTR)STR_DRAGFULLWINDOWS, 2, &fDragFullWindows }, 02484 { PMAP_DESKTOP, (LPWSTR)STR_FASTALTTABROWS, 3, &gnFastAltTabRows }, 02485 { PMAP_DESKTOP, (LPWSTR)STR_FASTALTTABCOLUMNS, 7, &gnFastAltTabColumns }, 02486 { PMAP_DESKTOP, (LPWSTR)STR_MAXLEFTOVERLAPCHARS, 3, &(gpsi->wMaxLeftOverlapChars) }, 02487 { PMAP_DESKTOP, (LPWSTR)STR_MAXRIGHTOVERLAPCHARS, 3, &(gpsi->wMaxRightOverlapChars) }, 02488 { PMAP_DESKTOP, (LPWSTR)STR_FONTSMOOTHING, 0, &dwFontSmoothing }, 02489 { PMAP_INPUTMETHOD, (LPWSTR)STR_HEXNUMPAD, 0, &gfEnableHexNumpad }, 02490 { 0, NULL, 0, NULL } 02491 }; 02492 02493 UserAssert(IsWinEventNotifyDeferredOK()); 02494 02495 UNREFERENCED_PARAMETER(hToken); 02496 02497 /* 02498 * Make sure the caller is the logon process 02499 */ 02500 if (GetCurrentProcessId() != gpidLogon) { 02501 RIPMSG0(RIP_WARNING, "Access denied in xxxUpdatePerUserSystemParameters"); 02502 return FALSE; 02503 } 02504 02505 pProfileUserName = CreateProfileUserName(&tlName); 02506 02507 /* 02508 * Check for new policy. 02509 */ 02510 CheckDesktopPolicyChange(pProfileUserName); 02511 02512 /* 02513 * Get the timeout for low level hooks from the registry 02514 */ 02515 FastGetProfileValue(pProfileUserName, 02516 PMAP_DESKTOP, 02517 (LPWSTR)STR_LLHOOKSTIMEOUT, 02518 NULL, 02519 (LPBYTE)&gnllHooksTimeout, 02520 sizeof(int) 02521 ); 02522 02523 /* 02524 * Control Panel User Preferences 02525 */ 02526 LoadCPUserPreferences(pProfileUserName); 02527 02528 /* 02529 * Set syscolors from registry. 02530 */ 02531 02532 xxxODI_ColorInit(pProfileUserName); 02533 02534 LW_LoadResources(pProfileUserName); 02535 02536 /* 02537 * This is the initialization from Chicago 02538 */ 02539 xxxSetWindowNCMetrics(pProfileUserName, NULL, TRUE, -1); // Colors must be set first 02540 SetMinMetrics(pProfileUserName, NULL); 02541 SetIconMetrics(pProfileUserName, NULL); 02542 02543 /* 02544 * Read the keyboard layout switching hot key 02545 */ 02546 GetKbdLangSwitch(pProfileUserName); 02547 02548 /* 02549 * Set the default thread locale for the system based on the value 02550 * in the current user's registry profile. 02551 */ 02552 ZwSetDefaultLocale( TRUE, 0 ); 02553 02554 /* 02555 * Set the default UI language based on the value in the current 02556 * user's registry profile. 02557 */ 02558 ZwSetDefaultUILanguage(0); 02559 02560 /* 02561 * And then Get it. 02562 */ 02563 ZwQueryDefaultUILanguage(&(gpsi->UILangID)); 02564 02565 02566 /* 02567 * Destroy the desktop system menus, so that they're recreated with 02568 * the correct UI language if the current user's UI language is different 02569 * from the previous one. This is done by finding the interactive 02570 * window station and destroying all its desktops's system menus. 02571 */ 02572 if (grpWinStaList != NULL) { 02573 PDESKTOP pdesk; 02574 PMENU pmenu; 02575 02576 UserAssert(!(grpWinStaList->dwWSF_Flags & WSF_NOIO)); 02577 for (pdesk = grpWinStaList->rpdeskList; pdesk != NULL; pdesk = pdesk->rpdeskNext) { 02578 if (pdesk->spmenuSys != NULL) { 02579 pmenu = pdesk->spmenuSys; 02580 if (UnlockDesktopSysMenu(&pdesk->spmenuSys)) 02581 _DestroyMenu(pmenu); 02582 } 02583 if (pdesk->spmenuDialogSys != NULL) { 02584 pmenu = pdesk->spmenuDialogSys; 02585 if (UnlockDesktopSysMenu(&pdesk->spmenuDialogSys)) 02586 _DestroyMenu(pmenu); 02587 } 02588 } 02589 } 02590 02591 xxxUpdateSystemCursorsFromRegistry(pProfileUserName); 02592 02593 /* 02594 * desktop Pattern now. Note no parameters. It just goes off 02595 * and reads win.ini and sets the desktop pattern. 02596 */ 02597 xxxSystemParametersInfo(SPI_SETDESKPATTERN, (UINT)-1, 0L, 0); // 265 version 02598 02599 /* 02600 * Initialize IME show status 02601 */ 02602 if (bUserLoggedOn) { 02603 gfIMEShowStatus = IMESHOWSTATUS_NOTINITIALIZED; 02604 } 02605 02606 /* 02607 * now go set a bunch of random values from the win.ini file. 02608 */ 02609 for (i = 0; i < ARRAY_SIZE(spi); i++) { 02610 02611 xxxSystemParametersInfo( 02612 spi[i].id, 02613 FastGetProfileIntFromID(pProfileUserName, 02614 spi[i].idSection, 02615 spi[i].idRes, 02616 spi[i].def 02617 ), 02618 0L, 02619 0 02620 ); 02621 } 02622 02623 /* 02624 * read profile integers and do any fixups 02625 */ 02626 FastGetProfileIntsW(pProfileUserName, apii); 02627 02628 if (gnFastAltTabColumns < 2) 02629 gnFastAltTabColumns = 7; 02630 02631 if (gnFastAltTabRows < 1) 02632 gnFastAltTabRows = 3; 02633 02634 /* 02635 * If this is the first time the user logs on, set the DragFullWindows 02636 * to the default. If we have an accelerated device, enable full drag. 02637 */ 02638 if (fDragFullWindows == 2) { 02639 02640 LPWSTR pwszd = L"%d"; 02641 WCHAR szTemp[40]; 02642 WCHAR szDragFullWindows[40]; 02643 02644 SET_OR_CLEAR_PUDF( 02645 PUDF_DRAGFULLWINDOWS, 02646 GreGetDeviceCaps(gpDispInfo->hdcScreen, BLTALIGNMENT) == 0); 02647 02648 if (bUserLoggedOn) { 02649 swprintf(szTemp, pwszd, TEST_BOOL_PUDF(PUDF_DRAGFULLWINDOWS)); 02650 02651 ServerLoadString(hModuleWin, 02652 STR_DRAGFULLWINDOWS, 02653 szDragFullWindows, 02654 sizeof(szDragFullWindows) / sizeof(WCHAR)); 02655 02656 FastWriteProfileStringW(pProfileUserName, 02657 PMAP_DESKTOP, 02658 szDragFullWindows, 02659 szTemp); 02660 } 02661 } else { 02662 SET_OR_CLEAR_PUDF(PUDF_DRAGFULLWINDOWS, fDragFullWindows); 02663 } 02664 02665 /* 02666 * !!!LATER!!! (adams) See if the following profile retrievals can't 02667 * be done in the "spi" array above (e.g. SPI_SETSNAPTO). 02668 */ 02669 02670 /* 02671 * Set mouse settings 02672 */ 02673 gMouseSensitivity = FastGetProfileIntFromID(pProfileUserName,PMAP_MOUSE, STR_MOUSESENSITIVITY, MOUSE_SENSITIVITY_DEFAULT); 02674 if ((gMouseSensitivity < MOUSE_SENSITIVITY_MIN) || (gMouseSensitivity > MOUSE_SENSITIVITY_MAX)) { 02675 gMouseSensitivity = MOUSE_SENSITIVITY_DEFAULT ; 02676 } 02677 gMouseSensitivityFactor = CalculateMouseSensitivity(gMouseSensitivity) ; 02678 02679 _SetCaretBlinkTime(FastGetProfileIntFromID(pProfileUserName,PMAP_DESKTOP, STR_BLINK, 500)); 02680 02681 /* 02682 * Font Information 02683 */ 02684 GreSetFontEnumeration( FastGetProfileIntW(pProfileUserName,PMAP_TRUETYPE, TEXT("TTOnly"), FALSE)); 02685 02686 /* 02687 * Mouse tracking variables 02688 */ 02689 gcxMouseHover = FastGetProfileIntFromID(pProfileUserName,PMAP_MOUSE, STR_MOUSEHOVERWIDTH, SYSMET(CXDOUBLECLK)); 02690 gcyMouseHover = FastGetProfileIntFromID(pProfileUserName,PMAP_MOUSE, STR_MOUSEHOVERHEIGHT, SYSMET(CYDOUBLECLK)); 02691 gdtMouseHover = FastGetProfileIntFromID(pProfileUserName,PMAP_MOUSE, STR_MOUSEHOVERTIME, gdtMNDropDown); 02692 02693 /* 02694 * Window animation 02695 */ 02696 SET_OR_CLEAR_PUDF(PUDF_ANIMATE, 02697 FastGetProfileIntFromID(pProfileUserName,PMAP_METRICS, STR_MINANIMATE, TRUE)); 02698 02699 /* 02700 * Initial Keyboard state: ScrollLock, NumLock and CapsLock state; 02701 * global (per-user) kbd layout attributes (such as ShiftLock/CapsLock) 02702 */ 02703 UpdatePerUserKeyboardIndicators(pProfileUserName); 02704 02705 gdwKeyboardAttributes = KLL_GLOBAL_ATTR_FROM_KLF(FastGetProfileDwordW(pProfileUserName,PMAP_UKBDLAYOUT, L"Attributes", 0)); 02706 02707 xxxUpdatePerUserAccessPackSettings(pProfileUserName); 02708 02709 /* 02710 * If we successfully opened this, we assume we have a network. 02711 */ 02712 if (hKey = OpenCacheKeyEx(NULL, PMAP_NETWORK, KEY_READ, NULL)) { 02713 RIPMSG0(RIP_WARNING | RIP_NONAME, ""); 02714 SYSMET(NETWORK) = RNC_NETWORKS; 02715 02716 ZwClose(hKey); 02717 } 02718 02719 SYSMET(NETWORK) |= RNC_LOGON; 02720 02721 /* 02722 * Font smoothing 02723 */ 02724 UserAssert ((dwFontSmoothing == 0) || (dwFontSmoothing == FE_AA_ON)); 02725 GreSetFontEnumeration( dwFontSmoothing | FE_SET_AA ); 02726 02727 /* 02728 * Desktop Build Number Painting 02729 */ 02730 if (USER_SHARED_DATA->SystemExpirationDate.QuadPart || gfUnsignedDrivers) { 02731 gdwCanPaintDesktop = 1; 02732 } else { 02733 gdwCanPaintDesktop = FastGetProfileDwordW(pProfileUserName, PMAP_DESKTOP, L"PaintDesktopVersion", 0); 02734 } 02735 02736 FreeProfileUserName(pProfileUserName, &tlName); 02737 return TRUE; 02738 } 02739 02740 /* 02741 * Called by InitOemXlateTables via SFI_INITANSIOEM 02742 */ 02743 void InitAnsiOem(PCHAR pOemToAnsi, PCHAR pAnsiToOem) { 02744 02745 UserAssert(gpsi); 02746 UserAssert(pOemToAnsi); 02747 UserAssert(pAnsiToOem); 02748 02749 try { 02750 ProbeForRead(pOemToAnsi, NCHARS, sizeof(BYTE)); 02751 ProbeForRead(pAnsiToOem, NCHARS, sizeof(BYTE)); 02752 02753 RtlCopyMemory(gpsi->acOemToAnsi, pOemToAnsi, NCHARS); 02754 RtlCopyMemory(gpsi->acAnsiToOem, pAnsiToOem, NCHARS); 02755 02756 02757 } except (W32ExceptionHandler(FALSE, RIP_WARNING)) { 02758 } 02759 } 02760 02761 /***************************************************************************\ 02762 * RegisterLPK 02763 * 02764 * Called by InitializeLpkHooks on the client side after an LPK is 02765 * loaded for the current process. 02766 * 02767 * 05-Nov-1996 GregoryW Created. 02768 \***************************************************************************/ 02769 VOID RegisterLPK( 02770 DWORD dwLpkEntryPoints) 02771 { 02772 PpiCurrent()->dwLpkEntryPoints = dwLpkEntryPoints; 02773 } 02774 02775 /***************************************************************************\ 02776 * Enforce color-depth dependent settings on systems with less 02777 * then 256 colors. 02778 * 02779 * 2/13/1998 vadimg created 02780 \***************************************************************************/ 02781 02782 void EnforceColorDependentSettings(void) 02783 { 02784 if (gpDispInfo->fAnyPalette) { 02785 gbDisableAlpha = TRUE; 02786 } else if (GreGetDeviceCaps(gpDispInfo->hdcScreen, NUMCOLORS) == -1) { 02787 gbDisableAlpha = FALSE; 02788 } else { 02789 gbDisableAlpha = TRUE; 02790 } 02791 } 02792 02793 #if DBG 02794 void InitGlobalThreadLockArray(DWORD dwIndex) 02795 { 02796 PTL pTLArray = gpaThreadLocksArrays[dwIndex]; 02797 int i; 02798 for (i = 0; i < MAX_THREAD_LOCKS-1; i++) { 02799 pTLArray[i].next = &pTLArray[i+1]; 02800 } 02801 pTLArray[MAX_THREAD_LOCKS-1].next = NULL; 02802 } 02803 #endif // DBG 02804

Generated on Sat May 15 19:40:22 2004 for test by doxygen 1.3.7