Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

3236 lines
93 KiB

  1. /****************************** Module Header ******************************\
  2. * Module Name: init.c
  3. *
  4. * Copyright (c) 1985 - 1999, Microsoft Corporation
  5. *
  6. * This module contains all the init code for win32k.sys.
  7. *
  8. * History:
  9. * 18-Sep-1990 DarrinM Created.
  10. \***************************************************************************/
  11. #include "precomp.h"
  12. #pragma hdrstop
  13. #if DBG
  14. LIST_ENTRY gDesktopList;
  15. #endif
  16. PVOID gpCountTable;
  17. //
  18. // External references
  19. //
  20. extern PVOID *apObjects;
  21. extern PKWAIT_BLOCK gWaitBlockArray;
  22. extern PVOID UserAtomTableHandle;
  23. extern PKTIMER gptmrWD;
  24. extern UNICODE_STRING* gpastrSetupExe;
  25. extern WCHAR* glpSetupPrograms;
  26. extern PHANDLEPAGE gpHandlePages;
  27. extern PBWL pbwlCache;
  28. //
  29. // Forward references
  30. //
  31. #if DBG
  32. VOID InitGlobalThreadLockArray(
  33. DWORD dwIndex);
  34. #endif
  35. VOID CheckLUIDDosDevicesEnabled(
  36. PBOOL result);
  37. /*
  38. * Local Constants.
  39. */
  40. #define GRAY_STRLEN 40
  41. /*
  42. * Globals local to this file only.
  43. */
  44. BOOL bPermanentFontsLoaded;
  45. /*
  46. * Globals shared with W32
  47. */
  48. CONST ULONG W32ProcessSize = sizeof(PROCESSINFO);
  49. CONST ULONG W32ProcessTag = TAG_PROCESSINFO;
  50. CONST ULONG W32ThreadSize = sizeof(THREADINFO);
  51. CONST ULONG W32ThreadTag = TAG_THREADINFO;
  52. PFAST_MUTEX gpW32FastMutex;
  53. NTSTATUS
  54. DriverEntry(
  55. IN PDRIVER_OBJECT DriverObject,
  56. IN PUNICODE_STRING RegistryPath);
  57. #pragma alloc_text(INIT, DriverEntry)
  58. NTSTATUS Win32UserInitialize(VOID);
  59. #if defined(_X86_)
  60. ULONG Win32UserProbeAddress;
  61. #endif
  62. /*
  63. * holds the result of "Are LUID DosDevices maps enabled?"
  64. * TRUE - LUID DosDevices are enabled
  65. * FALSE - LUID DosDevices are not enabled
  66. */
  67. ULONG gLUIDDeviceMapsEnabled;
  68. VOID FreeSMS(PSMS psms);
  69. VOID FreeImeHotKeys(VOID);
  70. extern PPAGED_LOOKASIDE_LIST SMSLookaside;
  71. extern PPAGED_LOOKASIDE_LIST QEntryLookaside;
  72. /*
  73. * Max time is 10 minutes. The count is 10 min * 60 sec * 4 for 250 ms.
  74. */
  75. #define MAX_TIME_OUT (10 * 60 * 4)
  76. /***************************************************************************\
  77. * Win32kNtUserCleanup
  78. *
  79. * History:
  80. * 5-Jan-1997 CLupu Created.
  81. \***************************************************************************/
  82. BOOL Win32kNtUserCleanup(
  83. VOID)
  84. {
  85. int i;
  86. TRACE_HYDAPI(("Win32kNtUserCleanup: Cleanup Resources\n"));
  87. if (gpresUser != NULL) {
  88. EnterCrit();
  89. }
  90. DbgDumpTrackedDesktops(TRUE);
  91. /*
  92. * Anything in this list must be cleaned up when threads go away.
  93. */
  94. UserAssert(gpbwlList == NULL);
  95. UserAssert(gpWinEventHooks == NULL);
  96. UserAssert(gpScancodeMap == NULL);
  97. /*
  98. * Free IME hotkeys.
  99. */
  100. FreeImeHotKeys();
  101. /*
  102. * Free the wallpaper name string.
  103. */
  104. if (gpszWall != NULL) {
  105. UserFreePool(gpszWall);
  106. gpszWall = NULL;
  107. }
  108. /*
  109. * Free the hung redraw stuff.
  110. */
  111. if (gpvwplHungRedraw != NULL) {
  112. UserFreePool(gpvwplHungRedraw);
  113. gpvwplHungRedraw = NULL;
  114. }
  115. /*
  116. * Free the arrary of setup app names.
  117. */
  118. if (gpastrSetupExe) {
  119. UserFreePool(gpastrSetupExe);
  120. gpastrSetupExe = NULL;
  121. }
  122. if (glpSetupPrograms) {
  123. UserFreePool(glpSetupPrograms);
  124. glpSetupPrograms = NULL;
  125. }
  126. /*
  127. * Free the cached window list.
  128. */
  129. if (pbwlCache != NULL) {
  130. UserFreePool(pbwlCache);
  131. pbwlCache = NULL;
  132. }
  133. /*
  134. * Free outstanding timers.
  135. */
  136. while (gptmrFirst != NULL) {
  137. FreeTimer(gptmrFirst);
  138. }
  139. if (gptmrWD) {
  140. KeCancelTimer(gptmrWD);
  141. UserFreePool(gptmrWD);
  142. gptmrWD = NULL;
  143. }
  144. if (gptmrMaster) {
  145. KeCancelTimer(gptmrMaster);
  146. UserFreePool(gptmrMaster);
  147. gptmrMaster = NULL;
  148. }
  149. /*
  150. * Cleanup monitors and windows layout snapshots
  151. */
  152. CleanupMonitorsAndWindowsSnapShot();
  153. /*
  154. * Cleanup PnP input device synchronization event.
  155. */
  156. if (gpEventPnPWainting != NULL) {
  157. FreeKernelEvent(&gpEventPnPWainting);
  158. }
  159. /*
  160. * Cleanup mouse & kbd change events
  161. */
  162. for (i = 0; i <= DEVICE_TYPE_MAX; i++) {
  163. UserAssert(gptiRit == NULL);
  164. if (aDeviceTemplate[i].pkeHidChange) {
  165. FreeKernelEvent(&aDeviceTemplate[i].pkeHidChange);
  166. }
  167. }
  168. /*
  169. * Cleanup any system thread parameters.
  170. */
  171. CSTCleanupStack(FALSE);
  172. CSTCleanupStack(TRUE);
  173. EnterDeviceInfoListCrit();
  174. #ifdef GENERIC_INPUT
  175. CleanupHidRequestList();
  176. #endif
  177. while (gpDeviceInfoList) {
  178. /*
  179. * Assert that there is no outstanding read or PnP thread waiting
  180. * in RequestDeviceChanges() for this device.
  181. * Clear these flags anyway, to force the free.
  182. */
  183. UserAssert((gpDeviceInfoList->bFlags & GDIF_READING) == 0);
  184. UserAssert((gpDeviceInfoList->usActions & GDIAF_PNPWAITING) == 0);
  185. gpDeviceInfoList->bFlags &= ~GDIF_READING;
  186. gpDeviceInfoList->usActions &= ~GDIAF_PNPWAITING;
  187. FreeDeviceInfo(gpDeviceInfoList);
  188. }
  189. #ifdef TRACK_PNP_NOTIFICATION
  190. CleanupPnpNotificationRecord();
  191. #endif
  192. LeaveDeviceInfoListCrit();
  193. /*
  194. * Cleanup object references
  195. */
  196. if (gThinwireFileObject)
  197. ObDereferenceObject(gThinwireFileObject);
  198. if (gVideoFileObject)
  199. ObDereferenceObject(gVideoFileObject);
  200. if (gpRemoteBeepDevice)
  201. ObDereferenceObject(gpRemoteBeepDevice);
  202. /*
  203. * Cleanup our resources. There should be no threads in here
  204. * when we get called.
  205. */
  206. if (gpresMouseEventQueue) {
  207. ExDeleteResourceLite(gpresMouseEventQueue);
  208. ExFreePool(gpresMouseEventQueue);
  209. gpresMouseEventQueue = NULL;
  210. }
  211. if (gpresDeviceInfoList) {
  212. ExDeleteResourceLite(gpresDeviceInfoList);
  213. ExFreePool(gpresDeviceInfoList);
  214. gpresDeviceInfoList = NULL;
  215. }
  216. if (gpkeMouseData != NULL) {
  217. FreeKernelEvent(&gpkeMouseData);
  218. }
  219. if (apObjects) {
  220. UserFreePool(apObjects);
  221. apObjects = NULL;
  222. }
  223. if (gWaitBlockArray) {
  224. UserFreePool(gWaitBlockArray);
  225. gWaitBlockArray = NULL;
  226. }
  227. if (gpEventDiconnectDesktop != NULL) {
  228. FreeKernelEvent(&gpEventDiconnectDesktop);
  229. }
  230. if (gpevtDesktopDestroyed != NULL) {
  231. FreeKernelEvent(&gpevtDesktopDestroyed);
  232. }
  233. if (gpEventScanGhosts != NULL) {
  234. FreeKernelEvent(&gpEventScanGhosts);
  235. }
  236. if (gpevtVideoportCallout != NULL) {
  237. FreeKernelEvent(&gpevtVideoportCallout);
  238. }
  239. if (UserAtomTableHandle != NULL) {
  240. RtlDestroyAtomTable(UserAtomTableHandle);
  241. UserAtomTableHandle = NULL;
  242. }
  243. /*
  244. * cleanup the SMS lookaside buffer
  245. */
  246. {
  247. PSMS psmsNext;
  248. while (gpsmsList != NULL) {
  249. psmsNext = gpsmsList->psmsNext;
  250. UserAssert(gpsmsList->spwnd == NULL);
  251. FreeSMS(gpsmsList);
  252. gpsmsList = psmsNext;
  253. }
  254. if (SMSLookaside != NULL) {
  255. ExDeletePagedLookasideList(SMSLookaside);
  256. UserFreePool(SMSLookaside);
  257. SMSLookaside = NULL;
  258. }
  259. }
  260. /*
  261. * Let go of the attached queue for hard error handling.
  262. * Do this before we free the Qlookaside !
  263. */
  264. if (gHardErrorHandler.pqAttach != NULL) {
  265. UserAssert(gHardErrorHandler.pqAttach > 0);
  266. UserAssert(gHardErrorHandler.pqAttach->QF_flags & QF_INDESTROY);
  267. FreeQueue(gHardErrorHandler.pqAttach);
  268. gHardErrorHandler.pqAttach = NULL;
  269. }
  270. /*
  271. * Free the cached array of queues
  272. */
  273. FreeCachedQueues();
  274. /*
  275. * cleanup the QEntry lookaside buffer
  276. */
  277. if (QEntryLookaside != NULL) {
  278. ExDeletePagedLookasideList(QEntryLookaside);
  279. UserFreePool(QEntryLookaside);
  280. QEntryLookaside = NULL;
  281. }
  282. /*
  283. * Cleanup the keyboard layouts
  284. */
  285. CleanupKeyboardLayouts();
  286. {
  287. PWOWTHREADINFO pwti;
  288. /*
  289. * Cleanup gpwtiFirst list. This list is supposed to be empty
  290. * at this point. In one case during stress we hit the case where
  291. * it was not empty. The assert is to catch that case in
  292. * checked builds.
  293. */
  294. while (gpwtiFirst != NULL) {
  295. pwti = gpwtiFirst;
  296. gpwtiFirst = pwti->pwtiNext;
  297. UserFreePool(pwti);
  298. }
  299. }
  300. /*
  301. * Cleanup cached SMWP array
  302. */
  303. if (gSMWP.acvr != NULL) {
  304. UserFreePool(gSMWP.acvr);
  305. }
  306. /*
  307. * Free gpsdInitWinSta. This is != NULL only if the session didn't
  308. * make it to UserInitialize.
  309. */
  310. if (gpsdInitWinSta != NULL) {
  311. UserFreePool(gpsdInitWinSta);
  312. gpsdInitWinSta = NULL;
  313. }
  314. if (gpHandleFlagsMutex != NULL) {
  315. ExFreePool(gpHandleFlagsMutex);
  316. gpHandleFlagsMutex = NULL;
  317. }
  318. /*
  319. * Delete the power request structures.
  320. */
  321. DeletePowerRequestList();
  322. if (gpresUser != NULL) {
  323. LeaveCrit();
  324. ExDeleteResourceLite(gpresUser);
  325. ExFreePool(gpresUser);
  326. gpresUser = NULL;
  327. }
  328. #if DBG
  329. /*
  330. * Cleanup the global thread lock structures
  331. */
  332. for (i = 0; i < gcThreadLocksArraysAllocated; i++) {
  333. UserFreePool(gpaThreadLocksArrays[i]);
  334. gpaThreadLocksArrays[i] = NULL;
  335. }
  336. #endif // DBG
  337. #ifdef GENERIC_INPUT
  338. #if DBG
  339. /*
  340. * Checkup the HID related memory leak.
  341. */
  342. CheckupHidLeak();
  343. #endif // DBG
  344. #endif // GENERIC_INPUT
  345. return TRUE;
  346. }
  347. #if DBG
  348. /***************************************************************************\
  349. * TrackAddDesktop
  350. *
  351. * Track desktops for cleanup purposes
  352. *
  353. * History:
  354. * 04-Dec-1997 clupu Created.
  355. \***************************************************************************/
  356. VOID TrackAddDesktop(
  357. PVOID pDesktop)
  358. {
  359. PLIST_ENTRY Entry;
  360. PVOID Atom;
  361. TRACE_HYDAPI(("TrackAddDesktop %#p\n", pDesktop));
  362. Atom = (PVOID)UserAllocPool(sizeof(PVOID) + sizeof(LIST_ENTRY),
  363. TAG_TRACKDESKTOP);
  364. if (Atom) {
  365. *(PVOID*)Atom = pDesktop;
  366. Entry = (PLIST_ENTRY)(((PCHAR)Atom) + sizeof(PVOID));
  367. InsertTailList(&gDesktopList, Entry);
  368. }
  369. }
  370. /***************************************************************************\
  371. * TrackRemoveDesktop
  372. *
  373. * Track desktops for cleanup purposes
  374. *
  375. * History:
  376. * 04-Dec-1997 clupu Created.
  377. \***************************************************************************/
  378. VOID TrackRemoveDesktop(
  379. PVOID pDesktop)
  380. {
  381. PLIST_ENTRY NextEntry;
  382. PVOID Atom;
  383. TRACE_HYDAPI(("TrackRemoveDesktop %#p\n", pDesktop));
  384. NextEntry = gDesktopList.Flink;
  385. while (NextEntry != &gDesktopList) {
  386. Atom = (PVOID)(((PCHAR)NextEntry) - sizeof(PVOID));
  387. if (pDesktop == *(PVOID*)Atom) {
  388. RemoveEntryList(NextEntry);
  389. UserFreePool(Atom);
  390. break;
  391. }
  392. NextEntry = NextEntry->Flink;
  393. }
  394. }
  395. /***************************************************************************\
  396. * DumpTrackedDesktops
  397. *
  398. * Dumps the tracked desktops
  399. *
  400. * History:
  401. * 04-Dec-1997 clupu Created.
  402. \***************************************************************************/
  403. VOID DumpTrackedDesktops(
  404. BOOL bBreak)
  405. {
  406. PLIST_ENTRY NextEntry;
  407. PVOID pdesk;
  408. PVOID Atom;
  409. int nAlive = 0;
  410. TRACE_HYDAPI(("DumpTrackedDesktops\n"));
  411. NextEntry = gDesktopList.Flink;
  412. while (NextEntry != &gDesktopList) {
  413. Atom = (PVOID)(((PCHAR)NextEntry) - sizeof(PVOID));
  414. pdesk = *(PVOID*)Atom;
  415. KdPrint(("pdesk %#p\n", pdesk));
  416. /*
  417. * Restart at the begining of the list since our
  418. * entry got deleted
  419. */
  420. NextEntry = NextEntry->Flink;
  421. nAlive++;
  422. }
  423. if (bBreak && nAlive > 0) {
  424. RIPMSG0(RIP_ERROR, "Desktop objects still around\n");
  425. }
  426. }
  427. #endif // DBG
  428. VOID DestroyRegion(
  429. HRGN* prgn)
  430. {
  431. if (*prgn != NULL) {
  432. GreSetRegionOwner(*prgn, OBJECT_OWNER_CURRENT);
  433. GreDeleteObject(*prgn);
  434. *prgn = NULL;
  435. }
  436. }
  437. VOID DestroyBrush(
  438. HBRUSH* pbr)
  439. {
  440. if (*pbr != NULL) {
  441. //GreSetBrushOwner(*pbr, OBJECT_OWNER_CURRENT);
  442. GreDeleteObject(*pbr);
  443. *pbr = NULL;
  444. }
  445. }
  446. VOID DestroyBitmap(
  447. HBITMAP* pbm)
  448. {
  449. if (*pbm != NULL) {
  450. GreSetBitmapOwner(*pbm, OBJECT_OWNER_CURRENT);
  451. GreDeleteObject(*pbm);
  452. *pbm = NULL;
  453. }
  454. }
  455. VOID DestroyDC(
  456. HDC* phdc)
  457. {
  458. if (*phdc != NULL) {
  459. GreSetDCOwner(*phdc, OBJECT_OWNER_CURRENT);
  460. GreDeleteDC(*phdc);
  461. *phdc = NULL;
  462. }
  463. }
  464. VOID DestroyFont(
  465. HFONT* pfnt)
  466. {
  467. if (*pfnt != NULL) {
  468. GreDeleteObject(*pfnt);
  469. *pfnt = NULL;
  470. }
  471. }
  472. /***************************************************************************\
  473. * CleanupGDI
  474. *
  475. * Cleanup all the GDI global objects used in USERK
  476. *
  477. * History:
  478. * 29-Jan-1998 clupu Created.
  479. \***************************************************************************/
  480. VOID CleanupGDI(
  481. VOID)
  482. {
  483. int i;
  484. /*
  485. * Free gpDispInfo stuff
  486. */
  487. DestroyDC(&gpDispInfo->hdcScreen);
  488. DestroyDC(&gpDispInfo->hdcBits);
  489. DestroyDC(&gpDispInfo->hdcGray);
  490. DestroyDC(&ghdcMem);
  491. DestroyDC(&ghdcMem2);
  492. DestroyDC(&gfade.hdc);
  493. /*
  494. * Free the cache DC stuff before the GRE cleanup.
  495. * Also notice that we call DelayedDestroyCacheDC which
  496. * we usualy call from DestroyProcessInfo. We do it
  497. * here because this is the last WIN32 thread.
  498. */
  499. DestroyCacheDCEntries(PtiCurrent());
  500. DestroyCacheDCEntries(NULL);
  501. DelayedDestroyCacheDC();
  502. UserAssert(gpDispInfo->pdceFirst == NULL);
  503. /*
  504. * Free bitmaps
  505. */
  506. DestroyBitmap(&gpDispInfo->hbmGray);
  507. DestroyBitmap(&ghbmBits);
  508. DestroyBitmap(&ghbmCaption);
  509. /*
  510. * Cleanup brushes
  511. */
  512. DestroyBrush(&ghbrHungApp);
  513. DestroyBrush(&gpsi->hbrGray);
  514. DestroyBrush(&ghbrWhite);
  515. DestroyBrush(&ghbrBlack);
  516. for (i = 0; i < COLOR_MAX; i++) {
  517. DestroyBrush(&(SYSHBRUSH(i)));
  518. }
  519. /*
  520. * Cleanup regions
  521. */
  522. DestroyRegion(&gpDispInfo->hrgnScreen);
  523. DestroyRegion(&ghrgnInvalidSum);
  524. DestroyRegion(&ghrgnVisNew);
  525. DestroyRegion(&ghrgnSWP1);
  526. DestroyRegion(&ghrgnValid);
  527. DestroyRegion(&ghrgnValidSum);
  528. DestroyRegion(&ghrgnInvalid);
  529. DestroyRegion(&ghrgnInv0);
  530. DestroyRegion(&ghrgnInv1);
  531. DestroyRegion(&ghrgnInv2);
  532. DestroyRegion(&ghrgnGDC);
  533. DestroyRegion(&ghrgnSCR);
  534. DestroyRegion(&ghrgnSPB1);
  535. DestroyRegion(&ghrgnSPB2);
  536. DestroyRegion(&ghrgnSW);
  537. DestroyRegion(&ghrgnScrl1);
  538. DestroyRegion(&ghrgnScrl2);
  539. DestroyRegion(&ghrgnScrlVis);
  540. DestroyRegion(&ghrgnScrlSrc);
  541. DestroyRegion(&ghrgnScrlDst);
  542. DestroyRegion(&ghrgnScrlValid);
  543. /*
  544. * Cleanup fonts
  545. */
  546. DestroyFont(&ghSmCaptionFont);
  547. DestroyFont(&ghMenuFont);
  548. DestroyFont(&ghMenuFontDef);
  549. DestroyFont(&ghStatusFont);
  550. DestroyFont(&ghIconFont);
  551. DestroyFont(&ghFontSys);
  552. #ifdef LAME_BUTTON
  553. DestroyFont(&ghLameFont);
  554. #endif // LAME_BUTTON
  555. /*
  556. * wallpaper stuff.
  557. */
  558. if (ghpalWallpaper != NULL) {
  559. GreSetPaletteOwner(ghpalWallpaper, OBJECT_OWNER_CURRENT);
  560. GreDeleteObject(ghpalWallpaper);
  561. ghpalWallpaper = NULL;
  562. }
  563. DestroyBitmap(&ghbmWallpaper);
  564. /*
  565. * Unload the video driver
  566. */
  567. if (gpDispInfo->pmdev) {
  568. DrvDestroyMDEV(gpDispInfo->pmdev);
  569. GreFreePool(gpDispInfo->pmdev);
  570. gpDispInfo->pmdev = NULL;
  571. gpDispInfo->hDev = NULL;
  572. }
  573. /*
  574. * Free the monitor stuff
  575. */
  576. {
  577. PMONITOR pMonitor;
  578. PMONITOR pMonitorNext;
  579. pMonitor = gpDispInfo->pMonitorFirst;
  580. while (pMonitor != NULL) {
  581. pMonitorNext = pMonitor->pMonitorNext;
  582. DestroyMonitor(pMonitor);
  583. pMonitor = pMonitorNext;
  584. }
  585. UserAssert(gpDispInfo->pMonitorFirst == NULL);
  586. if (gpMonitorCached != NULL) {
  587. DestroyMonitor(gpMonitorCached);
  588. }
  589. }
  590. }
  591. /***************************************************************************\
  592. * DestroyHandleTableObjects
  593. *
  594. * Destroy any object still in the handle table.
  595. *
  596. \***************************************************************************/
  597. VOID DestroyHandleFirstPass(PHE phe)
  598. {
  599. /*
  600. * First pass for the handle object destruction.
  601. * Destroy the object, when we can. Otherwise,
  602. * links to the other handle object should be cleared
  603. * so that there will not be a dependency issues
  604. * in the final, second pass.
  605. */
  606. if (phe->phead->cLockObj == 0) {
  607. HMDestroyObject(phe->phead);
  608. } else {
  609. /*
  610. * The object couldn't be destroyed.
  611. */
  612. if (phe->bType == TYPE_KBDLAYOUT) {
  613. PKL pkl = (PKL)phe->phead;
  614. UINT i;
  615. /*
  616. * Clear out the pkf references (they will be
  617. * destroyed cleanly in the second run anyway)
  618. */
  619. pkl->spkf = NULL;
  620. pkl->spkfPrimary = NULL;
  621. if (pkl->pspkfExtra) {
  622. for (i = 0; i < pkl->uNumTbl; ++i) {
  623. pkl->pspkfExtra[i] = NULL;
  624. }
  625. }
  626. pkl->uNumTbl = 0;
  627. }
  628. }
  629. }
  630. VOID DestroyHandleSecondPass(PHE phe)
  631. {
  632. /*
  633. * Destroy the object.
  634. */
  635. if (phe->phead->cLockObj > 0) {
  636. RIPMSG2(RIP_WARNING, "DestroyHandleSecondPass: phe %#p still locked (%d)!", phe, phe->phead->cLockObj);
  637. /*
  638. * We're going to die, why bothered by the lock count?
  639. * We're forcing the lockcount to 0, and call the destroy routine.
  640. */
  641. phe->phead->cLockObj = 0;
  642. }
  643. HMDestroyUnlockedObject(phe);
  644. UserAssert(phe->bType == TYPE_FREE);
  645. }
  646. VOID DestroyHandleTableObjects(VOID)
  647. {
  648. PHE pheT;
  649. DWORD i;
  650. VOID (*HandleDestroyer)(PHE);
  651. #if DBG
  652. DWORD nLeak;
  653. #endif
  654. /*
  655. * Make sure the handle table was created !
  656. */
  657. if (gSharedInfo.aheList == NULL) {
  658. return;
  659. }
  660. /*
  661. * Loop through the table destroying all remaining objects.
  662. */
  663. #if DBG
  664. RIPMSG0(RIP_WARNING, "==== Start handle leak check\n");
  665. nLeak = 0;
  666. for (i = 0; i <= giheLast; ++i) {
  667. pheT = gSharedInfo.aheList + i;
  668. if (pheT->bType != TYPE_FREE) {
  669. ++nLeak;
  670. RIPMSG3(RIP_WARNING, " LEAK -- Handle %p @%p type=%x\n", pheT->phead->h, pheT, pheT->bType);
  671. }
  672. }
  673. RIPMSG1(RIP_WARNING, "==== Handle leak check finished: 0n%d leaks detected.\n", nLeak);
  674. #endif
  675. /*
  676. * First pass: destroy it, or cut the link to other handle based object
  677. */
  678. HandleDestroyer = DestroyHandleFirstPass;
  679. repeat:
  680. for (i = 0; i <= giheLast; ++i) {
  681. pheT = gSharedInfo.aheList + i;
  682. if (pheT->bType == TYPE_FREE)
  683. continue;
  684. UserAssert(!(gahti[pheT->bType].bObjectCreateFlags & OCF_PROCESSOWNED) &&
  685. !(gahti[pheT->bType].bObjectCreateFlags & OCF_THREADOWNED));
  686. UserAssert(!(pheT->bFlags & HANDLEF_DESTROY));
  687. HandleDestroyer(pheT);
  688. }
  689. if (HandleDestroyer == DestroyHandleFirstPass) {
  690. /*
  691. * Go for the second pass.
  692. */
  693. HandleDestroyer = DestroyHandleSecondPass;
  694. goto repeat;
  695. }
  696. }
  697. /***************************************************************************\
  698. * Win32KDriverUnload
  699. *
  700. * Exit point for win32k.sys
  701. *
  702. \***************************************************************************/
  703. #ifdef TRACE_MAP_VIEWS
  704. extern PWin32Section gpSections;
  705. #endif
  706. VOID Win32KDriverUnload(
  707. IN PDRIVER_OBJECT DriverObject)
  708. {
  709. TRACE_HYDAPI(("Win32KDriverUnload\n"));
  710. UNREFERENCED_PARAMETER(DriverObject);
  711. HYDRA_HINT(HH_DRIVERUNLOAD);
  712. /*
  713. * Cleanup all resources in GRE
  714. */
  715. MultiUserNtGreCleanup();
  716. HYDRA_HINT(HH_GRECLEANUP);
  717. /*
  718. * Cleanup CSRSS
  719. */
  720. if (gpepCSRSS) {
  721. ObDereferenceObject(gpepCSRSS);
  722. gpepCSRSS = NULL;
  723. }
  724. /*
  725. * BUG 305965. There might be cases when we end up with DCEs still
  726. * in the list. Go ahead and clean it up here.
  727. */
  728. if (gpDispInfo != NULL && gpDispInfo->pdceFirst != NULL) {
  729. PDCE pdce, pdceNext;
  730. RIPMSG0(RIP_ERROR, "Win32KDriverUnload: the DCE list is not empty");
  731. pdce = gpDispInfo->pdceFirst;
  732. while (pdce != NULL) {
  733. pdceNext = pdce->pdceNext;
  734. UserFreePool(pdce);
  735. pdce = pdceNext;
  736. }
  737. gpDispInfo->pdceFirst = NULL;
  738. }
  739. /*
  740. * Cleanup all resources in ntuser
  741. */
  742. Win32kNtUserCleanup();
  743. /*
  744. * Cleanup the handle table for any object that is neither process
  745. * owned nor thread owned
  746. */
  747. DestroyHandleTableObjects();
  748. HYDRA_HINT(HH_USERKCLEANUP);
  749. #if DBG || FRE_LOCK_RECORD
  750. HMCleanUpHandleTable();
  751. #endif
  752. /*
  753. * Free the handle page array
  754. */
  755. if (gpHandlePages != NULL) {
  756. UserFreePool(gpHandlePages);
  757. gpHandlePages = NULL;
  758. }
  759. if (CsrApiPort != NULL) {
  760. ObDereferenceObject(CsrApiPort);
  761. CsrApiPort = NULL;
  762. }
  763. /*
  764. * Destroy the shared memory.
  765. */
  766. if (ghSectionShared != NULL) {
  767. NTSTATUS Status;
  768. gpsi = NULL;
  769. if (gpvSharedBase != NULL) {
  770. Win32HeapDestroy(gpvSharedAlloc);
  771. Status = Win32UnmapViewInSessionSpace(gpvSharedBase);
  772. UserAssert(NT_SUCCESS(Status));
  773. }
  774. Win32DestroySection(ghSectionShared);
  775. }
  776. CleanupWin32HeapStubs();
  777. #ifdef TRACE_MAP_VIEWS
  778. if (gpSections != NULL) {
  779. FRE_RIPMSG3(RIP_ERROR, "Section being leaked; do \"d%cs 0x%p l%x\" to find stacktrace of the offender and triage against that", (sizeof(ULONG_PTR) == 8 ? 'q' : 'd'), (ULONG_PTR)gpSections + FIELD_OFFSET(Win32Section, trace), ARRAY_SIZE(gpSections->trace));
  780. }
  781. #endif // TRACE_MAP_VIEWS
  782. /*
  783. * Cleanup all the user pool allocations by hand
  784. */
  785. CleanupMediaChange();
  786. CleanupPoolAllocations();
  787. CleanUpPoolLimitations();
  788. CleanUpSections();
  789. /*
  790. * Cleanup W32 structures.
  791. */
  792. if (gpW32FastMutex != NULL) {
  793. ExFreePool(gpW32FastMutex);
  794. gpW32FastMutex = NULL;
  795. }
  796. /*
  797. * Remove and free the service vector.
  798. */
  799. if (!gbRemoteSession) {
  800. KeRemoveSystemServiceTable(W32_SERVICE_NUMBER);
  801. if (gpCountTable != NULL) {
  802. ExFreePool(gpCountTable);
  803. gpCountTable = NULL;
  804. }
  805. }
  806. }
  807. /***************************************************************************\
  808. * DriverEntry
  809. *
  810. * Entry point needed to initialize win32k.sys.
  811. *
  812. \***************************************************************************/
  813. NTSTATUS DriverEntry(
  814. IN PDRIVER_OBJECT DriverObject,
  815. IN PUNICODE_STRING RegistryPath)
  816. {
  817. NTSTATUS Status;
  818. OBJECT_ATTRIBUTES obja;
  819. UNICODE_STRING strName;
  820. HANDLE hEventFirstSession;
  821. UNREFERENCED_PARAMETER(RegistryPath);
  822. HYDRA_HINT(HH_DRIVERENTRY);
  823. gpvWin32kImageBase = DriverObject->DriverStart;
  824. #if DBG
  825. /*
  826. * Initialize the desktop tracking list.
  827. */
  828. InitializeListHead(&gDesktopList);
  829. #endif // DBG
  830. #ifdef GENERIC_INPUT
  831. /*
  832. * Initialize the global HID request list.
  833. */
  834. InitializeHidRequestList();
  835. #endif
  836. /*
  837. * Find out if this is a remote session.
  838. */
  839. RtlInitUnicodeString(&strName, L"\\UniqueSessionIdEvent");
  840. InitializeObjectAttributes(&obja,
  841. &strName,
  842. OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
  843. NULL,
  844. NULL);
  845. Status = ZwCreateEvent(&hEventFirstSession,
  846. EVENT_ALL_ACCESS,
  847. &obja,
  848. SynchronizationEvent,
  849. FALSE);
  850. if (!NT_SUCCESS(Status)) {
  851. if (Status == STATUS_OBJECT_NAME_COLLISION) {
  852. gbRemoteSession = TRUE;
  853. } else {
  854. goto Failure;
  855. }
  856. } else {
  857. gbRemoteSession = FALSE;
  858. }
  859. /*
  860. * Set the unload address
  861. */
  862. DriverObject->DriverUnload = Win32KDriverUnload;
  863. /*
  864. * Initialize data used for the timers. We want to do this really early,
  865. * before any Win32 Timer will be created. We need to be very careful to
  866. * not do anything that will need Win32 initialized yet.
  867. */
  868. gcmsLastTimer = NtGetTickCount();
  869. /*
  870. * Initialize the Win32 structures. We need to do this before we create
  871. * any threads.
  872. */
  873. gpW32FastMutex = ExAllocatePoolWithTag(NonPagedPool,
  874. sizeof(FAST_MUTEX),
  875. TAG_SYSTEM);
  876. if (gpW32FastMutex == NULL) {
  877. Status = STATUS_NO_MEMORY;
  878. goto Failure;
  879. }
  880. ExInitializeFastMutex(gpW32FastMutex);
  881. if (!gbRemoteSession) {
  882. #if DBG
  883. /*
  884. * Allocate and zero the system service count table. Do not use
  885. * UserAllocPool for this allocation.
  886. */
  887. gpCountTable = ExAllocatePoolWithTag(NonPagedPool,
  888. W32pServiceLimit * sizeof(ULONG),
  889. 'llac');
  890. if (gpCountTable == NULL) {
  891. Status = STATUS_NO_MEMORY;
  892. goto Failure;
  893. }
  894. RtlZeroMemory(gpCountTable, W32pServiceLimit * sizeof(ULONG));
  895. #endif
  896. /*
  897. * We only establish the system entry table once for the
  898. * whole system, even though WIN32K.SYS is instanced on a winstation
  899. * basis. This is because the VM changes assure that all loads of
  900. * WIN32K.SYS are at the exact same address, even if a fixup had
  901. * to occur.
  902. */
  903. UserVerify(KeAddSystemServiceTable(W32pServiceTable,
  904. gpCountTable,
  905. W32pServiceLimit,
  906. W32pArgumentTable,
  907. W32_SERVICE_NUMBER));
  908. }
  909. /*
  910. * Initialize the critical section before establishing the callouts so
  911. * we can assume that it's always valid.
  912. */
  913. if (!InitCreateUserCrit()) {
  914. Status = STATUS_NO_MEMORY;
  915. goto Failure;
  916. }
  917. if (!gbRemoteSession) {
  918. WIN32_CALLOUTS_FPNS Win32Callouts;
  919. Win32Callouts.ProcessCallout = W32pProcessCallout;
  920. Win32Callouts.ThreadCallout = W32pThreadCallout;
  921. Win32Callouts.GlobalAtomTableCallout = UserGlobalAtomTableCallout;
  922. Win32Callouts.PowerEventCallout = UserPowerEventCallout;
  923. Win32Callouts.PowerStateCallout = UserPowerStateCallout;
  924. Win32Callouts.JobCallout = UserJobCallout;
  925. Win32Callouts.BatchFlushRoutine = (PVOID)NtGdiFlushUserBatch;
  926. Win32Callouts.DesktopOpenProcedure = (PKWIN32_OBJECT_CALLOUT)DesktopOpenProcedure;
  927. Win32Callouts.DesktopOkToCloseProcedure = (PKWIN32_OBJECT_CALLOUT)OkayToCloseDesktop;
  928. Win32Callouts.DesktopCloseProcedure = (PKWIN32_OBJECT_CALLOUT)UnmapDesktop;
  929. Win32Callouts.DesktopDeleteProcedure = (PKWIN32_OBJECT_CALLOUT)FreeDesktop;
  930. Win32Callouts.WindowStationOkToCloseProcedure = (PKWIN32_OBJECT_CALLOUT)OkayToCloseWindowStation;
  931. Win32Callouts.WindowStationCloseProcedure = (PKWIN32_OBJECT_CALLOUT)DestroyWindowStation;
  932. Win32Callouts.WindowStationDeleteProcedure = (PKWIN32_OBJECT_CALLOUT)FreeWindowStation;
  933. Win32Callouts.WindowStationParseProcedure = (PKWIN32_OBJECT_CALLOUT)ParseWindowStation;
  934. Win32Callouts.WindowStationOpenProcedure = (PKWIN32_OBJECT_CALLOUT)WindowStationOpenProcedure;
  935. PsEstablishWin32Callouts(&Win32Callouts);
  936. }
  937. Status = InitSectionTrace();
  938. if (!NT_SUCCESS(Status)) {
  939. goto Failure;
  940. }
  941. if (!InitWin32HeapStubs()) {
  942. Status = STATUS_NO_MEMORY;
  943. goto Failure;
  944. }
  945. /*
  946. * Initialize pool limitation array.
  947. */
  948. Status = InitPoolLimitations();
  949. if (!NT_SUCCESS(Status)) {
  950. goto Failure;
  951. }
  952. /*
  953. * Create the event that is signaled when a desktop does away
  954. */
  955. gpevtDesktopDestroyed = CreateKernelEvent(SynchronizationEvent, FALSE);
  956. if (gpevtDesktopDestroyed == NULL) {
  957. RIPMSG0(RIP_WARNING, "Couldn't create gpevtDesktopDestroyed");
  958. Status = STATUS_NO_MEMORY;
  959. goto Failure;
  960. }
  961. /*
  962. * Create the event that is signaled when no disconnect/reconnect is pending
  963. */
  964. gpevtVideoportCallout = CreateKernelEvent(NotificationEvent, FALSE);
  965. if (gpevtVideoportCallout == NULL) {
  966. RIPMSG0(RIP_WARNING, "Couldn't create gpevtVideoportCallout");
  967. Status = STATUS_NO_MEMORY;
  968. goto Failure;
  969. }
  970. #if defined(_X86_)
  971. /*
  972. * Keep our own copy of this to avoid double indirections on probing
  973. */
  974. Win32UserProbeAddress = *MmUserProbeAddress;
  975. #endif
  976. if ((hModuleWin = MmPageEntireDriver(DriverEntry)) == NULL) {
  977. RIPMSG0(RIP_WARNING, "MmPageEntireDriver failed");
  978. Status = STATUS_NO_MEMORY;
  979. goto Failure;
  980. }
  981. #if DBG
  982. /*
  983. * Initialize the gpaThreadLocksArray mechanism
  984. */
  985. gFreeTLList = gpaThreadLocksArrays[gcThreadLocksArraysAllocated] =
  986. UserAllocPoolZInit(sizeof(TL)*MAX_THREAD_LOCKS, TAG_GLOBALTHREADLOCK);
  987. if (gFreeTLList == NULL) {
  988. Status = STATUS_NO_MEMORY;
  989. goto Failure;
  990. }
  991. InitGlobalThreadLockArray(0);
  992. gcThreadLocksArraysAllocated = 1;
  993. #endif
  994. if (!InitializeGre()) {
  995. RIPMSG0(RIP_WARNING, "InitializeGre failed");
  996. Status = STATUS_NO_MEMORY;
  997. goto Failure;
  998. }
  999. Status = Win32UserInitialize();
  1000. if (!NT_SUCCESS(Status)) {
  1001. RIPMSG1(RIP_WARNING, "Win32UserInitialize failed with Status %x",
  1002. Status);
  1003. goto Failure;
  1004. }
  1005. /*
  1006. * Remember Session Creation Time. This is used to decide if power
  1007. * messages need to be sent.
  1008. */
  1009. gSessionCreationTime = KeQueryInterruptTime();
  1010. //
  1011. // Initialize rundown protection for WindowStation objects.
  1012. //
  1013. ExInitializeRundownProtection(&gWinstaRunRef);
  1014. /*
  1015. * Check if LUID DosDevices are enabled
  1016. */
  1017. CheckLUIDDosDevicesEnabled(&gLUIDDeviceMapsEnabled);
  1018. return STATUS_SUCCESS;
  1019. Failure:
  1020. RIPMSG1(RIP_WARNING,
  1021. "Initialization of WIN32K.SYS failed with Status = 0x%x",
  1022. Status);
  1023. Win32KDriverUnload(NULL);
  1024. return Status;
  1025. }
  1026. /***************************************************************************\
  1027. * xxxAddFontResourceW
  1028. *
  1029. *
  1030. * History:
  1031. \***************************************************************************/
  1032. int xxxAddFontResourceW(
  1033. LPWSTR lpFile,
  1034. FLONG flags,
  1035. DESIGNVECTOR *pdv)
  1036. {
  1037. UNICODE_STRING strFile;
  1038. RtlInitUnicodeString(&strFile, lpFile);
  1039. return xxxClientAddFontResourceW(&strFile, flags, pdv);
  1040. }
  1041. /***************************************************************************\
  1042. * LW_DriversInit
  1043. *
  1044. *
  1045. * History:
  1046. \***************************************************************************/
  1047. VOID LW_DriversInit(VOID)
  1048. {
  1049. /*
  1050. * Initialize the keyboard typematic rate.
  1051. */
  1052. SetKeyboardRate((UINT)gnKeyboardSpeed);
  1053. /*
  1054. * Adjust VK modification table if not default (type 4) kbd.
  1055. */
  1056. if (gKeyboardInfo.KeyboardIdentifier.Type == 3)
  1057. gapulCvt_VK = gapulCvt_VK_84;
  1058. /*
  1059. * Adjust VK modification table for IBM 5576 002/003 keyboard.
  1060. */
  1061. if (JAPANESE_KEYBOARD(gKeyboardInfo.KeyboardIdentifier) &&
  1062. (gKeyboardInfo.KeyboardIdentifier.Subtype == 3))
  1063. gapulCvt_VK = gapulCvt_VK_IBM02;
  1064. /*
  1065. * Initialize NLS keyboard globals.
  1066. */
  1067. NlsKbdInitializePerSystem();
  1068. }
  1069. /***************************************************************************\
  1070. * LoadCPUserPreferences
  1071. *
  1072. * 06/07/96 GerardoB Created
  1073. \***************************************************************************/
  1074. BOOL LoadCPUserPreferences(
  1075. PUNICODE_STRING pProfileUserName,
  1076. DWORD dwPolicyOnly)
  1077. {
  1078. DWORD pdwValue[SPI_BOOLMASKDWORDSIZE], dw;
  1079. PPROFILEVALUEINFO ppvi = gpviCPUserPreferences;
  1080. UserAssert(1 + SPI_DWORDRANGECOUNT == ARRAY_SIZE(gpviCPUserPreferences));
  1081. /*
  1082. * The first value in gpviCPUserPreferences corresponds to the bit mask
  1083. */
  1084. dw = FastGetProfileValue(pProfileUserName,
  1085. ppvi->uSection,
  1086. ppvi->pwszKeyName,
  1087. NULL,
  1088. (LPBYTE)pdwValue,
  1089. sizeof(*pdwValue),
  1090. dwPolicyOnly);
  1091. /*
  1092. * Copy only the amount of data read and no more than what we expect.
  1093. */
  1094. if (dw != 0) {
  1095. if (dw > sizeof(gpdwCPUserPreferencesMask)) {
  1096. dw = sizeof(gpdwCPUserPreferencesMask);
  1097. }
  1098. RtlCopyMemory(gpdwCPUserPreferencesMask, pdwValue, dw);
  1099. }
  1100. ppvi++;
  1101. /*
  1102. * DWORD values
  1103. */
  1104. for (dw = 1; dw < 1 + SPI_DWORDRANGECOUNT; dw++, ppvi++) {
  1105. if (FastGetProfileValue(pProfileUserName,
  1106. ppvi->uSection,
  1107. ppvi->pwszKeyName,
  1108. NULL,
  1109. (LPBYTE)pdwValue,
  1110. sizeof(DWORD),
  1111. dwPolicyOnly)) {
  1112. ppvi->dwValue = *pdwValue;
  1113. }
  1114. }
  1115. /*
  1116. * Propagate gpsi flags
  1117. */
  1118. PropagetUPBOOLTogpsi(COMBOBOXANIMATION);
  1119. PropagetUPBOOLTogpsi(LISTBOXSMOOTHSCROLLING);
  1120. PropagetUPBOOLTogpsi(KEYBOARDCUES);
  1121. SET_OR_CLEAR_SRVIF(SRVIF_KEYBOARDPREF, TEST_BOOL_ACCF(ACCF_KEYBOARDPREF));
  1122. gpsi->uCaretWidth = UP(CARETWIDTH);
  1123. SYSMET(CXFOCUSBORDER) = UP(FOCUSBORDERWIDTH);
  1124. SYSMET(CYFOCUSBORDER) = UP(FOCUSBORDERHEIGHT);
  1125. PropagetUPBOOLTogpsi(UIEFFECTS);
  1126. EnforceColorDependentSettings();
  1127. return TRUE;
  1128. }
  1129. /***************************************************************************\
  1130. * LW_LoadProfileInitData
  1131. *
  1132. * Only stuff that gets initialized at boot should go here. Per user settings
  1133. * should be initialized in xxxUpdatePerUserSystemParameters.
  1134. \***************************************************************************/
  1135. VOID LW_LoadProfileInitData(
  1136. PUNICODE_STRING pProfileUserName)
  1137. {
  1138. FastGetProfileIntFromID(pProfileUserName,
  1139. PMAP_WINDOWSM,
  1140. STR_DDESENDTIMEOUT,
  1141. 0,
  1142. &guDdeSendTimeout,
  1143. 0);
  1144. }
  1145. /***************************************************************************\
  1146. * LW_LoadResources
  1147. *
  1148. *
  1149. * History:
  1150. \***************************************************************************/
  1151. VOID LW_LoadResources(
  1152. PUNICODE_STRING pProfileUserName)
  1153. {
  1154. WCHAR rgch[4];
  1155. /*
  1156. * See if the Mouse buttons need swapping.
  1157. */
  1158. FastGetProfileStringFromIDW(pProfileUserName,
  1159. PMAP_MOUSE,
  1160. STR_SWAPBUTTONS,
  1161. szN,
  1162. rgch,
  1163. ARRAY_SIZE(rgch),
  1164. 0);
  1165. SYSMET(SWAPBUTTON) = (*rgch == '1' || *rgch == *szY || *rgch == *szy);
  1166. /*
  1167. * See if we should beep.
  1168. */
  1169. FastGetProfileStringFromIDW(pProfileUserName,
  1170. PMAP_BEEP,
  1171. STR_BEEP,
  1172. szY,
  1173. rgch,
  1174. ARRAY_SIZE(rgch),
  1175. 0);
  1176. SET_OR_CLEAR_PUDF(PUDF_BEEP, (rgch[0] == *szY) || (rgch[0] == *szy));
  1177. /*
  1178. * See if we should have extended sounds.
  1179. */
  1180. FastGetProfileStringFromIDW(pProfileUserName,
  1181. PMAP_BEEP,
  1182. STR_EXTENDEDSOUNDS,
  1183. szN,
  1184. rgch,
  1185. ARRAY_SIZE(rgch),
  1186. 0);
  1187. SET_OR_CLEAR_PUDF(PUDF_EXTENDEDSOUNDS, (rgch[0] == *szY || rgch[0] == *szy));
  1188. }
  1189. /***************************************************************************\
  1190. * xxxLoadSomeStrings
  1191. *
  1192. * This function loads a bunch of strings from the user32 resource string
  1193. * table
  1194. * This is done to keep all the localizable strings in user side to be MUI
  1195. * Manageable.
  1196. *
  1197. * History:
  1198. * 4-Mar-2000 MHamid Created.
  1199. \***************************************************************************/
  1200. VOID xxxLoadSomeStrings(
  1201. VOID)
  1202. {
  1203. int i, str, id;
  1204. /*
  1205. * MessageBox strings.
  1206. */
  1207. for (i = 0, str = STR_OK, id = IDOK; i<MAX_MB_STRINGS; i++, str++, id++) {
  1208. gpsi->MBStrings[i].uStr = str;
  1209. gpsi->MBStrings[i].uID = id;
  1210. xxxClientLoadStringW(str,
  1211. gpsi->MBStrings[i].szName,
  1212. ARRAY_SIZE(gpsi->MBStrings[i].szName));
  1213. }
  1214. /*
  1215. * Load ToolTip strings.
  1216. */
  1217. xxxClientLoadStringW(STR_TT_MIN, gszMIN, ARRAY_SIZE(gszMIN));
  1218. xxxClientLoadStringW(STR_TT_MAX, gszMAX, ARRAY_SIZE(gszMAX));
  1219. xxxClientLoadStringW(STR_TT_RESUP, gszRESUP, ARRAY_SIZE(gszRESUP));
  1220. xxxClientLoadStringW(STR_TT_RESDOWN, gszRESDOWN, ARRAY_SIZE(gszRESDOWN));
  1221. xxxClientLoadStringW(STR_TT_SCLOSE, gszSCLOSE, ARRAY_SIZE(gszSCLOSE));
  1222. xxxClientLoadStringW(STR_TT_HELP, gszHELP, ARRAY_SIZE(gszHELP));
  1223. }
  1224. /***************************************************************************\
  1225. * xxxInitWindowStation
  1226. *
  1227. * History:
  1228. * 6-Sep-1996 CLupu Created.
  1229. * 21-Jan-98 SamerA Renamed to xxxInitWindowStation since it may leave the
  1230. * critical section.
  1231. \***************************************************************************/
  1232. BOOL xxxInitWindowStation(
  1233. VOID)
  1234. {
  1235. TL tlName;
  1236. PUNICODE_STRING pProfileUserName = CreateProfileUserName(&tlName);
  1237. BOOL fRet;
  1238. /*
  1239. * Load all profile data first
  1240. */
  1241. LW_LoadProfileInitData(pProfileUserName);
  1242. /*
  1243. * Initialize User in a specific order.
  1244. */
  1245. LW_DriversInit();
  1246. xxxLoadSomeStrings();
  1247. /*
  1248. * This is the initialization from Chicago
  1249. */
  1250. if (!(fRet = xxxSetWindowNCMetrics(pProfileUserName, NULL, TRUE, -1))) {
  1251. RIPMSG0(RIP_WARNING, "xxxInitWindowStation failed in xxxSetWindowNCMetrics");
  1252. goto Exit;
  1253. }
  1254. SetMinMetrics(pProfileUserName, NULL);
  1255. if (!(fRet = SetIconMetrics(pProfileUserName, NULL))) {
  1256. RIPMSG0(RIP_WARNING, "xxxInitWindowStation failed in SetIconMetrics");
  1257. goto Exit;
  1258. }
  1259. if (!(fRet = FinalUserInit())) {
  1260. RIPMSG0(RIP_WARNING, "xxxInitWindowStation failed in FinalUserInit");
  1261. goto Exit;
  1262. }
  1263. /*
  1264. * Initialize the key cache index.
  1265. */
  1266. gpsi->dwKeyCache = 1;
  1267. Exit:
  1268. FreeProfileUserName(pProfileUserName, &tlName);
  1269. return fRet;
  1270. }
  1271. /***************************************************************************\
  1272. * CreateTerminalInput
  1273. *
  1274. *
  1275. * History:
  1276. * 6-Sep-1996 CLupu Created.
  1277. \***************************************************************************/
  1278. BOOL CreateTerminalInput(
  1279. PTERMINAL pTerm)
  1280. {
  1281. UserAssert(pTerm != NULL);
  1282. /*
  1283. * call to the client side to clean up the [Fonts] section
  1284. * of the registry. This will only take significant chunk of time
  1285. * if the [Fonts] key changed during since the last boot and if
  1286. * there are lots of fonts loaded
  1287. */
  1288. ClientFontSweep();
  1289. /*
  1290. * Load the standard fonts before we create any DCs. At this time we can
  1291. * only add the fonts that do not reside on the net. They may be needed
  1292. * by winlogon. Our winlogon needs only ms sans serif, but private
  1293. * winlogon's may need some other fonts as well. The fonts on the net
  1294. * will be added later, right after all the net connections have been
  1295. * restored.
  1296. */
  1297. xxxLW_LoadFonts(FALSE);
  1298. /*
  1299. * Initialize the input system.
  1300. */
  1301. if (!xxxInitInput(pTerm)) {
  1302. return FALSE;
  1303. }
  1304. return TRUE;
  1305. }
  1306. /***************************************************************************\
  1307. * CI_GetClrVal
  1308. *
  1309. * Returns the RGB value of a color string from WIN.INI.
  1310. *
  1311. * History:
  1312. \***************************************************************************/
  1313. DWORD CI_GetClrVal(
  1314. LPWSTR p,
  1315. DWORD clrDefval)
  1316. {
  1317. LPBYTE pl;
  1318. BYTE val;
  1319. int i;
  1320. DWORD clrval;
  1321. if (*p == UNICODE_NULL) {
  1322. return clrDefval;
  1323. }
  1324. /*
  1325. * Initialize the pointer to the LONG return value. Set to MSB.
  1326. */
  1327. pl = (LPBYTE)&clrval;
  1328. /*
  1329. * Get three goups of numbers seprated by non-numeric characters.
  1330. */
  1331. for (i = 0; i < 3; i++) {
  1332. /*
  1333. * Skip over any non-numeric characters within the string.
  1334. */
  1335. while ((*p != UNICODE_NULL) && !(*p >= TEXT('0') && *p <= TEXT('9'))) {
  1336. p++;
  1337. }
  1338. /*
  1339. * Are we (prematurely) at the end of the string?
  1340. */
  1341. if (*p == UNICODE_NULL) {
  1342. RIPMSG0(RIP_WARNING, "CI_GetClrVal: Color string is corrupted");
  1343. return clrDefval;
  1344. }
  1345. /*
  1346. * Get the next series of digits.
  1347. */
  1348. val = 0;
  1349. while (*p >= TEXT('0') && *p <= TEXT('9'))
  1350. val = (BYTE)((int)val*10 + (int)*p++ - '0');
  1351. /*
  1352. * HACK! Store the group in the LONG return value.
  1353. */
  1354. *pl++ = val;
  1355. }
  1356. /*
  1357. * Force the MSB to zero for GDI.
  1358. */
  1359. *pl = 0;
  1360. return clrval;
  1361. }
  1362. /***************************************************************************\
  1363. * xxxODI_ColorInit
  1364. *
  1365. *
  1366. * History:
  1367. \***************************************************************************/
  1368. VOID xxxODI_ColorInit(PUNICODE_STRING pProfileUserName)
  1369. {
  1370. int i;
  1371. COLORREF colorVals[STR_COLOREND - STR_COLORSTART + 1];
  1372. INT colorIndex[STR_COLOREND - STR_COLORSTART + 1];
  1373. WCHAR rgchValue[25];
  1374. #if COLOR_MAX - (STR_COLOREND - STR_COLORSTART + 1)
  1375. #error "COLOR_MAX value conflicts with STR_COLOREND - STR_COLORSTART"
  1376. #endif
  1377. /*
  1378. * Now set up default color values.
  1379. * These are not in display drivers anymore since we just want default.
  1380. * The real values are stored in the profile.
  1381. */
  1382. RtlCopyMemory(gpsi->argbSystem, gargbInitial, sizeof(COLORREF) * COLOR_MAX);
  1383. RtlCopyMemory(gpsi->argbSystemUnmatched, gpsi->argbSystem, sizeof(COLORREF) * COLOR_MAX);
  1384. for (i = 0; i < COLOR_MAX; i++) {
  1385. LUID luidCaller;
  1386. /*
  1387. * Try to find a WIN.INI entry for this object.
  1388. */
  1389. *rgchValue = 0;
  1390. /*
  1391. * Special case the background color. Try using Winlogon's value
  1392. * if present. If the value doesn't exist then use USER's value.
  1393. */
  1394. if ((COLOR_BACKGROUND == i) &&
  1395. NT_SUCCESS(GetProcessLuid(NULL, &luidCaller)) &&
  1396. RtlEqualLuid(&luidCaller, &luidSystem)) {
  1397. FastGetProfileStringFromIDW(pProfileUserName,
  1398. PMAP_WINLOGON,
  1399. STR_COLORSTART + COLOR_BACKGROUND,
  1400. szNull,
  1401. rgchValue,
  1402. ARRAY_SIZE(rgchValue),
  1403. 0);
  1404. }
  1405. if (*rgchValue == 0) {
  1406. FastGetProfileStringFromIDW(pProfileUserName,
  1407. PMAP_COLORS,
  1408. STR_COLORSTART + i,
  1409. szNull,
  1410. rgchValue,
  1411. ARRAY_SIZE(rgchValue),
  1412. 0);
  1413. }
  1414. /*
  1415. * Convert the string into an RGB value and store. Use the
  1416. * default RGB value if the profile value is missing.
  1417. */
  1418. colorVals[i] = CI_GetClrVal(rgchValue, gpsi->argbSystem[i]);
  1419. colorIndex[i] = i;
  1420. }
  1421. xxxSetSysColors(pProfileUserName,
  1422. i,
  1423. colorIndex,
  1424. colorVals,
  1425. SSCF_FORCESOLIDCOLOR | SSCF_SETMAGICCOLORS);
  1426. }
  1427. /***********************************************************************\
  1428. * _LoadIconsAndCursors
  1429. *
  1430. * Used in parallel with the client side - LoadIconsAndCursors. This
  1431. * assumes that only the default configurable cursors and icons have
  1432. * been loaded and searches the global icon cache for them to fixup
  1433. * the default resource ids to standard ids. Also initializes the
  1434. * rgsys arrays allowing SYSCUR and SYSICO macros to work.
  1435. *
  1436. * 14-Oct-1995 SanfordS created.
  1437. \***********************************************************************/
  1438. VOID _LoadCursorsAndIcons(
  1439. VOID)
  1440. {
  1441. PCURSOR pcur;
  1442. int i;
  1443. pcur = gpcurFirst;
  1444. /*
  1445. * Only CSR can call this (and only once).
  1446. */
  1447. if (!ISCSRSS()) {
  1448. return;
  1449. }
  1450. HYDRA_HINT(HH_LOADCURSORS);
  1451. while (pcur) {
  1452. UserAssert(!IS_PTR(pcur->strName.Buffer));
  1453. switch (pcur->rt) {
  1454. case RT_ICON:
  1455. UserAssert((LONG_PTR)pcur->strName.Buffer >= OIC_FIRST_DEFAULT);
  1456. UserAssert((LONG_PTR)pcur->strName.Buffer <
  1457. OIC_FIRST_DEFAULT + COIC_CONFIGURABLE);
  1458. i = PTR_TO_ID(pcur->strName.Buffer) - OIC_FIRST_DEFAULT;
  1459. pcur->strName.Buffer = (LPWSTR)gasysico[i].Id;
  1460. if (pcur->CURSORF_flags & CURSORF_LRSHARED) {
  1461. UserAssert(gasysico[i].spcur == NULL);
  1462. Lock(&gasysico[i].spcur, pcur);
  1463. } else {
  1464. UserAssert(gpsi->hIconSmWindows == NULL);
  1465. UserAssert((int)pcur->cx == SYSMET(CXSMICON));
  1466. /*
  1467. * The special small winlogo icon is not shared.
  1468. */
  1469. gpsi->hIconSmWindows = PtoH(pcur);
  1470. }
  1471. break;
  1472. case RT_CURSOR:
  1473. UserAssert((LONG_PTR)pcur->strName.Buffer >= OCR_FIRST_DEFAULT);
  1474. UserAssert((LONG_PTR)pcur->strName.Buffer <
  1475. OCR_FIRST_DEFAULT + COCR_CONFIGURABLE);
  1476. i = PTR_TO_ID(pcur->strName.Buffer) - OCR_FIRST_DEFAULT;
  1477. pcur->strName.Buffer = (LPWSTR)gasyscur[i].Id;
  1478. Lock(&gasyscur[i].spcur, pcur);
  1479. break;
  1480. default:
  1481. // Should be nothing in the cache but these!
  1482. RIPMSG1(RIP_ERROR, "Bogus object in cursor list: 0x%p", pcur);
  1483. }
  1484. pcur = pcur->pcurNext;
  1485. }
  1486. /*
  1487. * copy special icon handles to global spots for later use.
  1488. */
  1489. gpsi->hIcoWindows = PtoH(SYSICO(WINLOGO));
  1490. }
  1491. /***********************************************************************\
  1492. * UnloadCursorsAndIcons
  1493. *
  1494. * Used for cleanup of win32k.
  1495. *
  1496. * Dec-10-1997 clupu created.
  1497. \***********************************************************************/
  1498. VOID UnloadCursorsAndIcons(
  1499. VOID)
  1500. {
  1501. PCURSOR pcur;
  1502. int ind;
  1503. TRACE_HYDAPI(("UnloadCursorsAndIcons\n"));
  1504. /*
  1505. * Unlock the icons.
  1506. */
  1507. for (ind = 0; ind < COIC_CONFIGURABLE; ind++) {
  1508. pcur = gasysico[ind].spcur;
  1509. if (pcur == NULL) {
  1510. continue;
  1511. }
  1512. pcur->head.ppi = PpiCurrent();
  1513. Unlock(&gasysico[ind].spcur);
  1514. }
  1515. /*
  1516. * Unlock the cursors.
  1517. */
  1518. for (ind = 0; ind < COCR_CONFIGURABLE; ind++) {
  1519. pcur = gasyscur[ind].spcur;
  1520. if (pcur == NULL) {
  1521. continue;
  1522. }
  1523. pcur->head.ppi = PpiCurrent();
  1524. Unlock(&gasyscur[ind].spcur);
  1525. }
  1526. }
  1527. /***********************************************************************\
  1528. * xxxUpdateSystemCursorsFromRegistry
  1529. *
  1530. * Reloads all customizable cursors from the registry.
  1531. *
  1532. * 09-Oct-1995 SanfordS created.
  1533. \***********************************************************************/
  1534. VOID xxxUpdateSystemCursorsFromRegistry(
  1535. PUNICODE_STRING pProfileUserName)
  1536. {
  1537. int i;
  1538. UNICODE_STRING strName;
  1539. TCHAR szFilename[MAX_PATH];
  1540. PCURSOR pCursor;
  1541. UINT LR_flags;
  1542. for (i = 0; i < COCR_CONFIGURABLE; i++) {
  1543. FastGetProfileStringFromIDW(pProfileUserName,
  1544. PMAP_CURSORS,
  1545. gasyscur[i].StrId,
  1546. TEXT(""),
  1547. szFilename,
  1548. ARRAY_SIZE(szFilename),
  1549. 0);
  1550. if (*szFilename) {
  1551. RtlInitUnicodeString(&strName, szFilename);
  1552. LR_flags = LR_LOADFROMFILE | LR_ENVSUBST | LR_DEFAULTSIZE;
  1553. } else {
  1554. RtlInitUnicodeStringOrId(&strName,
  1555. MAKEINTRESOURCE(i + OCR_FIRST_DEFAULT));
  1556. LR_flags = LR_ENVSUBST | LR_DEFAULTSIZE;
  1557. }
  1558. pCursor = xxxClientLoadImage(&strName,
  1559. 0,
  1560. IMAGE_CURSOR,
  1561. 0,
  1562. 0,
  1563. LR_flags,
  1564. FALSE);
  1565. if (pCursor) {
  1566. zzzSetSystemImage(pCursor, gasyscur[i].spcur);
  1567. } else {
  1568. RIPMSG1(RIP_WARNING, "Unable to update cursor. id=%x.", i + OCR_FIRST_DEFAULT);
  1569. }
  1570. }
  1571. }
  1572. /***********************************************************************\
  1573. * xxxUpdateSystemIconsFromRegistry
  1574. *
  1575. * Reloads all customizable icons from the registry.
  1576. *
  1577. * 09-Oct-1995 SanfordS created.
  1578. \***********************************************************************/
  1579. VOID xxxUpdateSystemIconsFromRegistry(
  1580. PUNICODE_STRING pProfileUserName)
  1581. {
  1582. int i;
  1583. UNICODE_STRING strName;
  1584. TCHAR szFilename[MAX_PATH];
  1585. PCURSOR pCursor;
  1586. UINT LR_flags;
  1587. for (i = 0; i < COIC_CONFIGURABLE; i++) {
  1588. FastGetProfileStringFromIDW(pProfileUserName,
  1589. PMAP_ICONS,
  1590. gasysico[i].StrId,
  1591. TEXT(""),
  1592. szFilename,
  1593. ARRAY_SIZE(szFilename),
  1594. 0);
  1595. if (*szFilename) {
  1596. RtlInitUnicodeString(&strName, szFilename);
  1597. LR_flags = LR_LOADFROMFILE | LR_ENVSUBST;
  1598. } else {
  1599. RtlInitUnicodeStringOrId(&strName,
  1600. MAKEINTRESOURCE(i + OIC_FIRST_DEFAULT));
  1601. LR_flags = LR_ENVSUBST;
  1602. }
  1603. pCursor = xxxClientLoadImage(&strName,
  1604. 0,
  1605. IMAGE_ICON,
  1606. 0,
  1607. 0,
  1608. LR_flags,
  1609. FALSE);
  1610. RIPMSG3(RIP_VERBOSE,
  1611. (!IS_PTR(strName.Buffer)) ?
  1612. "%#.8lx = Loaded id %ld" :
  1613. "%#.8lx = Loaded file %ws for id %ld",
  1614. PtoH(pCursor),
  1615. strName.Buffer,
  1616. i + OIC_FIRST_DEFAULT);
  1617. if (pCursor) {
  1618. zzzSetSystemImage(pCursor, gasysico[i].spcur);
  1619. } else {
  1620. RIPMSG1(RIP_WARNING, "Unable to update icon. id=%ld", i + OIC_FIRST_DEFAULT);
  1621. }
  1622. /*
  1623. * update the small winlogo icon which is referenced by gpsi.
  1624. * Seems like we should load the small version for all configurable
  1625. * icons anyway. What is needed is for CopyImage to support
  1626. * copying of images loaded from files with LR_COPYFROMRESOURCE
  1627. * allowing a reaload of the bits. (SAS)
  1628. */
  1629. if (i == OIC_WINLOGO_DEFAULT - OIC_FIRST_DEFAULT) {
  1630. PCURSOR pCurSys = HtoP(gpsi->hIconSmWindows);
  1631. if (pCurSys != NULL) {
  1632. pCursor = xxxClientLoadImage(&strName,
  1633. 0,
  1634. IMAGE_ICON,
  1635. SYSMET(CXSMICON),
  1636. SYSMET(CYSMICON),
  1637. LR_flags,
  1638. FALSE);
  1639. if (pCursor) {
  1640. zzzSetSystemImage(pCursor, pCurSys);
  1641. } else {
  1642. RIPMSG0(RIP_WARNING, "Unable to update small winlogo icon.");
  1643. }
  1644. }
  1645. }
  1646. }
  1647. }
  1648. /***************************************************************************\
  1649. * LW_BrushInit
  1650. *
  1651. *
  1652. * History:
  1653. \***************************************************************************/
  1654. BOOL LW_BrushInit(
  1655. VOID)
  1656. {
  1657. HBITMAP hbmGray;
  1658. CONST static WORD patGray[8] = {0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa};
  1659. /*
  1660. * Create a gray brush to be used with GrayString.
  1661. */
  1662. hbmGray = GreCreateBitmap(8, 8, 1, 1, (LPBYTE)patGray);
  1663. if (hbmGray == NULL) {
  1664. return FALSE;
  1665. }
  1666. gpsi->hbrGray = GreCreatePatternBrush(hbmGray);
  1667. ghbrWhite = GreGetStockObject(WHITE_BRUSH);
  1668. ghbrBlack = GreGetStockObject(BLACK_BRUSH);
  1669. UserAssert(ghbrWhite != NULL && ghbrBlack != NULL);
  1670. if (gpsi->hbrGray == NULL) {
  1671. return FALSE;
  1672. }
  1673. GreDeleteObject(hbmGray);
  1674. GreSetBrushOwnerPublic(gpsi->hbrGray);
  1675. ghbrHungApp = GreCreateSolidBrush(0);
  1676. if (ghbrHungApp == NULL) {
  1677. return FALSE;
  1678. }
  1679. GreSetBrushOwnerPublic(ghbrHungApp);
  1680. return TRUE;
  1681. }
  1682. /***************************************************************************\
  1683. * LW_RegisterWindows
  1684. *
  1685. *
  1686. * History:
  1687. \***************************************************************************/
  1688. BOOL LW_RegisterWindows(
  1689. VOID)
  1690. {
  1691. int i;
  1692. WNDCLASSVEREX wndcls;
  1693. PTHREADINFO ptiCurrent = PtiCurrent();
  1694. BOOL fSuccess = TRUE;
  1695. BOOL fSystem = (ptiCurrent->TIF_flags & TIF_SYSTEMTHREAD) != 0;
  1696. CONST static struct {
  1697. BOOLEAN fSystem;
  1698. BOOLEAN fGlobalClass;
  1699. WORD fnid;
  1700. UINT style;
  1701. WNDPROC lpfnWndProc;
  1702. int cbWndExtra;
  1703. BOOL fNormalCursor : 1;
  1704. HBRUSH hbrBackground;
  1705. LPCTSTR lpszClassName;
  1706. } rc[] = {
  1707. { TRUE, TRUE, FNID_DESKTOP,
  1708. CS_DBLCLKS,
  1709. (WNDPROC)xxxDesktopWndProc,
  1710. sizeof(DESKWND) - sizeof(WND),
  1711. TRUE,
  1712. (HBRUSH)(COLOR_BACKGROUND + 1),
  1713. DESKTOPCLASS},
  1714. { TRUE, FALSE, FNID_SWITCH,
  1715. CS_VREDRAW | CS_HREDRAW | CS_SAVEBITS,
  1716. (WNDPROC)xxxSwitchWndProc,
  1717. sizeof(SWITCHWND) - sizeof(WND),
  1718. TRUE,
  1719. NULL,
  1720. SWITCHWNDCLASS},
  1721. { TRUE, FALSE, FNID_MENU,
  1722. CS_DBLCLKS | CS_SAVEBITS | CS_DROPSHADOW,
  1723. (WNDPROC)xxxMenuWindowProc,
  1724. sizeof(PPOPUPMENU),
  1725. FALSE,
  1726. (HBRUSH)(COLOR_MENU + 1),
  1727. MENUCLASS},
  1728. { FALSE, FALSE, FNID_SCROLLBAR,
  1729. CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS | CS_PARENTDC,
  1730. (WNDPROC)xxxSBWndProc,
  1731. sizeof(SBWND) - sizeof(WND),
  1732. TRUE,
  1733. NULL,
  1734. L"ScrollBar"},
  1735. { TRUE, FALSE, FNID_TOOLTIP,
  1736. CS_DBLCLKS | CS_SAVEBITS,
  1737. (WNDPROC)xxxTooltipWndProc,
  1738. sizeof(TOOLTIPWND) - sizeof(WND),
  1739. TRUE,
  1740. NULL,
  1741. TOOLTIPCLASS},
  1742. { TRUE, TRUE, FNID_ICONTITLE,
  1743. 0,
  1744. (WNDPROC)xxxDefWindowProc,
  1745. 0,
  1746. TRUE,
  1747. NULL,
  1748. ICONTITLECLASS},
  1749. { FALSE, FALSE, 0,
  1750. 0,
  1751. (WNDPROC)xxxEventWndProc,
  1752. sizeof(PSVR_INSTANCE_INFO),
  1753. FALSE,
  1754. NULL,
  1755. L"DDEMLEvent"},
  1756. #ifdef HUNGAPP_GHOSTING
  1757. { TRUE, TRUE, FNID_GHOST,
  1758. 0,
  1759. (WNDPROC)xxxGhostWndProc,
  1760. 0,
  1761. TRUE,
  1762. NULL,
  1763. L"Ghost"},
  1764. #endif // HUNGAPP_GHOSTING
  1765. { TRUE, TRUE, 0,
  1766. 0,
  1767. (WNDPROC)xxxDefWindowProc,
  1768. 0,
  1769. TRUE,
  1770. NULL,
  1771. L"SysShadow"},
  1772. { TRUE, TRUE, FNID_MESSAGEWND,
  1773. 0,
  1774. (WNDPROC)xxxDefWindowProc,
  1775. 4,
  1776. TRUE,
  1777. NULL,
  1778. szMESSAGE}
  1779. };
  1780. /*
  1781. * All other classes are registered via the table.
  1782. */
  1783. wndcls.cbClsExtra = 0;
  1784. wndcls.hInstance = hModuleWin;
  1785. wndcls.hIcon = NULL;
  1786. wndcls.hIconSm = NULL;
  1787. wndcls.lpszMenuName = NULL;
  1788. for (i = 0; i < ARRAY_SIZE(rc); i++) {
  1789. if (fSystem && !rc[i].fSystem) {
  1790. continue;
  1791. }
  1792. wndcls.style = rc[i].style;
  1793. wndcls.lpfnWndProc = rc[i].lpfnWndProc;
  1794. wndcls.cbWndExtra = rc[i].cbWndExtra;
  1795. wndcls.hCursor = rc[i].fNormalCursor ? PtoH(SYSCUR(ARROW)) : NULL;
  1796. wndcls.hbrBackground= rc[i].hbrBackground;
  1797. wndcls.lpszClassName= rc[i].lpszClassName;
  1798. wndcls.lpszClassNameVer= rc[i].lpszClassName;
  1799. if (InternalRegisterClassEx(&wndcls,
  1800. rc[i].fnid,
  1801. CSF_SERVERSIDEPROC | CSF_WIN40COMPAT) == NULL) {
  1802. RIPMSG0(RIP_WARNING, "LW_RegisterWindows: InternalRegisterClassEx failed");
  1803. fSuccess = FALSE;
  1804. break;
  1805. }
  1806. if (fSystem && rc[i].fGlobalClass) {
  1807. if (InternalRegisterClassEx(&wndcls,
  1808. rc[i].fnid,
  1809. CSF_SERVERSIDEPROC | CSF_SYSTEMCLASS | CSF_WIN40COMPAT) == NULL) {
  1810. RIPMSG0(RIP_WARNING, "LW_RegisterWindows: InternalRegisterClassEx failed");
  1811. fSuccess = FALSE;
  1812. break;
  1813. }
  1814. }
  1815. }
  1816. if (fSuccess) {
  1817. ptiCurrent->ppi->W32PF_Flags |= W32PF_CLASSESREGISTERED;
  1818. #ifndef LAZY_CLASS_INIT
  1819. if (!fSystem && ptiCurrent->pClientInfo) {
  1820. try {
  1821. ptiCurrent->pClientInfo->CI_flags |= CI_REGISTERCLASSES;
  1822. } except (W32ExceptionHandler(TRUE, RIP_WARNING)) {
  1823. fSuccess = FALSE;
  1824. }
  1825. }
  1826. #endif
  1827. }
  1828. return fSuccess;
  1829. }
  1830. /**********************************************************\
  1831. * VOID vCheckMMInstance
  1832. *
  1833. * History:
  1834. * Feb-06-98 Xudong Wu [TessieW]
  1835. * Wrote it.
  1836. \**********************************************************/
  1837. VOID vCheckMMInstance(
  1838. LPWSTR pchSrch,
  1839. DESIGNVECTOR *pdv)
  1840. {
  1841. LPWSTR pKeyName;
  1842. WCHAR szName[MAX_PATH], *pszName = szName;
  1843. WCHAR szCannonicalName[MAX_PATH];
  1844. ULONG NumAxes;
  1845. pdv->dvNumAxes = 0;
  1846. pKeyName = pchSrch;
  1847. while (*pKeyName && (*pKeyName++ != TEXT('('))) {
  1848. /* do nothing */;
  1849. }
  1850. if (*pKeyName){
  1851. if (!_wcsicmp(pKeyName, L"OpenType)")) {
  1852. pKeyName = pchSrch;
  1853. while(*pKeyName != TEXT('(')) {
  1854. *pszName++ = *pKeyName++;
  1855. }
  1856. *pszName = 0;
  1857. GreGetCannonicalName(szName, szCannonicalName, &NumAxes, pdv);
  1858. }
  1859. }
  1860. }
  1861. BOOL bEnumerateRegistryFonts(
  1862. BOOL bPermanent)
  1863. {
  1864. LPWSTR pchKeys, pchSrch, lpchT;
  1865. int cchReal, cFont;
  1866. WCHAR szFontFile[MAX_PATH];
  1867. FLONG flAFRW;
  1868. TL tlPool;
  1869. DESIGNVECTOR dv;
  1870. WCHAR szPreloadFontFile[MAX_PATH];
  1871. static int LastFontLoaded = -1;
  1872. /*
  1873. * if we are not just checking whether this is a registry font
  1874. */
  1875. flAFRW = (bPermanent ? AFRW_ADD_LOCAL_FONT : AFRW_ADD_REMOTE_FONT);
  1876. cchReal = (int)FastGetProfileKeysW(NULL,
  1877. PMAP_FONTS,
  1878. TEXT("vgasys.fnt"),
  1879. &pchKeys
  1880. );
  1881. #if DBG
  1882. if (cchReal == 0) {
  1883. RIPMSG0(RIP_WARNING, "bEnumerateRegistryFonts: cchReal is 0");
  1884. }
  1885. #endif
  1886. if (!pchKeys) {
  1887. return FALSE;
  1888. }
  1889. ThreadLockPool(PtiCurrent(), pchKeys, &tlPool);
  1890. /*
  1891. * If we got here first, we load the fonts until this preload font.
  1892. * Preload fonts will be used by Winlogon UI, then we need to make sure
  1893. * the font is available when Winlogon UI comes up.
  1894. */
  1895. if (LastFontLoaded == -1) {
  1896. FastGetProfileStringW(NULL, PMAP_WINLOGON,
  1897. TEXT("PreloadFontFile"),
  1898. TEXT("Micross.ttf"),
  1899. szPreloadFontFile,
  1900. MAX_PATH,
  1901. 0);
  1902. RIPMSG1(RIP_VERBOSE, "Winlogon preload font = %ws\n",szPreloadFontFile);
  1903. }
  1904. /*
  1905. * Now we have all the key names in pchKeys.
  1906. */
  1907. if (cchReal != 0) {
  1908. cFont = 0;
  1909. pchSrch = pchKeys;
  1910. do {
  1911. // check to see whether this is MM(OpenType) instance
  1912. vCheckMMInstance(pchSrch, &dv);
  1913. if (FastGetProfileStringW(NULL,
  1914. PMAP_FONTS,
  1915. pchSrch,
  1916. TEXT("vgasys.fon"),
  1917. szFontFile,
  1918. (MAX_PATH - 5),
  1919. 0)) {
  1920. /*
  1921. * If no extension, append ".FON"
  1922. */
  1923. for (lpchT = szFontFile; *lpchT != TEXT('.'); lpchT++) {
  1924. if (*lpchT == 0) {
  1925. wcscat(szFontFile, TEXT(".FON"));
  1926. break;
  1927. }
  1928. }
  1929. if ((cFont > LastFontLoaded) && bPermanent) {
  1930. /*
  1931. * skip if we've already loaded this local font.
  1932. */
  1933. xxxAddFontResourceW(szFontFile, flAFRW, dv.dvNumAxes ? &dv : NULL);
  1934. }
  1935. if (!bPermanent) {
  1936. xxxAddFontResourceW(szFontFile, flAFRW, dv.dvNumAxes ? &dv : NULL);
  1937. }
  1938. if ((LastFontLoaded == -1) &&
  1939. /*
  1940. * Compare with the font file name from Registry.
  1941. */
  1942. (!_wcsnicmp(szFontFile, szPreloadFontFile, wcslen(szPreloadFontFile))) &&
  1943. (bPermanent)) {
  1944. /*
  1945. * On the first time through only load up until
  1946. * ms sans serif for winlogon to use. Later we
  1947. * will spawn off a thread which loads the remaining
  1948. * fonts in the background.
  1949. */
  1950. LastFontLoaded = cFont;
  1951. ThreadUnlockAndFreePool(PtiCurrent(), &tlPool);
  1952. return TRUE;
  1953. }
  1954. }
  1955. /*
  1956. * Skip to the next key.
  1957. */
  1958. while (*pchSrch++) {
  1959. /* do nothing */;
  1960. }
  1961. cFont += 1;
  1962. } while (pchSrch < ((LPWSTR)pchKeys + cchReal));
  1963. }
  1964. /*
  1965. * signal that all the permanent fonts have been loaded
  1966. */
  1967. bPermanentFontsLoaded = TRUE;
  1968. ThreadUnlockAndFreePool(PtiCurrent(), &tlPool);
  1969. if (!bPermanent) {
  1970. SET_PUDF(PUDF_FONTSARELOADED);
  1971. }
  1972. return TRUE;
  1973. }
  1974. extern VOID CloseFNTCache(VOID);
  1975. /***************************************************************************\
  1976. * xxxLW_LoadFonts
  1977. *
  1978. *
  1979. * History:
  1980. \***************************************************************************/
  1981. VOID xxxLW_LoadFonts(
  1982. BOOL bRemote)
  1983. {
  1984. BOOL bTimeOut = FALSE;
  1985. if (bRemote) {
  1986. LARGE_INTEGER li;
  1987. ULONG ulWaitCount = 0;
  1988. /*
  1989. * Before we can proceed we must make sure that all the permanent
  1990. * fonts have been loaded.
  1991. */
  1992. while (!bPermanentFontsLoaded) {
  1993. if (!gbRemoteSession || ulWaitCount < MAX_TIME_OUT) {
  1994. LeaveCrit();
  1995. li.QuadPart = (LONGLONG)-10000 * CMSSLEEP;
  1996. KeDelayExecutionThread(KernelMode, FALSE, &li);
  1997. EnterCrit();
  1998. } else {
  1999. bTimeOut = TRUE;
  2000. break;
  2001. }
  2002. ulWaitCount++;
  2003. }
  2004. if (!bTimeOut) {
  2005. if (!bEnumerateRegistryFonts(FALSE)) {
  2006. return; // Nothing we can do.
  2007. }
  2008. // Add remote type 1 fonts.
  2009. ClientLoadRemoteT1Fonts();
  2010. }
  2011. } else {
  2012. xxxAddFontResourceW(L"marlett.ttf", AFRW_ADD_LOCAL_FONT,NULL);
  2013. if (!bEnumerateRegistryFonts(TRUE)) {
  2014. return; // Nothing we can do.
  2015. }
  2016. //
  2017. // Add local type 1 fonts.
  2018. // Only want to be called once, the second time after ms sans serif
  2019. // was installed
  2020. //
  2021. if (bPermanentFontsLoaded) {
  2022. ClientLoadLocalT1Fonts();
  2023. // All the fonts loaded, we can close the FNTCache.
  2024. CloseFNTCache();
  2025. }
  2026. }
  2027. }
  2028. /***************************************************************************\
  2029. * FinalUserInit
  2030. *
  2031. * History:
  2032. \***************************************************************************/
  2033. BOOL FinalUserInit(
  2034. VOID)
  2035. {
  2036. HBITMAP hbm;
  2037. PPCLS ppcls;
  2038. gpDispInfo->hdcGray = GreCreateCompatibleDC(gpDispInfo->hdcScreen);
  2039. if (gpDispInfo->hdcGray == NULL) {
  2040. return FALSE;
  2041. }
  2042. GreSelectFont(gpDispInfo->hdcGray, ghFontSys);
  2043. GreSetDCOwner(gpDispInfo->hdcGray, OBJECT_OWNER_PUBLIC);
  2044. gpDispInfo->cxGray = gpsi->cxSysFontChar * GRAY_STRLEN;
  2045. gpDispInfo->cyGray = gpsi->cySysFontChar + 2;
  2046. gpDispInfo->hbmGray = GreCreateBitmap(gpDispInfo->cxGray, gpDispInfo->cyGray, 1, 1, 0L);
  2047. if (gpDispInfo->hbmGray == NULL) {
  2048. return FALSE;
  2049. }
  2050. GreSetBitmapOwner(gpDispInfo->hbmGray, OBJECT_OWNER_PUBLIC);
  2051. hbm = GreSelectBitmap(gpDispInfo->hdcGray, gpDispInfo->hbmGray);
  2052. GreSetTextColor(gpDispInfo->hdcGray, 0x00000000L);
  2053. GreSelectBrush(gpDispInfo->hdcGray, gpsi->hbrGray);
  2054. GreSetBkMode(gpDispInfo->hdcGray, OPAQUE);
  2055. GreSetBkColor(gpDispInfo->hdcGray, 0x00FFFFFFL);
  2056. /*
  2057. * Setup menu animation dc for global menu state
  2058. */
  2059. if (MNSetupAnimationDC(&gMenuState)) {
  2060. GreSetDCOwner(gMenuState.hdcAni, OBJECT_OWNER_PUBLIC);
  2061. } else {
  2062. RIPMSG0(RIP_WARNING, "FinalUserInit: MNSetupAnimationDC failed");
  2063. }
  2064. /*
  2065. * Creation of the queue registers some bogus classes. Get rid
  2066. * of them and register the real ones.
  2067. */
  2068. ppcls = &PpiCurrent()->pclsPublicList;
  2069. while ((*ppcls != NULL) && !((*ppcls)->style & CS_GLOBALCLASS)) {
  2070. DestroyClass(ppcls);
  2071. }
  2072. return TRUE;
  2073. }
  2074. /***************************************************************************\
  2075. * InitializeClientPfnArrays
  2076. *
  2077. * This routine gets called by the client to tell the kernel where
  2078. * its important functions can be located.
  2079. *
  2080. * 18-Apr-1995 JimA Created.
  2081. \***************************************************************************/
  2082. NTSTATUS InitializeClientPfnArrays(
  2083. CONST PFNCLIENT *ppfnClientA,
  2084. CONST PFNCLIENT *ppfnClientW,
  2085. CONST PFNCLIENTWORKER *ppfnClientWorker,
  2086. HANDLE hModUser)
  2087. {
  2088. static BOOL fHaveClientPfns = FALSE;
  2089. /*
  2090. * Remember client side addresses in this global structure. These are
  2091. * always constant, so this is ok. Note that if either of the pointers
  2092. * are invalid, the exception will be handled in the thunk and
  2093. * fHaveClientPfns will not be set.
  2094. */
  2095. if (!fHaveClientPfns && ppfnClientA != NULL) {
  2096. if (!ISCSRSS()) {
  2097. RIPMSG0(RIP_WARNING, "InitializeClientPfnArrays failed !csrss");
  2098. return STATUS_ACCESS_DENIED;
  2099. }
  2100. gpsi->apfnClientA = *ppfnClientA;
  2101. gpsi->apfnClientW = *ppfnClientW;
  2102. gpsi->apfnClientWorker = *ppfnClientWorker;
  2103. gpfnwp[ICLS_BUTTON] = gpsi->apfnClientW.pfnButtonWndProc;
  2104. gpfnwp[ICLS_EDIT] = gpsi->apfnClientW.pfnDefWindowProc;
  2105. gpfnwp[ICLS_STATIC] = gpsi->apfnClientW.pfnStaticWndProc;
  2106. gpfnwp[ICLS_LISTBOX] = gpsi->apfnClientW.pfnListBoxWndProc;
  2107. gpfnwp[ICLS_SCROLLBAR] = (PROC)xxxSBWndProc;
  2108. gpfnwp[ICLS_COMBOBOX] = gpsi->apfnClientW.pfnComboBoxWndProc;
  2109. gpfnwp[ICLS_DESKTOP] = (PROC)xxxDesktopWndProc;
  2110. gpfnwp[ICLS_DIALOG] = gpsi->apfnClientW.pfnDialogWndProc;
  2111. gpfnwp[ICLS_MENU] = (PROC)xxxMenuWindowProc;
  2112. gpfnwp[ICLS_SWITCH] = (PROC)xxxSwitchWndProc;
  2113. gpfnwp[ICLS_ICONTITLE] = gpsi->apfnClientW.pfnTitleWndProc;
  2114. gpfnwp[ICLS_MDICLIENT] = gpsi->apfnClientW.pfnMDIClientWndProc;
  2115. gpfnwp[ICLS_COMBOLISTBOX] = gpsi->apfnClientW.pfnComboListBoxProc;
  2116. gpfnwp[ICLS_TOOLTIP] = (PROC)xxxTooltipWndProc;
  2117. /*
  2118. * Change this assert when new classes are added.
  2119. */
  2120. UserAssert(ICLS_MAX == ICLS_GHOST + 1);
  2121. hModClient = hModUser;
  2122. fHaveClientPfns = TRUE;
  2123. }
  2124. /*
  2125. * Assert that user32.dll on the client side has loaded at the correct
  2126. * address.
  2127. */
  2128. UserAssert(ppfnClientA == NULL ||
  2129. gpsi->apfnClientA.pfnButtonWndProc == ppfnClientA->pfnButtonWndProc);
  2130. return STATUS_SUCCESS;
  2131. }
  2132. /***************************************************************************\
  2133. * GetKbdLangSwitch
  2134. *
  2135. * read the kbd language hotkey setting - if any - from the registry and set
  2136. * LangToggle[] appropriately.
  2137. *
  2138. * values are:
  2139. * 1 : VK_MENU (this is the default)
  2140. * 2 : VK_CONTROL
  2141. * 3 : none
  2142. * History:
  2143. \***************************************************************************/
  2144. BOOL GetKbdLangSwitch(
  2145. PUNICODE_STRING pProfileUserName)
  2146. {
  2147. DWORD dwToggle;
  2148. LCID lcid;
  2149. FastGetProfileIntW(pProfileUserName,
  2150. PMAP_UKBDLAYOUTTOGGLE,
  2151. TEXT("Hotkey"),
  2152. 1,
  2153. &dwToggle,
  2154. 0);
  2155. gbGraveKeyToggle = FALSE;
  2156. switch (dwToggle) {
  2157. case 4:
  2158. /*
  2159. * Grave accent keyboard switch for thai locales
  2160. */
  2161. ZwQueryDefaultLocale(FALSE, &lcid);
  2162. gbGraveKeyToggle = (PRIMARYLANGID(lcid) == LANG_THAI) ? TRUE : FALSE;
  2163. /*
  2164. * fall through (intentional) and disable the ctrl/alt toggle mechanism
  2165. */
  2166. case 3:
  2167. gLangToggle[0].bVkey = 0;
  2168. gLangToggle[0].bScan = 0;
  2169. break;
  2170. case 2:
  2171. gLangToggle[0].bVkey = VK_CONTROL;
  2172. break;
  2173. default:
  2174. gLangToggle[0].bVkey = VK_MENU;
  2175. break;
  2176. }
  2177. return TRUE;
  2178. }
  2179. /***************************************************************************\
  2180. * HideMouseTrails
  2181. *
  2182. * Hide the mouse trails one by one.
  2183. *
  2184. * History:
  2185. * 04-10-00 MHamid Created.
  2186. \***************************************************************************/
  2187. VOID HideMouseTrails(
  2188. PWND pwnd,
  2189. UINT message,
  2190. UINT_PTR nID,
  2191. LPARAM lParam)
  2192. {
  2193. if (gMouseTrailsToHide > 0) {
  2194. if (InterlockedDecrement(&gMouseTrailsToHide) < gMouseTrails) {
  2195. GreMovePointer(gpDispInfo->hDev, gpsi->ptCursor.x, gpsi->ptCursor.y,
  2196. MP_PROCEDURAL);
  2197. }
  2198. }
  2199. UNREFERENCED_PARAMETER(pwnd);
  2200. UNREFERENCED_PARAMETER(message);
  2201. UNREFERENCED_PARAMETER(nID);
  2202. UNREFERENCED_PARAMETER(lParam);
  2203. }
  2204. /***************************************************************************\
  2205. *
  2206. * SetMouseTrails
  2207. *
  2208. * n = 0,1 turn off mouse trails.
  2209. * n > 1 turn on mouse trails (Trials = n-1).
  2210. *
  2211. \***************************************************************************/
  2212. VOID SetMouseTrails(
  2213. UINT n)
  2214. {
  2215. CheckCritIn();
  2216. SetPointer(FALSE);
  2217. gMouseTrails = n ? n-1 : n;
  2218. SetPointer(TRUE);
  2219. if (!IsRemoteConnection() && (!!gtmridMouseTrails ^ !!gMouseTrails)) {
  2220. if (gMouseTrails) {
  2221. /*
  2222. * Create the gtmridMouseTrails timer in the desktop thread,
  2223. * becuase if we creat it here it will get killed when the current
  2224. * thread (App thread calling SPI_SETMOUSETRAILS) get destroied.
  2225. */
  2226. _PostMessage(gTermIO.ptiDesktop->pDeskInfo->spwnd, WM_CREATETRAILTIMER, 0, 0);
  2227. } else {
  2228. FindTimer(NULL, gtmridMouseTrails, TMRF_RIT, TRUE);
  2229. gtmridMouseTrails = 0;
  2230. }
  2231. }
  2232. }
  2233. #ifdef IMM_PER_LOGON
  2234. extern BOOL IsIMMEnabledSystem(VOID);
  2235. extern BOOL IsCTFIMEEnabledSystem(VOID);
  2236. BOOL UpdatePerUserImmEnabling(
  2237. VOID)
  2238. {
  2239. /*
  2240. * Update the IME enabling flag
  2241. */
  2242. SET_OR_CLEAR_SRVIF(SRVIF_IME, IsIMMEnabledSystem());
  2243. RIPMSGF1(RIP_VERBOSE, "New Imm flag = %d", !!IS_IME_ENABLED());
  2244. /*
  2245. * Update the CTFIME enabling flag
  2246. */
  2247. SET_OR_CLEAR_SRVIF(SRVIF_CTFIME_ENABLED, IsCTFIMEEnabledSystem());
  2248. RIPMSG1(RIP_VERBOSE, "_UpdatePerUserImmEnabling: new CTFIME flag = %d", !!IS_CICERO_ENABLED());
  2249. return TRUE;
  2250. }
  2251. #endif
  2252. /***************************************************************************\
  2253. * xxxUpdatePerUserSystemParameters
  2254. *
  2255. * Called by winlogon to set Window system parameters to the current user's
  2256. * profile.
  2257. *
  2258. * 18-Sep-1992 IanJa Created.
  2259. * 18-Nov-1993 SanfordS Moved more winlogon init code to here for speed.
  2260. * 31-Mar-2001 Msadek Changed parm from BOOL to flags for TS Slow Link
  2261. * Perf DCR.
  2262. * 02-Feb-2002 MMcCr Added SPI_SETBLOCKSENDINPUTRESETS feature
  2263. \***************************************************************************/
  2264. BOOL xxxUpdatePerUserSystemParameters(
  2265. DWORD dwFlags)
  2266. {
  2267. /*
  2268. * NB - Any local variables that are used in appiPolicy must be initialized.
  2269. * Otherwise, during a policy change, it is possible for them to be used w/o
  2270. * being initialized and all heck breaks loose. Windows Bug #314150.
  2271. */
  2272. int i;
  2273. HANDLE hKey;
  2274. DWORD dwFontSmoothing = GreGetFontEnumeration();
  2275. DWORD dwFontSmoothingContrast;
  2276. DWORD dwFontSmoothingOrientation;
  2277. BOOL fDragFullWindows = TEST_PUDF(PUDF_DRAGFULLWINDOWS);
  2278. TL tlName;
  2279. PUNICODE_STRING pProfileUserName = NULL;
  2280. DWORD dwPolicyFlags = 0;
  2281. DWORD dwData;
  2282. BOOL bPolicyChange;
  2283. BOOL bUserLoggedOn;
  2284. BOOL bRemoteSettings;
  2285. SPINFO spiPolicy[] = {
  2286. { PMAP_DESKTOP, SPI_SETBLOCKSENDINPUTRESETS, STR_BLOCKSENDINPUTRESETS, 0 },
  2287. { PMAP_DESKTOP, SPI_SETSCREENSAVETIMEOUT, STR_SCREENSAVETIMEOUT, 0 },
  2288. { PMAP_DESKTOP, SPI_SETSCREENSAVEACTIVE, STR_SCREENSAVEACTIVE, 0 },
  2289. { PMAP_DESKTOP, SPI_SETDRAGHEIGHT, STR_DRAGHEIGHT, 4 },
  2290. { PMAP_DESKTOP, SPI_SETDRAGWIDTH, STR_DRAGWIDTH, 4 },
  2291. { PMAP_DESKTOP, SPI_SETWHEELSCROLLLINES, STR_WHEELSCROLLLINES, 3 },
  2292. };
  2293. SPINFO spiNotPolicy[] = {
  2294. { PMAP_KEYBOARD, SPI_SETKEYBOARDDELAY, STR_KEYDELAY, 0 },
  2295. { PMAP_KEYBOARD, SPI_SETKEYBOARDSPEED, STR_KEYSPEED, 15 },
  2296. { PMAP_MOUSE, SPI_SETDOUBLECLICKTIME, STR_DBLCLKSPEED, 500 },
  2297. { PMAP_MOUSE, SPI_SETDOUBLECLKWIDTH, STR_DOUBLECLICKWIDTH, 4 },
  2298. { PMAP_MOUSE, SPI_SETDOUBLECLKHEIGHT, STR_DOUBLECLICKHEIGHT, 4 },
  2299. { PMAP_MOUSE, SPI_SETSNAPTODEFBUTTON, STR_SNAPTO, 0 },
  2300. { PMAP_WINDOWSU, SPI_SETMENUDROPALIGNMENT, STR_MENUDROPALIGNMENT, 0 },
  2301. { PMAP_INPUTMETHOD, SPI_SETSHOWIMEUI, STR_SHOWIMESTATUS, 1 },
  2302. };
  2303. PROFINTINFO apiiPolicy[] = {
  2304. { PMAP_DESKTOP, (LPWSTR)STR_MENUSHOWDELAY, 400, &gdtMNDropDown },
  2305. { PMAP_DESKTOP, (LPWSTR)STR_DRAGFULLWINDOWS, 2, &fDragFullWindows },
  2306. { PMAP_DESKTOP, (LPWSTR)STR_FASTALTTABROWS, 3, &gnFastAltTabRows },
  2307. { PMAP_DESKTOP, (LPWSTR)STR_FASTALTTABCOLUMNS, 7, &gnFastAltTabColumns },
  2308. { PMAP_DESKTOP, (LPWSTR)STR_MAXLEFTOVERLAPCHARS, 3, &(gpsi->wMaxLeftOverlapChars) },
  2309. { PMAP_DESKTOP, (LPWSTR)STR_MAXRIGHTOVERLAPCHARS, 3, &(gpsi->wMaxRightOverlapChars) },
  2310. { PMAP_DESKTOP, (LPWSTR)STR_FONTSMOOTHING, 0, &dwFontSmoothing },
  2311. { 0, NULL, 0, NULL }
  2312. };
  2313. PROFINTINFO apiiNoPolicy[] = {
  2314. { PMAP_MOUSE, (LPWSTR)STR_MOUSETHRESH1, 6, &gMouseThresh1 },
  2315. { PMAP_MOUSE, (LPWSTR)STR_MOUSETHRESH2, 10, &gMouseThresh2 },
  2316. { PMAP_MOUSE, (LPWSTR)STR_MOUSESPEED, 1, &gMouseSpeed },
  2317. { PMAP_INPUTMETHOD, (LPWSTR)STR_HEXNUMPAD, 0, &gfEnableHexNumpad },
  2318. { 0, NULL, 0, NULL }
  2319. };
  2320. UserAssert(IsWinEventNotifyDeferredOK());
  2321. bPolicyChange = dwFlags & UPUSP_POLICYCHANGE;
  2322. bUserLoggedOn = dwFlags & UPUSP_USERLOGGEDON;
  2323. bRemoteSettings = dwFlags & UPUSP_REMOTESETTINGS;
  2324. /*
  2325. * Make sure the caller is the logon process.
  2326. */
  2327. if (PsGetCurrentProcessId() != gpidLogon) {
  2328. if (!bPolicyChange) {
  2329. RIPMSG0(RIP_WARNING, "Access denied in xxxUpdatePerUserSystemParameters");
  2330. }
  2331. return FALSE;
  2332. }
  2333. pProfileUserName = CreateProfileUserName(&tlName);
  2334. /*
  2335. * If the desktop policy hasn't changed and we came here because we
  2336. * thought it had, we're done.
  2337. */
  2338. if (bPolicyChange && !bRemoteSettings) {
  2339. if (!CheckDesktopPolicyChange(pProfileUserName)) {
  2340. FreeProfileUserName(pProfileUserName, &tlName);
  2341. return FALSE;
  2342. }
  2343. dwPolicyFlags = POLICY_ONLY;
  2344. UserAssert(!bUserLoggedOn);
  2345. }
  2346. /*
  2347. * If new user is logging in, we need to recheck for
  2348. * user policy changes.
  2349. */
  2350. if (bUserLoggedOn) {
  2351. gdwPolicyFlags |= POLICY_USER;
  2352. }
  2353. /*
  2354. * We don't want remote settings to be read all the time so spcify it here
  2355. * if the caller wants to.Update it here since we do not save it in
  2356. * gdwPolicyFlags [msadek].
  2357. */
  2358. if (bRemoteSettings) {
  2359. dwPolicyFlags |= POLICY_REMOTE;
  2360. }
  2361. /*
  2362. * Get the timeout for low level hooks from the registry.
  2363. */
  2364. dwData = 300;
  2365. FastGetProfileValue(pProfileUserName,
  2366. PMAP_DESKTOP,
  2367. (LPWSTR)STR_LLHOOKSTIMEOUT,
  2368. (LPBYTE)&dwData,
  2369. (LPBYTE)&gnllHooksTimeout,
  2370. sizeof(int),
  2371. dwPolicyFlags);
  2372. /*
  2373. * Control Panel User Preferences.
  2374. */
  2375. LoadCPUserPreferences(pProfileUserName, dwPolicyFlags);
  2376. #ifdef LAME_BUTTON
  2377. /*
  2378. * Lame button text.
  2379. */
  2380. FastGetProfileValue(pProfileUserName,
  2381. PMAP_DESKTOP,
  2382. (LPWSTR)STR_LAMEBUTTONENABLED,
  2383. NULL,
  2384. (LPBYTE)&gdwLameFlags,
  2385. sizeof(DWORD),
  2386. dwPolicyFlags);
  2387. #endif // LAME_BUTTON
  2388. if (!bPolicyChange) {
  2389. /*
  2390. * Set syscolors from registry.
  2391. */
  2392. xxxODI_ColorInit(pProfileUserName);
  2393. LW_LoadResources(pProfileUserName);
  2394. /*
  2395. * This is the initialization from Chicago.
  2396. */
  2397. xxxSetWindowNCMetrics(pProfileUserName, NULL, TRUE, -1); // Colors must be set first
  2398. SetMinMetrics(pProfileUserName, NULL);
  2399. SetIconMetrics(pProfileUserName, NULL);
  2400. /*
  2401. * Read the keyboard layout switching hot key.
  2402. */
  2403. GetKbdLangSwitch(pProfileUserName);
  2404. /*
  2405. * Set the default thread locale for the system based on the value
  2406. * in the current user's registry profile.
  2407. */
  2408. ZwSetDefaultLocale( TRUE, 0 );
  2409. /*
  2410. * Set the default UI language based on the value in the current
  2411. * user's registry profile.
  2412. */
  2413. ZwSetDefaultUILanguage(0);
  2414. /*
  2415. * And then Get it.
  2416. */
  2417. ZwQueryDefaultUILanguage(&(gpsi->UILangID));
  2418. /*
  2419. * Now load strings using the currnet UILangID.
  2420. */
  2421. xxxLoadSomeStrings();
  2422. /*
  2423. * Destroy the desktop system menus, so that they're recreated with
  2424. * the correct UI language if the current user's UI language is
  2425. * different from the previous one. This is done by finding the
  2426. * interactive window station and destroying all its desktops's
  2427. * system menus.
  2428. */
  2429. if (grpWinStaList != NULL) {
  2430. PDESKTOP pdesk;
  2431. PMENU pmenu;
  2432. UserAssert(!(grpWinStaList->dwWSF_Flags & WSF_NOIO));
  2433. for (pdesk = grpWinStaList->rpdeskList; pdesk != NULL; pdesk = pdesk->rpdeskNext) {
  2434. if (pdesk->spmenuSys != NULL) {
  2435. pmenu = pdesk->spmenuSys;
  2436. if (UnlockDesktopSysMenu(&pdesk->spmenuSys)) {
  2437. _DestroyMenu(pmenu);
  2438. }
  2439. }
  2440. if (pdesk->spmenuDialogSys != NULL) {
  2441. pmenu = pdesk->spmenuDialogSys;
  2442. if (UnlockDesktopSysMenu(&pdesk->spmenuDialogSys)) {
  2443. _DestroyMenu(pmenu);
  2444. }
  2445. }
  2446. }
  2447. }
  2448. xxxUpdateSystemCursorsFromRegistry(pProfileUserName);
  2449. /*
  2450. * now go set a bunch of random values from the win.ini file.
  2451. */
  2452. for (i = 0; i < ARRAY_SIZE(spiNotPolicy); i++) {
  2453. if (FastGetProfileIntFromID(pProfileUserName,
  2454. spiNotPolicy[i].idSection,
  2455. spiNotPolicy[i].idRes,
  2456. spiNotPolicy[i].def,
  2457. &dwData,
  2458. 0)) {
  2459. xxxSystemParametersInfo(spiNotPolicy[i].id, dwData, 0L, 0);
  2460. }
  2461. }
  2462. FastGetProfileIntsW(pProfileUserName, apiiNoPolicy, 0);
  2463. }
  2464. /*
  2465. * Reset desktop pattern now. Note no parameters. It just goes off
  2466. * and reads the registry and sets the desktop pattern.
  2467. */
  2468. xxxSystemParametersInfo(SPI_SETDESKPATTERN, (UINT)-1, 0L, 0); // 265 version
  2469. /*
  2470. * Initialize IME show status
  2471. */
  2472. if (bUserLoggedOn) {
  2473. gfIMEShowStatus = IMESHOWSTATUS_NOTINITIALIZED;
  2474. }
  2475. /*
  2476. * Now go set a bunch of random values from the registry.
  2477. */
  2478. for (i = 0; i < ARRAY_SIZE(spiPolicy); i++) {
  2479. if (FastGetProfileIntFromID(pProfileUserName,
  2480. spiPolicy[i].idSection,
  2481. spiPolicy[i].idRes,
  2482. spiPolicy[i].def,
  2483. &dwData,
  2484. dwPolicyFlags)) {
  2485. xxxSystemParametersInfo(spiPolicy[i].id, dwData, 0L, 0);
  2486. }
  2487. }
  2488. /*
  2489. * Read profile integers and do any fixups.
  2490. */
  2491. FastGetProfileIntsW(pProfileUserName, apiiPolicy, dwPolicyFlags);
  2492. if (gnFastAltTabColumns < 2) {
  2493. gnFastAltTabColumns = 7;
  2494. }
  2495. if (gnFastAltTabRows < 1) {
  2496. gnFastAltTabRows = 3;
  2497. }
  2498. /*
  2499. * If this is the first time the user logs on, set the DragFullWindows
  2500. * to the default. If we have an accelerated device, enable full drag.
  2501. */
  2502. if (fDragFullWindows == 2) {
  2503. WCHAR szTemp[40], szDragFullWindows[40];
  2504. SET_OR_CLEAR_PUDF(
  2505. PUDF_DRAGFULLWINDOWS,
  2506. GreGetDeviceCaps(gpDispInfo->hdcScreen, BLTALIGNMENT) == 0);
  2507. if (bUserLoggedOn) {
  2508. swprintf(szTemp, L"%d", TEST_BOOL_PUDF(PUDF_DRAGFULLWINDOWS));
  2509. ServerLoadString(hModuleWin,
  2510. STR_DRAGFULLWINDOWS,
  2511. szDragFullWindows,
  2512. ARRAY_SIZE(szDragFullWindows));
  2513. FastWriteProfileStringW(pProfileUserName,
  2514. PMAP_DESKTOP,
  2515. szDragFullWindows,
  2516. szTemp);
  2517. }
  2518. } else {
  2519. SET_OR_CLEAR_PUDF(PUDF_DRAGFULLWINDOWS, fDragFullWindows);
  2520. }
  2521. /*
  2522. * !!!LATER!!! (adams) See if the following profile retrievals can't
  2523. * be done in the "spi" array above (e.g. SPI_SETSNAPTO).
  2524. */
  2525. /*
  2526. * For remote connections or remote assistance, we may not want a
  2527. * blinking caret for perf reasons. So, we try to read the value from
  2528. * the registry, if there is one set. If nothing is set, we will
  2529. * default to whatever is on desktop.
  2530. */
  2531. dwData = gpsi->dtCaretBlink;
  2532. if (FastGetProfileIntFromID(pProfileUserName,
  2533. PMAP_DESKTOP,
  2534. STR_BLINK,
  2535. 500,
  2536. &dwData,
  2537. bRemoteSettings? dwPolicyFlags : bPolicyChange)) {
  2538. _SetCaretBlinkTime(dwData);
  2539. }
  2540. if (!bPolicyChange) {
  2541. /*
  2542. * Set mouse settings
  2543. */
  2544. FastGetProfileIntFromID(pProfileUserName, PMAP_MOUSE, STR_MOUSESENSITIVITY, MOUSE_SENSITIVITY_DEFAULT, &gMouseSensitivity, 0);
  2545. if ((gMouseSensitivity < MOUSE_SENSITIVITY_MIN) || (gMouseSensitivity > MOUSE_SENSITIVITY_MAX)) {
  2546. gMouseSensitivity = MOUSE_SENSITIVITY_DEFAULT;
  2547. }
  2548. gMouseSensitivityFactor = CalculateMouseSensitivity(gMouseSensitivity);
  2549. #ifdef SUBPIXEL_MOUSE
  2550. ReadDefaultAccelerationCurves(pProfileUserName);
  2551. ResetMouseAccelerationCurves();
  2552. #endif
  2553. /*
  2554. * Set mouse trails.
  2555. */
  2556. FastGetProfileIntFromID(pProfileUserName, PMAP_MOUSE, STR_MOUSETRAILS, 0, &dwData, 0);
  2557. SetMouseTrails(dwData);
  2558. /*
  2559. * Font Information
  2560. */
  2561. FastGetProfileIntW(pProfileUserName, PMAP_TRUETYPE, TEXT("TTOnly"), FALSE, &dwData, 0);
  2562. GreSetFontEnumeration(dwData);
  2563. /*
  2564. * Window animation
  2565. */
  2566. FastGetProfileIntFromID(pProfileUserName, PMAP_METRICS, STR_MINANIMATE, TRUE, &dwData, 0);
  2567. SET_OR_CLEAR_PUDF(PUDF_ANIMATE, dwData);
  2568. /*
  2569. * Mouse tracking variables
  2570. */
  2571. FastGetProfileIntFromID(pProfileUserName, PMAP_MOUSE, STR_MOUSEHOVERWIDTH, SYSMET(CXDOUBLECLK), &gcxMouseHover, 0);
  2572. FastGetProfileIntFromID(pProfileUserName, PMAP_MOUSE, STR_MOUSEHOVERHEIGHT, SYSMET(CYDOUBLECLK), &gcyMouseHover, 0);
  2573. FastGetProfileIntFromID(pProfileUserName, PMAP_MOUSE, STR_MOUSEHOVERTIME, gdtMNDropDown, &gdtMouseHover, 0);
  2574. }
  2575. /*
  2576. * Initial Keyboard state: ScrollLock, NumLock and CapsLock state;
  2577. * global (per-user) kbd layout attributes (such as ShiftLock/CapsLock)
  2578. */
  2579. if (!bPolicyChange) {
  2580. UpdatePerUserKeyboardIndicators(pProfileUserName);
  2581. UpdatePerUserKeyboardMappings(pProfileUserName);
  2582. FastGetProfileDwordW(pProfileUserName, PMAP_UKBDLAYOUT, L"Attributes", 0, &gdwKeyboardAttributes, 0);
  2583. gdwKeyboardAttributes = KLL_GLOBAL_ATTR_FROM_KLF(gdwKeyboardAttributes);
  2584. xxxUpdatePerUserAccessPackSettings(pProfileUserName);
  2585. }
  2586. /*
  2587. * If we successfully opened this, we assume we have a network.
  2588. */
  2589. if (hKey = OpenCacheKeyEx(NULL, PMAP_NETWORK, KEY_READ, NULL)) {
  2590. RIPMSG0(RIP_WARNING | RIP_NONAME, "");
  2591. SYSMET(NETWORK) = RNC_NETWORKS;
  2592. ZwClose(hKey);
  2593. }
  2594. SYSMET(NETWORK) |= RNC_LOGON;
  2595. /*
  2596. * Font smoothing
  2597. */
  2598. /* clear the flags from what could have been set for the previous user */
  2599. GreSetFontEnumeration(FE_SET_AA);
  2600. GreSetFontEnumeration(FE_SET_CT);
  2601. if (dwFontSmoothing & FE_AA_ON)
  2602. GreSetFontEnumeration( dwFontSmoothing | FE_SET_AA );
  2603. if (UPDWORDValue(SPI_GETFONTSMOOTHINGTYPE) & FE_FONTSMOOTHINGCLEARTYPE)
  2604. GreSetFontEnumeration( dwFontSmoothing | FE_SET_CT | FE_CT_ON);
  2605. dwFontSmoothingContrast = UPDWORDValue(SPI_GETFONTSMOOTHINGCONTRAST);
  2606. if (dwFontSmoothingContrast == 0)
  2607. dwFontSmoothingContrast = DEFAULT_CT_CONTRAST;
  2608. GreSetFontContrast(dwFontSmoothingContrast);
  2609. dwFontSmoothingOrientation = UPDWORDValue(SPI_GETFONTSMOOTHINGORIENTATION);
  2610. GreSetLCDOrientation(dwFontSmoothingOrientation);
  2611. /*
  2612. * Desktop Build Number Painting
  2613. */
  2614. if (USER_SHARED_DATA->SystemExpirationDate.QuadPart || gfUnsignedDrivers) {
  2615. gdwCanPaintDesktop = 1;
  2616. } else {
  2617. FastGetProfileDwordW(pProfileUserName, PMAP_DESKTOP, L"PaintDesktopVersion", 0, &gdwCanPaintDesktop, dwPolicyFlags);
  2618. }
  2619. if (!bPolicyChange) {
  2620. FastGetProfileStringW(pProfileUserName,
  2621. PMAP_WINLOGON,
  2622. TEXT("DefaultUserName"),
  2623. TEXT("Unknown"),
  2624. gszUserName,
  2625. ARRAY_SIZE(gszUserName),
  2626. 0);
  2627. FastGetProfileStringW(pProfileUserName,
  2628. PMAP_WINLOGON,
  2629. TEXT("DefaultDomainName"),
  2630. TEXT("Unknown"),
  2631. gszDomainName,
  2632. ARRAY_SIZE(gszDomainName),
  2633. 0);
  2634. FastGetProfileStringW(pProfileUserName,
  2635. PMAP_COMPUTERNAME,
  2636. TEXT("ComputerName"),
  2637. TEXT("Unknown"),
  2638. gszComputerName,
  2639. ARRAY_SIZE(gszComputerName),
  2640. 0);
  2641. }
  2642. FreeProfileUserName(pProfileUserName, &tlName);
  2643. /*
  2644. * Do this if we are here for real policy change
  2645. * i.e. not a remote settings policy change.
  2646. */
  2647. if (dwFlags == UPUSP_POLICYCHANGE) {
  2648. xxxUserResetDisplayDevice();
  2649. }
  2650. return TRUE;
  2651. }
  2652. /*
  2653. * Called by InitOemXlateTables via SFI_INITANSIOEM
  2654. */
  2655. VOID InitAnsiOem(PCHAR pOemToAnsi, PCHAR pAnsiToOem)
  2656. {
  2657. UserAssert(gpsi != NULL);
  2658. UserAssert(pOemToAnsi != NULL);
  2659. UserAssert(pAnsiToOem != NULL);
  2660. try {
  2661. ProbeForRead(pOemToAnsi, NCHARS, sizeof(BYTE));
  2662. ProbeForRead(pAnsiToOem, NCHARS, sizeof(BYTE));
  2663. RtlCopyMemory(gpsi->acOemToAnsi, pOemToAnsi, NCHARS);
  2664. RtlCopyMemory(gpsi->acAnsiToOem, pAnsiToOem, NCHARS);
  2665. } except (W32ExceptionHandler(FALSE, RIP_WARNING)) {
  2666. }
  2667. }
  2668. /***************************************************************************\
  2669. * RegisterLPK
  2670. *
  2671. * Called by InitializeLpkHooks on the client side after an LPK is
  2672. * loaded for the current process.
  2673. *
  2674. * 05-Nov-1996 GregoryW Created.
  2675. \***************************************************************************/
  2676. VOID RegisterLPK(
  2677. DWORD dwLpkEntryPoints)
  2678. {
  2679. PpiCurrent()->dwLpkEntryPoints = dwLpkEntryPoints;
  2680. }
  2681. /***************************************************************************\
  2682. * Enforce color-depth dependent settings on systems with less
  2683. * then 256 colors.
  2684. *
  2685. * 2/13/1998 vadimg created
  2686. \***************************************************************************/
  2687. VOID EnforceColorDependentSettings(VOID)
  2688. {
  2689. if (gpDispInfo->fAnyPalette) {
  2690. gbDisableAlpha = TRUE;
  2691. } else if (GreGetDeviceCaps(gpDispInfo->hdcScreen, NUMCOLORS) == -1) {
  2692. gbDisableAlpha = FALSE;
  2693. } else {
  2694. gbDisableAlpha = TRUE;
  2695. }
  2696. }
  2697. #if DBG
  2698. VOID InitGlobalThreadLockArray(
  2699. DWORD dwIndex)
  2700. {
  2701. PTL pTLArray = gpaThreadLocksArrays[dwIndex];
  2702. int i;
  2703. for (i = 0; i < MAX_THREAD_LOCKS - 1; i++) {
  2704. pTLArray[i].next = &pTLArray[i + 1];
  2705. }
  2706. pTLArray[MAX_THREAD_LOCKS - 1].next = NULL;
  2707. }
  2708. #endif
  2709. /***************************************************************************\
  2710. * CheckLUIDDosDevicesEnabled
  2711. *
  2712. * Checks if LUID DosDevices are Enabled.
  2713. *
  2714. * 8/20/2000 ELi created
  2715. \***************************************************************************/
  2716. VOID CheckLUIDDosDevicesEnabled(
  2717. PBOOL pResult)
  2718. {
  2719. ULONG LUIDDeviceMapsEnabled;
  2720. NTSTATUS Status;
  2721. UserAssert(pResult != NULL);
  2722. Status = NtQueryInformationProcess(NtCurrentProcess(),
  2723. ProcessLUIDDeviceMapsEnabled,
  2724. &LUIDDeviceMapsEnabled,
  2725. sizeof(LUIDDeviceMapsEnabled),
  2726. NULL);
  2727. if (NT_SUCCESS(Status)) {
  2728. *pResult = (LUIDDeviceMapsEnabled != 0);
  2729. } else {
  2730. *pResult = FALSE;
  2731. }
  2732. }