00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
#include "precomp.h"
00016
#pragma hdrstop
00017
00018
#include "ntuser.h"
00019
00020
#include <winsta.h>
00021
#include <wstmsg.h>
00022
00023 #define SESSION_ROOT L"\\Sessions"
00024 #define MAX_SESSION_PATH 256
00025
00026
extern NTSTATUS CsrPopulateDosDevices(
void);
00027
00028
NTSTATUS
00029
CleanupSessionObjectDirectories(
void);
00030
00031 HANDLE
CsrQueryApiPort(
void);
00032
extern BOOL CtxInitUser32(VOID);
00033
00034
extern DrChangeDisplaySettings(WINSTATIONDORECONNECTMSG*);
00035
00036 USHORT gHRes = 0;
00037 USHORT gVRes = 0;
00038 USHORT gColorDepth = 0;
00039
00040 HANDLE
ghportLPC =
NULL;
00041
00042 BOOLEAN
gbExitInProgress =
FALSE;
00043
00044
#if DBG
00045
ULONG gulConnectCount = 0;
00046
#endif // DBG
00047
00048
00049
00050
00051
00052
00053 HANDLE
G_IcaVideoChannel =
NULL;
00054 HANDLE
G_IcaMouseChannel =
NULL;
00055 HANDLE
G_IcaKeyboardChannel =
NULL;
00056 HANDLE
G_IcaBeepChannel =
NULL;
00057 HANDLE
G_IcaCommandChannel =
NULL;
00058 HANDLE
G_IcaThinwireChannel =
NULL;
00059 WCHAR
G_WinStationName[WINSTATIONNAME_LENGTH];
00060
00061
00062
00063
00064
00065 typedef NTSTATUS (*
PWIN32WINSTATION_API)(IN OUT PWINSTATION_APIMSG ApiMsg);
00066
00067 typedef struct _WIN32WINSTATION_DISPATCH {
00068 PWIN32WINSTATION_API pWin32ApiProc;
00069 }
WIN32WINSTATION_DISPATCH, *
PWIN32WINSTATION_DISPATCH;
00070
00071
NTSTATUS W32WinStationDoConnect( IN OUT PWINSTATION_APIMSG );
00072
00073
NTSTATUS W32WinStationDoDisconnect( IN OUT PWINSTATION_APIMSG );
00074
00075
NTSTATUS W32WinStationDoReconnect( IN OUT PWINSTATION_APIMSG );
00076
00077
NTSTATUS W32WinStationExitWindows( IN OUT PWINSTATION_APIMSG );
00078
00079
NTSTATUS W32WinStationTerminate( IN OUT PWINSTATION_APIMSG );
00080
00081
NTSTATUS W32WinStationNtSecurity( IN OUT PWINSTATION_APIMSG );
00082
00083
NTSTATUS W32WinStationDoMessage( IN OUT PWINSTATION_APIMSG );
00084
00085
NTSTATUS W32WinStationThinwireStats( IN OUT PWINSTATION_APIMSG );
00086
00087
NTSTATUS W32WinStationShadowSetup( IN OUT PWINSTATION_APIMSG );
00088
00089
NTSTATUS W32WinStationShadowStart( IN OUT PWINSTATION_APIMSG );
00090
00091
NTSTATUS W32WinStationShadowStop( IN OUT PWINSTATION_APIMSG );
00092
00093
NTSTATUS W32WinStationShadowCleanup( IN OUT PWINSTATION_APIMSG );
00094
00095
NTSTATUS W32WinStationPassthruEnable( IN OUT PWINSTATION_APIMSG );
00096
00097
NTSTATUS W32WinStationPassthruDisable( IN OUT PWINSTATION_APIMSG );
00098
00099
00100
NTSTATUS W32WinStationBroadcastSystemMessage( IN OUT PWINSTATION_APIMSG );
00101
00102
NTSTATUS W32WinStationSendWindowMessage( IN OUT PWINSTATION_APIMSG );
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120 #define API_W32WINSTATIONTERMINATE 12 // includes -- W32WinStationSendWindowMessage
00121
00122 WIN32WINSTATION_DISPATCH Win32WinStationDispatch[SMWinStationMaxApiNumber] = {
00123
NULL,
00124
NULL,
00125
NULL,
00126
NULL,
00127
NULL,
00128
NULL,
00129
NULL,
00130
NULL,
00131
W32WinStationDoConnect,
00132
W32WinStationDoDisconnect,
00133
W32WinStationDoReconnect,
00134
W32WinStationExitWindows,
00135
W32WinStationTerminate,
00136
W32WinStationNtSecurity,
00137
W32WinStationDoMessage,
00138
NULL,
00139
W32WinStationThinwireStats,
00140
W32WinStationShadowSetup,
00141
W32WinStationShadowStart,
00142
W32WinStationShadowStop,
00143
W32WinStationShadowCleanup,
00144
W32WinStationPassthruEnable,
00145
W32WinStationPassthruDisable,
00146
NULL,
00147
NULL,
00148
W32WinStationBroadcastSystemMessage,
00149
W32WinStationSendWindowMessage,
00150 };
00151
00152
#if DBG
00153
PSZ Win32WinStationAPIName[SMWinStationMaxApiNumber] = {
00154
"SmWinStationCreate",
00155
"SmWinStationReset",
00156
"SmWinStationDisconnect",
00157
"SmWinStationWCharLog",
00158
"SmWinStationGetSMCommand",
00159
"SmWinStationBrokenConnection",
00160
"SmWinStationIcaReplyMessage",
00161
"SmWinStationIcaShadowHotkey",
00162
"SmWinStationDoConnect",
00163
"SmWinStationDoDisconnect",
00164
"SmWinStationDoReconnect",
00165
"SmWinStationExitWindows",
00166
"SmWinStationTerminate",
00167
"SmWinStationNtSecurity",
00168
"SmWinStationDoMessage",
00169
"SmWinstationDoBreakPoint",
00170
"SmWinStationThinwireStats",
00171
"SmWinStationShadowSetup",
00172
"SmWinStationShadowStart",
00173
"SmWinStationShadowStop",
00174
"SmWinStationShadowCleanup",
00175
"SmWinStationPassthruEnable",
00176
"SmWinStationPassthruDisable",
00177
"SMWinStationInitialProgram",
00178
"SMWinStationNtsdDebug",
00179
"W32WinStationBroadcastSystemMessage",
00180
"W32WinStationSendWindowMessage",
00181 };
00182
#endif
00183
00184
NTSTATUS TerminalServerRequestThread( PVOID );
00185
00186
extern NTSTATUS Win32CommandChannelThread( PVOID );
00187
extern NTSTATUS RemoteDoMessage( PWINSTATION_APIMSG pMsg );
00188
extern NTSTATUS MultiUserSpoolerInit();
00189
00190
00191 extern HANDLE
g_hDoMessageEvent;
00192
00193
extern NTSTATUS RemoteDoBroadcastSystemMessage( PWINSTATION_APIMSG pMsg );
00194
extern NTSTATUS RemoteDoSendWindowMessage( PWINSTATION_APIMSG pMsg);
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
NTSTATUS
00212 WinStationAPIInit(
00213 VOID)
00214 {
00215
NTSTATUS Status;
00216 CLIENT_ID ClientId;
00217 HANDLE
ThreadHandle;
00218 KPRIORITY Priority;
00219
00220
#if DBG
00221
static BOOL Inited =
FALSE;
00222
#endif
00223
00224 UserAssert(Inited ==
FALSE);
00225
00226
gSessionId = NtCurrentPeb()->SessionId;
00227
00228
#if DBG
00229
if (Inited)
00230
DBGHYD((
"WinStationAPIInit called twice !!!\n"));
00231
00232 Inited =
TRUE;
00233
#endif
00234
00235
Status =
RtlCreateUserThread(NtCurrentProcess(),
00236
NULL,
00237
TRUE,
00238 0
L,
00239 0
L,
00240 0
L,
00241
TerminalServerRequestThread,
00242
NULL,
00243 &
ThreadHandle,
00244 &ClientId);
00245
00246
if (!
NT_SUCCESS(
Status)) {
00247
DBGHYD((
"WinStationAPIInit: failed to create TerminalServerRequestThread\n"));
00248
goto Exit;
00249 }
00250
00251
00252
00253 CsrAddStaticServerThread(
ThreadHandle, &ClientId, 0);
00254
00255
00256
00257
00258 Priority = THREAD_BASE_PRIORITY_MAX;
00259
00260
Status =
NtSetInformationThread(
ThreadHandle, ThreadBasePriority,
00261 &Priority,
sizeof(Priority));
00262
00263
if (!
NT_SUCCESS(
Status)) {
00264
DBGHYD((
"WinStationAPIInit: failed to set thread priority\n"));
00265
goto Exit;
00266 }
00267
00268
00269
00270
00271
NtResumeThread(
ThreadHandle,
NULL);
00272
00273
00274 Exit:
00275
return Status;
00276 }
00277
00278
NTSTATUS
00279 TerminalServerRequestThread(
00280 IN PVOID ThreadParameter)
00281 {
00282 PTEB Teb;
00283 UNICODE_STRING
PortName;
00284 SECURITY_QUALITY_OF_SERVICE
DynamicQos;
00285 WINSTATIONAPI_CONNECT_INFO info;
00286 ULONG ConnectInfoLength;
00287 WINSTATION_APIMSG ApiMsg;
00288
PWIN32WINSTATION_DISPATCH pDispatch;
00289
NTSTATUS Status;
00290 REMOTE_PORT_VIEW ServerView;
00291 HANDLE CsrStartHandle, hevtTermSrvInit;
00292
00293
00294
00295
00296 Teb = NtCurrentTeb();
00297 Teb->GdiClientPID = 4;
00298 Teb->GdiClientTID = HandleToUlong(Teb->ClientId.UniqueThread);
00299
00300
00301
00302
00303
00304 hevtTermSrvInit = CreateEvent(
NULL,
TRUE,
FALSE,
00305
L"Global\\TermSrvReadyEvent");
00306
00307 UserAssert(hevtTermSrvInit !=
NULL);
00308
#if DBG
00309
if (hevtTermSrvInit ==
NULL) {
00310
DBGHYD((
"ERROR: could not create TermSrvReadyEvent !!!\n"));
00311 }
00312
#endif
00313
00314
Status =
NtWaitForSingleObject(hevtTermSrvInit,
FALSE,
NULL);
00315
00316
NtClose(hevtTermSrvInit);
00317
00318
00319
00320
00321
DynamicQos.ImpersonationLevel = SecurityImpersonation;
00322
DynamicQos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING;
00323
DynamicQos.EffectiveOnly =
TRUE;
00324
00325
RtlInitUnicodeString(&
PortName,
L"\\SmSsWinStationApiPort");
00326
00327
00328
00329
00330 ServerView.Length =
sizeof(ServerView);
00331 ServerView.ViewSize = 0;
00332 ServerView.ViewBase = 0;
00333
00334
00335
00336
00337 info.Version = CITRIX_WINSTATIONAPI_VERSION;
00338 info.RequestedAccess = 0;
00339 ConnectInfoLength =
sizeof(WINSTATIONAPI_CONNECT_INFO);
00340
00341
Status =
NtConnectPort( &
ghportLPC,
00342 &
PortName,
00343 &
DynamicQos,
00344
NULL,
00345 &ServerView,
00346
NULL,
00347 (PVOID)&info,
00348 &ConnectInfoLength);
00349
00350
if (!
NT_SUCCESS(
Status)) {
00351 RIPMSG0(RIP_WARNING,
"TerminalServerRequestThread: Failed to connect to LPC port");
00352
return Status;
00353 }
00354
00355 RtlZeroMemory(&ApiMsg,
sizeof(ApiMsg));
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
if (NtCurrentPeb()->SessionId != 0) {
00368
00369 CsrStartHandle = CreateEvent(
NULL,
TRUE,
FALSE,
L"CsrStartEvent");
00370
00371
if (!CsrStartHandle) {
00372
00373 RIPMSG1(RIP_WARNING,
"TerminalServerRequestThread: Failed to create 'CsrStartEvent' with Status 0x%x",
00374
Status);
00375
00376
return Status;
00377
00378 }
else {
00379
00380
Status =
NtWaitForSingleObject(CsrStartHandle,
FALSE,
NULL);
00381
00382
NtClose(CsrStartHandle);
00383
if (!
NT_SUCCESS(
Status)) {
00384
DBGHYD((
"TerminalServerRequestThread: Wait for object 'CsrStartEvent' failed Status=0x%x\n",
00385
Status));
00386 }
00387 }
00388 }
00389
00390
for (;;) {
00391
00392
00393
00394
00395 ApiMsg.h.u1.s1.DataLength =
sizeof(ApiMsg) -
sizeof(PORT_MESSAGE);
00396 ApiMsg.h.u1.s1.TotalLength =
sizeof(ApiMsg);
00397 ApiMsg.h.u2.s2.Type = 0;
00398 ApiMsg.h.u2.s2.DataInfoOffset = 0;
00399 ApiMsg.ApiNumber = SMWinStationGetSMCommand;
00400
00401
Status =
NtRequestWaitReplyPort(
ghportLPC,
00402 (PPORT_MESSAGE)&ApiMsg,
00403 (PPORT_MESSAGE)&ApiMsg);
00404
00405
if (!
NT_SUCCESS(
Status)) {
00406
DBGHYD((
"TerminalServerRequestThread wait failed with Status %lx\n",
00407
Status));
00408
break;
00409 }
00410
00411
if (ApiMsg.ApiNumber >= SMWinStationMaxApiNumber ) {
00412
00413
DBGHYD((
"TerminalServerRequestThread Bad API number %d\n",
00414 ApiMsg.ApiNumber));
00415
00416 ApiMsg.ReturnedStatus = STATUS_NOT_IMPLEMENTED;
00417
00418 }
else {
00419
00420
00421
00422
00423 pDispatch = &
Win32WinStationDispatch[ApiMsg.ApiNumber];
00424
00425
if (pDispatch->
pWin32ApiProc) {
00426
00427
BOOL bRestoreDesktop =
FALSE;
00428
NTSTATUS Status;
00429 USERTHREAD_USEDESKTOPINFO utudi;
00430
00431
00432
00433
00434
00435
if (ApiMsg.ApiNumber !=
API_W32WINSTATIONTERMINATE) {
00436 utudi.hThread =
NULL;
00437 utudi.drdRestore.pdeskRestore =
NULL;
00438
Status =
NtUserSetInformationThread(NtCurrentThread(),
00439 UserThreadUseActiveDesktop,
00440 &utudi,
sizeof(utudi));
00441
00442
if (
NT_SUCCESS(
Status)) {
00443 bRestoreDesktop =
TRUE;
00444 }
00445 }
00446
00447
00448
00449
00450 ApiMsg.ReturnedStatus = (pDispatch->
pWin32ApiProc)(&ApiMsg);
00451
00452
if (bRestoreDesktop) {
00453
NtUserSetInformationThread(NtCurrentThread(),
00454 UserThreadUseDesktop,
00455 &utudi,
00456
sizeof(utudi));
00457 }
00458
00459 }
else {
00460
00461 ApiMsg.ReturnedStatus = STATUS_NOT_IMPLEMENTED;
00462 }
00463 }
00464 }
00465
00466 ExitThread(0);
00467
00468
return STATUS_UNSUCCESSFUL;
00469
00470 UNREFERENCED_PARAMETER(ThreadParameter);
00471 }
00472
00473
#if DBG
00474
VOID
00475
W32WinStationDumpReconnectInfo(
00476 WINSTATIONDORECONNECTMSG *pDoReconnect,
00477 BOOLEAN bReconnect)
00478 {
00479 PSTR pCallerName;
00480
00481
if (bReconnect) {
00482 pCallerName =
"W32WinStationDoReconnect";
00483 }
else {
00484 pCallerName =
"W32WinStationDoConnect";
00485 }
00486
00487
DbgPrint(pCallerName);
00488
DbgPrint(
" - Display resolution information for session %d :\n", gSessionId);
00489
00490
DbgPrint(
"\tProtocolType : %04d\n", pDoReconnect->ProtocolType);
00491
DbgPrint(
"\tHRes : %04d\n", pDoReconnect->HRes);
00492
DbgPrint(
"\tVRes : %04d\n", pDoReconnect->VRes);
00493
DbgPrint(
"\tColorDepth : %04d\n", pDoReconnect->ColorDepth);
00494
00495
DbgPrint(
"\tKeyboardType : %d\n", pDoReconnect->KeyboardType);
00496
DbgPrint(
"\tKeyboardSubType : %d\n", pDoReconnect->KeyboardSubType);
00497
DbgPrint(
"\tKeyboardFunctionKey : %d\n", pDoReconnect->KeyboardFunctionKey);
00498 }
00499
#else
00500 #define W32WinStationDumpReconnectInfo(p, b)
00501
#endif // DBG
00502
00503
NTSTATUS
00504 W32WinStationDoConnect(
00505 PWINSTATION_APIMSG pMsg)
00506 {
00507
NTSTATUS Status = STATUS_SUCCESS;
00508 WINSTATIONDOCONNECTMSG* m = &pMsg->u.DoConnect;
00509 WCHAR DisplayDriverName[10];
00510 CLIENT_ID ClientId;
00511 HANDLE
ThreadHandle;
00512 KPRIORITY Priority;
00513
DOCONNECTDATA DoConnectData;
00514 WINSTATIONDORECONNECTMSG mDoReconnect;
00515
00516 UserAssert(gulConnectCount == 0);
00517
00518
00519
00520
00521
00522
Status =
CsrPopulateDosDevices();
00523
if( !
NT_SUCCESS(
Status) ) {
00524
DBGHYD((
"CsrPopulateDosDevices failed with Status %lx\n",
Status));
00525
goto Exit;
00526 }
00527
00528
00529
G_IcaVideoChannel = m->hIcaVideoChannel;
00530
G_IcaMouseChannel = m->hIcaMouseChannel;
00531
G_IcaKeyboardChannel = m->hIcaKeyboardChannel;
00532
G_IcaBeepChannel = m->hIcaBeepChannel;
00533
G_IcaCommandChannel = m->hIcaCommandChannel;
00534
G_IcaThinwireChannel = m->hIcaThinwireChannel;
00535
00536 memset(
G_WinStationName, 0,
sizeof(
G_WinStationName));
00537 memcpy(
G_WinStationName, m->WinStationName,
00538
min(
sizeof(
G_WinStationName),
sizeof(m->WinStationName)));
00539
00540
00541
00542
00543 memset(DisplayDriverName, 0,
sizeof(DisplayDriverName));
00544 memcpy(DisplayDriverName, m->DisplayDriverName,
sizeof(DisplayDriverName) - 2);
00545
00546
00547
00548
00549 memset(&DoConnectData, 0,
sizeof(DoConnectData));
00550
00551 DoConnectData.fMouse = m->fMouse;
00552 DoConnectData.IcaBeepChannel =
G_IcaBeepChannel;
00553 DoConnectData.IcaVideoChannel =
G_IcaVideoChannel;
00554 DoConnectData.IcaMouseChannel =
G_IcaMouseChannel;
00555 DoConnectData.fEnableWindowsKey = m->fEnableWindowsKey;;
00556
00557 DoConnectData.IcaKeyboardChannel =
G_IcaKeyboardChannel;
00558 DoConnectData.IcaThinwireChannel =
G_IcaThinwireChannel;
00559 DoConnectData.fClientDoubleClickSupport = m->fClientDoubleClickSupport;
00560
00561
00562
00563
00564 DoConnectData.ClientKeyboardType.Type = m->KeyboardType;
00565 DoConnectData.ClientKeyboardType.SubType = m->KeyboardSubType;
00566 DoConnectData.ClientKeyboardType.FunctionKey = m->KeyboardFunctionKey;
00567
00568 memcpy(DoConnectData.WinStationName,
G_WinStationName,
00569
min(
sizeof(
G_WinStationName),
sizeof(DoConnectData.WinStationName)));
00570
00571 DoConnectData.drProtocolType = m->ProtocolType;
00572 DoConnectData.drPelsHeight = m->VRes;
00573 DoConnectData.drPelsWidth = m->HRes;
00574 DoConnectData.drBitsPerPel = m->ColorDepth;
00575
00576
00577
00578
00579
00580
00581 mDoReconnect.ProtocolType = m->ProtocolType;
00582 mDoReconnect.HRes = m->HRes;
00583 mDoReconnect.VRes = m->VRes;
00584 mDoReconnect.ColorDepth = m->ColorDepth;
00585
00586
W32WinStationDumpReconnectInfo(&mDoReconnect,
FALSE);
00587
00588
00589 memset(DoConnectData.ProtocolName, 0,
sizeof(DoConnectData.ProtocolName));
00590 memcpy(DoConnectData.ProtocolName, m->ProtocolName,
sizeof(DoConnectData.ProtocolName) - 2);
00591
00592
00593 memset(DoConnectData.AudioDriverName, 0,
sizeof(DoConnectData.AudioDriverName));
00594 memcpy(DoConnectData.AudioDriverName, m->AudioDriverName,
sizeof(DoConnectData.AudioDriverName) - 2);
00595
00596
Status =
NtUserRemoteConnect(&DoConnectData,
00597
sizeof(DisplayDriverName),
00598 DisplayDriverName);
00599
00600
if (!
NT_SUCCESS(
Status)) {
00601
DBGHYD((
"NtUserRemoteConnect failed with Status %lx\n",
Status));
00602
goto Exit;
00603 }
00604
00605
Status =
RtlCreateUserThread( NtCurrentProcess(),
00606
NULL,
00607
TRUE,
00608 0
L,
00609 0
L,
00610 0
L,
00611
Win32CommandChannelThread,
00612
NULL,
00613 &
ThreadHandle,
00614 &ClientId );
00615
00616 UserAssert(
NT_SUCCESS(
Status));
00617
00618
if (!
NT_SUCCESS(
Status)) {
00619
DBGHYD((
"RtlCreateUserThread failed with Status %lx\n",
Status));
00620
goto Exit;
00621 }
00622
00623
00624
00625
00626
if (CsrAddStaticServerThread(
ThreadHandle, &ClientId, 0) ==
NULL) {
00627
DBGHYD((
"CsrAddStaticServerThread failed\n"));
00628
goto Exit;
00629 }
00630
00631
00632
00633
00634 Priority = THREAD_BASE_PRIORITY_MAX;
00635
00636
Status =
NtSetInformationThread(
ThreadHandle, ThreadBasePriority,
00637 &Priority,
sizeof(Priority));
00638
00639 UserAssert(
NT_SUCCESS(
Status));
00640
00641
if (!
NT_SUCCESS(
Status)) {
00642
DBGHYD((
"NtSetInformationThread failed with Status %lx\n",
Status));
00643
Status = STATUS_NO_MEMORY;
00644
goto Exit;
00645 }
00646
00647
00648
00649
00650
NtResumeThread(
ThreadHandle,
NULL);
00651
00652
if (CsrConnectToUser() ==
NULL) {
00653
DBGHYD((
"CsrConnectToUser failed\n"));
00654
Status = STATUS_NO_MEMORY;
00655
goto Exit;
00656 }
00657
00658
if (!
CtxInitUser32()) {
00659
DBGHYD((
"CtxInitUser32 failed\n"));
00660
Status = STATUS_NO_MEMORY;
00661
goto Exit;
00662 }
00663
00664
00665
00666
00667
if (
gSessionId != 0) {
00668
Status =
MultiUserSpoolerInit();
00669 }
00670
00671
00672
00673
00674
gHRes = mDoReconnect.HRes;
00675
gVRes = mDoReconnect.VRes;
00676
gColorDepth = mDoReconnect.ColorDepth;
00677
00678
00679 Exit:
00680
00681
#if DBG
00682
if (
NT_SUCCESS(
Status)) {
00683 gulConnectCount++;
00684 }
00685
#endif // DBG
00686
00687
return Status;
00688 }
00689
00690
00691
NTSTATUS
00692 W32WinStationDoDisconnect(
00693 PWINSTATION_APIMSG pMsg)
00694 {
00695
NTSTATUS Status = STATUS_SUCCESS;
00696
00697 memset(
G_WinStationName, 0,
sizeof(
G_WinStationName));
00698
00699
Status = (
NTSTATUS)
NtUserCallNoParam(SFI_XXXREMOTEDISCONNECT);
00700
00701
if (!
NT_SUCCESS(
Status)) {
00702
DBGHYD((
"xxxRemoteDisconnect failed with Status %lx\n",
Status));
00703 }
00704
00705
#if DBG
00706
else {
00707 gulConnectCount--;
00708 }
00709
#endif // DBG
00710
00711
return Status;
00712
00713 UNREFERENCED_PARAMETER(pMsg);
00714 }
00715
00716
00717
NTSTATUS
00718 W32WinStationDoReconnect(
00719 PWINSTATION_APIMSG pMsg)
00720 {
00721
NTSTATUS Status = STATUS_SUCCESS;
00722
DORECONNECTDATA DoReconnectData;
00723 WINSTATIONDORECONNECTMSG* m = &pMsg->u.DoReconnect;
00724
00725 UserAssert(gulConnectCount == 0);
00726
00727
00728 memset(&DoReconnectData, 0,
sizeof(DoReconnectData));
00729
00730 DoReconnectData.fMouse = m->fMouse;
00731 DoReconnectData.fEnableWindowsKey = m->fEnableWindowsKey;
00732 DoReconnectData.fClientDoubleClickSupport = m->fClientDoubleClickSupport;
00733
00734 memcpy(
G_WinStationName, m->WinStationName,
00735
min(
sizeof(
G_WinStationName),
sizeof(m->WinStationName)));
00736
00737 memcpy(DoReconnectData.WinStationName,
G_WinStationName,
00738
min(
sizeof(
G_WinStationName),
sizeof(DoReconnectData.WinStationName)));
00739
00740 DoReconnectData.drProtocolType = m->ProtocolType;
00741 DoReconnectData.drPelsHeight = m->VRes;
00742 DoReconnectData.drPelsWidth = m->HRes;
00743 DoReconnectData.drBitsPerPel = m->ColorDepth;
00744
if ((m->fDynamicReconnect) && (
gHRes != m->HRes ||
gVRes != m->VRes ||
gColorDepth != m->ColorDepth ) ) {
00745 DoReconnectData.fChangeDisplaySettings =
TRUE;
00746 }
else{
00747 DoReconnectData.fChangeDisplaySettings =
FALSE;
00748 }
00749
00750 DoReconnectData.drDisplayFrequency = 0;
00751
00752
00753
00754
00755 DoReconnectData.ClientKeyboardType.Type = m->KeyboardType;
00756 DoReconnectData.ClientKeyboardType.SubType = m->KeyboardSubType;
00757 DoReconnectData.ClientKeyboardType.FunctionKey = m->KeyboardFunctionKey;
00758
00759
W32WinStationDumpReconnectInfo( m,
TRUE);
00760
00761
00762
00763
00764
00765
Status = (
NTSTATUS)
NtUserCallOneParam((ULONG_PTR)&DoReconnectData,
00766 SFI_XXXREMOTERECONNECT);
00767
00768
if (!
NT_SUCCESS(
Status)) {
00769
DBGHYD((
"xxxRemoteReconnect failed with Status %lx\n",
Status));
00770 }
else{
00771
00772
00773
00774
00775
gHRes = m->HRes;
00776
gVRes = m->VRes;
00777
gColorDepth = m->ColorDepth;
00778
00779
#if DBG
00780
gulConnectCount++;
00781
#endif // DBG
00782
}
00783
00784
00785
return Status;
00786 }
00787
00788
00789
NTSTATUS
00790 W32WinStationExitWindows(
00791 PWINSTATION_APIMSG pMsg)
00792 {
00793
NTSTATUS Status = STATUS_SUCCESS;
00794 WINSTATIONEXITWINDOWSMSG* m = &pMsg->u.ExitWindows;
00795
00796
if (
gSessionId == 0) {
00797
00798
DBGHYD((
"W32WinStationExitWindows meaningless for main session\n"));
00799
return STATUS_INVALID_PARAMETER;
00800 }
00801
00802 UserAssert(gulConnectCount <= 1);
00803
00804
00805
00806
00807
Status = (
NTSTATUS)
NtUserCallNoParam(SFI_REMOTELOGOFF);
00808
00809
if (!
NT_SUCCESS(
Status)) {
00810
DBGHYD((
"RemoteLogoff failed with Status %lx\n",
Status));
00811 }
00812
00813
return Status;
00814 }
00815
00816
00817
NTSTATUS
00818 W32WinStationTerminate(
00819 PWINSTATION_APIMSG pMsg)
00820 {
00821
NTSTATUS Status = STATUS_SUCCESS;
00822 HANDLE hevtShutDown;
00823 HANDLE hevtRitExited, hevtRitStuck;
00824
00825
extern HANDLE
WinStationIcaApiPort;
00826
00827
gbExitInProgress =
TRUE;
00828
00829
00830
00831
00832
00833
00834
if (
gdwHardErrorThreadId != 0) {
00835
00836
BoostHardError(-1,
BHE_FORCE);
00837
00838
00839
00840
00841
00842
while (
gdwHardErrorThreadId != 0) {
00843
DBGHYD((
"Waiting for hard error thread to stop...\n"));
00844
00845 Sleep(3 * 1000);
00846 }
00847
00848
DBGHYD((
"Stopped hard error thread\n"));
00849 }
00850
00851
if (
g_hDoMessageEvent)
00852
NtSetEvent(
g_hDoMessageEvent,
NULL);
00853
00854
if (
G_IcaMouseChannel) {
00855 CloseHandle(
G_IcaMouseChannel);
00856
G_IcaMouseChannel =
NULL;
00857 }
00858
00859
if (
G_IcaKeyboardChannel) {
00860 CloseHandle(
G_IcaKeyboardChannel);
00861
G_IcaKeyboardChannel =
NULL;
00862 }
00863
00864
if (
G_IcaCommandChannel) {
00865 CloseHandle(
G_IcaCommandChannel);
00866
G_IcaCommandChannel =
NULL;
00867 }
00868
00869
if (
G_IcaVideoChannel) {
00870 CloseHandle(
G_IcaVideoChannel);
00871
G_IcaVideoChannel =
NULL;
00872 }
00873
if (
G_IcaBeepChannel) {
00874 CloseHandle(
G_IcaBeepChannel);
00875
G_IcaBeepChannel =
NULL;
00876 }
00877
if (
G_IcaThinwireChannel) {
00878 CloseHandle(
G_IcaThinwireChannel);
00879
G_IcaThinwireChannel =
NULL;
00880 }
00881
00882 hevtShutDown = OpenEvent(EVENT_ALL_ACCESS,
00883
FALSE,
00884
L"EventShutDownCSRSS");
00885
00886
if (hevtShutDown ==
NULL) {
00887
00888
00889
00890
00891
DBGHYD((
"W32WinStationTerminate terminating CSRSS ...\n"));
00892
00893
Status =
CleanupSessionObjectDirectories();
00894
00895
if (
ghportLPC) {
00896
NtClose(
ghportLPC);
00897
ghportLPC =
NULL;
00898 }
00899
00900
return 0;
00901 }
00902
00903 hevtRitExited = CreateEvent(
NULL,
00904
FALSE,
00905
FALSE,
00906
L"EventRitExited");
00907
00908 UserAssert(hevtRitExited !=
NULL);
00909
00910 hevtRitStuck = CreateEvent(
NULL,
00911
FALSE,
00912
FALSE,
00913
L"EventRitStuck");
00914
00915 UserAssert(hevtRitStuck !=
NULL);
00916
00917
00918
00919
00920
00921 SetEvent(hevtShutDown);
00922
00923
DBGHYD((
"EventShutDownCSRSS set in CSRSS ...\n"));
00924
00925
00926
while (1) {
00927
00928 HANDLE arHandles[2] = {hevtRitExited, hevtRitStuck};
00929
DWORD result;
00930
00931 result = WaitForMultipleObjects(2, arHandles,
FALSE, INFINITE);
00932
00933
switch (result) {
00934
case WAIT_OBJECT_0:
00935
goto RITExited;
00936
00937
case WAIT_OBJECT_0 + 1:
00938
00939
00940
00941
00942
00943
00944 UserAssert(
ghportLPC !=
NULL);
00945
00946
if (
ghportLPC) {
00947
NtClose(
ghportLPC);
00948
ghportLPC =
NULL;
00949 }
00950
break;
00951
default:
00952 UserAssert(0);
00953
break;
00954 }
00955 }
00956
00957 RITExited:
00958
00959
DBGHYD((
"EventRitExited set in CSRSS ...\n"));
00960
00961 CloseHandle(hevtRitExited);
00962 CloseHandle(hevtRitStuck);
00963
00964 CloseHandle(hevtShutDown);
00965
00966
Status =
CleanupSessionObjectDirectories();
00967
00968
if (
ghportLPC) {
00969
NtClose(
ghportLPC);
00970
ghportLPC =
NULL;
00971 }
00972
00973
return Status;
00974 UNREFERENCED_PARAMETER(pMsg);
00975 }
00976
00977
00978
NTSTATUS
00979 W32WinStationNtSecurity(
00980 PWINSTATION_APIMSG pMsg)
00981 {
00982
NTSTATUS Status = STATUS_SUCCESS;
00983
00984
Status = (
NTSTATUS)
NtUserCallNoParam(SFI_REMOTENTSECURITY);
00985
00986
if (!
NT_SUCCESS(
Status)) {
00987
DBGHYD((
"RemoteNtSecurity failed with Status %lx\n",
Status));
00988 }
00989
00990
return Status;
00991 UNREFERENCED_PARAMETER(pMsg);
00992 }
00993
00994
00995
NTSTATUS
00996 W32WinStationDoMessage(
00997 PWINSTATION_APIMSG pMsg)
00998 {
00999
NTSTATUS Status = STATUS_SUCCESS;
01000
01001
Status =
RemoteDoMessage(pMsg);
01002
01003
if (!
NT_SUCCESS(
Status)) {
01004
DBGHYD((
"RemoteDoMessage failed with Status %lx\n",
Status));
01005 }
01006
01007
return Status;
01008 }
01009
01010
01011
NTSTATUS
01012 W32WinStationBroadcastSystemMessage(
01013 PWINSTATION_APIMSG pMsg )
01014 {
01015
01016
NTSTATUS Status = STATUS_SUCCESS;
01017
01018
Status =
RemoteDoBroadcastSystemMessage(pMsg);
01019
01020
if (!
NT_SUCCESS(
Status)) {
01021
DBGHYD((
"RemoteDoBroadcastSystemMessage(): failed with status 0x%lx\n",
Status));
01022 }
01023
01024
return Status;
01025 }
01026
01027
NTSTATUS
01028 W32WinStationSendWindowMessage(
01029 PWINSTATION_APIMSG pMsg)
01030 {
01031
01032
NTSTATUS Status = STATUS_SUCCESS;
01033
01034
Status =
RemoteDoSendWindowMessage(pMsg);
01035
01036
if (!
NT_SUCCESS(
Status)) {
01037
DBGHYD((
"RemoteDoSendWindowMessage failed with Status 0x%lx\n",
Status));
01038 }
01039
01040
return Status;
01041 }
01042
01043
01044
NTSTATUS
01045 W32WinStationThinwireStats(
01046 PWINSTATION_APIMSG pMsg)
01047 {
01048
NTSTATUS Status = STATUS_SUCCESS;
01049 WINSTATIONTHINWIRESTATSMSG* m = &pMsg->u.ThinwireStats;
01050
01051
Status = (
NTSTATUS)
NtUserCallOneParam((ULONG_PTR)&m->Stats,
01052 SFI_REMOTETHINWIRESTATS);
01053
01054
if (!
NT_SUCCESS(
Status)) {
01055
DBGHYD((
"RemoteThinwireStats failed with Status %lx\n",
Status));
01056 }
01057
01058
return Status;
01059 }
01060
01061
01062
NTSTATUS
01063 W32WinStationShadowSetup(
01064 PWINSTATION_APIMSG pMsg)
01065 {
01066
NTSTATUS Status = STATUS_SUCCESS;
01067 WINSTATIONSHADOWSETUPMSG* m = &pMsg->u.ShadowSetup;
01068
01069
Status = (
NTSTATUS)
NtUserCallNoParam(SFI_XXXREMOTESHADOWSETUP);
01070
01071
if (!
NT_SUCCESS(
Status)) {
01072
DBGHYD((
"xxxRemoteShadowSetup failed with Status %lx\n",
Status));
01073 }
01074
01075
return Status;
01076 }
01077
01078
01079
NTSTATUS
01080 W32WinStationShadowStart(
01081 PWINSTATION_APIMSG pMsg)
01082 {
01083
NTSTATUS Status = STATUS_SUCCESS;
01084 WINSTATIONSHADOWSTARTMSG* m = &pMsg->u.ShadowStart;
01085
01086
Status = (
NTSTATUS)
NtUserCallTwoParam((ULONG_PTR)m->pThinwireData,
01087 (ULONG_PTR)m->ThinwireDataLength,
01088 SFI_REMOTESHADOWSTART);
01089
01090
if (!
NT_SUCCESS(
Status)) {
01091
DBGHYD((
"RemoteShadowStart failed with Status %lx\n",
Status));
01092 }
01093
01094
return Status;
01095 }
01096
01097
01098
NTSTATUS
01099 W32WinStationShadowStop(
01100 PWINSTATION_APIMSG pMsg)
01101 {
01102
NTSTATUS Status = STATUS_SUCCESS;
01103 WINSTATIONSHADOWSTOPMSG* m = &pMsg->u.ShadowStop;
01104
01105
Status = (
NTSTATUS)
NtUserCallNoParam(SFI_XXXREMOTESHADOWSTOP);
01106
01107
if (!
NT_SUCCESS(
Status)) {
01108
DBGHYD((
"xxxRemoteShadowStop failed with Status %lx\n",
Status));
01109 }
01110
01111
return Status;
01112 }
01113
01114
01115
NTSTATUS
01116 W32WinStationShadowCleanup(
01117 PWINSTATION_APIMSG pMsg)
01118 {
01119
NTSTATUS Status = STATUS_SUCCESS;
01120 WINSTATIONSHADOWCLEANUPMSG* m = &pMsg->u.ShadowCleanup;
01121
01122
Status = (
NTSTATUS)
NtUserCallTwoParam((ULONG_PTR)m->pThinwireData,
01123 (ULONG_PTR)m->ThinwireDataLength,
01124 SFI_REMOTESHADOWCLEANUP);
01125
01126
if (!
NT_SUCCESS(
Status)) {
01127
DBGHYD((
"RemoteShadowCleanup failed with Status %lx\n",
Status));
01128 }
01129
01130
return Status;
01131 }
01132
01133
01134
NTSTATUS
01135 W32WinStationPassthruEnable(
01136 PWINSTATION_APIMSG pMsg)
01137 {
01138
NTSTATUS Status = STATUS_SUCCESS;
01139
01140
Status = (
NTSTATUS)
NtUserCallNoParam(SFI_XXXREMOTEPASSTHRUENABLE);
01141
01142
if (!
NT_SUCCESS(
Status)) {
01143
DBGHYD((
"xxxRemotePassthruEnable failed with Status %lx\n",
Status));
01144 }
01145
01146
return Status;
01147 UNREFERENCED_PARAMETER(pMsg);
01148 }
01149
01150
01151
NTSTATUS
01152 W32WinStationPassthruDisable(
01153 PWINSTATION_APIMSG pMsg)
01154 {
01155
NTSTATUS Status = STATUS_SUCCESS;
01156
01157
Status = (
NTSTATUS)
NtUserCallNoParam(SFI_REMOTEPASSTHRUDISABLE);
01158
01159
if (!
NT_SUCCESS(
Status)) {
01160
DBGHYD((
"RemotePassthruDisable failed with Status %lx\n",
Status));
01161 }
01162
01163
return Status;
01164 UNREFERENCED_PARAMETER(pMsg);
01165 }
01166
01167
01168
NTSTATUS
01169 CleanupSessionObjectDirectories(
01170 VOID)
01171 {
01172
NTSTATUS Status;
01173 OBJECT_ATTRIBUTES Attributes;
01174 UNICODE_STRING UnicodeString;
01175 HANDLE LinkHandle;
01176 POBJECT_DIRECTORY_INFORMATION DirInfo;
01177 BOOLEAN RestartScan;
01178 UCHAR DirInfoBuffer[ 4096 ];
01179 WCHAR szSessionString [
MAX_SESSION_PATH ];
01180 ULONG Context = 0;
01181 ULONG ReturnedLength;
01182 HANDLE DosDevicesDirectory;
01183 HANDLE *HandleArray;
01184 ULONG
Size = 100;
01185 ULONG i,
Count = 0;
01186
01187 swprintf(szSessionString,
L"%ws\\%ld\\DosDevices",
SESSION_ROOT,NtCurrentPeb()->SessionId);
01188
01189
RtlInitUnicodeString(&UnicodeString, szSessionString);
01190
01191 InitializeObjectAttributes(&Attributes,
01192 &UnicodeString,
01193 OBJ_CASE_INSENSITIVE,
01194
NULL,
01195
NULL);
01196
01197
Status =
NtOpenDirectoryObject(&DosDevicesDirectory,
01198 DIRECTORY_ALL_ACCESS,
01199 &Attributes);
01200
01201
if (!
NT_SUCCESS(
Status)) {
01202
DBGHYD((
"NtOpenDirectoryObject failed with Status %lx\n",
Status));
01203
return Status;
01204 }
01205
01206 Restart:
01207 HandleArray = (HANDLE *)LocalAlloc(LPTR,
Size *
sizeof(HANDLE));
01208
01209
if (HandleArray ==
NULL) {
01210
01211
NtClose(DosDevicesDirectory);
01212
return STATUS_NO_MEMORY;
01213 }
01214
01215 RestartScan =
TRUE;
01216 DirInfo = (POBJECT_DIRECTORY_INFORMATION)&DirInfoBuffer;
01217
01218
while (
TRUE) {
01219
Status =
NtQueryDirectoryObject( DosDevicesDirectory,
01220 (PVOID)DirInfo,
01221
sizeof(DirInfoBuffer),
01222
TRUE,
01223 RestartScan,
01224 &Context,
01225 &ReturnedLength);
01226
01227
01228
01229
01230
if (!
NT_SUCCESS(
Status)) {
01231
01232
if (
Status == STATUS_NO_MORE_ENTRIES) {
01233
Status = STATUS_SUCCESS;
01234 }
01235
break;
01236 }
01237
01238
if (!wcscmp(DirInfo->TypeName.Buffer,
L"SymbolicLink")) {
01239
01240
if (
Count >=
Size ) {
01241
01242
for (i = 0; i <
Count ; i++) {
01243
NtClose (HandleArray[i]);
01244 }
01245
Size += 20;
01246
Count = 0;
01247 LocalFree(HandleArray);
01248
goto Restart;
01249
01250 }
01251
01252 InitializeObjectAttributes( &Attributes,
01253 &DirInfo->Name,
01254 OBJ_CASE_INSENSITIVE,
01255 DosDevicesDirectory,
01256
NULL);
01257
01258
Status =
NtOpenSymbolicLinkObject( &LinkHandle,
01259 SYMBOLIC_LINK_ALL_ACCESS,
01260 &Attributes);
01261
01262
if (
NT_SUCCESS(
Status)) {
01263
01264
Status =
NtMakeTemporaryObject( LinkHandle );
01265
01266
if (
NT_SUCCESS(
Status )) {
01267 HandleArray[
Count] = LinkHandle;
01268
Count++;
01269 }
01270 }
01271
01272 }
01273 RestartScan =
FALSE;
01274 }
01275
01276
for (i = 0; i <
Count ; i++) {
01277
01278
NtClose (HandleArray[i]);
01279
01280 }
01281
01282 LocalFree(HandleArray);
01283
01284
NtClose(DosDevicesDirectory);
01285
01286
return Status;
01287 }