00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
#include "precomp.h"
00015
#pragma hdrstop
00016
00017 typedef struct _DESKTOP_CONTEXT {
00018 PUNICODE_STRING
pstrDevice;
00019 LPDEVMODE
lpDevMode;
00020 DWORD dwFlags;
00021 }
DESKTOP_CONTEXT, *
PDESKTOP_CONTEXT;
00022
00023 extern BOOL fGdiEnabled;
00024
00025
00026
00027
00028 PEPROCESS gProcessInUse;
00029 HANDLE
gHandleInUse;
00030
00031
00032
00033
00034
#if DBG
00035
DWORD gDesktopsBusy;
00036
#endif
00037
00038
VOID FreeView(
00039
PEPROCESS Process,
00040
PDESKTOP pdesk);
00041
00042
#ifdef POOL_INSTR
00043
extern FAST_MUTEX* gpAllocFastMutex;
00044
#endif // POOL_INSTR
00045
00046
00047 PVOID
DesktopAlloc(
00048
PDESKTOP pdesk,
00049 UINT uSize,
00050 DWORD tag)
00051 {
00052
if (pdesk->
dwDTFlags &
DF_DESTROYED) {
00053 RIPMSG2(RIP_ERROR,
00054
"DesktopAlloc: tag %d pdesk %#p is destroyed",
00055 tag,
00056 pdesk);
00057
return NULL;
00058 }
00059
00060
return Win32HeapAlloc(pdesk->
pheapDesktop, uSize, tag, 0);
00061 }
00062
00063
#if DBG
00064
00065 WCHAR s_strName[64];
00066 WCHAR s_strNameNull[] =
L"null";
00067
00068
00069
00070
00071
00072
00073
00074
00075 PWCHAR GetDesktopName(
00076
PDESKTOP pdesk)
00077 {
00078
POBJECT_HEADER pHead;
00079
POBJECT_HEADER_NAME_INFO pNameInfo;
00080
00081
if (pdesk ==
NULL) {
00082
return s_strNameNull;
00083 }
00084 pHead =
OBJECT_TO_OBJECT_HEADER(pdesk);
00085 pNameInfo = (
POBJECT_HEADER_NAME_INFO)((
char*)pHead - pHead->
NameInfoOffset);
00086
00087 UserAssert(pNameInfo->
Name.Length <
sizeof(s_strName));
00088
00089 RtlCopyMemory(s_strName, pNameInfo->
Name.Buffer, pNameInfo->
Name.Length);
00090 s_strName[pNameInfo->
Name.Length /
sizeof(WCHAR)] = 0;
00091
00092
return s_strName;
00093 }
00094
00095
#endif // DBG
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
#ifdef LOCK_MOUSE_CODE
00109
#pragma alloc_text(MOUSE, xxxDesktopThread)
00110
#endif
00111
00112 #define OBJECTS_COUNT 4
00113
00114 VOID xxxDesktopThread(
00115
PTERMINAL pTerm)
00116 {
00117 KPRIORITY Priority;
00118
PTHREADINFO ptiCurrent;
00119
PQ pqOriginal;
00120 UNICODE_STRING strThreadName;
00121
PKEVENT *apRITEvents;
00122
PKEVENT pEvent;
00123
MSGWAITCALLBACK pfnHidChangeRoutine =
NULL;
00124
DWORD nEvents = 0;
00125
UINT idMouseInput;
00126
UINT idDesktopDestroy;
00127
UINT idPumpMessages;
00128
UINT idHungThread;
00129
PKWAIT_BLOCK WaitBlockArray;
00130
00131 UserAssert(pTerm !=
NULL);
00132
00133
00134
00135
00136 Priority = LOW_REALTIME_PRIORITY;
00137 ZwSetInformationThread(NtCurrentThread(),
00138 ThreadPriority,
00139 &Priority,
00140
sizeof(KPRIORITY));
00141
00142
00143
00144
00145
00146
00147
if (pTerm->
dwTERMF_Flags &
TERMF_NOIO) {
00148
RtlInitUnicodeString(&strThreadName,
L"NOIO_DT");
00149 }
else {
00150
RtlInitUnicodeString(&strThreadName,
L"IO_DT");
00151 }
00152
00153
if (!
NT_SUCCESS(
InitSystemThread(&strThreadName))) {
00154 pTerm->
dwTERMF_Flags |=
TERMF_DTINITFAILED;
00155
KeSetEvent(pTerm->
pEventTermInit,
EVENT_INCREMENT,
FALSE);
00156 RIPMSG0(RIP_ERROR,
"Fail to create the desktop thread");
00157
return;
00158 }
00159
00160 ptiCurrent =
PtiCurrentShared();
00161
00162 pTerm->
ptiDesktop = ptiCurrent;
00163 pTerm->
pqDesktop = pqOriginal = ptiCurrent->
pq;
00164
00165 (pqOriginal->
cLockCount)++;
00166 ptiCurrent->
pDeskInfo = &
diStatic;
00167
00168
00169
00170
00171
00172
00173 ptiCurrent->
pwinsta =
NULL;
00174
00175
00176
00177
00178
00179 apRITEvents = UserAllocPoolNonPaged((
OBJECTS_COUNT *
sizeof(
PKEVENT)),
00180 TAG_SYSTEM);
00181
00182
if (apRITEvents ==
NULL) {
00183 pTerm->
dwTERMF_Flags |=
TERMF_DTINITFAILED;
00184
KeSetEvent(pTerm->
pEventTermInit,
EVENT_INCREMENT,
FALSE);
00185
return;
00186 }
00187
00188 WaitBlockArray = UserAllocPoolNonPaged((
OBJECTS_COUNT *
sizeof(
KWAIT_BLOCK)),
00189 TAG_SYSTEM);
00190
if (WaitBlockArray ==
NULL) {
00191 pTerm->
dwTERMF_Flags |=
TERMF_DTINITFAILED;
00192
KeSetEvent(pTerm->
pEventTermInit,
EVENT_INCREMENT,
FALSE);
00193 UserFreePool(apRITEvents);
00194
return;
00195 }
00196
00197 idMouseInput = 0xFFFF;
00198 idDesktopDestroy = 0xFFFF;
00199 idHungThread = 0xFFFF;
00200
00201
00202
00203
00204
00205
if (!(pTerm->
dwTERMF_Flags &
TERMF_NOIO)) {
00206 pfnHidChangeRoutine = (
MSGWAITCALLBACK)
ProcessDeviceChanges;
00207 idMouseInput = nEvents++;
00208 UserAssert(
aDeviceTemplate[
DEVICE_TYPE_MOUSE].pkeHidChange);
00209 apRITEvents[idMouseInput] =
aDeviceTemplate[
DEVICE_TYPE_MOUSE].
pkeHidChange;
00210 }
00211
00212
00213
00214
00215 idDesktopDestroy = nEvents++;
00216 apRITEvents[idDesktopDestroy] =
CreateKernelEvent(SynchronizationEvent,
FALSE);
00217
if (apRITEvents[idDesktopDestroy] ==
NULL) {
00218 pTerm->
dwTERMF_Flags |=
TERMF_DTINITFAILED;
00219
KeSetEvent(pTerm->
pEventTermInit,
EVENT_INCREMENT,
FALSE);
00220 UserFreePool(apRITEvents);
00221 UserFreePool(WaitBlockArray);
00222
return;
00223 }
00224 pTerm->
pEventDestroyDesktop = apRITEvents[idDesktopDestroy];
00225
00226
00227
00228
00229
if (!(pTerm->
dwTERMF_Flags &
TERMF_NOIO)) {
00230 idHungThread = nEvents++;
00231 apRITEvents[idHungThread] =
CreateKernelEvent(SynchronizationEvent,
FALSE);
00232
if (apRITEvents[idHungThread] ==
NULL) {
00233 pTerm->
dwTERMF_Flags |=
TERMF_DTINITFAILED;
00234
KeSetEvent(pTerm->
pEventTermInit,
EVENT_INCREMENT,
FALSE);
00235
FreeKernelEvent(&apRITEvents[idDesktopDestroy]);
00236 UserFreePool(apRITEvents);
00237 UserFreePool(WaitBlockArray);
00238
return;
00239 }
00240
00241
gpEventHungThread = apRITEvents[idHungThread];
00242 }
00243
00244
EnterCrit();
00245 UserAssert(
IsWinEventNotifyDeferredOK());
00246
00247
00248
00249
00250
00251 pTerm->
dwTERMF_Flags |=
TERMF_DTINITSUCCESS;
00252
KeSetEvent(pTerm->
pEventTermInit,
EVENT_INCREMENT,
FALSE);
00253
00254
00255
00256
00257 pEvent = pTerm->
pEventInputReady;
00258
ObReferenceObjectByPointer(pEvent,
00259 EVENT_ALL_ACCESS,
00260 *
ExEventObjectType,
00261
KernelMode);
00262
00263
LeaveCrit();
00264
00265
KeWaitForSingleObject(pEvent,
WrUserRequest,
KernelMode,
FALSE,
NULL);
00266
ObDereferenceObject(pEvent);
00267
00268
EnterCrit();
00269
00270
00271
00272
00273 idMouseInput += WAIT_OBJECT_0;
00274 idDesktopDestroy += WAIT_OBJECT_0;
00275 idHungThread += WAIT_OBJECT_0;
00276 idPumpMessages = WAIT_OBJECT_0 + nEvents;
00277
00278
00279
00280
00281
00282
while (
TRUE) {
00283
DWORD result;
00284
00285
00286
00287
00288
00289
00290 result =
xxxMsgWaitForMultipleObjects(nEvents,
00291 apRITEvents,
00292 pfnHidChangeRoutine,
00293 WaitBlockArray);
00294
00295
#if DBG
00296
gDesktopsBusy++;
00297
if (gDesktopsBusy >= 2) {
00298 RIPMSG0(RIP_WARNING,
"2 or more desktop threads busy");
00299 }
00300
#endif
00301
00302
00303
00304
00305
00306
00307
00308
if (result == (
DWORD)idPumpMessages) {
00309
00310
00311
00312
00313 MSG
msg ;
00314
00315
CheckCritIn();
00316
00317
00318
00319
00320
00321
while (
xxxPeekMessage(&
msg,
NULL, 0, 0, PM_REMOVE)) {
00322
00323
00324
00325
00326
if (
msg.message == WM_QUIT && ptiCurrent->
cWindows == 1) {
00327
00328
TRACE_DESKTOP((
"WM_QUIT: Destroying the desktop thread. cWindows %d\n",
00329 ptiCurrent->
cWindows));
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
Unlock(&ptiCurrent->
rpdesk->
spwndTrack);
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353 UserAssert(ptiCurrent->
rpdesk !=
NULL &&
00354 ptiCurrent->
rpdesk->
pDeskInfo !=
NULL &&
00355 ptiCurrent->
rpdesk->
pDeskInfo->
spwnd !=
NULL);
00356
00357
Unlock(&ptiCurrent->
rpdesk->
pDeskInfo->
spwnd);
00358
00359
00360
00361
00362
00363
00364 ptiCurrent->
pDeskInfo = &
diStatic;
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376 UserAssert(pqOriginal->
cLockCount);
00377 (pqOriginal->
cLockCount)--;
00378
if (ptiCurrent->
pq != pqOriginal) {
00379
zzzDestroyQueue(pqOriginal, ptiCurrent);
00380 }
00381
00382
#if DBG
00383
gDesktopsBusy--;
00384
#endif
00385
00386
LeaveCrit();
00387
00388
00389
00390
00391
00392
if (!(pTerm->
dwTERMF_Flags &
TERMF_NOIO)) {
00393
FreeKernelEvent(&
gpEventHungThread);
00394 }
00395
FreeKernelEvent(&apRITEvents[idDesktopDestroy]);
00396 UserFreePool(apRITEvents);
00397 UserFreePool(WaitBlockArray);
00398
00399
00400
00401
00402
00403
TRACE_DESKTOP((
"call PsTerminateSystemThread\n"));
00404
00405 pTerm->
ptiDesktop =
NULL;
00406 pTerm->
pqDesktop =
NULL;
00407
00408 pTerm->
dwTERMF_Flags &=
TERMF_DTDESTROYED;
00409
00410
PsTerminateSystemThread(0);
00411 }
00412
00413 UserAssert(
msg.message != WM_QUIT);
00414
00415
00416
00417
00418
xxxDispatchMessage(&
msg);
00419
00420 }
00421
00422 }
else if (result == idDesktopDestroy) {
00423
00424
PDESKTOP *ppdesk;
00425
PDESKTOP pdesk;
00426
PWND pwnd;
00427
PMENU pmenu;
00428
TL tlpwinsta;
00429
PWINDOWSTATION pwinsta;
00430
TL tlpdesk;
00431
TL tlpwnd;
00432
PDESKTOP pdeskTemp;
00433 HDESK hdeskTemp;
00434
TL tlpdeskTemp;
00435
00436
00437
00438
00439
for (ppdesk = &pTerm->
rpdeskDestroy; *ppdesk !=
NULL; ) {
00440
00441
00442
00443 pdesk = *ppdesk;
00444
00445
TRACE_DESKTOP((
"Destroying desktop '%ws' %#p ...\n",
00446 GetDesktopName(pdesk), pdesk));
00447
00448 UserAssert(!(pdesk->
dwDTFlags &
DF_DYING));
00449
00450
ThreadLockDesktop(ptiCurrent, pdesk, &tlpdesk, LDLT_FN_DESKTOPTHREAD_DESK);
00451 pwinsta = pdesk->
rpwinstaParent;
00452
ThreadLockWinSta(ptiCurrent, pdesk->
rpwinstaParent, &tlpwinsta);
00453
00454
LockDesktop(ppdesk, pdesk->
rpdeskNext, LDL_TERM_DESKDESTROY1, (ULONG_PTR)pTerm);
00455
UnlockDesktop(&pdesk->
rpdeskNext, LDU_DESK_DESKNEXT, 0);
00456
00457
00458
00459
00460
if (pdesk ==
grpdeskRitInput) {
00461
PDESKTOP pdeskNew;
00462
00463
TRACE_DESKTOP((
"Destroying the current active desktop\n"));
00464
00465
if (pwinsta->
dwWSF_Flags &
WSF_SWITCHLOCK) {
00466
00467
TRACE_DESKTOP((
"The windowstation is locked\n"));
00468
00469
00470
00471
00472 UserAssert(!(pwinsta->
dwWSF_Flags &
WSF_NOIO));
00473
00474
00475
00476
00477
00478
00479
if (
gbRemoteSession &&
gspdeskDisconnect &&
00480 (pdesk ==
grpdeskLogon ||
00481
grpdeskLogon ==
NULL ||
00482 (
grpdeskLogon->
dwDTFlags &
DF_DESKWNDDESTROYED))) {
00483
TRACE_DESKTOP((
"disable the screen and switch to the disconnect desktop\n"));
00484
RemoteDisableScreen();
00485
goto skip;
00486
00487 }
else {
00488
TRACE_DESKTOP((
"Switch to the logon desktop '%ws' %#p ...\n",
00489 GetDesktopName(
grpdeskLogon),
grpdeskLogon));
00490
00491 pdeskNew =
grpdeskLogon;
00492 }
00493 }
else {
00494 pdeskNew = pwinsta->
rpdeskList;
00495
if (pdeskNew == pdesk)
00496 pdeskNew = pdesk->
rpdeskNext;
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
if (
gbRemoteSession) {
00508
if (pdeskNew ==
NULL) {
00509
00510
TRACE_DESKTOP((
"NO INPUT FOR DT FROM THIS POINT ON ...\n"));
00511
00512
ClearWakeBit(ptiCurrent, QS_INPUT | QS_EVENT | QS_MOUSEMOVE,
FALSE);
00513 }
00514 }
else {
00515 UserAssert(pdeskNew);
00516 }
00517 }
00518
00519
TRACE_DESKTOP((
"Switch to desktop '%ws' %#p\n",
00520 GetDesktopName(pdeskNew), pdeskNew));
00521
00522
xxxSwitchDesktop(pwinsta, pdeskNew,
FALSE);
00523 }
00524 skip:
00525
00526
00527
00528
00529
00530
if ((pdesk->
pDispInfo->
hDev !=
NULL) &&
00531 (pdesk->
pDispInfo->
hDev !=
gpDispInfo->
hDev)) {
00532
00533
TRACE_DESKTOP((
"Destroy MDEV\n"));
00534
00535 DrvDestroyMDEV(pdesk->
pDispInfo->
pmdev);
00536 GreFreePool(pdesk->
pDispInfo->
pmdev);
00537 pdesk->
pDispInfo->
pmdev =
NULL;
00538 }
00539
00540
if (pdesk->
pDispInfo !=
gpDispInfo) {
00541 UserAssert(pdesk->
pDispInfo->
pMonitorFirst ==
NULL);
00542 UserFreePool(pdesk->
pDispInfo);
00543 pdesk->
pDispInfo =
NULL;
00544 }
00545
00546
00547
00548
00549 pdeskTemp = ptiCurrent->
rpdesk;
00550 hdeskTemp = ptiCurrent->
hdesk;
00551
ThreadLockDesktop(ptiCurrent, pdeskTemp, &tlpdeskTemp, LDLT_FN_DESKTOPTHREAD_DESKTEMP);
00552
xxxSetThreadDesktop(
NULL, pdesk);
00553
Unlock(&pdesk->
spwndForeground);
00554
Unlock(&pdesk->
spwndTray);
00555
00556
Unlock(&pdesk->
spwndTrack);
00557 pdesk->
dwDTFlags &= ~
DF_MOUSEMOVETRK;
00558
00559
if (pdesk->
spmenuSys !=
NULL) {
00560 pmenu = pdesk->
spmenuSys;
00561
if (
UnlockDesktopSysMenu(&pdesk->
spmenuSys))
00562
_DestroyMenu(pmenu);
00563 }
00564
00565
if (pdesk->
spmenuDialogSys !=
NULL) {
00566 pmenu = pdesk->
spmenuDialogSys;
00567
if (
UnlockDesktopSysMenu(&pdesk->
spmenuDialogSys))
00568
_DestroyMenu(pmenu);
00569 }
00570
00571
if (pdesk->
spmenuHScroll !=
NULL) {
00572 pmenu = pdesk->
spmenuHScroll;
00573
if (
UnlockDesktopMenu(&pdesk->
spmenuHScroll))
00574
_DestroyMenu(pmenu);
00575 }
00576
00577
if (pdesk->
spmenuVScroll !=
NULL) {
00578 pmenu = pdesk->
spmenuVScroll;
00579
if (
UnlockDesktopMenu(&pdesk->
spmenuVScroll))
00580
_DestroyMenu(pmenu);
00581 }
00582
00583
00584
00585
00586
00587
00588
if (pdesk->
pDeskInfo ==
NULL) {
00589 RIPMSG0(RIP_ERROR,
00590
"xxxDesktopThread: There is no pDeskInfo for this desktop");
00591 }
00592
00593
if (pdesk->
pDeskInfo) {
00594
if (pdesk->
pDeskInfo->
spwnd ==
gspwndFullScreen)
00595
Unlock(&
gspwndFullScreen);
00596
00597
if (pdesk->
pDeskInfo->
spwndShell)
00598
Unlock(&pdesk->
pDeskInfo->
spwndShell);
00599
00600
if (pdesk->
pDeskInfo->
spwndBkGnd)
00601
Unlock(&pdesk->
pDeskInfo->
spwndBkGnd);
00602
00603
if (pdesk->
pDeskInfo->
spwndTaskman)
00604
Unlock(&pdesk->
pDeskInfo->
spwndTaskman);
00605
00606
if (pdesk->
pDeskInfo->
spwndProgman)
00607
Unlock(&pdesk->
pDeskInfo->
spwndProgman);
00608 }
00609
00610 UserAssert(!(pdesk->
dwDTFlags &
DF_DYING));
00611
00612
if (pdesk->
spwndMenu !=
NULL) {
00613
00614 pwnd = pdesk->
spwndMenu;
00615
00616
00617
00618
00619
if (
TestWF(pwnd,
WFVISIBLE)) {
00620
ThreadLockAlwaysWithPti(ptiCurrent, pwnd, &tlpwnd);
00621
xxxSetWindowPos(pwnd,
00622
NULL,
00623 0,
00624 0,
00625 0,
00626 0,
00627 SWP_HIDEWINDOW | SWP_NOACTIVATE |
00628 SWP_NOMOVE | SWP_NOSIZE |
00629 SWP_NOZORDER | SWP_NOREDRAW |
00630 SWP_NOSENDCHANGING);
00631
00632
ThreadUnlock(&tlpwnd);
00633 }
00634
00635
00636
00637
00638
00639 ((
PMENUWND)pwnd)->ppopupmenu->fDesktopMenu =
FALSE;
00640 ((
PMENUWND)pwnd)->ppopupmenu->fDelayedFree =
FALSE;
00641
#if DBG
00642
00643
00644
00645
00646
00647 ((
PMENUWND)pwnd)->ppopupmenu->ppopupmenuRoot =
NULL;
00648
#endif
00649
00650
if (
Unlock(&pdesk->
spwndMenu)) {
00651
xxxDestroyWindow(pwnd);
00652 }
00653 }
00654
00655
if (pdesk->
spwndMessage !=
NULL) {
00656
00657 pwnd = pdesk->
spwndMessage;
00658
00659
if (
Unlock(&pdesk->
spwndMessage)) {
00660
xxxDestroyWindow(pwnd);
00661 }
00662 }
00663
00664
if (pdesk->
spwndTooltip !=
NULL) {
00665
00666 pwnd = pdesk->
spwndTooltip;
00667
00668
if (
Unlock(&pdesk->
spwndTooltip)) {
00669
xxxDestroyWindow(pwnd);
00670 }
00671 UserAssert(!(pdesk->
dwDTFlags &
DF_TOOLTIPSHOWING));
00672 }
00673
00674 UserAssert(!(pdesk->
dwDTFlags &
DF_DYING));
00675
00676
00677
00678
00679
00680
00681
00682
if (pTerm->spwndDesktopOwner !=
NULL &&
00683 pTerm->spwndDesktopOwner->head.rpdesk == pdesk) {
00684
00685
PDESKTOP pdeskR;
00686
00687
00688
00689
00690
00691
00692
00693
if (pTerm->dwTERMF_Flags &
TERMF_NOIO) {
00694
00695
PWINDOWSTATION pwinstaW;
00696
00697 UserAssert(
grpWinStaList !=
NULL);
00698
00699 pwinstaW =
grpWinStaList->
rpwinstaNext;
00700
00701 pdeskR =
NULL;
00702
00703
while (pwinstaW !=
NULL) {
00704
if (pwinstaW->
rpdeskList !=
NULL) {
00705 pdeskR = pwinstaW->
rpdeskList;
00706
break;
00707 }
00708 pwinstaW = pwinstaW->
rpwinstaNext;
00709 }
00710 }
else {
00711 pdeskR = pwinsta->
rpdeskList;
00712 }
00713
00714
if (pdeskR ==
NULL) {
00715
00716
PWND pwnd;
00717
00718
TRACE_DESKTOP((
"DESTROYING THE MOTHER DESKTOP WINDOW %#p\n",
00719 pTerm->spwndDesktopOwner));
00720
00721 pwnd = pTerm->spwndDesktopOwner;
00722
00723
00724
00725
00726
SetVisible(pwnd,
SV_UNSET);
00727
00728
Unlock(&(pTerm->spwndDesktopOwner));
00729
00730
xxxDestroyWindow(pwnd);
00731
00732 }
else {
00733
TRACE_DESKTOP((
"MOVING THE MOTHER DESKTOP WINDOW %#p to pdesk %#p '%ws'\n",
00734 pTerm->spwndDesktopOwner, pdeskR, GetDesktopName(pdeskR)));
00735
00736
LockDesktop(&(pTerm->spwndDesktopOwner->head.rpdesk),
00737 pdeskR, LDL_MOTHERDESK_DESK1, (ULONG_PTR)(pTerm->spwndDesktopOwner));
00738 }
00739 }
00740
00741
if (pdesk->
pDeskInfo && (pdesk->
pDeskInfo->
spwnd !=
NULL)) {
00742
00743 UserAssert(!(pdesk->
dwDTFlags &
DF_DESKWNDDESTROYED));
00744
00745 pwnd = pdesk->
pDeskInfo->
spwnd;
00746
00747
00748
00749
00750
if (
TestWF(pwnd,
WFVISIBLE)) {
00751
ThreadLockAlwaysWithPti(ptiCurrent, pwnd, &tlpwnd);
00752
xxxSetWindowPos(pwnd,
00753
NULL,
00754 0,
00755 0,
00756 0,
00757 0,
00758 SWP_HIDEWINDOW | SWP_NOACTIVATE |
00759 SWP_NOMOVE | SWP_NOSIZE |
00760 SWP_NOZORDER | SWP_NOREDRAW |
00761 SWP_NOSENDCHANGING);
00762
00763
ThreadUnlock(&tlpwnd);
00764 }
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
TRACE_DESKTOP((
"Destroying the desktop window\n"));
00777
00778
xxxDestroyWindow(pdesk->
pDeskInfo->
spwnd);
00779
if (pdesk !=
grpdeskRitInput) {
00780
Unlock(&pdesk->
pDeskInfo->
spwnd);
00781 }
else {
00782
00783
00784
00785
00786
if (
ISTS() &&
gspwndShouldBeForeground !=
NULL) {
00787
Unlock(&
gspwndShouldBeForeground);
00788 }
00789
00790
00791
00792
00793 RIPMSG1(RIP_WARNING,
"xxxDesktopThread: Running on zombie desk:%#p", pdesk);
00794 }
00795 pdesk->
dwDTFlags |=
DF_DESKWNDDESTROYED;
00796 }
00797
00798
00799
00800
00801
xxxSetThreadDesktop(hdeskTemp, pdeskTemp);
00802
00803
00804
ThreadUnlockDesktop(ptiCurrent, &tlpdeskTemp, LDUT_FN_DESKTOPTHREAD_DESKTEMP);
00805
ThreadUnlockWinSta(ptiCurrent, &tlpwinsta);
00806
ThreadUnlockDesktop(ptiCurrent, &tlpdesk, LDUT_FN_DESKTOPTHREAD_DESK);
00807 }
00808
00809
if (
gbRemoteSession) {
00810
00811
00812
00813
TRACE_DESKTOP((
"Wakeup ntinput thread for exit processing\n"));
00814
00815 UserAssert(
gpevtDesktopDestroyed !=
NULL);
00816
00817
KeSetEvent(
gpevtDesktopDestroyed,
EVENT_INCREMENT,
FALSE);
00818 }
00819
00820 }
else if (result == idHungThread) {
00821
00822
00823
00824
00825
00826
PWND pwnd =
gspwndMouseOwner;
00827
if (pwnd !=
NULL &&
FHungApp(
GETPTI(pwnd),
CMSHUNGAPPTIMEOUT)) {
00828
00829
int ht =
FindNCHit(pwnd, POINTTOPOINTS(
glinp.
ptLastClick));
00830
00831
if (ht == HTCLOSE) {
00832
00833
00834
00835
00836
00837
PostShellHookMessages(HSHELL_ENDTASK, (LPARAM)
HWq(pwnd));
00838 }
else if (ht == HTMINBUTTON) {
00839
TL tlpwnd;
00840
00841
ThreadLockAlways(pwnd, &tlpwnd);
00842
xxxMinimizeHungWindow(pwnd);
00843
ThreadUnlock(&tlpwnd);
00844 }
00845 }
00846
00847 }
else {
00848 RIPMSG0(RIP_WARNING,
"Desktop woke up for what?");
00849 }
00850
00851
#if DBG
00852
gDesktopsBusy--;
00853
#endif
00854
}
00855 }
00856
00857
00858
00859
00860
00861
00862
00863 VOID xxxRealizeDesktop(
PWND pwnd)
00864 {
00865
CheckLock(pwnd);
00866 UserAssert(
GETFNID(pwnd) ==
FNID_DESKTOP);
00867
00868
if (
ghpalWallpaper) {
00869 HDC hdc =
_GetDC(pwnd);
00870
xxxInternalPaintDesktop(pwnd, hdc,
FALSE);
00871
_ReleaseDC(hdc);
00872 }
00873 }
00874
00875
00876
00877
00878
00879
00880
00881
00882
00883 LRESULT
xxxDesktopWndProc(
00884
PWND pwnd,
00885 UINT message,
00886 WPARAM wParam,
00887 LPARAM lParam)
00888 {
00889
PTHREADINFO ptiCurrent =
PtiCurrent();
00890 HDC hdcT;
00891 PAINTSTRUCT ps;
00892 PWINDOWPOS pwp;
00893
00894
00895
CheckLock(pwnd);
00896 UserAssert(
IsWinEventNotifyDeferredOK());
00897
00898
VALIDATECLASSANDSIZE(pwnd, message, wParam, lParam,
FNID_DESKTOP, WM_CREATE);
00899
00900
00901
if (pwnd->
spwndParent ==
NULL) {
00902
switch (message) {
00903
00904
case WM_SETICON:
00905
00906
00907
00908
00909 RIPMSG0(RIP_WARNING,
"WM_ICON sent to desktop window was discarded.\n") ;
00910
return 0
L ;
00911
00912
default:
00913
break;
00914 }
00915
00916
return xxxDefWindowProc(pwnd, message, wParam, lParam);
00917 }
00918
00919
switch (message) {
00920
00921
case WM_WINDOWPOSCHANGING:
00922
00923
00924
00925
00926
00927
00928 pwp = (PWINDOWPOS)lParam;
00929
if (!(pwp->flags & SWP_NOZORDER) && pwp->hwndInsertAfter == HWND_TOP) {
00930
00931
xxxSetThreadDesktop(
NULL,
grpdeskRitInput);
00932
00933
00934
00935
00936
00937
00938
if (GreGetSystemPaletteUse(
gpDispInfo->
hdcScreen) != SYSPAL_STATIC)
00939 GreRealizeDefaultPalette(
gpDispInfo->
hdcScreen,
TRUE);
00940
00941
00942
00943
00944
if (
grpdeskRitInput->
dwDTFlags &
DTF_NEEDSPALETTECHANGED) {
00945
xxxSendNotifyMessage(
PWND_BROADCAST,
00946 WM_PALETTECHANGED,
00947 (WPARAM)
HWq(pwnd),
00948 0);
00949
grpdeskRitInput->
dwDTFlags &= ~
DTF_NEEDSPALETTECHANGED;
00950 }
00951 }
00952
break;
00953
00954
case WM_FULLSCREEN: {
00955
TL tlpwndT;
00956
00957
ThreadLockWithPti(ptiCurrent,
grpdeskRitInput->
pDeskInfo->
spwnd, &tlpwndT);
00958
xxxMakeWindowForegroundWithState(
00959
grpdeskRitInput->
pDeskInfo->
spwnd, GDIFULLSCREEN);
00960
ThreadUnlock(&tlpwndT);
00961
00962
00963
00964
00965
00966
if (
gspwndAltTab !=
NULL) {
00967
ThreadLockAlwaysWithPti(ptiCurrent,
gspwndAltTab, &tlpwndT);
00968
xxxSendMessage(
gspwndAltTab, WM_FULLSCREEN, 0, 0);
00969
ThreadUnlock(&tlpwndT);
00970 }
00971
00972
break;
00973 }
00974
00975
case WM_CLOSE:
00976
00977
00978
00979
00980
00981
break;
00982
00983
case WM_SETICON:
00984
00985
00986
00987
00988 RIPMSG0(RIP_WARNING,
"WM_ICON sent to desktop window was discarded.\n") ;
00989
break;
00990
00991
case WM_CREATE: {
00992
TL tlName;
00993 PUNICODE_STRING pProfileUserName =
CreateProfileUserName(&tlName);
00994
00995
00996
00997
xxxSetDeskPattern(pProfileUserName, (LPWSTR)-1,
TRUE);
00998
00999
FreeProfileUserName(pProfileUserName, &tlName);
01000
01001
01002
01003
xxxSendNotifyMessage(pwnd, WM_SYSCOLORCHANGE, 0, 0
L);
01004
01005 hdcT =
_GetDC(pwnd);
01006
xxxInternalPaintDesktop(pwnd, hdcT,
FALSE);
01007
_ReleaseDC(hdcT);
01008
01009
01010
01011
01012
xxxSetWindowLong(pwnd,
01013 0,
01014 HandleToUlong(
PsGetCurrentThread()->Cid.UniqueProcess),
01015
FALSE);
01016
01017
xxxSetWindowLong(pwnd,
01018 4,
01019 HandleToUlong(
PsGetCurrentThread()->Cid.UniqueThread),
01020
FALSE);
01021
break;
01022 }
01023
case WM_PALETTECHANGED:
01024
if (
HWq(pwnd) == (HWND)wParam)
01025
break;
01026
01027
01028
01029
case WM_QUERYNEWPALETTE:
01030
xxxRealizeDesktop(pwnd);
01031
break;
01032
01033
case WM_SYSCOLORCHANGE:
01034
01035
01036
01037
01038
01039
01040
01041
01042
01043
01044
01045
01046
xxxRedrawWindow(pwnd,
01047
NULL,
01048
NULL,
01049 RDW_INVALIDATE | RDW_ALLCHILDREN | RDW_ERASE);
01050
break;
01051
01052
case WM_ERASEBKGND:
01053 hdcT = (HDC)wParam;
01054
xxxInternalPaintDesktop(pwnd, hdcT,
TRUE);
01055
return TRUE;
01056
01057
case WM_PAINT:
01058
xxxBeginPaint(pwnd, (LPPAINTSTRUCT)&ps);
01059
xxxEndPaint(pwnd, (LPPAINTSTRUCT)&ps);
01060
break;
01061
01062
#ifdef HUNGAPP_GHOSTING
01063
case WM_HUNGTHREAD:
01064 {
01065
PWND pwnd =
RevalidateHwnd((HWND)lParam);
01066
01067
if (pwnd !=
NULL &&
FHungApp(
GETPTI(pwnd),
CMSHUNGAPPTIMEOUT)) {
01068
TL tlpwnd;
01069
01070 pwnd =
GetTopLevelWindow(pwnd);
01071
01072
ThreadLockAlways(pwnd, &tlpwnd);
01073 xxxCreateGhost(pwnd);
01074
ThreadUnlock(&tlpwnd);
01075 }
01076
break;
01077 }
01078
#endif // HUNGAPP_GHOSTING
01079
01080
case WM_LBUTTONDBLCLK:
01081 message = WM_SYSCOMMAND;
01082 wParam = SC_TASKLIST;
01083
01084
01085
01086
01087
01088
default:
01089
return xxxDefWindowProc(pwnd, message, wParam, lParam);
01090 }
01091
01092
return 0
L;
01093 }
01094
01095
01096
01097
01098
01099
01100
01101
01102
01103
01104
01105 BOOL xxxSetDeskPattern(PUNICODE_STRING pProfileUserName,
01106 LPWSTR lpszPattern,
01107 BOOL fCreation)
01108 {
01109 LPWSTR p;
01110
int i;
01111
UINT val;
01112 WCHAR wszNone[20];
01113 WCHAR wchValue[
MAX_PATH];
01114 WORD rgBits[
CXYDESKPATTERN];
01115 HBRUSH hBrushTemp;
01116
01117
CheckCritIn();
01118
01119
01120
01121
01122
if (
ghbmDesktop !=
NULL) {
01123 GreDeleteObject(
ghbmDesktop);
01124
ghbmDesktop =
NULL;
01125 }
01126
01127
01128
01129
01130
if (lpszPattern != (LPWSTR)LongToPtr( (LONG)-1 )) {
01131
01132
01133
01134
01135 p = lpszPattern;
01136
goto GotThePattern;
01137 }
01138
01139
01140
01141
01142
01143
if (!
FastGetProfileStringFromIDW(pProfileUserName,
01144
PMAP_DESKTOP,
01145 STR_DESKPATTERN,
01146 TEXT(
""),
01147 wchValue,
01148
sizeof(wchValue)/
sizeof(WCHAR)
01149 )) {
01150
return FALSE;
01151 }
01152
01153
ServerLoadString(
hModuleWin,
01154 STR_NONE,
01155 wszNone,
01156
sizeof(wszNone)/
sizeof(WCHAR));
01157
01158 p = wchValue;
01159
01160 GotThePattern:
01161
01162
01163
01164
01165
if (*p == TEXT(
'\0') || _wcsicmp(p, wszNone) == 0) {
01166 hBrushTemp = GreCreateSolidBrush(
SYSRGB(
DESKTOP));
01167
if (hBrushTemp !=
NULL) {
01168
if (
SYSHBR(
DESKTOP)) {
01169 GreMarkDeletableBrush(
SYSHBR(
DESKTOP));
01170 GreDeleteObject(
SYSHBR(
DESKTOP));
01171 }
01172 GreMarkUndeletableBrush(hBrushTemp);
01173
SYSHBR(
DESKTOP) = hBrushTemp;
01174 }
01175 GreSetBrushOwnerPublic(hBrushTemp);
01176
goto SDPExit;
01177 }
01178
01179
01180
01181
01182
for (i = 0; i <
CXYDESKPATTERN; i++) {
01183 val = 0;
01184
01185
01186
01187
01188
while (*p && !(*p >= TEXT(
'0') && *p <= TEXT(
'9')))
01189 p++;
01190
01191
01192
01193
01194
while (*p >= TEXT(
'0') && *p <= TEXT(
'9'))
01195 val = val * (
UINT)10 + (
UINT)(*p++ - TEXT(
'0'));
01196
01197 rgBits[i] = (WORD)val;
01198 }
01199
01200
ghbmDesktop = GreCreateBitmap(
CXYDESKPATTERN,
01201
CXYDESKPATTERN,
01202 1,
01203 1,
01204 (LPBYTE)rgBits);
01205
01206
if (
ghbmDesktop ==
NULL)
01207
return FALSE;
01208
01209 GreSetBitmapOwner(
ghbmDesktop, OBJECT_OWNER_PUBLIC);
01210
01211
RecolorDeskPattern();
01212
01213 SDPExit:
01214
if (!fCreation) {
01215
01216
01217
01218
01219
xxxSendNotifyMessage(
PWND_BROADCAST, WM_SYSCOLORCHANGE, 0, 0
L);
01220
01221
01222
01223
01224
01225
01226
xxxRedrawScreen();
01227 }
01228
01229
return TRUE;
01230 }
01231
01232
01233
01234
01235
01236
01237
01238
01239
01240
01241
01242 VOID RecolorDeskPattern(VOID)
01243 {
01244 HBITMAP hbmOldDesk;
01245 HBITMAP hbmOldMem;
01246 HBITMAP hbmMem;
01247 HBRUSH hBrushTemp;
01248
if (
ghbmDesktop ==
NULL)
01249
return;
01250
01251
01252
01253
01254
01255
if (hbmOldDesk = GreSelectBitmap(
ghdcMem,
ghbmDesktop)) {
01256
01257
if (!
SYSMET(SAMEDISPLAYFORMAT)) {
01258
01259
BYTE bmi[
sizeof(BITMAPINFOHEADER)+
sizeof(RGBQUAD)*2];
01260 PBITMAPINFO pbmi = (PBITMAPINFO) &bmi;
01261
01262 pbmi->bmiHeader.biSize =
sizeof(BITMAPINFOHEADER);
01263 pbmi->bmiHeader.biWidth =
CXYDESKPATTERN;
01264 pbmi->bmiHeader.biHeight =
CXYDESKPATTERN;
01265 pbmi->bmiHeader.biPlanes = 1;
01266 pbmi->bmiHeader.biBitCount = 1;
01267 pbmi->bmiHeader.biCompression = BI_RGB;
01268 pbmi->bmiHeader.biSizeImage = 0;
01269 pbmi->bmiHeader.biXPelsPerMeter = 0;
01270 pbmi->bmiHeader.biYPelsPerMeter = 0;
01271 pbmi->bmiHeader.biClrUsed = 2;
01272 pbmi->bmiHeader.biClrImportant = 2;
01273
01274 pbmi->bmiColors[0].rgbBlue = (
BYTE)((
SYSRGB(
DESKTOP) >> 16) & 0xff);
01275 pbmi->bmiColors[0].rgbGreen = (
BYTE)((
SYSRGB(
DESKTOP) >> 8) & 0xff);
01276 pbmi->bmiColors[0].rgbRed = (
BYTE)((
SYSRGB(
DESKTOP) ) & 0xff);
01277
01278 pbmi->bmiColors[1].rgbBlue = (
BYTE)((
SYSRGB(WINDOWTEXT) >> 16) & 0xff);
01279 pbmi->bmiColors[1].rgbGreen = (
BYTE)((
SYSRGB(WINDOWTEXT) >> 8) & 0xff);
01280 pbmi->bmiColors[1].rgbRed = (
BYTE)((
SYSRGB(WINDOWTEXT) ) & 0xff);
01281
01282 hbmMem = GreCreateDIBitmapReal(
01283
HDCBITS(), 0,
NULL,
01284 pbmi,DIB_RGB_COLORS,
sizeof(bmi),0,
01285
NULL,0,
NULL,0,0);
01286
01287 }
else {
01288
01289 hbmMem = GreCreateCompatibleBitmap(
01290
HDCBITS(),
CXYDESKPATTERN,
CXYDESKPATTERN);
01291 }
01292
01293
if (hbmMem) {
01294
01295
if (hbmOldMem = GreSelectBitmap(
ghdcMem2, hbmMem)) {
01296
01297 GreSetTextColor(
ghdcMem2,
SYSRGB(
DESKTOP));
01298 GreSetBkColor(
ghdcMem2,
SYSRGB(WINDOWTEXT));
01299
01300 GreBitBlt(
ghdcMem2,
01301 0,
01302 0,
01303
CXYDESKPATTERN,
01304
CXYDESKPATTERN,
01305
ghdcMem,
01306 0,
01307 0,
01308 SRCCOPY,
01309 0);
01310
01311
if (hBrushTemp = GreCreatePatternBrush(hbmMem)) {
01312
01313
if (
SYSHBR(
DESKTOP) !=
NULL) {
01314 GreMarkDeletableBrush(
SYSHBR(
DESKTOP));
01315 GreDeleteObject(
SYSHBR(
DESKTOP));
01316 }
01317
01318 GreMarkUndeletableBrush(hBrushTemp);
01319
SYSHBR(
DESKTOP) = hBrushTemp;
01320 }
01321
01322 GreSetBrushOwnerPublic(hBrushTemp);
01323 GreSelectBitmap(
ghdcMem2, hbmOldMem);
01324 }
01325
01326 GreDeleteObject(hbmMem);
01327 }
01328
01329 GreSelectBitmap(
ghdcMem, hbmOldDesk);
01330 }
01331 }
01332
01333
01334
01335
01336
01337
01338
01339
01340
01341
01342
01343 NTSTATUS xxxCreateDesktop2(
01344
PWINDOWSTATION pwinsta,
01345
PACCESS_STATE pAccessState,
01346 KPROCESSOR_MODE AccessMode,
01347 PUNICODE_STRING pstrName,
01348 PDESKTOP_CONTEXT Context,
01349 PVOID *pObject)
01350 {
01351 LUID luidCaller;
01352 OBJECT_ATTRIBUTES
ObjectAttributes;
01353
PEPROCESS Process;
01354
PDESKTOP pdesk;
01355
PDESKTOPINFO pdi;
01356 ULONG ulHeapSize;
01357
NTSTATUS Status;
01358
01359
CheckCritIn();
01360
01361
01362
01363
01364
01365
if (!
ObCheckCreateObjectAccess(
01366 pwinsta,
01367 WINSTA_CREATEDESKTOP,
01368 pAccessState,
01369 pstrName,
01370
TRUE,
01371 AccessMode,
01372 &
Status)) {
01373
01374
return Status;
01375 }
01376
01377
01378
01379 Process =
PsGetCurrentProcess();
01380
01381
if (pwinsta->
dwWSF_Flags &
WSF_OPENLOCK &&
01382 Process->
UniqueProcessId !=
gpidLogon) {
01383
01384
01385
01386
01387
01388
01389
Status =
GetProcessLuid(
NULL, &luidCaller);
01390
01391
if (!
NT_SUCCESS(
Status) ||
01392 !(pwinsta->
dwWSF_Flags &
WSF_SHUTDOWN) ||
01393
RtlEqualLuid(&luidCaller, &pwinsta->
luidEndSession)) {
01394
return STATUS_DEVICE_BUSY;
01395 }
01396 }
01397
01398
01399
01400
01401
01402
if (Context->
lpDevMode !=
NULL && (pwinsta->
dwWSF_Flags &
WSF_OPENLOCK) &&
01403 Process->
UniqueProcessId !=
gpidLogon) {
01404
return STATUS_DEVICE_BUSY;
01405 }
01406
01407
01408
01409
01410 InitializeObjectAttributes(&
ObjectAttributes, pstrName, 0,
NULL,
NULL);
01411
Status =
ObCreateObject(
01412
KernelMode,
01413 *
ExDesktopObjectType,
01414 &
ObjectAttributes,
01415
UserMode,
01416
NULL,
01417
sizeof(
DESKTOP),
01418 0,
01419 0,
01420 &pdesk);
01421
if (!
NT_SUCCESS(
Status)) {
01422 RIPMSG1(RIP_WARNING,
"xxxCreateDesktop2: ObCreateObject failed with Status 0x%x",
01423
Status);
01424
return Status;
01425 }
01426 RtlZeroMemory(pdesk,
sizeof(
DESKTOP));
01427
01428
01429
01430
01431 pdesk->
dwSessionId =
gSessionId;
01432
01433
01434
01435
01436
Status =
ObAssignSecurity(
01437 pAccessState,
01438
OBJECT_TO_OBJECT_HEADER(pwinsta)->SecurityDescriptor,
01439 pdesk,
01440 *
ExDesktopObjectType);
01441
01442
if (!
NT_SUCCESS(
Status))
01443
goto Error;
01444
01445
01446
01447
01448
01449
if (!(pwinsta->
dwWSF_Flags &
WSF_NOIO) && (pwinsta->
rpdeskList ==
NULL)) {
01450
#ifdef _WIN64
01451
01452
01453
01454
01455 ulHeapSize =
gdwDesktopSectionSize;
01456
#else
01457
ulHeapSize = 128;
01458
#endif
01459
}
else {
01460
if (pwinsta->
dwWSF_Flags &
WSF_NOIO) {
01461 ulHeapSize =
gdwNOIOSectionSize;
01462 }
else {
01463
01464
01465
01466
01467
if (
gbRemoteSession &&
gspdeskDisconnect ==
NULL)
01468 ulHeapSize = 64;
01469
else
01470 ulHeapSize =
gdwDesktopSectionSize;
01471 }
01472 }
01473
01474 ulHeapSize *= 1024;
01475
01476
01477
01478 pdesk->
hsectionDesktop =
CreateDesktopHeap(&pdesk->
pheapDesktop, ulHeapSize);
01479
if (pdesk->
hsectionDesktop ==
NULL) {
01480 RIPMSG1(RIP_WARNING,
"xxxCreateDesktop: CreateDesktopHeap failed for pdesk %#p",
01481 pdesk);
01482
goto ErrorOutOfMemory;
01483 }
01484
01485
if (pwinsta->
rpdeskList ==
NULL || (pwinsta->
dwWSF_Flags &
WSF_NOIO)) {
01486
01487
01488
01489
01490
01491
01492
01493 Context->
lpDevMode =
NULL;
01494 }
01495
01496
01497
01498
01499 pdi = (
PDESKTOPINFO)
DesktopAlloc(pdesk,
sizeof(
DESKTOPINFO),
DTAG_DESKTOPINFO);
01500
if (pdi ==
NULL) {
01501 RIPMSG0(RIP_WARNING,
"xxxCreateDesktop: failed DeskInfo Alloc");
01502
goto ErrorOutOfMemory;
01503 }
01504
01505
01506
01507
01508 pdesk->
pDeskInfo = pdi;
01509 InitializeListHead(&pdesk->
PtiList);
01510
01511
01512
01513
01514
01515
01516
01517
if (Context->
lpDevMode) {
01518
01519
BOOL bDisabled =
FALSE;
01520 PMDEV pmdev =
NULL;
01521 LONG ChangeStat = GRE_DISP_CHANGE_FAILED;
01522
01523
01524
01525
01526 pdesk->
pDispInfo = (
PDISPLAYINFO)UserAllocPoolZInit(
01527
sizeof(
DISPLAYINFO), TAG_DISPLAYINFO);
01528
01529
if (!pdesk->
pDispInfo) {
01530 RIPMSG1(RIP_WARNING,
"xxxCreateDesktop: failed to allocate pDispInfo for pdesk %#p",
01531 pdesk);
01532
goto ErrorOutOfMemory;
01533 }
01534
01535
if ((bDisabled = DrvDisableMDEV(
gpDispInfo->
pmdev,
TRUE)) ==
TRUE) {
01536
01537 ChangeStat = DrvChangeDisplaySettings(Context->
pstrDevice,
01538
NULL,
01539 Context->
lpDevMode,
01540 LongToPtr(
gdwDesktopId ),
01541
UserMode,
01542
FALSE,
01543
TRUE,
01544
NULL,
01545 &pmdev,
01546 GRE_DEFAULT,
01547
FALSE);
01548 }
01549
01550
if (ChangeStat != GRE_DISP_CHANGE_SUCCESSFUL) {
01551
01552
if (bDisabled) {
01553 DrvEnableMDEV(
gpDispInfo->
pmdev,
TRUE);
01554 }
01555
01556
01557
01558
01559
01560 RIPMSG1(RIP_WARNING,
"xxxCreateDesktop2 callback for pdesk %#p !",
01561 pdesk);
01562
01563
xxxUserResetDisplayDevice();
01564
01565
Status = STATUS_UNSUCCESSFUL;
01566
goto Error;
01567 }
01568
01569 pdesk->
pDispInfo->
hDev = pmdev->hdevParent;
01570 pdesk->
pDispInfo->
pmdev = pmdev;
01571 pdesk->
dwDesktopId =
gdwDesktopId++;
01572
01573
CopyRect(&pdesk->
pDispInfo->
rcScreen, &
gpDispInfo->
rcScreen);
01574 pdesk->
pDispInfo->
dmLogPixels =
gpDispInfo->
dmLogPixels;
01575
01576 pdesk->
pDispInfo->
pMonitorFirst =
NULL;
01577 pdesk->
pDispInfo->
pMonitorPrimary =
NULL;
01578
01579 }
else {
01580
01581 pdesk->
pDispInfo =
gpDispInfo;
01582 pdesk->
dwDesktopId =
GW_DESKTOP_ID;
01583
01584 }
01585
01586
01587
01588
01589 UserAssert(pdi->
pvwplShellHook ==
NULL);
01590
01591 pdi->
pvDesktopBase = Win32HeapGetHandle(pdesk->
pheapDesktop);
01592 pdi->
pvDesktopLimit = (
PBYTE)pdi->
pvDesktopBase + ulHeapSize;
01593
01594
01595
01596
01597
LockWinSta(&(pdesk->
rpwinstaParent), pwinsta);
01598
01599
01600
01601
01602
if (pwinsta->
rpdeskList ==
NULL) {
01603
01604
if (!(pwinsta->
dwWSF_Flags &
WSF_NOIO))
01605
LockDesktop(&
grpdeskLogon, pdesk, LDL_DESKLOGON, 0);
01606
01607
01608
01609
01610
01611
LockDesktop(&(pwinsta->
pTerm->
spwndDesktopOwner->
head.rpdesk),
01612 pdesk, LDL_MOTHERDESK_DESK2, (ULONG_PTR)(pwinsta->
pTerm->
spwndDesktopOwner));
01613 }
01614
01615
01616
LockDesktop(&pdesk->
rpdeskNext, pwinsta->
rpdeskList, LDL_DESK_DESKNEXT1, (ULONG_PTR)pwinsta);
01617
LockDesktop(&pwinsta->rpdeskList, pdesk, LDL_WINSTA_DESKLIST1, (ULONG_PTR)pwinsta);
01618
01619
01620
01621
01622
if (pAccessState->
RemainingDesiredAccess & MAXIMUM_ALLOWED) {
01623 pAccessState->
RemainingDesiredAccess &= ~MAXIMUM_ALLOWED;
01624 pAccessState->
RemainingDesiredAccess |= GENERIC_ALL;
01625 }
01626
01627
RtlMapGenericMask( &pAccessState->
RemainingDesiredAccess, (PGENERIC_MAPPING)&
DesktopMapping);
01628 pAccessState->
RemainingDesiredAccess &=
01629 (
DesktopMapping.GenericAll | ACCESS_SYSTEM_SECURITY);
01630
01631 *pObject = pdesk;
01632
01633
01634
01635
01636
01637
DbgTrackAddDesktop(pdesk);
01638
01639
return STATUS_SUCCESS;
01640
01641 ErrorOutOfMemory:
01642
Status = STATUS_NO_MEMORY;
01643
01644
01645
Error:
01646
LogDesktop(pdesk, LD_DEREF_FN_2CREATEDESKTOP,
FALSE, 0);
01647
ObDereferenceObject(pdesk);
01648
01649 UserAssert(!
NT_SUCCESS(
Status));
01650
01651
return Status;
01652 }
01653
01654 BOOL xxxCreateDisconnectDesktop(
01655 HWINSTA hwinsta,
01656
PWINDOWSTATION pwinsta)
01657 {
01658 UNICODE_STRING strDesktop;
01659 OBJECT_ATTRIBUTES oa;
01660 HDESK hdeskDisconnect;
01661 HRGN hrgn;
01662
NTSTATUS Status;
01663
01664
01665
01666
01667
01668
01669
RtlInitUnicodeString(&strDesktop, TEXT(
"Disconnect"));
01670 InitializeObjectAttributes(&oa, &strDesktop,
01671 OBJ_OPENIF | OBJ_CASE_INSENSITIVE, hwinsta,
NULL);
01672
01673 hdeskDisconnect =
xxxCreateDesktop(&oa,
KernelMode,
01674
NULL,
NULL, 0, MAXIMUM_ALLOWED);
01675
01676
if (hdeskDisconnect ==
NULL) {
01677 RIPMSG0(RIP_WARNING,
"Could not create Disconnect desktop");
01678
return FALSE;
01679 }
01680
01681
01682
01683
01684
01685
Status =
ObReferenceObjectByHandle(hdeskDisconnect,
01686 0,
01687
NULL,
01688
KernelMode,
01689 &
gspdeskDisconnect,
01690
NULL);
01691
if (!
NT_SUCCESS(
Status)) {
01692
01693 RIPMSG1(RIP_WARNING,
"Disconnect Desktop reference failed 0x%x",
Status);
01694
01695
xxxCloseDesktop(hdeskDisconnect,
KernelMode);
01696
gspdeskDisconnect =
NULL;
01697
return FALSE;
01698 }
01699
01700
LogDesktop(
gspdeskDisconnect, LDL_DESKDISCONNECT,
TRUE, 0);
01701
01702
01703
01704
01705
01706 hrgn =
CreateEmptyRgn();
01707
01708 UserAssert(
gspdeskDisconnect->
pDeskInfo !=
NULL);
01709
01710
SelectWindowRgn(
gspdeskDisconnect->
pDeskInfo->
spwnd, hrgn);
01711
01712
KeAttachProcess(&
gpepCSRSS->
Pcb);
01713
01714
Status =
ObOpenObjectByPointer(
01715
gspdeskDisconnect,
01716 0,
01717
NULL,
01718 EVENT_ALL_ACCESS,
01719
NULL,
01720
KernelMode,
01721 &
ghDisconnectDesk);
01722
01723
if (
NT_SUCCESS(
Status)) {
01724
01725
Status =
ObOpenObjectByPointer(
01726 pwinsta,
01727 0,
01728
NULL,
01729 EVENT_ALL_ACCESS,
01730
NULL,
01731
KernelMode,
01732 &
ghDisconnectWinSta);
01733 }
01734
01735
KeDetachProcess();
01736
01737
if (!
NT_SUCCESS(
Status)) {
01738
01739 RIPMSG0(RIP_WARNING,
"Could not create Disconnect desktop");
01740
01741
if (
ghDisconnectDesk !=
NULL) {
01742
CloseProtectedHandle(
ghDisconnectDesk);
01743
ghDisconnectDesk =
NULL;
01744 }
01745
01746
xxxCloseDesktop(hdeskDisconnect,
KernelMode);
01747
return FALSE;
01748 }
01749
01750
01751
01752
01753
if (!
gbConnected) {
01754 RIPMSG0(RIP_WARNING,
01755
"RemoteDisconnect was issued during CreateDesktop(\"Winlogon\"...");
01756 }
01757
01758
return TRUE;
01759 }
01760
01761 VOID CleanupDirtyDesktops(
01762 VOID)
01763 {
01764
PWINDOWSTATION pwinsta;
01765
PDESKTOP* ppdesk;
01766
01767
CheckCritIn();
01768
01769
for (pwinsta =
grpWinStaList; pwinsta !=
NULL; pwinsta = pwinsta->
rpwinstaNext) {
01770
01771 ppdesk = &pwinsta->
rpdeskList;
01772
01773
while (*ppdesk !=
NULL) {
01774
01775
if (!((*ppdesk)->dwDTFlags &
DF_DESKCREATED)) {
01776 RIPMSG1(RIP_WARNING,
"Desktop %#p in a dirty state", *ppdesk);
01777
01778
if (
grpdeskLogon == *ppdesk) {
01779
UnlockDesktop(&
grpdeskLogon, LDU_DESKLOGON, 0);
01780 }
01781
01782
if (pwinsta->
pTerm->
spwndDesktopOwner &&
01783 pwinsta->
pTerm->
spwndDesktopOwner->
head.rpdesk == *ppdesk) {
01784
01785
UnlockDesktop(&(pwinsta->
pTerm->
spwndDesktopOwner->
head.rpdesk),
01786 LDU_MOTHERDESK_DESK, (ULONG_PTR)(pwinsta->
pTerm->
spwndDesktopOwner));
01787 }
01788
01789
LockDesktop(ppdesk, (*ppdesk)->
rpdeskNext, LDL_WINSTA_DESKLIST1, (ULONG_PTR)pwinsta);
01790 }
else {
01791 ppdesk = &(*ppdesk)->
rpdeskNext;
01792 }
01793 }
01794 }
01795 }
01796
01797 HDESK
xxxCreateDesktop(
01798 POBJECT_ATTRIBUTES ccxObjectAttributes,
01799 KPROCESSOR_MODE ProbeMode,
01800 PUNICODE_STRING ccxpstrDevice,
01801 LPDEVMODE ccxlpdevmode,
01802 DWORD dwFlags,
01803 DWORD dwDesiredAccess)
01804 {
01805 HWINSTA hwinsta;
01806 HDESK hdesk;
01807
DESKTOP_CONTEXT Context;
01808
PDESKTOP pdesk;
01809
PDESKTOPINFO pdi;
01810
PWINDOWSTATION pwinsta;
01811
PDESKTOP pdeskTemp;
01812 HDESK hdeskTemp;
01813
PWND pwndDesktop =
NULL;
01814
PWND pwndMessage =
NULL;
01815
PWND pwndTooltip =
NULL;
01816
PWND pwndMenu =
NULL;
01817
TL tlpwnd;
01818
PTHREADINFO ptiCurrent =
PtiCurrent();
01819
BOOL fWasNull;
01820
BOOL bSuccess;
01821
PPROCESSINFO ppi;
01822
PPROCESSINFO ppiSave;
01823
PTERMINAL pTerm;
01824
NTSTATUS Status;
01825
DWORD dwDisableHooks;
01826
01827
#if DBG
01828
01829
01830
01831
DWORD dwCritSecUseSave = gdwCritSecUseCount;
01832
#endif
01833
01834
CheckCritIn();
01835
01836 UserAssert(
IsWinEventNotifyDeferredOK());
01837
01838
01839
01840
01841
try {
01842 hwinsta = ccxObjectAttributes->RootDirectory;
01843 } except (W32ExceptionHandler(
TRUE, RIP_WARNING)) {
01844
return NULL;
01845 }
01846
if (hwinsta !=
NULL) {
01847
Status =
ObReferenceObjectByHandle(
01848 hwinsta,
01849 WINSTA_CREATEDESKTOP,
01850 *
ExWindowStationObjectType,
01851 ProbeMode,
01852 &pwinsta,
01853
NULL);
01854
if (
NT_SUCCESS(
Status)) {
01855
ObDereferenceObject(pwinsta);
01856 }
else {
01857 RIPNTERR0(
Status, RIP_VERBOSE,
"ObReferenceObjectByHandle Failed");
01858
return NULL;
01859 }
01860 }
01861
01862
01863
01864
01865 Context.
lpDevMode = ccxlpdevmode;
01866 Context.
pstrDevice = ccxpstrDevice;
01867 Context.
dwFlags =
dwFlags;
01868
01869
01870
01871
01872
Status =
ObOpenObjectByName(
01873 ccxObjectAttributes,
01874 *
ExDesktopObjectType,
01875 ProbeMode,
01876
NULL,
01877 dwDesiredAccess,
01878 &Context,
01879 &hdesk);
01880
01881
if (!
NT_SUCCESS(
Status)) {
01882
01883 RIPNTERR1(
Status,
01884 RIP_WARNING,
01885
"xxxCreateDesktop: ObOpenObjectByName failed with Status 0x%x",
01886
Status);
01887
01888
01889
01890
01891
01892
01893
CleanupDirtyDesktops();
01894
01895
return NULL;
01896 }
01897
01898
01899
01900
01901
01902
if (
Status == STATUS_OBJECT_NAME_EXISTS) {
01903
SetHandleFlag(hdesk,
HF_PROTECTED,
TRUE);
01904 RIPMSG0(RIP_WARNING,
"xxxCreateDesktop: Object name exists");
01905
return hdesk;
01906 }
01907
01908
01909
01910
01911
Status =
ObReferenceObjectByHandle(
01912 hdesk,
01913 0,
01914 *
ExDesktopObjectType,
01915
KernelMode,
01916 &pdesk,
01917
NULL);
01918
if (!
NT_SUCCESS(
Status)) {
01919 RIPNTERR0(
Status, RIP_VERBOSE,
"");
01920
CloseProtectedHandle(hdesk);
01921
return NULL;
01922 }
01923
01924 pdesk->
dwDTFlags |=
DF_DESKCREATED;
01925
01926
LogDesktop(pdesk, LD_REF_FN_CREATEDESKTOP,
TRUE, (ULONG_PTR)
PtiCurrent());
01927
01928 pwinsta = pdesk->
rpwinstaParent;
01929 pTerm = pwinsta->
pTerm;
01930 pdi = pdesk->
pDeskInfo;
01931
01932 pdi->
ppiShellProcess =
NULL;
01933
01934
01935
01936
01937
01938 ppi =
PpiCurrent();
01939
if (
GetDesktopView(ppi, pdesk) ==
NULL) {
01940
01941
01942
01943
01944
CloseProtectedHandle(hdesk);
01945
01946
LogDesktop(pdesk, LD_DEREF_FN_CREATEDESKTOP1,
FALSE, (ULONG_PTR)
PtiCurrent());
01947
01948
ObDereferenceObject(pdesk);
01949 RIPNTERR0(STATUS_ACCESS_DENIED, RIP_WARNING,
"Desktop mapping failed");
01950
return NULL;
01951 }
01952
01953
if (
gpepCSRSS !=
NULL) {
01954
01955
01956
01957
01958
try {
01959
MapDesktop(
ObOpenHandle,
gpepCSRSS, pdesk, 0, 1);
01960 } except (W32ExceptionHandler(
TRUE, RIP_WARNING)) {
01961
01962
01963
01964
01965
CloseProtectedHandle(hdesk);
01966
01967
LogDesktop(pdesk, LD_DEREF_FN_CREATEDESKTOP2,
FALSE, (ULONG_PTR)
PtiCurrent());
01968
01969
ObDereferenceObject(pdesk);
01970 RIPNTERR0(STATUS_ACCESS_DENIED, RIP_WARNING,
"Desktop mapping failed (2)");
01971
return NULL;
01972 }
01973
01974 UserAssert(
GetDesktopView(
PpiFromProcess(
gpepCSRSS), pdesk) !=
NULL);
01975 }
01976
01977
01978
01979
01980
SetHandleFlag(hdesk,
HF_DESKTOPHOOK,
dwFlags & DF_ALLOWOTHERACCOUNTHOOK);
01981
01982
01983
01984
01985 fWasNull = (ptiCurrent->
ppi->
rpdeskStartup ==
NULL);
01986 pdeskTemp = ptiCurrent->
rpdesk;
01987 hdeskTemp = ptiCurrent->
hdesk;
01988
01989
01990
01991
01992
01993 ppiSave = ptiCurrent->
ppi;
01994 ptiCurrent->
ppi = pTerm->
ptiDesktop->
ppi;
01995
01996
DeferWinEventNotify();
01997
BeginAtomicCheck();
01998
01999
zzzSetDesktop(ptiCurrent, pdesk, hdesk);
02000
02001
02002
02003
02004
02005
02006
02007
02008
02009
02010
02011
02012
02013
02014 dwDisableHooks = ptiCurrent->
TIF_flags &
TIF_DISABLEHOOKS;
02015 ptiCurrent->
TIF_flags |=
TIF_DISABLEHOOKS;
02016
02017 pwndDesktop =
xxxCreateWindowEx(
02018 (
DWORD)0,
02019 (
PLARGE_STRING)
DESKTOPCLASS,
02020
NULL,
02021 (WS_POPUP | WS_CLIPCHILDREN),
02022 pdesk->
pDispInfo->
rcScreen.left,
02023 pdesk->
pDispInfo->
rcScreen.top,
02024 pdesk->
pDispInfo->
rcScreen.right - pdesk->
pDispInfo->
rcScreen.left,
02025 pdesk->
pDispInfo->
rcScreen.bottom - pdesk->
pDispInfo->
rcScreen.top,
02026
NULL,
02027
NULL,
02028
hModuleWin,
02029
NULL,
02030
VER31);
02031
02032
if (pwndDesktop ==
NULL) {
02033 RIPMSG1(RIP_WARNING,
02034
"xxxCreateDesktop: Failed to create the desktop window for pdesk %#p",
02035 pdesk);
02036
goto Error;
02037 }
02038
02039
02040
02041
02042
02043
02044
02045 pwndMessage =
xxxCreateWindowEx(
02046 (
DWORD)0,
02047 (
PLARGE_STRING)
gatomMessage,
02048
NULL,
02049 (WS_POPUP | WS_CLIPCHILDREN),
02050 0,
02051 0,
02052 100,
02053 100,
02054
NULL,
02055
NULL,
02056
hModuleWin,
02057
NULL,
02058
VER31);
02059
02060
if (pwndMessage ==
NULL) {
02061 RIPMSG0(RIP_WARNING,
"xxxCreateDesktop: Failed to create the message window");
02062
goto Error;
02063 }
02064
02065 UserAssert(pdi->
spwnd ==
NULL);
02066
02067
Lock(&(pdi->
spwnd), pwndDesktop);
02068
02069
SetFullScreen(pwndDesktop, GDIFULLSCREEN);
02070
02071
02072
02073
02074
02075
02076
02077
02078
02079
02080
02081
02082
02083
02084
02085 UserAssert(
fGdiEnabled ==
TRUE);
02086
02087
if (
gspwndFullScreen ==
NULL && !(pwinsta->
dwWSF_Flags &
WSF_NOIO)) {
02088
Lock(&(
gspwndFullScreen), pwndDesktop);
02089 }
02090
02091
02092
02093
02094
02095
02096
02097
Lock(&pwndMessage->
spwndParent, pTerm->
spwndDesktopOwner);
02098
LinkWindow(pwndMessage,
NULL, pTerm->
spwndDesktopOwner);
02099
Lock(&pdesk->
spwndMessage, pwndMessage);
02100
Unlock(&pwndMessage->
spwndOwner);
02101
02102
02103
02104
02105
LinkWindow(pwndDesktop,
NULL, pTerm->
spwndDesktopOwner);
02106
Lock(&pwndDesktop->
spwndParent, pTerm->
spwndDesktopOwner);
02107
Unlock(&pwndDesktop->
spwndOwner);
02108
02109
02110
02111
02112
if (!pdesk->
pDispInfo->
fDesktopIsRect) {
02113 pwndDesktop->
hrgnClip = pdesk->
pDispInfo->
hrgnScreen;
02114 }
02115
02116
02117
02118
02119
ThreadLock(pdesk->
spwndMessage, &tlpwnd);
02120
02121
02122
02123
02124
02125
if (!(pwinsta->
dwWSF_Flags &
WSF_NOIO)) {
02126 pwndTooltip =
xxxCreateWindowEx(
02127 WS_EX_TOOLWINDOW | WS_EX_TOPMOST,
02128 (
PLARGE_STRING)
TOOLTIPCLASS,
02129
NULL,
02130 WS_POPUP | WS_BORDER,
02131 0,
02132 0,
02133 100,
02134 100,
02135 pdesk->
spwndMessage,
02136
NULL,
02137
hModuleWin,
02138
NULL,
02139
VER31);
02140
02141
02142
if (pwndTooltip ==
NULL) {
02143
ThreadUnlock(&tlpwnd);
02144 RIPMSG0(RIP_WARNING,
"xxxCreateDesktop: Failed to create the tooltip window");
02145
goto Error;
02146 }
02147
02148
Lock(&pdesk->
spwndTooltip, pwndTooltip);
02149 }
02150
02151 pwndMenu =
xxxCreateWindowEx(
02152 WS_EX_TOOLWINDOW | WS_EX_DLGMODALFRAME | WS_EX_WINDOWEDGE,
02153 (
PLARGE_STRING)
MENUCLASS,
02154
NULL,
02155 WS_POPUP | WS_BORDER,
02156 0,
02157 0,
02158 100,
02159 100,
02160 pdesk->
spwndMessage,
02161
NULL,
02162
hModuleWin,
02163
NULL,
02164 WINVER);
02165
02166
ThreadUnlock(&tlpwnd);
02167
02168
if (pwndMenu ==
NULL) {
02169 RIPMSG0(RIP_WARNING,
"xxxCreateDesktop: Failed to create the menu window");
02170
goto Error;
02171 }
02172
02173
Lock(&(pdesk->
spwndMenu), pwndMenu);
02174
02175
02176
02177
02178
02179 ((
PMENUWND)pdesk->
spwndMenu)->ppopupmenu->fDesktopMenu =
TRUE;
02180
02181
02182
02183
02184
Unlock(&((
PMENUWND)pdesk->
spwndMenu)->ppopupmenu->spwndPopupMenu);
02185
02186
HMChangeOwnerThread(pdi->
spwnd, pTerm->
ptiDesktop);
02187
HMChangeOwnerThread(pwndMessage, pTerm->
ptiDesktop);
02188
HMChangeOwnerThread(pdesk->
spwndMenu, pTerm->
ptiDesktop);
02189
02190
if (!(pwinsta->
dwWSF_Flags &
WSF_NOIO)) {
02191
HMChangeOwnerThread(pwndTooltip, pTerm->
ptiDesktop);
02192 }
02193
02194
02195
02196
02197
PtiCurrent()->ppi = ppiSave;
02198
02199
02200
02201
02202 UserAssert(ptiCurrent->
TIF_flags &
TIF_DISABLEHOOKS);
02203 ptiCurrent->
TIF_flags = (ptiCurrent->
TIF_flags & ~
TIF_DISABLEHOOKS) | dwDisableHooks;
02204
02205
02206
02207
02208
zzzSetDesktop(ptiCurrent, pdeskTemp, hdeskTemp);
02209
02210
EndAtomicCheck();
02211 UserAssert(dwCritSecUseSave == gdwCritSecUseCount);
02212
zzzEndDeferWinEventNotify();
02213
02214
02215
02216
02217
02218
02219
if (pTerm->
pEventInputReady !=
NULL) {
02220
02221
02222
02223
02224
02225
02226
if (!(pTerm->
dwTERMF_Flags &
TERMF_NOIO)) {
02227
gptiRit->
pwinsta = pwinsta;
02228 }
else {
02229
02230
02231
02232
02233
zzzSetDesktop(pTerm->
ptiDesktop, pdesk,
NULL);
02234 }
02235
02236 pTerm->
ptiDesktop->
pwinsta = pwinsta;
02237
02238
KeSetEvent(pTerm->
pEventInputReady,
EVENT_INCREMENT,
FALSE);
02239
02240
if (!(pTerm->
dwTERMF_Flags &
TERMF_NOIO)) {
02241
02242
LeaveCrit();
02243
while (
grpdeskRitInput ==
NULL) {
02244
UserSleep(20);
02245 RIPMSG0(RIP_WARNING,
"Waiting for grpdeskRitInput to be set ...");
02246 }
02247
EnterCrit();
02248 }
02249
02250
ObDereferenceObject(pTerm->
pEventInputReady);
02251 pTerm->
pEventInputReady =
NULL;
02252 }
02253
02254
02255
02256
02257
02258
02259
02260
02261
02262
if (ccxlpdevmode) {
02263
02264
TRACE_INIT((
"xxxCreateDesktop: about to call switch desktop\n"));
02265
02266 bSuccess =
xxxSwitchDesktop(pwinsta, pdesk,
TRUE);
02267
if (!bSuccess) {
02268 RIPMSG0(RIP_ERROR,
"Failed to switch desktop on Create\n");
02269 }
02270
02271 }
else if (pTerm == &
gTermIO){
02272
02273 UserAssert(
grpdeskRitInput !=
NULL);
02274
02275
02276
02277
02278
02279
02280
02281
02282
ThreadLockWithPti(ptiCurrent, pwndDesktop, &tlpwnd);
02283
xxxSetWindowPos(pwndDesktop,
PWND_BOTTOM, 0, 0, 0, 0,
02284 SWP_SHOWWINDOW | SWP_NOACTIVATE | SWP_NOMOVE |
02285 SWP_NOREDRAW | SWP_NOSIZE | SWP_NOSENDCHANGING);
02286
ThreadUnlock(&tlpwnd);
02287 }
02288
02289
02290
02291
02292
02293
if (fWasNull)
02294
UnlockDesktop(&ptiCurrent->
ppi->
rpdeskStartup,
02295 LDU_PPI_DESKSTARTUP1, (ULONG_PTR)(ptiCurrent->
ppi));
02296
02297
if (
gbRemoteSession &&
02298
gspdeskDisconnect ==
NULL &&
02299 pdesk ==
grpdeskLogon) {
02300
02301 UserAssert(hdesk !=
NULL);
02302
02303
02304
02305
02306
if (!
xxxCreateDisconnectDesktop(hwinsta, pwinsta)) {
02307 RIPMSG0(RIP_WARNING,
"Failed to create the 'disconnect' desktop");
02308
02309
LogDesktop(pdesk, LD_DEREF_FN_CREATEDESKTOP3,
FALSE, (ULONG_PTR)
PtiCurrent());
02310
ObDereferenceObject(pdesk);
02311
02312
xxxCloseDesktop(hdesk,
KernelMode);
02313
02314
return NULL;
02315 }
02316
02317
02318
02319
02320
KeSetEvent(
gpEventDiconnectDesktop,
EVENT_INCREMENT,
FALSE);
02321
02322
HYDRA_HINT(
HH_DISCONNECTDESKTOP);
02323 }
02324
02325 Cleanup:
02326
02327
LogDesktop(pdesk, LD_DEREF_FN_CREATEDESKTOP3,
FALSE, (ULONG_PTR)
PtiCurrent());
02328
ObDereferenceObject(pdesk);
02329
02330
TRACE_INIT((
"xxxCreateDesktop: Leaving\n"));
02331
02332
if (hdesk !=
NULL) {
02333
SetHandleFlag(hdesk,
HF_PROTECTED,
TRUE);
02334 }
02335
return hdesk;
02336
02337
Error:
02338
02339
EndAtomicCheck();
02340 UserAssert(dwCritSecUseSave == gdwCritSecUseCount);
02341
zzzEndDeferWinEventNotify();
02342
02343 UserAssert(pwndMenu ==
NULL);
02344
02345
if (pwndTooltip !=
NULL) {
02346
xxxDestroyWindow(pwndTooltip);
02347
Unlock(&pdesk->spwndTooltip);
02348 }
02349
if (pwndMessage !=
NULL) {
02350
xxxDestroyWindow(pwndMessage);
02351
Unlock(&pdesk->spwndMessage);
02352 }
02353
if (pwndDesktop !=
NULL) {
02354
xxxDestroyWindow(pwndDesktop);
02355
Unlock(&pdi->
spwnd);
02356
Unlock(&
gspwndFullScreen);
02357 }
02358
02359
02360
02361
PtiCurrent()->ppi = ppiSave;
02362
02363 UserAssert(ptiCurrent->
TIF_flags &
TIF_DISABLEHOOKS);
02364 ptiCurrent->
TIF_flags = (ptiCurrent->
TIF_flags & ~
TIF_DISABLEHOOKS) | dwDisableHooks;
02365
zzzSetDesktop(ptiCurrent, pdeskTemp, hdeskTemp);
02366
02367
CloseProtectedHandle(hdesk);
02368 hdesk =
NULL;
02369
02370
02371
02372
02373
02374
if (fWasNull)
02375
UnlockDesktop(&ptiCurrent->
ppi->
rpdeskStartup,
02376 LDU_PPI_DESKSTARTUP1, (ULONG_PTR)(ptiCurrent->
ppi));
02377
02378
goto Cleanup;
02379
02380 }
02381
02382
02383
02384
02385
02386
02387
02388
02389
02390
02391 NTSTATUS ParseDesktop(
02392 PVOID pContainerObject,
02393
POBJECT_TYPE pObjectType,
02394
PACCESS_STATE pAccessState,
02395 KPROCESSOR_MODE AccessMode,
02396 ULONG Attributes,
02397 PUNICODE_STRING pstrCompleteName,
02398 PUNICODE_STRING pstrRemainingName,
02399 PVOID Context,
02400 PSECURITY_QUALITY_OF_SERVICE pqos,
02401 PVOID *pObject)
02402 {
02403
PWINDOWSTATION pwinsta = pContainerObject;
02404
PDESKTOP pdesk;
02405 PUNICODE_STRING pstrName;
02406
NTSTATUS Status = STATUS_OBJECT_NAME_NOT_FOUND;
02407
02408 *pObject =
NULL;
02409
02410 BEGIN_REENTERCRIT();
02411
02412 UserAssert(
OBJECT_TO_OBJECT_HEADER(pContainerObject)->Type == *
ExWindowStationObjectType);
02413 UserAssert(pObjectType == *
ExDesktopObjectType);
02414
02415
02416
02417
02418
for (pdesk = pwinsta->
rpdeskList; pdesk !=
NULL; pdesk = pdesk->
rpdeskNext) {
02419 pstrName =
POBJECT_NAME(pdesk);
02420
if (pstrName &&
RtlEqualUnicodeString(pstrRemainingName, pstrName,
02421 (BOOLEAN)((Attributes & OBJ_CASE_INSENSITIVE) != 0))) {
02422
if (Context !=
NULL) {
02423
if (!(Attributes & OBJ_OPENIF)) {
02424
02425
02426
02427
02428
02429
Status = STATUS_OBJECT_NAME_COLLISION;
02430
goto Exit;
02431
02432 }
else {
02433
Status = STATUS_OBJECT_NAME_EXISTS;
02434 }
02435 }
else {
02436
Status = STATUS_SUCCESS;
02437 }
02438
02439
ObReferenceObject(pdesk);
02440
02441 *pObject = pdesk;
02442
goto Exit;
02443 }
02444 }
02445
02446
02447
02448
02449
if (Context !=
NULL) {
02450
Status =
xxxCreateDesktop2(pContainerObject,
02451 pAccessState,
02452 AccessMode,
02453 pstrRemainingName,
02454 Context,
02455 pObject);
02456 }
02457
02458 Exit:
02459 END_REENTERCRIT();
02460
02461
return Status;
02462
02463 UNREFERENCED_PARAMETER(pObjectType);
02464 UNREFERENCED_PARAMETER(pstrCompleteName);
02465 UNREFERENCED_PARAMETER(pqos);
02466 }
02467
02468
02469
02470
02471
02472
02473
02474
02475
02476
02477
02478 BOOL DestroyDesktop(
02479
PDESKTOP pdesk)
02480 {
02481
PWINDOWSTATION pwinsta = pdesk->
rpwinstaParent;
02482
PTERMINAL pTerm;
02483
PDESKTOP *ppdesk;
02484
02485
if (pdesk->
dwDTFlags &
DF_DESTROYED) {
02486 RIPMSG1(RIP_WARNING,
"DestroyDesktop: Already destroyed:%#p", pdesk);
02487
return FALSE;
02488 }
02489
02490
02491
02492
02493
if (pwinsta !=
NULL) {
02494
02495 ppdesk = &pwinsta->
rpdeskList;
02496
while (*ppdesk !=
NULL && *ppdesk != pdesk) {
02497 ppdesk = &((*ppdesk)->rpdeskNext);
02498 }
02499
02500
if (*ppdesk !=
NULL) {
02501
02502
02503
02504
02505
LockDesktop(ppdesk, pdesk->
rpdeskNext, LDL_WINSTA_DESKLIST2, (ULONG_PTR)pwinsta);
02506
UnlockDesktop(&pdesk->
rpdeskNext, LDU_DESK_DESKNEXT, (ULONG_PTR)pwinsta);
02507 }
02508 }
02509
02510
02511
02512
02513 pTerm = pwinsta->
pTerm;
02514
02515
LockDesktop(&pdesk->
rpdeskNext, pTerm->
rpdeskDestroy, LDL_DESK_DESKNEXT2, 0);
02516
LockDesktop(&pTerm->
rpdeskDestroy, pdesk, LDL_TERM_DESKDESTROY2, (ULONG_PTR)pTerm);
02517
KeSetEvent(pTerm->pEventDestroyDesktop,
EVENT_INCREMENT,
FALSE);
02518
02519 pdesk->
dwDTFlags |=
DF_DESTROYED;
02520
02521
TRACE_DESKTOP((
"pdesk %#p '%ws' marked as destroyed\n", pdesk, GetDesktopName(pdesk)));
02522
02523
return TRUE;
02524 }
02525
02526
02527
02528
02529
02530
02531
02532
02533
02534
02535 VOID FreeDesktop(
02536 PVOID pobj)
02537 {
02538
PDESKTOP pdesk = (
PDESKTOP)pobj;
02539
NTSTATUS Status;
02540
02541 BEGIN_REENTERCRIT();
02542
02543 UserAssert(
OBJECT_TO_OBJECT_HEADER(pobj)->Type == *
ExDesktopObjectType);
02544
02545
#ifdef LOGDESKTOPLOCKS
02546
02547
if (pdesk->pLog !=
NULL) {
02548
02549
02550
02551
02552
02553
if (pdesk->nLockCount != 0) {
02554 RIPMSG3(RIP_WARNING,
02555
"FreeDesktop pdesk %#p, pLog %#p, nLockCount %d should be 0",
02556 pdesk, pdesk->pLog, pdesk->nLockCount);
02557 }
02558 UserFreePool(pdesk->pLog);
02559 pdesk->pLog =
NULL;
02560 }
02561
#endif // LOGDESKTOPLOCKS
02562
02563
#if DBG
02564
if (pdesk->
pDeskInfo && (pdesk->
pDeskInfo->
spwnd !=
NULL)) {
02565
02566
02567
02568
02569
02570 UserAssert(pdesk->
dwDTFlags &
DF_DESKWNDDESTROYED);
02571 }
02572
#endif // DBG
02573
02574
02575
02576
02577 UserAssert(!(pdesk->
dwDTFlags &
DF_DYING));
02578 pdesk->
dwDTFlags |=
DF_DYING;
02579
02580
#ifdef DEBUG_DESK
02581
{
02582
02583
02584
02585
#if 0
02586
PPROCESSINFO ppi;
02587
PCLS pcls, pclsClone;
02588
#endif
02589
PHE pheT, pheMax;
02590
BOOL fDirty =
FALSE;
02591
02592
#if 0
02593
for (ppi = gppiFirst; ppi !=
NULL; ppi = ppi->
ppiNext) {
02594
for (pcls = ppi->
pclsPrivateList; pcls !=
NULL; pcls = pcls->
pclsNext) {
02595
if (pcls->pheapDesktop == pdesk->
pheapDesktop) {
02596
DbgPrint(
"ppi %08x private class at %08x exists\n", ppi, pcls);
02597 fDirty =
TRUE;
02598 }
02599
for (pclsClone = pcls->
pclsClone; pclsClone !=
NULL;
02600 pclsClone = pclsClone->
pclsNext) {
02601
if (pclsClone->pheapDesktop == pdesk->
pheapDesktop) {
02602
DbgPrint(
"ppi %08x private class clone at %08x exists\n", ppi, pclsClone);
02603 fDirty =
TRUE;
02604 }
02605 }
02606 }
02607
for (pcls = ppi->
pclsPublicList; pcls !=
NULL; pcls = pcls->
pclsNext) {
02608
if (pcls->pheapDesktop == pdesk->
pheapDesktop) {
02609
DbgPrint(
"ppi %08x public class at %08x exists\n", ppi, pcls);
02610 fDirty =
TRUE;
02611 }
02612
for (pclsClone = pcls->
pclsClone; pclsClone !=
NULL;
02613 pclsClone = pclsClone->
pclsNext) {
02614
if (pclsClone->pheapDesktop == pdesk->
pheapDesktop) {
02615
DbgPrint(
"ppi %08x public class clone at %08x exists\n", ppi, pclsClone);
02616 fDirty =
TRUE;
02617 }
02618 }
02619 }
02620 }
02621
#endif
02622
02623 pheMax = &
gSharedInfo.
aheList[
giheLast];
02624
for (pheT =
gSharedInfo.
aheList; pheT <= pheMax; pheT++) {
02625
switch (pheT->
bType) {
02626
case TYPE_WINDOW:
02627
if (((
PWND)pheT->
phead)->head.rpdesk == pdesk) {
02628
DbgPrint(
"Window at %08x exists\n", pheT->
phead);
02629
break;
02630 }
02631
continue;
02632
case TYPE_MENU:
02633
if (((
PMENU)pheT->
phead)->head.rpdesk == pdesk) {
02634
DbgPrint(
"Menu at %08x exists\n", pheT->
phead);
02635
break;
02636 }
02637
continue;
02638
case TYPE_CALLPROC:
02639
if (((
PCALLPROCDATA)pheT->
phead)->head.rpdesk == pdesk) {
02640
DbgPrint(
"Callproc at %08x exists\n", pheT->
phead);
02641
break;
02642 }
02643
continue;
02644
case TYPE_HOOK:
02645
if (((
PHOOK)pheT->
phead)->head.rpdesk == pdesk) {
02646
DbgPrint(
"Hook at %08x exists\n", pheT->
phead);
02647
break;
02648 }
02649
continue;
02650
default:
02651
continue;
02652 }
02653 fDirty =
TRUE;
02654 }
02655
if (fDirty) {
02656 RIPMSG0(RIP_ERROR,
"Desktop cleanup failed\n");
02657 }
02658 }
02659
#endif
02660
02661
02662
02663
02664
02665
02666
FreeView(
gpepCSRSS, pdesk);
02667
02668
if (pdesk->
pheapDesktop !=
NULL) {
02669
02670 PVOID hheap = Win32HeapGetHandle(pdesk->
pheapDesktop);
02671
02672 Win32HeapDestroy(pdesk->
pheapDesktop);
02673
02674
Status = Win32UnmapViewInSessionSpace(hheap);
02675
02676 UserAssert(
NT_SUCCESS(
Status));
02677 Win32DestroySection(pdesk->
hsectionDesktop);
02678 }
02679
02680
UnlockWinSta(&pdesk->
rpwinstaParent);
02681
02682
DbgTrackRemoveDesktop(pdesk);
02683
02684 END_REENTERCRIT();
02685 }
02686
02687
02688
02689
02690
02691
02692
02693
02694
02695
02696 HANDLE
CreateDesktopHeap(
02697 PWIN32HEAP* ppheapRet,
02698 ULONG ulHeapSize)
02699 {
02700 HANDLE hsection;
02701 LARGE_INTEGER SectionSize;
02702 SIZE_T ulViewSize;
02703
NTSTATUS Status;
02704 PWIN32HEAP pheap;
02705 PVOID pHeapBase;
02706
02707
02708
02709
02710 SectionSize.QuadPart = ulHeapSize;
02711
02712
Status = Win32CreateSection(&hsection,
02713 SECTION_ALL_ACCESS,
02714 (POBJECT_ATTRIBUTES)
NULL,
02715 &SectionSize,
02716 PAGE_EXECUTE_READWRITE,
02717 SEC_RESERVE,
02718 (HANDLE)
NULL,
02719
NULL,
02720 TAG_SECTION_DESKTOP);
02721
02722
if (!
NT_SUCCESS(
Status )) {
02723 RIPNTERR0(
Status, RIP_WARNING,
"Can't create section for desktop heap.");
02724
return NULL;
02725 }
02726
02727 ulViewSize = ulHeapSize;
02728 pHeapBase =
NULL;
02729
02730
Status = Win32MapViewInSessionSpace(hsection, &pHeapBase, &ulViewSize);
02731
02732
if (!
NT_SUCCESS(
Status)) {
02733 RIPNTERR0(
Status,
02734 RIP_WARNING,
02735
"Can't map section for desktop heap into system space.");
02736
goto Error;
02737 }
02738
02739
02740
02741
02742
if ((pheap =
UserCreateHeap(
02743 hsection,
02744 0,
02745 pHeapBase,
02746 ulHeapSize,
02747
UserCommitDesktopMemory)) ==
NULL) {
02748
02749 RIPERR0(ERROR_NOT_ENOUGH_MEMORY, RIP_WARNING,
"Can't create Desktop heap.");
02750
02751 Win32UnmapViewInSessionSpace(pHeapBase);
02752
Error:
02753 Win32DestroySection(hsection);
02754 *ppheapRet =
NULL;
02755
return NULL;
02756 }
02757
02758 UserAssert(Win32HeapGetHandle(pheap) == pHeapBase);
02759 *ppheapRet = pheap;
02760
02761
return hsection;
02762 }
02763
02764
02765
02766
02767
02768
02769
02770
02771
02772
02773 PDESKTOPVIEW GetDesktopView(
02774
PPROCESSINFO ppi,
02775
PDESKTOP pdesk)
02776 {
02777
PDESKTOPVIEW pdv;
02778
02779
if(ppi->Process !=
gpepCSRSS && pdesk ==
NULL) {
02780 RIPMSG1(RIP_WARNING,
"Process %#p isn't CSRSS but pdesk is NULL in GetDesktopView", ppi);
02781 }
02782
02783
for (pdv = ppi->
pdvList; pdv !=
NULL; pdv = pdv->
pdvNext)
02784
if (pdv->
pdesk == pdesk)
02785
break;
02786
return pdv;
02787 }
02788
02789
02790
02791
02792
02793
02794
02795
02796
02797
02798 PVOID
_MapDesktopObject(
02799 HANDLE h)
02800 {
02801
PDESKOBJHEAD pobj;
02802
PDESKTOPVIEW pdv;
02803
02804
02805
02806
02807 pobj =
HMValidateHandle(h,
TYPE_GENERIC);
02808
if (pobj ==
NULL)
02809
return NULL;
02810
02811 UserAssert(
HMObjectFlags(pobj) &
OCF_DESKTOPHEAP);
02812
02813
02814
02815
02816
02817 pdv =
GetDesktopView(
PpiCurrent(), pobj->rpdesk);
02818
if (pdv ==
NULL) {
02819 RIPMSG1(RIP_WARNING,
"MapDesktopObject: can not map handle %#p", h);
02820
return NULL;
02821 }
02822
02823 UserAssert(pdv->
ulClientDelta != 0);
02824
return (PVOID)((
PBYTE)pobj - pdv->
ulClientDelta);
02825 }
02826
02827
02828
02829
02830
02831
02832
02833
02834
02835
02836 VOID MapDesktop(
02837
OB_OPEN_REASON OpenReason,
02838
PEPROCESS Process,
02839 PVOID pobj,
02840 ACCESS_MASK amGranted,
02841 ULONG cHandles)
02842 {
02843
PPROCESSINFO ppi;
02844
PDESKTOP pdesk = (
PDESKTOP)pobj;
02845
NTSTATUS Status;
02846 SIZE_T ulViewSize;
02847 LARGE_INTEGER liOffset;
02848
PDESKTOPVIEW pdvNew;
02849
PBYTE pClientBase;
02850
BOOL bFailed =
FALSE;
02851
02852 UserAssert(
OBJECT_TO_OBJECT_HEADER(pobj)->Type == *
ExDesktopObjectType);
02853
02854
02855
02856
02857
02858
if (OpenReason ==
ObInheritHandle)
02859
return;
02860
02861
02862
02863
02864 ppi =
PpiFromProcess(Process);
02865
if (ppi ==
NULL)
02866
return;
02867
02868
02869
02870
02871
if (
GetDesktopView(ppi, pdesk) !=
NULL)
02872
return;
02873
02874
02875
02876
02877 pdvNew = UserAllocPoolWithQuota(
sizeof(*pdvNew), TAG_PROCESSINFO);
02878
if (pdvNew ==
NULL) {
02879 RIPERR0(ERROR_NOT_ENOUGH_MEMORY, RIP_VERBOSE,
"");
02880
02881
02882
02883
02884
02885
ExRaiseStatus(STATUS_NO_MEMORY);
02886
return;
02887 }
02888
02889 BEGIN_REENTERCRIT();
02890
02891
02892
02893
02894
02895 ulViewSize = 0;
02896 liOffset.QuadPart = 0;
02897 pClientBase =
NULL;
02898
02899
Status =
MmMapViewOfSection(pdesk->
hsectionDesktop,
02900 Process,
02901 &pClientBase,
02902 0,
02903 0,
02904 &liOffset,
02905 &ulViewSize,
02906 ViewUnmap,
02907 SEC_NO_CHANGE,
02908 PAGE_EXECUTE_READ);
02909
02910
if (!
NT_SUCCESS(
Status)) {
02911
#if DBG
02912
if (
Status != STATUS_NO_MEMORY &&
02913
Status != STATUS_PROCESS_IS_TERMINATING &&
02914
Status != STATUS_COMMITMENT_LIMIT) {
02915 RIPMSG1(RIP_WARNING,
"MapDesktop - failed to map to client process (status == %lX). Contact ChrisWil",
Status);
02916 }
02917
#endif
02918
02919 RIPNTERR0(
Status, RIP_VERBOSE,
"");
02920 UserFreePool(pdvNew);
02921 bFailed =
TRUE;
02922
goto Exit;
02923 }
02924
02925
02926
02927
02928 pdvNew->pdesk = pdesk;
02929 pdvNew->ulClientDelta = (ULONG_PTR)((
PBYTE)Win32HeapGetHandle(pdesk->
pheapDesktop) - pClientBase);
02930 pdvNew->pdvNext = ppi->
pdvList;
02931 ppi->
pdvList = pdvNew;
02932
02933 Exit:
02934 END_REENTERCRIT();
02935
02936
02937
02938
02939
02940
if (bFailed) {
02941
ExRaiseStatus(STATUS_NO_MEMORY);
02942 }
02943
02944 UNREFERENCED_PARAMETER(cHandles);
02945 UNREFERENCED_PARAMETER(amGranted);
02946 }
02947
02948
02949 VOID FreeView(
02950
PEPROCESS Process,
02951
PDESKTOP pdesk)
02952 {
02953
PPROCESSINFO ppi;
02954
NTSTATUS Status;
02955
PDESKTOPVIEW pdv;
02956
PDESKTOPVIEW *ppdv;
02957
02958
02959
02960
02961
02962
if (Process ==
NULL) {
02963
return;
02964 }
02965
02966 ppi =
PpiFromProcess(Process);
02967
02968
02969
02970
02971
02972
if (ppi !=
NULL) {
02973 pdv =
GetDesktopView(ppi, pdesk);
02974
02975
02976
02977
02978
02979
02980
if (pdv !=
NULL) {
02981
Status =
MmUnmapViewOfSection(Process,
02982 (
PBYTE)Win32HeapGetHandle(pdesk->
pheapDesktop) - pdv->
ulClientDelta);
02983 UserAssert(
NT_SUCCESS(
Status) ||
Status == STATUS_PROCESS_IS_TERMINATING);
02984
if (!
NT_SUCCESS(
Status)) {
02985 RIPMSG1(RIP_WARNING,
"FreeView unmap status = 0x%#lx",
Status);
02986 }
02987
02988
02989
02990
02991
for (ppdv = &ppi->
pdvList; *ppdv && *ppdv != pdv;
02992 ppdv = &(*ppdv)->
pdvNext)
02993 ;
02994 UserAssert(*ppdv);
02995 *ppdv = pdv->
pdvNext;
02996 UserFreePool(pdv);
02997 }
02998
02999
#if DBG
03000
03001
03002
03003 {
03004
PTHREADINFO pti = ppi->
ptiList;
03005
while (pti !=
NULL) {
03006
if (pti->
rpdesk == pdesk) {
03007 RIPMSG2(RIP_ERROR,
"FreeView: pti %#p still on pdesk %#p", pti, pdesk);
03008 }
03009 pti = pti->
ptiSibling;
03010 }
03011 }
03012
#endif
03013
}
03014 }
03015
03016
03017 VOID UnmapDesktop(
03018
PEPROCESS Process,
03019 PVOID pobj,
03020 ACCESS_MASK amGranted,
03021 ULONG cProcessHandles,
03022 ULONG cSystemHandles)
03023 {
03024
PDESKTOP pdesk = (
PDESKTOP)pobj;
03025
03026 BEGIN_REENTERCRIT();
03027
03028 UserAssert(
OBJECT_TO_OBJECT_HEADER(pobj)->Type == *
ExDesktopObjectType);
03029
03030
03031
03032
03033 cSystemHandles =
OBJECT_TO_OBJECT_HEADER(pobj)->HandleCount + 1;
03034
03035
03036
03037
03038
03039
if (cProcessHandles == 1 && Process !=
gpepCSRSS) {
03040
FreeView(Process, pdesk);
03041 }
03042
03043
if (cSystemHandles > 2)
03044
goto Exit;
03045
03046
if (cSystemHandles == 2 && pdesk->
dwConsoleThreadId != 0) {
03047
03048
03049
03050
03051
03052
03053
03054
TerminateConsole(pdesk);
03055 }
else if (cSystemHandles == 1) {
03056
03057
03058
03059
03060
03061
03062
03063
03064
03065
if ((&pdesk->
PtiList != pdesk->
PtiList.Flink)
03066 || (&pdesk->
PtiList != pdesk->
PtiList.Blink)) {
03067
03068 RIPMSG1(RIP_WARNING,
"UnmapDesktop: PtiList not Empty. pdesk:%#p", pdesk);
03069 }
03070
03071
DestroyDesktop(pdesk);
03072 }
03073
03074 Exit:
03075 END_REENTERCRIT();
03076
03077 UNREFERENCED_PARAMETER(amGranted);
03078 }
03079
03080
03081
03082
03083
03084
03085
03086
03087
03088
03089 BOOLEAN
OkayToCloseDesktop(
03090
PEPROCESS Process OPTIONAL,
03091 PVOID Object,
03092 HANDLE Handle)
03093 {
03094
PDESKTOP pdesk = (
PDESKTOP)Object;
03095
03096 UNREFERENCED_PARAMETER(Process);
03097
03098 UserAssert(
OBJECT_TO_OBJECT_HEADER(Object)->Type == *
ExDesktopObjectType);
03099
03100
03101
03102
03103
if (KeGetPreviousMode() ==
KernelMode) {
03104
return TRUE;
03105 }
03106
03107
03108
03109
03110
if (!(pdesk->
dwDTFlags &
DF_DESKCREATED)) {
03111 RIPMSG1(RIP_WARNING,
"Trying to close desktop %#p during initialization", pdesk);
03112
return FALSE;
03113 }
03114
03115
03116
03117
03118
if (
CheckHandleInUse(
Handle) ||
CheckHandleFlag(
Handle,
HF_PROTECTED)) {
03119 RIPMSG1(RIP_WARNING,
"Trying to close desktop %#p while still in use", pdesk);
03120
return FALSE;
03121 }
03122
03123
return TRUE;
03124 }
03125
03126
03127
03128
03129
03130
03131
03132
03133
03134
03135
03136 VOID xxxUserResetDisplayDevice()
03137 {
03138
TL tlpwnd;
03139
TRACE_INIT((
"xxxUserResetDisplayDevice: about to reset the device\n"));
03140
03141
03142
03143
03144
if (
grpdeskRitInput !=
NULL) {
03145
ThreadLock(
grpdeskRitInput->
pDeskInfo->
spwnd, &tlpwnd);
03146
#if 0
03147
03148
03149
03150
03151
03152
03153
03154
03155
xxxBroadcastMessage(
grpdeskRitInput->
pDeskInfo->
spwnd,
03156 WM_DISPLAYCHANGE,
03157
gpsi->BitCount,
03158 MAKELONG(
SYSMET(CXSCREEN),
SYSMET(CYSCREEN)),
03159
BMSG_SENDNOTIFYMSG,
03160
NULL);
03161
#endif
03162
xxxRedrawWindow(
grpdeskRitInput->
pDeskInfo->
spwnd,
03163
NULL,
03164
NULL,
03165 RDW_INVALIDATE | RDW_ERASE | RDW_ERASENOW |
03166 RDW_ALLCHILDREN);
03167
gpqCursor =
NULL;
03168
03169
03170
03171
03172
zzzInternalSetCursorPos(
gpsi->ptCursor.x,
gpsi->ptCursor.y);
03173
03174
SetPointer(
TRUE);
03175
03176
ThreadUnlock(&tlpwnd);
03177 }
03178
03179
TRACE_INIT((
"xxxUserResetDisplayDevice: complete\n"));
03180
03181 }
03182
03183
03184
03185
03186
03187
03188
03189
03190
03191
03192 BOOL OpenDesktopCompletion(
03193
PDESKTOP pdesk,
03194 HDESK hdesk,
03195 DWORD dwFlags,
03196 BOOL* pbShutDown)
03197 {
03198
PPROCESSINFO ppi =
PpiCurrent();
03199
PWINDOWSTATION pwinsta;
03200
BOOL fMapped;
03201
03202
03203
03204
03205
03206 fMapped = (
GetDesktopView(ppi, pdesk) !=
NULL);
03207
if (!fMapped) {
03208
03209 RIPMSG0(RIP_WARNING,
"OpenDesktopCompletion failed."
03210
" The desktop is not mapped");
03211
03212
03213
03214
03215
return FALSE;
03216 }
else {
03217
03218
03219
03220
03221 pwinsta = pdesk->
rpwinstaParent;
03222
if (pwinsta->
dwWSF_Flags &
WSF_OPENLOCK &&
03223 ppi->Process->UniqueProcessId !=
gpidLogon) {
03224 LUID luidCaller;
03225
NTSTATUS Status;
03226
03227
03228
03229
03230
03231
03232
Status =
GetProcessLuid(
NULL, &luidCaller);
03233
03234
if (!
NT_SUCCESS(
Status) ||
03235 (pwinsta->
dwWSF_Flags &
WSF_REALSHUTDOWN) ||
03236
RtlEqualLuid(&luidCaller, &pwinsta->
luidEndSession)) {
03237
03238 RIPERR0(ERROR_BUSY, RIP_WARNING,
"OpenDesktopCompletion failed");
03239
03240
03241
03242
03243 *pbShutDown =
TRUE;
03244
return FALSE;
03245 }
03246 }
03247 }
03248
03249
SetHandleFlag(hdesk,
HF_DESKTOPHOOK,
dwFlags & DF_ALLOWOTHERACCOUNTHOOK);
03250
03251
return TRUE;
03252 }
03253
03254
03255
03256
03257
03258
03259
03260
03261
03262
03263
03264
03265 HDESK
xxxOpenDesktop(
03266 POBJECT_ATTRIBUTES ccxObjA,
03267 KPROCESSOR_MODE AccessMode,
03268 DWORD dwFlags,
03269 DWORD dwDesiredAccess,
03270 BOOL* pbShutDown)
03271 {
03272 HDESK hdesk;
03273
PDESKTOP pdesk;
03274
NTSTATUS Status;
03275
03276
03277
03278
03279 dwDesiredAccess |= DESKTOP_READOBJECTS | DESKTOP_WRITEOBJECTS;
03280
03281
03282
03283
03284
Status =
ObOpenObjectByName(
03285 ccxObjA,
03286 *
ExDesktopObjectType,
03287 AccessMode,
03288
NULL,
03289 dwDesiredAccess,
03290
NULL,
03291 &hdesk);
03292
if (!
NT_SUCCESS(
Status)) {
03293 RIPNTERR0(
Status, RIP_VERBOSE,
"");
03294
return NULL;
03295 }
03296
03297
03298
03299
03300
ObReferenceObjectByHandle(
03301 hdesk,
03302 0,
03303 *
ExDesktopObjectType,
03304
KernelMode,
03305 &pdesk,
03306
NULL);
03307
if (!
NT_SUCCESS(
Status)) {
03308 RIPNTERR0(
Status, RIP_VERBOSE,
"");
03309
03310
Error:
03311
CloseProtectedHandle(hdesk);
03312
return NULL;
03313 }
03314
03315
if (pdesk->
dwSessionId !=
gSessionId) {
03316 RIPNTERR1(STATUS_INVALID_HANDLE, RIP_WARNING,
03317
"xxxOpenDesktop pdesk %#p belongs to a different session",
03318 pdesk);
03319
ObDereferenceObject(pdesk);
03320
goto Error;
03321 }
03322
03323
LogDesktop(pdesk, LD_REF_FN_OPENDESKTOP,
TRUE, (ULONG_PTR)
PtiCurrent());
03324
03325
03326
03327
03328
if (!
OpenDesktopCompletion(pdesk, hdesk,
dwFlags, pbShutDown)) {
03329
CloseProtectedHandle(hdesk);
03330 hdesk =
NULL;
03331 }
03332
03333
TRACE_INIT((
"xxxOpenDesktop: Leaving\n"));
03334
03335
LogDesktop(pdesk, LD_DEREF_FN_OPENDESKTOP,
FALSE, (ULONG_PTR)
PtiCurrent());
03336
ObDereferenceObject(pdesk);
03337
03338
if (hdesk !=
NULL) {
03339
SetHandleFlag(hdesk,
HF_PROTECTED,
TRUE);
03340 }
03341
03342
return hdesk;
03343 }
03344
03345
03346
03347
03348
03349
03350
03351
03352
03353
03354
03355
03356
03357
03358 BOOL xxxSwitchDesktop(
03359
PWINDOWSTATION pwinsta,
03360
PDESKTOP pdesk,
03361 BOOL bCreateNew)
03362 {
03363
PETHREAD Thread;
03364
PWND pwndSetForeground;
03365
TL tlpwndChild;
03366
TL tlpwnd;
03367
TL tlhdesk;
03368
PQ pq;
03369
BOOL bUpdateCursor =
FALSE;
03370 PLIST_ENTRY pHead, pEntry;
03371
PTHREADINFO pti;
03372
PTHREADINFO ptiCurrent =
PtiCurrent();
03373
PTERMINAL pTerm;
03374
NTSTATUS Status;
03375 HDESK hdesk;
03376
03377
CheckCritIn();
03378
03379 UserAssert(
IsWinEventNotifyDeferredOK());
03380
03381
if (pdesk ==
NULL) {
03382
return FALSE;
03383 }
03384
03385
if (pdesk ==
grpdeskRitInput) {
03386
return TRUE;
03387 }
03388
03389
if (pdesk->
dwDTFlags &
DF_DESTROYED) {
03390 RIPMSG1(RIP_ERROR,
"xxxSwitchDesktop: destroyed:%#p", pdesk);
03391
return FALSE;
03392 }
03393
03394 UserAssert(!(pdesk->
dwDTFlags & (
DF_DESKWNDDESTROYED |
DF_DYING)));
03395
03396
if (pwinsta ==
NULL)
03397 pwinsta = pdesk->
rpwinstaParent;
03398
03399
03400
03401
03402 UserAssert(pwinsta);
03403
if (pwinsta ==
NULL) {
03404 RIPMSG1(RIP_WARNING,
03405
"xxxSwitchDesktop: failed for pwinsta NULL pdesk %#p", pdesk);
03406
return FALSE;
03407 }
03408
03409
03410
03411
03412
if (pwinsta->
dwWSF_Flags &
WSF_NOIO) {
03413 RIPMSG1(RIP_VERBOSE,
03414
"xxxSwitchDesktop: failed for NOIO pdesk %#p", pdesk);
03415
return FALSE;
03416 }
03417
03418 pTerm = pwinsta->
pTerm;
03419
03420 UserAssert(
grpdeskRitInput == pwinsta->pdeskCurrent);
03421
03422
03423
03424
03425
TRACE_INIT((
"xxxSwitchDesktop: Entering, desktop = %ws, createdNew = %01lx\n",
POBJECT_NAME(pdesk), (
DWORD)bCreateNew));
03426
if (
grpdeskRitInput) {
03427
TRACE_INIT((
" coming from desktop = %ws\n",
POBJECT_NAME(
grpdeskRitInput)));
03428 }
03429
03430
03431
03432
03433 Thread =
PsGetCurrentThread();
03434
03435
03436
03437
03438
if (pdesk !=
gspdeskDisconnect)
03439
if (!
IS_SYSTEM_THREAD(Thread) && pwinsta->
dwWSF_Flags &
WSF_SWITCHLOCK &&
03440 pdesk !=
grpdeskLogon &&
03441 Thread->
Cid.UniqueProcess !=
gpidLogon)
03442
return FALSE;
03443
03444
03445
03446
03447
if (
gbDesktopLocked && ((!
gspdeskDisconnect) || (pdesk !=
gspdeskDisconnect))) {
03448
TRACE_DESKTOP((
"Attempt to switch away from the disconnect desktop\n"));
03449
03450
03451
03452
03453
LockDesktop(&
gspdeskShouldBeForeground, pdesk, LDL_DESKSHOULDBEFOREGROUND1, 0);
03454
return TRUE;
03455 }
03456
03457
03458
03459
03460
03461
03462
03463
03464 UserAssert(
grpdeskRitInput == pwinsta->pdeskCurrent);
03465
03466
if (!bCreateNew &&
grpdeskRitInput &&
03467 (
grpdeskRitInput->
pDispInfo->
hDev != pdesk->
pDispInfo->
hDev)) {
03468
03469
if (!DrvDisableMDEV(
grpdeskRitInput->
pDispInfo->
pmdev,
TRUE)) {
03470 RIPMSG1(RIP_WARNING,
"xxxSwitchDesktop: DrvDisableMDEV failed for pdesk %#p",
03471
grpdeskRitInput);
03472
return FALSE;
03473 }
03474 DrvEnableMDEV(pdesk->
pDispInfo->
pmdev,
TRUE);
03475 bUpdateCursor =
TRUE;
03476
03477 }
03478
03479
03480
03481
03482
Status =
ObOpenObjectByPointer(pdesk,
03483 0,
03484
NULL,
03485 EVENT_ALL_ACCESS,
03486
NULL,
03487
KernelMode,
03488 &hdesk);
03489
if (!
NT_SUCCESS(
Status)) {
03490
03491 RIPMSG2(RIP_ERROR,
"Could not get a handle for pdesk %#p Status %x",
03492 pdesk,
Status);
03493
return FALSE;
03494 }
03495
03496
ThreadLockDesktopHandle(ptiCurrent, &tlhdesk, hdesk);
03497
03498
#if DBG
03499
03500
03501
03502 pwinsta->pdeskCurrent = pdesk;
03503
#endif // DBG
03504
03505
03506
03507
03508
03509
if (ptiCurrent->
rpdesk !=
NULL)
03510
zzzCancelJournalling();
03511
03512
03513
03514
03515
03516
if (
gspwndAltTab !=
NULL) {
03517
03518
TL tlpwndT;
03519
03520
ThreadLockWithPti(ptiCurrent,
gspwndAltTab, &tlpwndT);
03521
xxxSendMessage(
gspwndAltTab, WM_CLOSE, 0, 0);
03522
ThreadUnlock(&tlpwndT);
03523 }
03524
03525
03526
03527
03528
if (
grpdeskRitInput !=
NULL) {
03529
03530 UserAssert(
grpdeskRitInput->
spwndForeground ==
NULL);
03531
03532
if (
grpdeskRitInput->
pDeskInfo->
spwnd !=
NULL) {
03533
if (
gpqForeground !=
NULL) {
03534
03535
Lock(&
grpdeskRitInput->
spwndForeground,
03536
gpqForeground->
spwndActive);
03537
03538
03539
03540
03541
03542
03543
03544
03545
03546
03547
03548
03549
03550
03551
03552
03553
03554
03555
03556
03557
03558
03559
03560
03561
03562
03563
03564 UserAssert((ptiCurrent->
pq !=
gpqForeground)
03565 || (ptiCurrent->
rpdesk ==
grpdeskRitInput));
03566
03567
03568
03569
03570
03571
xxxSetForegroundWindow2(
NULL, ptiCurrent, 0);
03572
03573 }
03574 }
03575 }
03576
03577
03578
03579
03580
03581
03582
if (
grpdeskRitInput !=
NULL) {
03583
03584 pHead = &
grpdeskRitInput->
PtiList;
03585
03586
for (pEntry = pHead->Flink; pEntry != pHead; pEntry = pEntry->Flink) {
03587
03588 pti = CONTAINING_RECORD(pEntry,
THREADINFO, PtiLink);
03589 pq = pti->
pq;
03590
03591
if (pq->
QF_flags &
QF_UPDATEKEYSTATE)
03592
PostUpdateKeyStateEvent(pq);
03593
03594
03595
03596
03597
03598
03599 pq->
QF_flags &= ~
QF_KEYSTATERESET;
03600 }
03601 }
03602
03603
03604
03605
03606
03607
03608
LockDesktop(&
grpdeskRitInput, pdesk, LDL_DESKRITINPUT, 0);
03609
03610
03611
03612
03613
FreeAllSpbs();
03614
03615
03616
03617
03618
03619
zzzSetDesktop(
gptiRit, pdesk,
NULL);
03620
03621
03622
03623
03624
03625
03626
03627
03628
if (pTerm->
ptiDesktop->
pq != pTerm->
pqDesktop) {
03629 UserAssert(pTerm->
pqDesktop->
cThreads == 0);
03630
AllocQueue(
NULL, pTerm->
pqDesktop);
03631 pTerm->
pqDesktop->
cThreads++;
03632
zzzAttachToQueue(pTerm->
ptiDesktop, pTerm->
pqDesktop,
NULL,
FALSE);
03633 }
03634
zzzSetDesktop(pTerm->
ptiDesktop, pdesk,
NULL);
03635
03636
03637
03638
03639
03640
ThreadLockWithPti(ptiCurrent, pdesk->
pDeskInfo->
spwnd, &tlpwnd);
03641
03642
03643
03644
03645
03646
03647
03648 GreSuspendDirectDraw(pdesk->
pDispInfo->
hDev,
TRUE);
03649
03650
xxxSetWindowPos(pdesk->
pDeskInfo->
spwnd,
03651
NULL,
03652 0,
03653 0,
03654 0,
03655 0,
03656 SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE | SWP_NOCOPYBITS);
03657
03658
03659
03660
03661
03662
03663
03664
03665
03666
03667
03668
03669
03670
03671
03672 GreResumeDirectDraw(pdesk->
pDispInfo->
hDev,
TRUE);
03673
03674
03675
03676
03677 pwndSetForeground = pdesk->
spwndForeground;
03678
if (pwndSetForeground ==
NULL ||
HMIsMarkDestroy(pwndSetForeground)) {
03679
03680 pwndSetForeground = pdesk->
pDeskInfo->
spwnd->
spwndChild;
03681
03682
while ((pwndSetForeground !=
NULL) &&
03683 !
TestWF(pwndSetForeground,
WFVISIBLE)) {
03684
03685 pwndSetForeground = pwndSetForeground->
spwndNext;
03686 }
03687 }
03688
Unlock(&pdesk->
spwndForeground);
03689
03690
03691
03692
03693
03694
if (pwndSetForeground ==
NULL) {
03695
xxxSetForegroundWindow2(
NULL,
NULL, 0);
03696 }
else {
03697
03698 UserAssert(
GETPTI(pwndSetForeground)->rpdesk ==
grpdeskRitInput);
03699
03700
03701
03702
03703
if (
GetFullScreen(pwndSetForeground) == FULLSCREENMIN) {
03704
SetFullScreen(pwndSetForeground, FULLSCREEN);
03705 }
03706
03707
ThreadLockAlwaysWithPti(ptiCurrent, pwndSetForeground, &tlpwndChild);
03708
03709
03710
03711
03712
xxxSetForegroundWindow2(pwndSetForeground, ptiCurrent, 0);
03713
ThreadUnlock(&tlpwndChild);
03714 }
03715
03716
03717
ThreadUnlock(&tlpwnd);
03718
03719
03720
03721
03722
03723
03724
03725
03726
03727
03728 pHead = &
grpdeskRitInput->
PtiList;
03729
for (pEntry = pHead->Flink; pEntry != pHead; pEntry = pEntry->Flink) {
03730
03731 pti = CONTAINING_RECORD(pEntry,
THREADINFO, PtiLink);
03732 pq = pti->
pq;
03733
03734
if (!(pq->
QF_flags &
QF_KEYSTATERESET)) {
03735 pq->
QF_flags |=
QF_UPDATEKEYSTATE |
QF_KEYSTATERESET;
03736 RtlFillMemory(pq->
afKeyRecentDown,
CBKEYSTATERECENTDOWN, 0xff);
03737
PostUpdateKeyStateEvent(pq);
03738 }
03739 }
03740
03741
03742
03743
03744
03745
if (
gHardErrorHandler.
pti) {
03746
IPostQuitMessage(
gHardErrorHandler.
pti, 0);
03747 }
03748
03749
03750
03751
03752 UserAssert(!(pdesk->
rpwinstaParent->
dwWSF_Flags &
WSF_NOIO));
03753
03754
KePulseEvent(
gpEventSwitchDesktop,
EVENT_INCREMENT,
FALSE);
03755
03756
03757
03758
03759
if (bUpdateCursor ==
TRUE) {
03760
03761
gpqCursor =
NULL;
03762
zzzInternalSetCursorPos(
gpsi->ptCursor.x,
gpsi->ptCursor.y);
03763
03764
SetPointer(
TRUE);
03765 }
03766
03767
03768
03769
03770
03771
03772
03773 {
03774
03775
03776
03777
03778
03779
03780
03781
03782
03783
03784
03785
03786
03787
03788
03789 }
03790
03791
03792
03793
03794
03795
03796
03797
03798
03799
if ((pdesk->
dwDTFlags &
DF_NEWDISPLAYSETTINGS) && pdesk->
pDeskInfo && pdesk->
pDeskInfo->
spwnd ){
03800
03801 pdesk->
dwDTFlags &= ~
DF_NEWDISPLAYSETTINGS;
03802
xxxBroadcastDisplaySettingsChange(pdesk,
TRUE);
03803
03804
03805 }
03806
03807
ThreadUnlockDesktopHandle(&tlhdesk);
03808
03809
TRACE_INIT((
"xxxSwitchDesktop: Leaving\n"));
03810
03811
return TRUE;
03812 }
03813
03814
03815
03816
03817
03818
03819
03820
03821
03822
03823 VOID zzzSetDesktop(
03824
PTHREADINFO pti,
03825
PDESKTOP pdesk,
03826 HDESK hdesk)
03827 {
03828 PTEB pteb;
03829
OBJECT_HANDLE_INFORMATION ohi;
03830
PDESKTOP pdeskRef;
03831
PDESKTOP pdeskOld;
03832
PCLIENTTHREADINFO pctiOld;
03833
TL tlpdesk;
03834
PTHREADINFO ptiCurrent =
PtiCurrent();
03835
03836
if (pti ==
NULL) {
03837 UserAssert(pti);
03838
return;
03839 }
03840
03841
03842
03843
03844 UserAssert(pdesk !=
NULL || hdesk ==
NULL);
03845
03846
03847
03848
03849
if (pdesk !=
NULL && (pdesk->
dwDTFlags & (
DF_DESKWNDDESTROYED |
DF_DYING)) &&
03850 pdesk != pti->
rpdesk) {
03851 RIPMSG2(RIP_ERROR,
"Assigning pti %#p to a dying desktop %#p",
03852 pti, pdesk);
03853
return;
03854 }
03855
03856
#if DBG
03857
03858
03859
03860
if (pti->
rpdesk && pti->
rpdesk->
dwConsoleThreadId ==
TIDq(pti) &&
03861 pti->
cWindows != 0) {
03862 RIPMSG0(RIP_ERROR,
"Reset of console desktop");
03863 }
03864
#endif
03865
03866
03867
03868
03869 pti->
TIF_flags &= ~
TIF_ALLOWOTHERACCOUNTHOOK;
03870
03871
03872
03873
03874 pti->
hdesk = hdesk;
03875
if (hdesk !=
NULL) {
03876
if (
NT_SUCCESS(
ObReferenceObjectByHandle(hdesk,
03877 0,
03878 *
ExDesktopObjectType,
03879
KernelMode,
03880 &pdeskRef,
03881 &ohi))) {
03882
03883 UserAssert(pdesk->
dwSessionId ==
gSessionId);
03884
03885
LogDesktop(pdeskRef, LD_REF_FN_SETDESKTOP,
TRUE, (ULONG_PTR)
PtiCurrent());
03886
03887 UserAssert(pdeskRef == pdesk);
03888
LogDesktop(pdesk, LD_DEREF_FN_SETDESKTOP,
FALSE, (ULONG_PTR)
PtiCurrent());
03889
ObDereferenceObject(pdeskRef);
03890 pti->
amdesk = ohi.
GrantedAccess;
03891
if (
CheckHandleFlag(hdesk,
HF_DESKTOPHOOK))
03892 pti->
TIF_flags |=
TIF_ALLOWOTHERACCOUNTHOOK;
03893
03894
SetHandleFlag(hdesk,
HF_PROTECTED,
TRUE);
03895
03896 }
else {
03897 pti->
amdesk = 0;
03898 }
03899
03900 }
else {
03901 pti->
amdesk = 0;
03902 }
03903
03904
03905
03906
03907
03908
if ((pdesk !=
NULL) && (pdesk == pti->
rpdesk))
03909
return;
03910
03911
03912
03913
03914
03915 pdeskOld = pti->
rpdesk;
03916
ThreadLockDesktop(ptiCurrent, pdeskOld, &tlpdesk, LDLT_FN_SETDESKTOP);
03917 pctiOld = pti->
pcti;
03918
03919
03920
03921
03922
if (pti->
rpdesk) {
03923 UserAssert(
ISATOMICCHECK() || pti->
pq ==
NULL || pti->
pq->
cThreads == 1);
03924 RemoveEntryList(&pti->
PtiLink);
03925 }
03926
03927
LockDesktop(&pti->
rpdesk, pdesk, LDL_PTI_DESK, (ULONG_PTR)pti);
03928
03929
03930
03931
03932
03933
03934
03935
if (pdesk !=
NULL) {
03936 pti->pDeskInfo = pdesk->
pDeskInfo;
03937 InsertHeadList(&pdesk->
PtiList, &pti->PtiLink);
03938 }
else {
03939 pti->pDeskInfo = &
diStatic;
03940 }
03941
03942
03943
03944 pteb = pti->pEThread->Tcb.Teb;
03945
if (pteb) {
03946
PDESKTOPVIEW pdv;
03947
if (pdesk && (pdv =
GetDesktopView(pti->ppi, pdesk))) {
03948
03949 pti->pClientInfo->pDeskInfo =
03950 (
PDESKTOPINFO)((
PBYTE)pti->pDeskInfo - pdv->ulClientDelta);
03951
03952 pti->pClientInfo->ulClientDelta = pdv->ulClientDelta;
03953
03954 }
else {
03955
03956 pti->pClientInfo->pDeskInfo =
NULL;
03957 pti->pClientInfo->ulClientDelta = 0;
03958
03959
03960
03961
03962 pti->iCursorLevel =
TEST_GTERMF(
GTERMF_MOUSE) ? 0 : -1;
03963
if (pti->pq)
03964 pti->pq->iCursorLevel = pti->iCursorLevel;
03965 }
03966 }
03967
03968
03969
03970
03971
03972
if (pdesk !=
NULL) {
03973
03974
03975
03976
03977
03978 pti->pcti =
DesktopAllocAlways(pdesk,
03979
sizeof(
CLIENTTHREADINFO),
03980
DTAG_CLIENTTHREADINFO);
03981 }
03982
03983
if (pdesk ==
NULL || pti->pcti ==
NULL) {
03984 pti->pcti = &(pti->cti);
03985 pti->pClientInfo->pClientThreadInfo =
NULL;
03986 }
else {
03987 pti->pClientInfo->pClientThreadInfo =
03988 (
PCLIENTTHREADINFO)((
PBYTE)pti->pcti - pti->pClientInfo->ulClientDelta);
03989 }
03990
03991
if (pctiOld !=
NULL) {
03992
03993
if (pctiOld != pti->pcti) {
03994 RtlCopyMemory(pti->pcti, pctiOld,
sizeof(
CLIENTTHREADINFO));
03995 }
03996
03997
if (pctiOld != &(pti->cti)) {
03998
DesktopFree(pdeskOld, pctiOld);
03999 }
04000
04001 }
else {
04002 RtlZeroMemory(pti->pcti,
sizeof(
CLIENTTHREADINFO));
04003 }
04004
04005
04006
04007
04008
04009
04010
04011 UserAssert((pdesk ==
NULL ) || (pti->pDeskInfo == pdesk->
pDeskInfo));
04012 UserAssert(pti->rpdesk == pdesk);
04013
if (pti->pq !=
NULL) {
04014
PQ pq =
GetJournallingQueue(pti);
04015
if (pq !=
NULL) {
04016 pq->
cThreads++;
04017
zzzAttachToQueue(pti, pq,
NULL,
FALSE);
04018 }
04019 }
04020
04021
ThreadUnlockDesktop(ptiCurrent, &tlpdesk, LDUT_FN_SETDESKTOP);
04022 }
04023
04024
04025
04026
04027
04028
04029
04030
04031
04032
04033 BOOL xxxSetThreadDesktop(
04034 HDESK hdesk,
04035
PDESKTOP pdesk)
04036 {
04037
PTHREADINFO ptiCurrent;
04038
PPROCESSINFO ppiCurrent;
04039
PQ pqAttach;
04040
04041 ptiCurrent =
PtiCurrent();
04042 ppiCurrent = ptiCurrent->
ppi;
04043
04044
04045
04046
04047
04048
if (pdesk !=
NULL) {
04049
try {
04050
MapDesktop(
ObOpenHandle, ppiCurrent->Process, pdesk, 0, 1);
04051 } except (W32ExceptionHandler(
TRUE, RIP_WARNING)) {
04052
return FALSE;
04053 }
04054
04055 UserAssert(
GetDesktopView(ppiCurrent, pdesk) !=
NULL);
04056 }
04057
04058
04059
04060
04061
if (ptiCurrent->pEThread->ThreadsProcess !=
gpepCSRSS) {
04062
04063
04064
04065
04066
if (ptiCurrent->
cWindows != 0 || ptiCurrent->
fsHooks) {
04067 RIPERR0(ERROR_BUSY, RIP_WARNING,
"Thread has windows or hooks");
04068
return FALSE;
04069 }
04070
04071
04072
04073
04074
04075
if (ppiCurrent->
rpdeskStartup ==
NULL && hdesk !=
NULL) {
04076
LockDesktop(&ppiCurrent->
rpdeskStartup, pdesk, LDL_PPI_DESKSTARTUP1, (ULONG_PTR)ppiCurrent);
04077 ppiCurrent->hdeskStartup = hdesk;
04078 }
04079 }
04080
04081
04082
04083
04084
04085
04086
04087
04088
04089
if (ptiCurrent->
rpdesk != pdesk) {
04090
if (ptiCurrent->
pq->
cThreads > 1) {
04091 pqAttach =
AllocQueue(
NULL,
NULL);
04092
if (pqAttach !=
NULL) {
04093 pqAttach->
cThreads++;
04094
zzzAttachToQueue(ptiCurrent, pqAttach,
NULL,
FALSE);
04095 }
else {
04096 RIPERR0(ERROR_NOT_ENOUGH_MEMORY, RIP_WARNING,
"Thread could not be detached");
04097
return FALSE;
04098 }
04099 }
else if (ptiCurrent->
pq ==
gpqForeground) {
04100
04101
04102
04103
04104
04105
04106
04107 UserAssert(ptiCurrent->
pq->
spwndActive ==
NULL);
04108 UserAssert(ptiCurrent->
pq->
spwndCapture ==
NULL);
04109 UserAssert(ptiCurrent->
pq->
spwndFocus ==
NULL);
04110 UserAssert(ptiCurrent->
pq->
spwndActivePrev ==
NULL);
04111
xxxSetForegroundWindow2(
NULL, ptiCurrent, 0);
04112 }
else if (ptiCurrent->
rpdesk ==
NULL) {
04113
04114
04115
04116 ptiCurrent->
iCursorLevel =
TEST_GTERMF(
GTERMF_MOUSE) ? 0 : -1;
04117 ptiCurrent->
pq->
iCursorLevel = ptiCurrent->
iCursorLevel;
04118 }
04119
04120 UserAssert(ptiCurrent->
pq !=
gpqForeground);
04121
04122 }
04123
04124
zzzSetDesktop(ptiCurrent, pdesk, hdesk);
04125
04126
return TRUE;
04127 }
04128
04129
04130
04131
04132
04133
04134
04135
04136
NTSTATUS
04137 xxxUserDuplicateObject(
04138 IN HANDLE SourceProcessHandle,
04139 IN HANDLE SourceHandle,
04140 IN HANDLE TargetProcessHandle OPTIONAL,
04141 OUT PHANDLE TargetHandle OPTIONAL,
04142 IN ACCESS_MASK DesiredAccess,
04143 IN ULONG HandleAttributes,
04144 IN ULONG Options
04145 )
04146
04147 {
04148
NTSTATUS Status;
04149
04150
CheckCritIn();
04151
04152
LeaveCrit();
04153
04154
Status = ZwDuplicateObject(SourceProcessHandle, SourceHandle, TargetProcessHandle,
04155 TargetHandle, DesiredAccess, HandleAttributes, Options);
04156
04157
EnterCrit();
04158
04159
return Status;
04160 }
04161
04162
04163
04164
04165
04166
04167
04168
04169
04170 BOOLEAN
04171 xxxUserFindHandleForObject(
04172 IN
PEPROCESS Process,
04173 IN PVOID Object OPTIONAL,
04174 IN
POBJECT_TYPE ObjectType OPTIONAL,
04175 IN
POBJECT_HANDLE_INFORMATION HandleInformation OPTIONAL,
04176 OUT PHANDLE Handle
04177 )
04178 {
04179 BOOLEAN fRet;
04180
BOOL fExclusive, fShared;
04181
04182 fExclusive =
ExIsResourceAcquiredExclusiveLite(
gpresUser);
04183
if (!fExclusive) {
04184 fShared =
ExIsResourceAcquiredSharedLite(
gpresUser);
04185 }
04186
04187
if (fExclusive || fShared) {
04188
LeaveCrit();
04189 }
04190
04191 fRet =
ObFindHandleForObject(Process, Object, ObjectType, HandleInformation,
Handle);
04192
04193
if (fExclusive) {
04194
EnterCrit();
04195 }
else if (fShared) {
04196
EnterSharedCrit();
04197 }
04198
04199
return fRet;
04200 }
04201
04202
04203
04204
04205
04206
04207
04208
04209
04210
04211 HDESK
xxxGetThreadDesktop(
04212 DWORD dwThread,
04213 HDESK hdeskConsole,
04214 KPROCESSOR_MODE AccessMode)
04215 {
04216
PTHREADINFO pti =
PtiFromThreadId(dwThread);
04217
PPROCESSINFO ppiThread;
04218 HDESK hdesk;
04219
NTSTATUS Status;
04220
04221
if (pti ==
NULL) {
04222
04223
04224
04225
04226
04227
04228
if (hdeskConsole ==
NULL) {
04229 RIPERR1(ERROR_INVALID_PARAMETER, RIP_VERBOSE,
04230
"xxxGetThreadDesktop: invalid threadId 0x%x",
04231 dwThread);
04232
return NULL;
04233 }
04234
04235 hdesk = hdeskConsole;
04236 ppiThread =
PpiFromProcess(
gpepCSRSS);
04237 }
else {
04238 hdesk = pti->
hdesk;
04239 ppiThread = pti->
ppi;
04240 }
04241
04242
04243
04244
04245
if (hdesk !=
NULL) {
04246
04247
04248
04249
04250
04251
04252
04253
if (ppiThread !=
PpiCurrent()) {
04254 PVOID pobj;
04255
OBJECT_HANDLE_INFORMATION ohi;
04256
04257 RIPMSG4(RIP_VERBOSE,
"[%x.%x] %s called xxxGetThreadDesktop for pti %#p\n",
04258
PsGetCurrentThread()->Cid.UniqueProcess,
04259
PsGetCurrentThread()->Cid.UniqueThread,
04260
PsGetCurrentProcess()->ImageFileName,
04261 pti);
04262
04263
KeAttachProcess(&ppiThread->Process->Pcb);
04264
Status =
ObReferenceObjectByHandle(hdesk,
04265 0,
04266 *
ExDesktopObjectType,
04267 AccessMode,
04268 &pobj,
04269 &ohi);
04270
KeDetachProcess();
04271
if (!
NT_SUCCESS(
Status) ||
04272 !
xxxUserFindHandleForObject(
PsGetCurrentProcess(), pobj,
NULL, &ohi, &hdesk)) {
04273
04274 RIPMSG0(RIP_VERBOSE,
"Cannot find hdesk for current process");
04275
04276 hdesk =
NULL;
04277
04278 }
else {
04279
LogDesktop(pobj, LD_REF_FN_GETTHREADDESKTOP,
TRUE, (ULONG_PTR)
PtiCurrent());
04280 }
04281
if (
NT_SUCCESS(
Status)) {
04282
LogDesktop(pobj, LD_DEREF_FN_GETTHREADDESKTOP,
FALSE, (ULONG_PTR)
PtiCurrent());
04283
ObDereferenceObject(pobj);
04284 }
04285 }
04286
04287
if (hdesk ==
NULL) {
04288 RIPERR0(ERROR_ACCESS_DENIED, RIP_VERBOSE,
"xxxGetThreadDesktop: hdesk is null");
04289 }
else {
04290
SetHandleFlag(hdesk,
HF_PROTECTED,
TRUE);
04291 }
04292 }
04293
04294
return hdesk;
04295 }
04296
04297
04298
04299
04300
04301
04302
04303
04304
04305
04306
04307
04308
04309 HDESK
xxxGetInputDesktop(VOID)
04310 {
04311 HDESK hdesk;
04312
04313
if (
xxxUserFindHandleForObject(
PsGetCurrentProcess(),
grpdeskRitInput,
NULL,
NULL, &hdesk)) {
04314
SetHandleFlag(hdesk,
HF_PROTECTED,
TRUE);
04315
return hdesk;
04316 }
else {
04317
return NULL;
04318 }
04319 }
04320
04321
04322
04323
04324
04325
04326
04327
04328
04329
04330
04331
04332 BOOL xxxCloseDesktop(
04333 HDESK hdesk,
04334 KPROCESSOR_MODE AccessMode)
04335 {
04336
PDESKTOP pdesk;
04337
PTHREADINFO ptiT;
04338
PPROCESSINFO ppi;
04339
NTSTATUS Status;
04340
04341 ppi =
PpiCurrent();
04342
04343
04344
04345
04346
Status =
ObReferenceObjectByHandle(
04347 hdesk,
04348 0,
04349 *
ExDesktopObjectType,
04350 AccessMode,
04351 &pdesk,
04352
NULL);
04353
if (!
NT_SUCCESS(
Status)) {
04354 RIPNTERR0(
Status, RIP_VERBOSE,
"");
04355
return FALSE;
04356 }
04357
04358 UserAssert(pdesk->
dwSessionId ==
gSessionId);
04359
04360
LogDesktop(pdesk, LD_REF_FN_CLOSEDESKTOP,
TRUE, (ULONG_PTR)
PtiCurrent());
04361
04362
if (ppi->Process !=
gpepCSRSS) {
04363
04364
04365
04366
04367
04368
for (ptiT = ppi->
ptiList; ptiT !=
NULL; ptiT = ptiT->
ptiSibling) {
04369
if (ptiT->
hdesk == hdesk) {
04370 RIPERR2(ERROR_BUSY, RIP_WARNING,
04371
"CloseDesktop: Desktop %#p still in use by thread %#p",
04372 pdesk, ptiT);
04373
LogDesktop(pdesk, LD_DEREF_FN_CLOSEDESKTOP1,
FALSE, (ULONG_PTR)
PtiCurrent());
04374
ObDereferenceObject(pdesk);
04375
return FALSE;
04376 }
04377 }
04378
04379
04380
04381
04382
04383
04384
04385
04386
04387
04388
if ((pdesk == ppi->
rpdeskStartup) && (hdesk == ppi->
hdeskStartup)) {
04389
UnlockDesktop(&ppi->
rpdeskStartup, LDU_PPI_DESKSTARTUP2, (ULONG_PTR)ppi);
04390 ppi->hdeskStartup =
NULL;
04391 }
04392 }
04393
04394
04395
04396
04397
SetHandleFlag(hdesk,
HF_DESKTOPHOOK,
FALSE);
04398
04399
04400
04401
04402
Status =
CloseProtectedHandle(hdesk);
04403
04404
LogDesktop(pdesk, LD_DEREF_FN_CLOSEDESKTOP2,
FALSE, (ULONG_PTR)
PtiCurrent());
04405
ObDereferenceObject(pdesk);
04406 UserAssert(
NT_SUCCESS(
Status));
04407
04408
return TRUE;
04409 }
04410
04411
04412
04413
04414
04415
04416
04417
04418
04419
04420 VOID TerminateConsole(
04421
PDESKTOP pdesk)
04422 {
04423
NTSTATUS Status;
04424
PETHREAD Thread;
04425
PTHREADINFO pti;
04426
04427
if (pdesk->
dwConsoleThreadId == 0)
04428
return;
04429
04430
04431
04432
04433
Status =
LockThreadByClientId((HANDLE)LongToHandle( pdesk->
dwConsoleThreadId ), &Thread);
04434
if (!
NT_SUCCESS(
Status))
04435
return;
04436
04437
04438
04439
04440 pti =
PtiFromThread(Thread);
04441 UserAssert(pti !=
NULL);
04442
if (pti !=
NULL) {
04443
_PostThreadMessage(pti, WM_QUIT, 0, 0);
04444 }
04445
04446
04447
04448
04449 pdesk->
dwConsoleThreadId = 0;
04450
04451
UnlockThread(Thread);
04452 }
04453
04454
04455
04456
04457
04458
04459
04460
04461
04462
04463
04464 BOOL CheckHandleFlag(
04465 HANDLE hObject,
04466 DWORD dwFlag)
04467 {
04468
PPROCESSINFO ppi;
04469 ULONG
Index = ((
PEXHANDLE)&hObject)->Index *
HF_LIMIT + dwFlag;
04470
BOOL fRet =
FALSE;
04471
04472
EnterHandleFlagsCrit();
04473
04474
if ((ppi =
PpiCurrent()) !=
NULL) {
04475 fRet = (
Index < ppi->
bmHandleFlags.SizeOfBitMap &&
04476 RtlCheckBit(&ppi->
bmHandleFlags,
Index));
04477 }
04478
04479
LeaveHandleFlagsCrit();
04480
04481
return fRet;
04482 }
04483
04484
04485
04486
04487
04488
04489
04490
04491
04492
04493
04494 BOOL SetHandleFlag(
04495 HANDLE hObject,
04496 DWORD dwFlag,
04497 BOOL fSet)
04498 {
04499
PPROCESSINFO ppi;
04500 ULONG
Index = ((
PEXHANDLE)&hObject)->Index *
HF_LIMIT + dwFlag;
04501 PRTL_BITMAP pbm;
04502 ULONG cBits;
04503 PULONG
Buffer;
04504
BOOL fRet =
TRUE;
04505
04506 UserAssert(dwFlag <
HF_LIMIT);
04507
04508
EnterHandleFlagsCrit();
04509
04510
if ((ppi =
PpiCurrent()) !=
NULL) {
04511 pbm = &ppi->
bmHandleFlags;
04512
if (fSet) {
04513
04514
04515
04516
04517
if (
Index >= pbm->SizeOfBitMap) {
04518
04519
04520
04521 cBits = ((
Index + 1) + 0x1F) & ~0x1F;
04522
Buffer = UserAllocPoolWithQuotaZInit(cBits / 8, TAG_PROCESSINFO);
04523
if (
Buffer ==
NULL) {
04524 fRet =
FALSE;
04525
goto Exit;
04526 }
04527
if (pbm->Buffer) {
04528 RtlCopyMemory(
Buffer, pbm->Buffer, pbm->SizeOfBitMap / 8);
04529 UserFreePool(pbm->Buffer);
04530 }
04531
04532
RtlInitializeBitMap(pbm,
Buffer, cBits);
04533 }
04534
04535
RtlSetBits(pbm,
Index, 1);
04536 }
else if (
Index < pbm->SizeOfBitMap) {
04537
RtlClearBits(pbm,
Index, 1);
04538 }
04539 }
04540
04541 Exit:
04542
LeaveHandleFlagsCrit();
04543
04544
return fRet;
04545 }
04546
04547
04548
04549
04550
04551
04552
04553
04554
04555
04556
04557 BOOL CheckHandleInUse(
04558 HANDLE hObject)
04559 {
04560
BOOL fRet;
04561
04562
EnterHandleFlagsCrit();
04563 fRet = ((
gProcessInUse ==
PsGetCurrentProcess()) &&
04564 (
gHandleInUse == hObject));
04565
LeaveHandleFlagsCrit();
04566
04567
return fRet;
04568 }
04569
04570
04571
04572
04573
04574
04575
04576
04577
04578
04579 VOID SetHandleInUse(
04580 HANDLE hObject)
04581 {
04582
EnterHandleFlagsCrit();
04583
gProcessInUse =
PsGetCurrentProcess();
04584
gHandleInUse = hObject;
04585
LeaveHandleFlagsCrit();
04586 }
04587
04588 NTSTATUS xxxResolveDesktopForWOW (
04589 IN OUT PUNICODE_STRING pstrDesktop)
04590 {
04591
NTSTATUS Status;
04592 UNICODE_STRING strDesktop, strWinSta, strStatic;
04593 LPWSTR pszDesktop;
04594
BOOL fWinStaDefaulted;
04595
BOOL fDesktopDefaulted;
04596 HWINSTA hwinsta;
04597 HDESK hdesk;
04598 OBJECT_ATTRIBUTES ObjA;
04599 PUNICODE_STRING pstrStatic;
04600 POBJECT_ATTRIBUTES pObjA =
NULL;
04601 SIZE_T cbObjA;
04602
BOOL bShutDown =
FALSE;
04603 PTEB pteb = NtCurrentTeb();
04604
04605 UserAssert(pteb);
04606
04607
04608
04609
04610
04611
04612
if (pstrDesktop ==
NULL) {
04613
return STATUS_INVALID_PARAMETER;
04614 }
04615
04616 strStatic.Length = 0;
04617 strStatic.MaximumLength = STATIC_UNICODE_BUFFER_LENGTH *
sizeof(WCHAR);
04618
04619
04620
04621
04622
04623
04624
04625
04626 strStatic.Buffer = pteb->StaticUnicodeBuffer;
04627
04628 UserAssert(pteb->StaticUnicodeBuffer == pteb->StaticUnicodeString.Buffer);
04629 UserAssert(pteb->StaticUnicodeString.MaximumLength ==STATIC_UNICODE_BUFFER_LENGTH *
sizeof(WCHAR));
04630
04631
if (pstrDesktop->Length == 0) {
04632
RtlInitUnicodeString(&strDesktop, TEXT(
"Default"));
04633 fWinStaDefaulted = fDesktopDefaulted =
TRUE;
04634 }
else {
04635
USHORT cch;
04636
04637
04638
04639
04640 strWinSta = *pstrDesktop;
04641 cch = strWinSta.Length /
sizeof(WCHAR);
04642 pszDesktop = strWinSta.Buffer;
04643
while (cch && *pszDesktop !=
L'\\') {
04644 cch--;
04645 pszDesktop++;
04646 }
04647 fDesktopDefaulted =
FALSE;
04648
04649
if (cch == 0) {
04650
04651
04652
04653
04654 strDesktop = strWinSta;
04655 fWinStaDefaulted =
TRUE;
04656 }
else {
04657
04658
04659
04660 strDesktop.Buffer = pszDesktop + 1;
04661 strDesktop.Length = strDesktop.MaximumLength = (cch - 1) *
sizeof(WCHAR);
04662 strWinSta.Length = (
USHORT)(pszDesktop - strWinSta.Buffer) *
sizeof(WCHAR);
04663
04664
04665
04666
04667
04668 *pszDesktop = (WCHAR)0;
04669
04670 fWinStaDefaulted =
FALSE;
04671
04672
RtlAppendUnicodeToString(&strStatic, (PWSTR)
szWindowStationDirectory);
04673
RtlAppendUnicodeToString(&strStatic,
L"\\");
04674
RtlAppendUnicodeStringToString(&strStatic, &strWinSta);
04675
04676 }
04677 }
04678
04679
if (fWinStaDefaulted) {
04680
04681
04682
RtlInitUnicodeString(&strWinSta,
L"WinSta0");
04683
04684
RtlAppendUnicodeToString(&strStatic, (PWSTR)
szWindowStationDirectory);
04685
RtlAppendUnicodeToString(&strStatic,
L"\\");
04686
RtlAppendUnicodeStringToString(&strStatic, &strWinSta);
04687
04688 }
04689
04690
04691
04692
04693
if (
gbSecureDesktop) {
04694
04695
04696
04697 cbObjA =
sizeof(*pObjA) +
sizeof(*pstrStatic);
04698
Status = ZwAllocateVirtualMemory(NtCurrentProcess(),
04699 &pObjA, 0, &cbObjA, MEM_COMMIT, PAGE_READWRITE);
04700 pstrStatic = (PUNICODE_STRING)((
PBYTE)pObjA +
sizeof(*pObjA));
04701
04702
if (
NT_SUCCESS(
Status)) {
04703
04704
04705
04706
04707
try {
04708 *pstrStatic = strStatic;
04709 InitializeObjectAttributes( pObjA,
04710 pstrStatic,
04711 OBJ_CASE_INSENSITIVE,
04712
NULL,
04713
NULL
04714 );
04715 } except (W32ExceptionHandler(
FALSE, RIP_WARNING)) {
04716
Status = GetExceptionCode();
04717 }
04718
04719
if (
NT_SUCCESS(
Status)) {
04720 hwinsta =
_OpenWindowStation(pObjA, MAXIMUM_ALLOWED,
UserMode);
04721 }
else {
04722 hwinsta =
NULL;
04723 }
04724
if (!hwinsta) {
04725 ZwFreeVirtualMemory(NtCurrentProcess(), &pObjA, &cbObjA,
04726 MEM_RELEASE);
04727
return STATUS_ACCESS_DENIED;
04728 }
04729 }
else {
04730
return STATUS_NO_MEMORY;
04731 }
04732 }
else {
04733 InitializeObjectAttributes( &ObjA,
04734 &strStatic,
04735 OBJ_CASE_INSENSITIVE,
04736
NULL,
04737
NULL
04738 );
04739 hwinsta =
_OpenWindowStation(&ObjA, MAXIMUM_ALLOWED,
KernelMode);
04740
if (!hwinsta) {
04741
return STATUS_ACCESS_DENIED;
04742 }
04743 }
04744
04745
04746
04747
04748
04749
RtlCopyUnicodeString(&strStatic, &strDesktop);
04750
04751
if (
gbSecureDesktop) {
04752
04753
04754
04755
04756
try {
04757 *pstrStatic = strStatic;
04758 InitializeObjectAttributes( pObjA,
04759 pstrStatic,
04760 OBJ_CASE_INSENSITIVE,
04761 hwinsta,
04762
NULL
04763 );
04764 } except (W32ExceptionHandler(
FALSE, RIP_WARNING)) {
04765
Status = GetExceptionCode();
04766 }
04767
04768
if (
NT_SUCCESS(
Status)) {
04769 hdesk =
xxxOpenDesktop(pObjA,
04770
UserMode,
04771 0,
04772 MAXIMUM_ALLOWED,
04773 &bShutDown);
04774 }
else {
04775 hdesk =
NULL;
04776 }
04777
04778 ZwFreeVirtualMemory(NtCurrentProcess(), &pObjA, &cbObjA,
04779 MEM_RELEASE);
04780 }
else {
04781 InitializeObjectAttributes( &ObjA,
04782 &strStatic,
04783 OBJ_CASE_INSENSITIVE,
04784 hwinsta,
04785
NULL
04786 );
04787 hdesk =
xxxOpenDesktop(&ObjA,
04788
KernelMode,
04789 0,
04790 MAXIMUM_ALLOWED,
04791 &bShutDown);
04792 }
04793
04794
if (!hdesk) {
04795 UserVerify(
NT_SUCCESS(ZwClose(hwinsta)));
04796
return STATUS_ACCESS_DENIED;
04797 }
04798
04799
CloseProtectedHandle(hdesk);
04800 UserVerify(
NT_SUCCESS(ZwClose(hwinsta)));
04801
04802
04803
04804
04805
RtlCopyUnicodeString(pstrDesktop, &strWinSta);
04806
RtlAppendUnicodeToString(pstrDesktop,
L"\\");
04807
RtlAppendUnicodeStringToString(pstrDesktop, &strDesktop);
04808
04809
return STATUS_SUCCESS;
04810 }
04811
04812
04813
04814
04815
04816
04817
04818
04819
04820
04821 HDESK
xxxResolveDesktop(
04822 HANDLE hProcess,
04823 PUNICODE_STRING pstrDesktop,
04824 HWINSTA *phwinsta,
04825 BOOL fInherit,
04826 BOOL* pbShutDown)
04827 {
04828
PEPROCESS Process;
04829
PPROCESSINFO ppi;
04830 HWINSTA hwinsta;
04831 HDESK hdesk;
04832
PDESKTOP pdesk;
04833
PWINDOWSTATION pwinsta;
04834
BOOL fInteractive;
04835 UNICODE_STRING strDesktop;
04836 UNICODE_STRING strWinSta, strStatic;
04837 OBJECT_ATTRIBUTES ObjA;
04838 PUNICODE_STRING pstrStatic;
04839 POBJECT_ATTRIBUTES pObjA =
NULL;
04840 SIZE_T cbObjA;
04841 LPWSTR pszDesktop;
04842 WCHAR awchName[
sizeof(
L"Service-0x0000-0000$") /
sizeof(WCHAR)];
04843
BOOL fWinStaDefaulted;
04844
BOOL fDesktopDefaulted;
04845 LUID luidService;
04846
NTSTATUS Status;
04847 HWINSTA hwinstaDup;
04848 PTEB pteb = NtCurrentTeb();
04849
04850
CheckCritIn();
04851
04852 UserAssert(pteb);
04853
04854
Status =
ObReferenceObjectByHandle(hProcess,
04855 PROCESS_QUERY_INFORMATION,
04856 *
PsProcessType,
04857
UserMode,
04858 &Process,
04859
NULL);
04860
if (!
NT_SUCCESS(
Status)) {
04861 RIPMSG1(RIP_WARNING,
"ResolveDesktop: Could not reference process handle (0x%X)", hProcess);
04862
return NULL;
04863 }
04864
04865 strStatic.Length = 0;
04866 strStatic.MaximumLength = STATIC_UNICODE_BUFFER_LENGTH *
sizeof(WCHAR);
04867
04868
04869
04870
04871
04872
04873
04874
04875 strStatic.Buffer = pteb->StaticUnicodeBuffer;
04876
04877 UserAssert(pteb->StaticUnicodeBuffer == pteb->StaticUnicodeString.Buffer);
04878 UserAssert(pteb->StaticUnicodeString.MaximumLength ==STATIC_UNICODE_BUFFER_LENGTH *
sizeof(WCHAR));
04879
04880
04881
04882
04883
04884
04885 hwinsta =
NULL;
04886 hwinstaDup =
NULL;
04887 hdesk =
NULL;
04888 ppi =
PpiFromProcess(Process);
04889
04890
04891
04892
04893
if (ppi !=
NULL) {
04894
04895
if (ppi->W32PF_Flags & W32PF_TERMINATED) {
04896
04897
ObDereferenceObject(Process);
04898
04899 RIPMSG1(RIP_WARNING,
"xxxResolveDesktop: ppi %#p has been destroyed", ppi);
04900
return NULL;
04901 }
04902
04903
if (ppi->
hwinsta !=
NULL && ppi->
hdeskStartup !=
NULL) {
04904
04905
04906
04907
04908
04909
if (Process ==
PsGetCurrentProcess()) {
04910 hwinsta = ppi->
hwinsta;
04911 hdesk = ppi->
hdeskStartup;
04912 }
else {
04913
Status =
ObOpenObjectByPointer(
04914 ppi->
rpwinsta,
04915 0,
04916
NULL,
04917 MAXIMUM_ALLOWED,
04918 *
ExWindowStationObjectType,
04919 (
KPROCESSOR_MODE)(
gbSecureDesktop ?
UserMode :
KernelMode),
04920 &hwinsta);
04921
if (
NT_SUCCESS(
Status)) {
04922
Status =
ObOpenObjectByPointer(
04923 ppi->
rpdeskStartup,
04924 0,
04925
NULL,
04926 MAXIMUM_ALLOWED,
04927 *
ExDesktopObjectType,
04928 (
KPROCESSOR_MODE)(
gbSecureDesktop ?
UserMode :
KernelMode),
04929 &hdesk);
04930
if (!
NT_SUCCESS(
Status)) {
04931 UserVerify(
NT_SUCCESS(ZwClose(hwinsta)));
04932 hwinsta =
NULL;
04933 }
04934 }
04935
if (!
NT_SUCCESS(
Status)) {
04936 RIPNTERR2(
04937
Status,
04938 RIP_WARNING,
04939
"ResolveDesktop: Could not reference winsta=%#p and/or desk=%#p",
04940 ppi->
rpwinsta, ppi->
rpdeskStartup);
04941 }
04942 }
04943
04944 RIPMSG2(RIP_VERBOSE,
04945
"ResolveDesktop: to hwinsta=%#p desktop=%#p",
04946 hwinsta, hdesk);
04947
04948
ObDereferenceObject(Process);
04949 *phwinsta = hwinsta;
04950
return hdesk;
04951 }
04952 }
04953
04954
04955
04956
04957
if (pstrDesktop ==
NULL || pstrDesktop->Length == 0) {
04958
RtlInitUnicodeString(&strDesktop, TEXT(
"Default"));
04959 fWinStaDefaulted = fDesktopDefaulted =
TRUE;
04960 }
else {
04961
USHORT cch;
04962
04963
04964
04965
04966 strWinSta = *pstrDesktop;
04967 cch = strWinSta.Length /
sizeof(WCHAR);
04968 pszDesktop = strWinSta.Buffer;
04969
while (cch && *pszDesktop !=
L'\\') {
04970 cch--;
04971 pszDesktop++;
04972 }
04973 fDesktopDefaulted =
FALSE;
04974
04975
if (cch == 0) {
04976
04977
04978
04979
04980 strDesktop = strWinSta;
04981 fWinStaDefaulted =
TRUE;
04982 }
else {
04983
04984
04985
04986 strDesktop.Buffer = pszDesktop + 1;
04987 strDesktop.Length = strDesktop.MaximumLength = (cch - 1) *
sizeof(WCHAR);
04988 strWinSta.Length = (
USHORT)(pszDesktop - strWinSta.Buffer) *
sizeof(WCHAR);
04989 fWinStaDefaulted =
FALSE;
04990
04991
RtlAppendUnicodeToString(&strStatic, (PWSTR)
szWindowStationDirectory);
04992
RtlAppendUnicodeToString(&strStatic,
L"\\");
04993
RtlAppendUnicodeStringToString(&strStatic, &strWinSta);
04994
04995
if (!
NT_SUCCESS(
Status =
_UserTestForWinStaAccess(&strStatic,
TRUE))) {
04996
if (strStatic.MaximumLength > strStatic.Length)
04997 strStatic.Buffer[strStatic.Length/
sizeof(WCHAR)] = 0;
04998
else
04999 strStatic.Buffer[(strStatic.Length -
sizeof(WCHAR))/
sizeof(WCHAR)] = 0;
05000 RIPMSG2(RIP_WARNING,
05001
"ResolveDesktop: Error (0x%X) resolving to WinSta='%ws'",
05002
Status, strStatic.Buffer);
05003
ObDereferenceObject(Process);
05004 *phwinsta =
NULL;
05005
return NULL;
05006 }
05007
05008 }
05009 }
05010
05011
05012
05013
05014
05015
if (fDesktopDefaulted)
05016 fInherit =
FALSE;
05017
05018
05019
05020
05021
05022
if (hwinsta ==
NULL &&
grpWinStaList) {
05023
05024
05025
05026
05027
05028
if (fWinStaDefaulted) {
05029
05030
RtlInitUnicodeString(&strWinSta,
L"WinSta0");
05031
05032
RtlAppendUnicodeToString(&strStatic, (PWSTR)
szWindowStationDirectory);
05033
RtlAppendUnicodeToString(&strStatic,
L"\\");
05034
RtlAppendUnicodeStringToString(&strStatic, &strWinSta);
05035
05036
if (
gbRemoteSession) {
05037
05038
05039
05040
05041 fInteractive =
NT_SUCCESS(
_UserTestForWinStaAccess(&strStatic,
TRUE));
05042 }
else {
05043 fInteractive =
NT_SUCCESS(
_UserTestForWinStaAccess(&strStatic,fInherit));
05044 }
05045
05046
if (!fInteractive) {
05047
GetProcessLuid(
NULL, &luidService);
05048 swprintf(awchName,
L"Service-0x%x-%x$",
05049 luidService.HighPart, luidService.LowPart);
05050
RtlInitUnicodeString(&strWinSta, awchName);
05051 }
05052 }
05053
05054
05055
05056
05057
05058
if (fWinStaDefaulted) {
05059
if (
xxxUserFindHandleForObject(Process,
NULL, *
ExWindowStationObjectType,
05060
NULL, &hwinsta)) {
05061
05062
05063
05064
05065
05066
if (Process !=
PsGetCurrentProcess()) {
05067
05068
Status =
xxxUserDuplicateObject(
05069 hProcess,
05070 hwinsta,
05071 NtCurrentProcess(),
05072 &hwinstaDup,
05073 0,
05074 0,
05075 DUPLICATE_SAME_ACCESS);
05076
if (!
NT_SUCCESS(
Status)) {
05077 hwinsta =
NULL;
05078 }
else {
05079 hwinsta = hwinstaDup;
05080 }
05081 }
05082 }
05083 }
05084
05085
05086
05087
05088
05089
if (hwinsta !=
NULL) {
05090
Status =
ObReferenceObjectByHandle(hwinsta,
05091 0,
05092 *
ExWindowStationObjectType,
05093
KernelMode,
05094 &pwinsta,
05095
NULL);
05096
if (
NT_SUCCESS(
Status)) {
05097
BOOL fIO = (pwinsta->
dwWSF_Flags &
WSF_NOIO) ?
FALSE :
TRUE;
05098
if (fIO != fInteractive) {
05099
if (hwinstaDup) {
05100
CloseProtectedHandle(hwinsta);
05101 }
05102 hwinsta =
NULL;
05103 }
05104
ObDereferenceObject(pwinsta);
05105 }
05106 }
05107
05108
05109
05110
05111
if (
NT_SUCCESS(
Status) && hwinsta ==
NULL) {
05112
05113
05114
05115
05116 strStatic.Length = 0;
05117
RtlAppendUnicodeToString(&strStatic, (PWSTR)
szWindowStationDirectory);
05118
RtlAppendUnicodeToString(&strStatic,
L"\\");
05119
RtlAppendUnicodeStringToString(&strStatic, &strWinSta);
05120
05121
if (
gbSecureDesktop) {
05122
05123
05124
05125 cbObjA =
sizeof(*pObjA) +
sizeof(*pstrStatic);
05126
Status = ZwAllocateVirtualMemory(NtCurrentProcess(),
05127 &pObjA, 0, &cbObjA, MEM_COMMIT, PAGE_READWRITE);
05128 pstrStatic = (PUNICODE_STRING)((
PBYTE)pObjA +
sizeof(*pObjA));
05129
05130
if (
NT_SUCCESS(
Status)) {
05131
05132
05133
05134
05135
try {
05136 *pstrStatic = strStatic;
05137 InitializeObjectAttributes( pObjA,
05138 pstrStatic,
05139 OBJ_CASE_INSENSITIVE,
05140
NULL,
05141
NULL
05142 );
05143
if (fInherit)
05144 pObjA->Attributes |= OBJ_INHERIT;
05145 } except (W32ExceptionHandler(
FALSE, RIP_WARNING)) {
05146
Status = GetExceptionCode();
05147 }
05148
05149
if (
NT_SUCCESS(
Status)) {
05150 hwinsta =
_OpenWindowStation(pObjA, MAXIMUM_ALLOWED,
UserMode);
05151 }
05152 }
05153 }
else {
05154 InitializeObjectAttributes( &ObjA,
05155 &strStatic,
05156 OBJ_CASE_INSENSITIVE,
05157
NULL,
05158
NULL
05159 );
05160
if (fInherit)
05161 ObjA.Attributes |= OBJ_INHERIT;
05162 hwinsta =
_OpenWindowStation(&ObjA, MAXIMUM_ALLOWED,
KernelMode);
05163 }
05164 }
05165
05166
05167
05168
05169
05170
05171
05172
05173
05174
05175
05176
if (!
gbRemoteSession &&
NT_SUCCESS(
Status) &&
05177 hwinsta ==
NULL && !fInteractive && fWinStaDefaulted) {
05178
05179 *phwinsta =
xxxConnectService(
05180 &strStatic,
05181 &hdesk);
05182
05183
05184
05185
05186
if (pObjA !=
NULL) {
05187 ZwFreeVirtualMemory(NtCurrentProcess(), &pObjA, &cbObjA,
05188 MEM_RELEASE);
05189 }
05190
ObDereferenceObject(Process);
05191
05192 RIPMSG2(RIP_VERBOSE,
05193
"ResolveDesktop: xxxConnectService was called\n"
05194
"to hwinsta=%#p desktop=%#p",
05195 *phwinsta, hdesk);
05196
05197
return hdesk;
05198 }
05199 }
05200
05201
05202
05203
05204
if (hwinsta !=
NULL) {
05205
05206
05207
05208
05209
05210
if (hdesk ==
NULL) {
05211
05212
05213
05214
05215
05216
if (fDesktopDefaulted) {
05217
if (
xxxUserFindHandleForObject(Process,
NULL, *
ExDesktopObjectType,
05218
NULL, &hdesk)) {
05219
05220
05221
05222
05223
05224
if (Process !=
PsGetCurrentProcess()) {
05225 HDESK hdeskDup;
05226
05227
Status =
xxxUserDuplicateObject(
05228 hProcess,
05229 hdesk,
05230 NtCurrentProcess(),
05231 &hdeskDup,
05232 0,
05233 0,
05234 DUPLICATE_SAME_ACCESS);
05235
if (!
NT_SUCCESS(
Status)) {
05236
CloseProtectedHandle(hdesk);
05237 hdesk =
NULL;
05238 }
else {
05239 hdesk = hdeskDup;
05240 }
05241 }
05242
05243
05244
05245
05246
if (hdesk !=
NULL && ppi !=
NULL) {
05247
Status =
ObReferenceObjectByHandle(hdesk,
05248 0,
05249 *
ExDesktopObjectType,
05250
KernelMode,
05251 &pdesk,
05252
NULL);
05253
if (
NT_SUCCESS(
Status)) {
05254
05255
LogDesktop(pdesk, LD_REF_FN_RESOLVEDESKTOP,
TRUE, (ULONG_PTR)
PtiCurrent());
05256
05257
try {
05258
MapDesktop(
ObOpenHandle, Process, pdesk, 0, 1);
05259 } except (W32ExceptionHandler(
TRUE, RIP_WARNING)) {
05260
Status = STATUS_NO_MEMORY;
05261
CloseProtectedHandle(hdesk);
05262 hdesk =
NULL;
05263 }
05264
#if DBG
05265
if (hdesk !=
NULL) {
05266 UserAssert(
GetDesktopView(ppi, pdesk) !=
NULL);
05267 }
05268
#endif // DBG
05269
LogDesktop(pdesk, LD_DEREF_FN_RESOLVEDESKTOP,
FALSE, (ULONG_PTR)
PtiCurrent());
05270
ObDereferenceObject(pdesk);
05271 }
else {
05272
CloseProtectedHandle(hdesk);
05273 hdesk =
NULL;
05274 }
05275 }
05276 }
05277 }
05278
05279
05280
05281
05282
if (
NT_SUCCESS(
Status) && hdesk ==
NULL) {
05283
RtlCopyUnicodeString(&strStatic, &strDesktop);
05284
05285
if (
gbSecureDesktop) {
05286
if (pObjA ==
NULL) {
05287
05288
05289
05290 cbObjA =
sizeof(*pObjA) +
sizeof(*pstrStatic);
05291
Status = ZwAllocateVirtualMemory(NtCurrentProcess(),
05292 &pObjA, 0, &cbObjA, MEM_COMMIT, PAGE_READWRITE);
05293 pstrStatic = (PUNICODE_STRING)((
PBYTE)pObjA +
sizeof(*pObjA));
05294 }
05295
05296
if (
NT_SUCCESS(
Status)) {
05297
05298
05299
05300
05301
try {
05302 *pstrStatic = strStatic;
05303 InitializeObjectAttributes( pObjA,
05304 pstrStatic,
05305 OBJ_CASE_INSENSITIVE,
05306 hwinsta,
05307
NULL
05308 );
05309
if (fInherit)
05310 pObjA->Attributes |= OBJ_INHERIT;
05311 } except (W32ExceptionHandler(
FALSE, RIP_WARNING)) {
05312
Status = GetExceptionCode();
05313 }
05314
05315
if (
NT_SUCCESS(
Status)) {
05316 hdesk =
xxxOpenDesktop(pObjA,
05317
UserMode,
05318 0,
05319 MAXIMUM_ALLOWED,
05320 pbShutDown);
05321 }
05322 }
05323 }
else {
05324 InitializeObjectAttributes( &ObjA,
05325 &strStatic,
05326 OBJ_CASE_INSENSITIVE,
05327 hwinsta,
05328
NULL
05329 );
05330
if (fInherit)
05331 ObjA.Attributes |= OBJ_INHERIT;
05332 hdesk =
xxxOpenDesktop(&ObjA,
05333
KernelMode,
05334 0,
05335 MAXIMUM_ALLOWED,
05336 pbShutDown);
05337 }
05338 }
05339 }
05340
if (hdesk ==
NULL) {
05341 UserVerify(
NT_SUCCESS(ZwClose(hwinsta)));
05342 hwinsta =
NULL;
05343 }
05344 }
05345
05346
ObDereferenceObject(Process);
05347
05348
if (pObjA !=
NULL) {
05349 ZwFreeVirtualMemory(NtCurrentProcess(), &pObjA, &cbObjA,
05350 MEM_RELEASE);
05351 }
05352
05353 *phwinsta = hwinsta;
05354
05355 RIPMSG2(RIP_VERBOSE,
05356
"ResolveDesktop: to hwinsta=%#p desktop=%#p",
05357 *phwinsta, hdesk);
05358
05359
return hdesk;
05360 }