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

misc.c

Go to the documentation of this file.
00001 /****************************** Module Header ******************************\ 00002 * Module Name: misc.c 00003 * 00004 * Copyright (c) 1985 - 1999, Microsoft Corporation 00005 * 00006 * This module contains citrix code. 00007 * 00008 \***************************************************************************/ 00009 00010 00011 #include "precomp.h" 00012 #pragma hdrstop 00013 00014 /* 00015 * All of the following are gotten from ICASRV 00016 */ 00017 00018 CACHE_STATISTICS ThinWireCache; 00019 00020 NTSTATUS RemoteConnect( 00021 IN PDOCONNECTDATA pDoConnectData, 00022 IN ULONG DisplayDriverNameLength, 00023 IN PWCHAR DisplayDriverName) 00024 { 00025 NTSTATUS Status = STATUS_SUCCESS; 00026 PFILE_OBJECT pFileObject = NULL; 00027 PDEVICE_OBJECT pDeviceObject = NULL; 00028 PWCHAR pSep; 00029 00030 TRACE_HYDAPI(("RemoteConnect: display %ws\n", DisplayDriverName)); 00031 00032 HYDRA_HINT(HH_REMOTECONNECT); 00033 00034 UserAssert(ISCSRSS()); 00035 00036 gpThinWireCache = &ThinWireCache; 00037 00038 if (pDoConnectData->fMouse) { 00039 ghRemoteMouseChannel = pDoConnectData->IcaMouseChannel; 00040 } else { 00041 ghRemoteMouseChannel = NULL; 00042 } 00043 00044 ghRemoteVideoChannel = pDoConnectData->IcaVideoChannel; 00045 ghRemoteBeepChannel = pDoConnectData->IcaBeepChannel; 00046 ghRemoteKeyboardChannel = pDoConnectData->IcaKeyboardChannel; 00047 ghRemoteThinwireChannel = pDoConnectData->IcaThinwireChannel; 00048 00049 gRemoteClientKeyboardType = pDoConnectData->ClientKeyboardType; 00050 00051 gbClientDoubleClickSupport = pDoConnectData->fClientDoubleClickSupport; 00052 00053 gfEnableWindowsKey = pDoConnectData->fEnableWindowsKey; 00054 00055 RtlCopyMemory(gWinStationInfo.ProtocolName, pDoConnectData->ProtocolName, 00056 WPROTOCOLNAME_LENGTH * sizeof(WCHAR)); 00057 00058 RtlCopyMemory(gWinStationInfo.AudioDriverName, pDoConnectData->AudioDriverName, 00059 WAUDIONAME_LENGTH * sizeof(WCHAR)); 00060 00061 RtlZeroMemory(gstrBaseWinStationName, 00062 WINSTATIONNAME_LENGTH * sizeof(WCHAR)); 00063 00064 RtlCopyMemory(gstrBaseWinStationName, pDoConnectData->WinStationName, 00065 min(WINSTATIONNAME_LENGTH * sizeof(WCHAR), sizeof(pDoConnectData->WinStationName))); 00066 00067 if (pSep = wcschr(gstrBaseWinStationName, L'#')) 00068 *pSep = UNICODE_NULL; 00069 00070 /* 00071 * Create the event that is signaled when a desktop does away 00072 */ 00073 gpevtDesktopDestroyed = CreateKernelEvent(SynchronizationEvent, FALSE); 00074 if (gpevtDesktopDestroyed == NULL) { 00075 RIPMSG0(RIP_WARNING, "RemoteConnect couldn't create gpevtDesktopDestroyed"); 00076 return STATUS_NO_MEMORY; 00077 } 00078 00079 gbConnected = TRUE; 00080 00081 /* 00082 * WinStations must have the video device handle passed to them. 00083 */ 00084 if (gbRemoteSession && !gVideoFileObject) { 00085 00086 PFILE_OBJECT pFileObject = NULL; 00087 PDEVICE_OBJECT pDeviceObject = NULL; 00088 00089 // 00090 // Dereference the file handle 00091 // and obtain a pointer to the device object for the handle. 00092 // 00093 00094 Status = ObReferenceObjectByHandle(ghRemoteVideoChannel, 00095 0, 00096 NULL, 00097 KernelMode, 00098 (PVOID*)&pFileObject, 00099 NULL); 00100 if (NT_SUCCESS(Status)) { 00101 00102 gVideoFileObject = pFileObject; 00103 00104 // 00105 // Get a pointer to the device object for this file. 00106 // 00107 pDeviceObject = IoGetRelatedDeviceObject(pFileObject); 00108 00109 Status = ObReferenceObjectByHandle(ghRemoteThinwireChannel, 00110 0, 00111 NULL, 00112 KernelMode, 00113 (PVOID*)&gThinwireFileObject, 00114 NULL); 00115 00116 /* 00117 * This must be done before any thinwire data. 00118 */ 00119 if (NT_SUCCESS(Status)) { 00120 00121 if (!GreMultiUserInitSession(ghRemoteThinwireChannel, 00122 (PBYTE)gpThinWireCache, 00123 gVideoFileObject, 00124 gThinwireFileObject, 00125 DisplayDriverNameLength, 00126 DisplayDriverName)) { 00127 RIPMSG0(RIP_WARNING, "UserInit: GreMultiUserInitSession failed"); 00128 Status = STATUS_UNSUCCESSFUL; 00129 } else { 00130 00131 DWORD BytesReturned; 00132 00133 Status = GreDeviceIoControl( pDeviceObject, 00134 IOCTL_VIDEO_ICA_ENABLE_GRAPHICS, 00135 NULL, 00136 0, 00137 NULL, 00138 0, 00139 &BytesReturned); 00140 if (!NT_SUCCESS(Status)) { 00141 RIPMSG1(RIP_WARNING, "UserInit: Enable graphics status %08lx", 00142 Status); 00143 } 00144 } 00145 } 00146 } 00147 } 00148 00149 if (!NT_SUCCESS(Status)) { 00150 RIPMSG0(RIP_WARNING, "RemoteConnect failed"); 00151 return Status; 00152 } 00153 00154 if (InitVideo(FALSE) == NULL) { 00155 gbConnected = FALSE; 00156 RIPMSG0(RIP_WARNING, "InitVideo failed"); 00157 return STATUS_UNSUCCESSFUL; 00158 } 00159 00160 if (!LW_BrushInit()) { 00161 RIPMSG0(RIP_WARNING, "LW_BrushInit failed"); 00162 return STATUS_NO_MEMORY; 00163 } 00164 00165 InitLoadResources(); 00166 00167 Status = ObReferenceObjectByHandle(ghRemoteBeepChannel, 00168 0, 00169 NULL, 00170 KernelMode, 00171 (PVOID*)&gpRemoteBeepDevice, 00172 NULL); 00173 00174 /* 00175 * video is initialized at this point 00176 */ 00177 if (NT_SUCCESS(Status)) { 00178 gbVideoInitialized = TRUE; 00179 } else { 00180 RIPMSG0(RIP_WARNING, "Bad Remote Beep Channel"); 00181 } 00182 00183 return Status; 00184 } 00185 00186 00187 NTSTATUS 00188 xxxRemoteDisconnect( 00189 VOID) 00190 { 00191 NTSTATUS Status = STATUS_SUCCESS; 00192 LARGE_INTEGER li; 00193 00194 TRACE_HYDAPI(("xxxRemoteDisconnect\n")); 00195 00196 /* 00197 * Only allow CSRSS to do this 00198 */ 00199 if (!ISCSRSS() || !ISTS()) { 00200 return STATUS_ACCESS_DENIED; 00201 } 00202 00203 HYDRA_HINT(HH_REMOTEDISCONNECT); 00204 00205 RtlZeroMemory(gstrBaseWinStationName, 00206 WINSTATIONNAME_LENGTH * sizeof(WCHAR)); 00207 00208 UserAssert(gbConnected); 00209 00210 if (gspdeskDisconnect == NULL) { 00211 /* 00212 * Convert dwMilliseconds to a relative-time(i.e. negative) 00213 * LARGE_INTEGER. NT Base calls take time values in 100 nanosecond 00214 * units. Timeout after 5 minutes. 00215 */ 00216 li.QuadPart = Int32x32To64(-10000, 300000); 00217 00218 KeWaitForSingleObject(gpEventDiconnectDesktop, 00219 WrUserRequest, 00220 KernelMode, 00221 FALSE, 00222 &li); 00223 } 00224 00225 00226 /* 00227 * If the disconnected desktop has not yet be setup. Do not do any 00228 * disconnect processing. It's better for the thinwire driver to try 00229 * and write rather than for the transmit buffers to be freed (trap). 00230 */ 00231 if (gspdeskDisconnect) { 00232 00233 /* 00234 * Blank the screen 00235 * 00236 * No need to stop graphics mode for disconnects 00237 */ 00238 Status = xxxRemoteStopScreenUpdates(FALSE); 00239 if (!NT_SUCCESS(Status)) { 00240 return Status; 00241 } 00242 00243 /* 00244 * If there are any shadow connections, then redraw the screen now. 00245 */ 00246 if (gnShadowers) 00247 RemoteRedrawScreen(); 00248 } else { 00249 RIPMSG0(RIP_WARNING, "xxxRemoteDisconnect failed. The disconnect desktop was not created"); 00250 return STATUS_UNSUCCESSFUL; 00251 } 00252 00253 /* 00254 * Tell thinwire driver about this 00255 */ 00256 bDrvDisconnect(gpDispInfo->hDev, ghRemoteThinwireChannel, 00257 gThinwireFileObject); 00258 00259 00260 /* 00261 * Tell winlogon about the disconnect 00262 */ 00263 if (gspwndLogonNotify != NULL) { 00264 _PostMessage(gspwndLogonNotify, WM_LOGONNOTIFY, SESSION_DISCONNECTED, 0); 00265 } 00266 00267 gbConnected = FALSE; 00268 00269 return Status; 00270 } 00271 00272 NTSTATUS 00273 xxxRemoteReconnect( 00274 IN PDORECONNECTDATA pDoReconnectData) 00275 { 00276 NTSTATUS Status = STATUS_SUCCESS; 00277 BOOL fResult; 00278 PWCHAR pSep; 00279 00280 TRACE_HYDAPI(("xxxRemoteReconnect\n")); 00281 00282 /* 00283 * Only allow CSRSS to do this 00284 */ 00285 if (!ISCSRSS() || !ISTS()) { 00286 return STATUS_ACCESS_DENIED; 00287 } 00288 00289 HYDRA_HINT(HH_REMOTERECONNECT); 00290 00291 UserAssert(ISCSRSS()); 00292 00293 gRemoteClientKeyboardType = pDoReconnectData->ClientKeyboardType; 00294 00295 gbClientDoubleClickSupport = pDoReconnectData->fClientDoubleClickSupport; 00296 00297 gfEnableWindowsKey = pDoReconnectData->fEnableWindowsKey; 00298 00299 RtlCopyMemory(gstrBaseWinStationName, pDoReconnectData->WinStationName, 00300 min(WINSTATIONNAME_LENGTH * sizeof(WCHAR), sizeof(pDoReconnectData->WinStationName))); 00301 00302 if (pSep = wcschr(gstrBaseWinStationName, L'#')) 00303 *pSep = UNICODE_NULL; 00304 00305 if (gnShadowers) 00306 xxxRemoteStopScreenUpdates(TRUE); 00307 00308 00309 /* 00310 * Call thinwire driver to check for thinwire mode compatibility 00311 */ 00312 fResult = bDrvReconnect(gpDispInfo->hDev, ghRemoteThinwireChannel, 00313 gThinwireFileObject); 00314 00315 if (!fResult) { 00316 if (gnShadowers) 00317 RemoteRedrawScreen(); 00318 00319 return STATUS_CTX_BAD_VIDEO_MODE; 00320 } 00321 00322 00323 00324 /* 00325 * If instructed to do so, change Display mode before Reconnecting. 00326 * Use display resolution information from Reconnect data. 00327 */ 00328 00329 if (pDoReconnectData->fChangeDisplaySettings) { 00330 DEVMODEW devmodew; 00331 UNICODE_STRING ustrDeviceName; 00332 PDEVMODEW pDevmodew = &devmodew; 00333 00334 RtlZeroMemory(pDevmodew, sizeof(DEVMODEW)); 00335 pDevmodew->dmPelsHeight = pDoReconnectData->drPelsHeight; 00336 pDevmodew->dmPelsWidth = pDoReconnectData->drPelsWidth; 00337 pDevmodew->dmBitsPerPel = pDoReconnectData->drBitsPerPel; 00338 pDevmodew->dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT; 00339 pDevmodew->dmSize = sizeof(DEVMODEW); 00340 00341 RtlInitUnicodeString(&ustrDeviceName, L"\\\\.\\DISPLAY1"); 00342 00343 00344 Status = xxxUserChangeDisplaySettings(NULL, //&ustrDeviceName, 00345 &devmodew, 00346 NULL, 00347 grpdeskRitInput, 00348 0, 00349 NULL, 00350 KernelMode); 00351 /* 00352 * If Display settings change fails, let us disconnect the display driver 00353 * as the reconnect is going to be failed anyway. 00354 */ 00355 00356 00357 if (!NT_SUCCESS(Status)) { 00358 bDrvDisconnect(gpDispInfo->hDev, ghRemoteThinwireChannel, gThinwireFileObject); 00359 return Status; 00360 } 00361 00362 /* 00363 * Code in RemoteRedrawScreen() Expects gpDispInfo->pmdev to disabled, but 00364 * it has been enabled by xxxUserChangeDisplaySettings(), so let's disable it 00365 * before calling RemoteRedrawScreen(). 00366 */ 00367 DrvDisableMDEV(gpDispInfo->pmdev, TRUE); 00368 00369 } 00370 00371 /* 00372 * Now we can swicth out from disconnected desktop, to normal 00373 * desktop, in order to renable screen update. 00374 */ 00375 00376 RemoteRedrawScreen(); 00377 00378 if (gspwndLogonNotify != NULL) { 00379 _PostMessage(gspwndLogonNotify, WM_LOGONNOTIFY, 00380 SESSION_RECONNECTED, 0); 00381 } 00382 00383 /* 00384 * We need to re-init the mouse, especially since we may not have had one before. 00385 */ 00386 UpdateMouseInfo(); 00387 00388 /* 00389 * Re-init'ing the keyboard may not be as neccessary. Possibly the keyboard 00390 * attributes have changed. 00391 */ 00392 InitKeyboard(); 00393 00394 /* 00395 * This is neccessary to sync up the client and the host. 00396 */ 00397 UpdateKeyLights(FALSE); 00398 00399 SetPointer(TRUE); 00400 00401 gbConnected = TRUE; 00402 00403 00404 00405 return Status; 00406 } 00407 00408 /* 00409 * This allows ICASRV to cleanly logoff the user. We send a message to winlogon and let 00410 * him do it. We used to call ExitWindowsEx() directly, but that caused too many problems 00411 * when it was called from CSRSS. 00412 * 00413 */ 00414 NTSTATUS 00415 RemoteLogoff( 00416 VOID) 00417 { 00418 NTSTATUS Status = STATUS_SUCCESS; 00419 00420 TRACE_HYDAPI(("RemoteLogoff\n")); 00421 00422 /* 00423 * Only allow CSRSS to do this 00424 */ 00425 if (!ISCSRSS() || !ISTS()) { 00426 return STATUS_ACCESS_DENIED; 00427 } 00428 00429 HYDRA_HINT(HH_REMOTELOGOFF); 00430 00431 UserAssert(ISCSRSS()); 00432 00433 /* 00434 * Tell winlogon about the logoff 00435 */ 00436 if (gspwndLogonNotify != NULL) { 00437 _PostMessage(gspwndLogonNotify, WM_LOGONNOTIFY, 00438 SESSION_LOGOFF, EWX_LOGOFF | EWX_FORCE); 00439 } 00440 00441 return Status; 00442 } 00443 00444 00445 NTSTATUS 00446 xxxRemoteStopScreenUpdates( 00447 BOOL fDisableGraphics) 00448 { 00449 NTSTATUS Status = STATUS_SUCCESS; 00450 NTSTATUS SaveStatus = STATUS_SUCCESS; 00451 //ULONG BytesReturned; 00452 WORD NewButtonState; 00453 00454 TRACE_HYDAPI(("xxxRemoteStopScreenUpdates fDisableGraphics %d\n", fDisableGraphics)); 00455 00456 CheckCritIn(); 00457 00458 UserAssert(ISCSRSS()); 00459 00460 /* 00461 * No need to do this multiple times. 00462 */ 00463 if (gbFreezeScreenUpdates) 00464 return STATUS_SUCCESS; 00465 00466 /* 00467 * This could be called directly from the command channel. 00468 */ 00469 if (!gspdeskDisconnect) 00470 return STATUS_SUCCESS; 00471 00472 /* 00473 * If not connected, forget it 00474 */ 00475 if (ghRemoteVideoChannel == NULL) 00476 return STATUS_NO_SUCH_DEVICE; 00477 00478 /* 00479 * Mouse buttons up. 00480 * (Ensures no mouse buttons are left in a down state) 00481 */ 00482 NewButtonState = gwMKButtonState & ~gwMKCurrentButton; 00483 00484 if ((NewButtonState & MOUSE_BUTTON_LEFT) != (gwMKButtonState & MOUSE_BUTTON_LEFT)) { 00485 xxxButtonEvent(MOUSE_BUTTON_LEFT, gptCursorAsync, TRUE, NtGetTickCount(), 00486 0L, 0L, FALSE); 00487 } 00488 00489 if ((NewButtonState & MOUSE_BUTTON_RIGHT) != (gwMKButtonState & MOUSE_BUTTON_RIGHT)) { 00490 xxxButtonEvent(MOUSE_BUTTON_RIGHT, gptCursorAsync, TRUE, NtGetTickCount(), 00491 0L, 0L, FALSE); 00492 } 00493 gwMKButtonState = NewButtonState; 00494 00495 /* 00496 * Send shift key breaks to win32 00497 * (Ensures no shift keys are left on) 00498 */ 00499 00500 // { 0, 0xb8, KEY_BREAK, 0, 0 }, // L alt 00501 xxxPushKeyEvent(VK_LMENU, 0xb8, KEYEVENTF_KEYUP, 0); 00502 00503 // { 0, 0xb8, KEY_BREAK | KEY_E0, 0, 0 }, // R alt 00504 xxxPushKeyEvent(VK_RMENU, 0xb8, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0); 00505 00506 // { 0, 0x9d, KEY_BREAK, 0, 0 }, // L ctrl 00507 xxxPushKeyEvent(VK_LCONTROL, 0x9d, KEYEVENTF_KEYUP, 0); 00508 00509 // { 0, 0x9d, KEY_BREAK | KEY_E0, 0, 0 }, // R ctrl 00510 xxxPushKeyEvent(VK_RCONTROL, 0x9d, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0); 00511 00512 // { 0, 0xaa, KEY_BREAK, 0, 0 }, // L shift 00513 xxxPushKeyEvent(VK_LSHIFT, 0xaa, KEYEVENTF_KEYUP, 0); 00514 00515 // { 0, 0xb6, KEY_BREAK, 0, 0 } // R shift 00516 xxxPushKeyEvent(VK_RSHIFT, 0xb6, KEYEVENTF_KEYUP, 0); 00517 00518 Status = RemoteDisableScreen(); 00519 00520 if (!NT_SUCCESS(Status)) { 00521 return STATUS_NO_SUCH_DEVICE; 00522 } 00523 00524 UserAssert(gspdeskDisconnect != NULL && grpdeskRitInput == gspdeskDisconnect); 00525 00526 gbFreezeScreenUpdates = TRUE; 00527 00528 return Status; 00529 UNREFERENCED_PARAMETER(fDisableGraphics); 00530 } 00531 00532 /* 00533 * Taken from Internal Key Event. 00534 * Minus any permissions checking. 00535 */ 00536 VOID xxxPushKeyEvent( 00537 BYTE bVk, 00538 BYTE bScan, 00539 DWORD dwFlags, 00540 DWORD dwExtraInfo) 00541 { 00542 USHORT usFlaggedVK; 00543 00544 usFlaggedVK = (USHORT)bVk; 00545 00546 if (dwFlags & KEYEVENTF_KEYUP) 00547 usFlaggedVK |= KBDBREAK; 00548 00549 // IanJa: not all extended keys are numpad, but this seems to work. 00550 if (dwFlags & KEYEVENTF_EXTENDEDKEY) 00551 usFlaggedVK |= KBDNUMPAD | KBDEXT; 00552 00553 xxxKeyEvent(usFlaggedVK, bScan, NtGetTickCount(), dwExtraInfo, FALSE); 00554 } 00555 00556 00557 NTSTATUS 00558 RemoteThinwireStats( 00559 OUT PVOID Stats) 00560 { 00561 static DWORD sThinwireStatsLength = sizeof(CACHE_STATISTICS); 00562 00563 TRACE_HYDAPI(("RemoteThinwireStats\n")); 00564 00565 /* 00566 * Only allow CSRSS to do this 00567 */ 00568 if (!ISCSRSS() || !ISTS()) { 00569 return STATUS_ACCESS_DENIED; 00570 } 00571 00572 UserAssert(ISCSRSS()); 00573 if (gpThinWireCache != NULL) { 00574 RtlCopyMemory(Stats, gpThinWireCache, sThinwireStatsLength); 00575 return STATUS_SUCCESS; 00576 } 00577 return STATUS_NO_SUCH_DEVICE; 00578 } 00579 00580 00581 NTSTATUS 00582 RemoteNtSecurity( 00583 VOID) 00584 { 00585 TRACE_HYDAPI(("RemoteNtSecurity\n")); 00586 00587 /* 00588 * Only allow CSRSS to do this 00589 */ 00590 if (!ISCSRSS() || !ISTS()) { 00591 return STATUS_ACCESS_DENIED; 00592 } 00593 00594 UserAssert(ISCSRSS()); 00595 00596 UserAssert(gspwndLogonNotify != NULL); 00597 00598 if (gspwndLogonNotify != NULL) { 00599 _PostMessage(gspwndLogonNotify, WM_HOTKEY, 0, 0); 00600 } 00601 return STATUS_SUCCESS; 00602 } 00603 00604 00605 NTSTATUS 00606 xxxRemoteShadowSetup( 00607 VOID) 00608 { 00609 NTSTATUS Status = STATUS_SUCCESS; 00610 00611 TRACE_HYDAPI(("xxxRemoteShadowSetup\n")); 00612 00613 /* 00614 * Only allow CSRSS to do this 00615 */ 00616 if (!ISCSRSS() || !ISTS()) { 00617 return STATUS_ACCESS_DENIED; 00618 } 00619 00620 UserAssert(ISCSRSS()); 00621 00622 /* 00623 * Blank the screen 00624 */ 00625 if (gnShadowers || gbConnected) 00626 xxxRemoteStopScreenUpdates(FALSE); 00627 00628 gnShadowers++; 00629 00630 return Status; 00631 } 00632 00633 00634 NTSTATUS 00635 RemoteShadowStart( 00636 IN PVOID pThinwireData, 00637 ULONG ThinwireDataLength) 00638 { 00639 BOOL fResult; 00640 NTSTATUS Status = STATUS_SUCCESS; 00641 00642 TRACE_HYDAPI(("RemoteShadowStart\n")); 00643 00644 /* 00645 * Only allow CSRSS to do this 00646 */ 00647 if (!ISCSRSS() || !ISTS()) { 00648 return STATUS_ACCESS_DENIED; 00649 } 00650 00651 UserAssert(ISCSRSS()); 00652 00653 /* 00654 * Call thinwire driver and check for thinwire mode compatibility 00655 */ 00656 fResult = bDrvShadowConnect(gpDispInfo->hDev, pThinwireData, 00657 ThinwireDataLength); 00658 00659 // Although originally defined as BOOL, allow more meaningful return codes. 00660 if (!fResult) { 00661 return STATUS_CTX_BAD_VIDEO_MODE; 00662 } 00663 else if (fResult != TRUE) { 00664 return fResult; 00665 } 00666 00667 RemoteRedrawScreen(); 00668 00669 return Status; 00670 } 00671 00672 00673 NTSTATUS 00674 xxxRemoteShadowStop( 00675 VOID) 00676 { 00677 NTSTATUS Status = STATUS_SUCCESS; 00678 00679 TRACE_HYDAPI(("xxxRemoteShadowStop\n")); 00680 00681 /* 00682 * Only allow CSRSS to do this 00683 */ 00684 if (!ISCSRSS() || !ISTS()) { 00685 return STATUS_ACCESS_DENIED; 00686 } 00687 00688 UserAssert(ISCSRSS()); 00689 00690 /* 00691 * Blank the screen 00692 */ 00693 xxxRemoteStopScreenUpdates(FALSE); 00694 00695 return Status; 00696 } 00697 00698 00699 NTSTATUS 00700 RemoteShadowCleanup( 00701 IN PVOID pThinwireData, 00702 ULONG ThinwireDataLength) 00703 { 00704 NTSTATUS Status = STATUS_SUCCESS; 00705 00706 TRACE_HYDAPI(("RemoteShadowCleanup\n")); 00707 00708 /* 00709 * Only allow CSRSS to do this 00710 */ 00711 if (!ISCSRSS() || !ISTS()) { 00712 return STATUS_ACCESS_DENIED; 00713 } 00714 00715 UserAssert(ISCSRSS()); 00716 00717 /* 00718 * Tell the Thinwire driver about it 00719 */ 00720 bDrvShadowDisconnect(gpDispInfo->hDev, pThinwireData, 00721 ThinwireDataLength); 00722 00723 if (gnShadowers > 0) 00724 gnShadowers--; 00725 00726 if (gnShadowers || gbConnected) { 00727 RemoteRedrawScreen(); 00728 } 00729 00730 return Status; 00731 } 00732 00733 00734 NTSTATUS 00735 xxxRemotePassthruEnable( 00736 VOID) 00737 { 00738 IO_STATUS_BLOCK IoStatus; 00739 static BOOL KeyboardType101; 00740 00741 TRACE_HYDAPI(("xxxRemotePassthruEnable\n")); 00742 00743 /* 00744 * Only allow CSRSS to do this 00745 */ 00746 if (!ISCSRSS() || !ISTS()) { 00747 return STATUS_ACCESS_DENIED; 00748 } 00749 00750 UserAssert(gbConnected); 00751 UserAssert(gnShadowers == 0); 00752 UserAssert(ISCSRSS()); 00753 00754 KeyboardType101 = !(gapulCvt_VK == gapulCvt_VK_84); 00755 00756 ZwDeviceIoControlFile(ghRemoteKeyboardChannel, NULL, NULL, NULL, 00757 &IoStatus, IOCTL_KEYBOARD_ICA_TYPE, 00758 &KeyboardType101, sizeof(KeyboardType101), 00759 NULL, 0); 00760 00761 if (guKbdTblSize != 0) { 00762 ZwDeviceIoControlFile(ghRemoteKeyboardChannel, NULL, NULL, NULL, 00763 &IoStatus, IOCTL_KEYBOARD_ICA_LAYOUT, 00764 ghKbdTblBase, guKbdTblSize, 00765 gpKbdTbl, 0); 00766 } 00767 00768 xxxRemoteStopScreenUpdates(FALSE); 00769 00770 /* 00771 * Tell thinwire driver about this 00772 */ 00773 bDrvDisconnect(gpDispInfo->hDev, ghRemoteThinwireChannel, 00774 gThinwireFileObject); 00775 00776 return STATUS_SUCCESS; 00777 } 00778 00779 00780 NTSTATUS 00781 RemotePassthruDisable( 00782 VOID) 00783 { 00784 BOOL fResult; 00785 00786 TRACE_HYDAPI(("RemotePassthruDisable\n")); 00787 00788 /* 00789 * Only allow CSRSS to do this 00790 */ 00791 if (!ISCSRSS() || !ISTS()) { 00792 return STATUS_ACCESS_DENIED; 00793 } 00794 00795 UserAssert(gnShadowers == 0); 00796 UserAssert(ISCSRSS()); 00797 00798 fResult = bDrvReconnect(gpDispInfo->hDev, ghRemoteThinwireChannel, 00799 gThinwireFileObject); 00800 if (!fResult) { 00801 return STATUS_CTX_BAD_VIDEO_MODE; 00802 } 00803 00804 if (gbConnected) { 00805 RemoteRedrawScreen(); 00806 UpdateKeyLights(FALSE); // Make sure LED's are correct 00807 } 00808 00809 return STATUS_SUCCESS; 00810 } 00811 00812 00813 NTSTATUS 00814 CtxDisplayIOCtl( 00815 ULONG DisplayIOCtlFlags, 00816 PUCHAR pDisplayIOCtlData, 00817 ULONG cbDisplayIOCtlData) 00818 { 00819 BOOL fResult; 00820 00821 TRACE_HYDAPI(("CtxDisplayIOCtl\n")); 00822 00823 fResult = bDrvDisplayIOCtl(gpDispInfo->hDev, pDisplayIOCtlData, cbDisplayIOCtlData); 00824 00825 if (!fResult) { 00826 return STATUS_CTX_BAD_VIDEO_MODE; 00827 } 00828 00829 if ((DisplayIOCtlFlags & DISPLAY_IOCTL_FLAG_REDRAW)) { 00830 RemoteRedrawRectangle(0,0,0xffff,0xffff); 00831 } 00832 00833 return STATUS_SUCCESS; 00834 } 00835 00836 00837 /* 00838 * This is for things like user32.dll init routines that don't want to use 00839 * winsta.dll for queries. 00840 * 00841 */ 00842 DWORD 00843 RemoteConnectState( 00844 VOID) 00845 { 00846 DWORD state = 0; 00847 00848 if (!gbRemoteSession) { 00849 00850 state = CTX_W32_CONNECT_STATE_CONSOLE; 00851 00852 } else if (!gbVideoInitialized) { 00853 00854 state = CTX_W32_CONNECT_STATE_IDLE; 00855 00856 } else if (gbExitInProgress) { 00857 00858 state = CTX_W32_CONNECT_STATE_EXIT_IN_PROGRESS; 00859 00860 } else if (gbConnected) { 00861 00862 state = CTX_W32_CONNECT_STATE_CONNECTED; 00863 00864 } else { 00865 state = CTX_W32_CONNECT_STATE_DISCONNECTED; 00866 } 00867 00868 return state; 00869 } 00870 00871 BOOL 00872 _GetWinStationInfo( 00873 WSINFO* pWsInfo) 00874 { 00875 CheckCritIn(); 00876 00877 try { 00878 00879 ProbeForWrite(pWsInfo, sizeof(gWinStationInfo), DATAALIGN); 00880 RtlCopyMemory(pWsInfo, &gWinStationInfo, sizeof(gWinStationInfo)); 00881 00882 } except (W32ExceptionHandler(FALSE, RIP_WARNING)) { 00883 return FALSE; 00884 } 00885 00886 return TRUE; 00887 }

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