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

549 lines
16 KiB

  1. /*************************************************************************
  2. *
  3. * wsxmgr.c
  4. *
  5. * Routines to manage Window Station extensions.
  6. *
  7. * Copyright Microsoft Corporation, 1998
  8. *
  9. *
  10. *************************************************************************/
  11. #include "precomp.h"
  12. #pragma hdrstop
  13. /*=============================================================================
  14. == Macros
  15. =============================================================================*/
  16. /*=============================================================================
  17. == External procedures defined
  18. =============================================================================*/
  19. PWSEXTENSION FindWinStationExtensionDll( PWSTR pszWsxDll, ULONG WdFlag );
  20. /*=============================================================================
  21. == Local Data
  22. =============================================================================*/
  23. RTL_CRITICAL_SECTION WsxListLock;
  24. RTL_CRITICAL_SECTION WsxLoadLock;
  25. LIST_ENTRY WsxListHead;
  26. /*=============================================================================
  27. == External Data
  28. =============================================================================*/
  29. extern LIST_ENTRY WinStationListHead; // protected by WinStationListLock
  30. /*******************************************************************************
  31. *
  32. * WsxInit
  33. *
  34. *
  35. *
  36. * ENTRY:
  37. * nothing
  38. *
  39. * EXIT:
  40. * STATUS_SUCCESS on success, the return value of InitCritSec on failure.
  41. *
  42. ******************************************************************************/
  43. NTSTATUS
  44. WsxInit( VOID )
  45. {
  46. NTSTATUS Status;
  47. InitializeListHead( &WsxListHead );
  48. Status = RtlInitializeCriticalSection( &WsxLoadLock );
  49. if (Status == STATUS_SUCCESS) {
  50. Status = RtlInitializeCriticalSection( &WsxListLock );
  51. if (Status != STATUS_SUCCESS) {
  52. RtlDeleteCriticalSection(&WsxLoadLock);
  53. }
  54. }
  55. return(Status);
  56. }
  57. /*******************************************************************************
  58. *
  59. * _WinStationEnumCallback
  60. *
  61. *
  62. *
  63. * ENTRY:
  64. * nothing
  65. *
  66. * EXIT:
  67. * nothing
  68. *
  69. ******************************************************************************/
  70. VOID
  71. _WinStationEnumCallback(PCALLBACK_PRIMARY pPrimaryCallback,
  72. PCALLBACK_COMPLETION pCompletionCallback,
  73. PVOID pWsxEnum
  74. )
  75. {
  76. PLIST_ENTRY Head, Next;
  77. PWINSTATION pWinStation;
  78. RtlEnterCriticalSection( &WinStationListLock );
  79. // call primary if valid
  80. if ( pPrimaryCallback ) {
  81. Head = &WinStationListHead;
  82. for ( Next = Head->Flink; Next != Head; Next = Next->Flink ) {
  83. pWinStation = CONTAINING_RECORD( Next, WINSTATION, Links );
  84. if ( pWinStation->pWsx ) {
  85. pPrimaryCallback( pWinStation->pWsx->hInstance, pWinStation->pWsxContext, pWsxEnum );
  86. } else {
  87. pPrimaryCallback( NULL, pWinStation->pWsxContext, pWsxEnum );
  88. }
  89. }
  90. }
  91. // call completion if valid
  92. if ( pCompletionCallback ) {
  93. pCompletionCallback( pWsxEnum );
  94. }
  95. RtlLeaveCriticalSection( &WinStationListLock );
  96. }
  97. /*******************************************************************************
  98. *
  99. * _SendWinStationMessage
  100. *
  101. *
  102. *
  103. * ENTRY:
  104. * nothing
  105. *
  106. * EXIT:
  107. * nothing
  108. *
  109. ******************************************************************************/
  110. NTSTATUS
  111. _SendWinStationMessage(
  112. ULONG LogonId,
  113. PWCHAR pTitle,
  114. PWCHAR pMessage,
  115. ULONG MessageTimeout )
  116. {
  117. PWINSTATION pWinStation;
  118. WINSTATION_APIMSG msg;
  119. NTSTATUS Status;
  120. /*
  121. * Find and lock the WinStation struct for the specified LogonId
  122. */
  123. pWinStation = FindWinStationById( LogonId, FALSE );
  124. if ( pWinStation == NULL ) {
  125. return( STATUS_CTX_WINSTATION_NOT_FOUND );
  126. }
  127. /*
  128. * Build message
  129. */
  130. msg.u.SendMessage.pTitle = pTitle;
  131. msg.u.SendMessage.TitleLength = wcslen( pTitle ) * sizeof(WCHAR);
  132. msg.u.SendMessage.pMessage = pMessage;
  133. msg.u.SendMessage.MessageLength = wcslen( pMessage ) * sizeof(WCHAR);
  134. msg.u.SendMessage.Style = MB_OK | MB_ICONSTOP;
  135. msg.u.SendMessage.Timeout = MessageTimeout;
  136. msg.u.SendMessage.Response = 0;
  137. msg.u.SendMessage.DoNotWait = TRUE;
  138. msg.u.SendMessage.DoNotWaitForCorrectDesktop = FALSE;
  139. msg.ApiNumber = SMWinStationDoMessage;
  140. // since we not going to wait for the message delievary, we dont care for status.
  141. msg.u.SendMessage.pStatus = NULL;
  142. msg.u.SendMessage.pResponse = NULL;
  143. msg.u.SendMessage.hEvent = NULL;
  144. /*
  145. * Send message
  146. */
  147. Status = SendWinStationCommand( pWinStation, &msg, 0 );
  148. /*
  149. * Done with winstation
  150. */
  151. ReleaseWinStation( pWinStation );
  152. return( Status );
  153. }
  154. /*******************************************************************************
  155. *
  156. * _GetContextForLogonId
  157. *
  158. *
  159. *
  160. * ENTRY:
  161. * nothing
  162. *
  163. * EXIT:
  164. * nothing
  165. *
  166. ******************************************************************************/
  167. NTSTATUS
  168. _GetContextForLogonId(
  169. ULONG LogonId,
  170. PVOID * ppWsxContext
  171. )
  172. {
  173. PWINSTATION pWinStation;
  174. WINSTATION_APIMSG msg;
  175. /*
  176. * Find and lock the WinStation struct for the specified LogonId
  177. */
  178. pWinStation = FindWinStationById( LogonId, FALSE );
  179. if ( pWinStation == NULL ) {
  180. *ppWsxContext = NULL;
  181. return( STATUS_CTX_WINSTATION_NOT_FOUND );
  182. }
  183. /*
  184. * Return context
  185. */
  186. *ppWsxContext = pWinStation->pWsxContext;
  187. /*
  188. * Done with winstation
  189. */
  190. ReleaseWinStation( pWinStation );
  191. return( STATUS_SUCCESS );
  192. }
  193. /*******************************************************************************
  194. *
  195. * _LoadWsxDll
  196. *
  197. * Load and Initialize Window Station Extension DLL.
  198. *
  199. * ENTRY:
  200. * nothing
  201. *
  202. * EXIT:
  203. * nothing
  204. *
  205. ******************************************************************************/
  206. PWSEXTENSION
  207. _LoadWsxDll( PWSTR pszWsxDll )
  208. {
  209. PWSEXTENSION pWsx;
  210. HINSTANCE hDllInstance;
  211. if ( pszWsxDll == NULL || *pszWsxDll == UNICODE_NULL )
  212. return( NULL );
  213. hDllInstance = LoadLibrary(pszWsxDll);
  214. if (!hDllInstance) {
  215. TRACE((hTrace,TC_ICASRV,TT_ERROR,"TERMSRV: Error %d, _LoadWsxDll(%s) failed\n",
  216. GetLastError(), pszWsxDll));
  217. return(NULL);
  218. }
  219. pWsx = MemAlloc( sizeof(WSEXTENSION) );
  220. if ( !pWsx ) {
  221. return(NULL);
  222. }
  223. RtlZeroMemory( pWsx, sizeof(WSEXTENSION) );
  224. RtlCopyMemory( pWsx->WsxDLL, pszWsxDll, sizeof(pWsx->WsxDLL) );
  225. pWsx->hInstance = hDllInstance;
  226. /*
  227. * Initialize Dll support functions
  228. */
  229. pWsx->pWsxInitialize = (PWSX_INITIALIZE) GetProcAddress(hDllInstance, WSX_INITIALIZE);
  230. if (!pWsx->pWsxInitialize) {
  231. TRACE((hTrace,TC_ICASRV,TT_ERROR,"TERMSRV: Could not find pWsxInitialize entry point\n"));
  232. goto LoadWsx_ErrorReturn;
  233. }
  234. /*
  235. * Client Drive Mapping Extensions
  236. */
  237. pWsx->pWsxCdmConnect = (PWSX_CDMCONNECT)
  238. GetProcAddress(hDllInstance, WSX_CDMCONNECT);
  239. pWsx->pWsxCdmDisconnect = (PWSX_CDMDISCONNECT)
  240. GetProcAddress(hDllInstance, WSX_CDMDISCONNECT);
  241. pWsx->pWsxVerifyClientLicense = (PWSX_VERIFYCLIENTLICENSE)
  242. GetProcAddress(hDllInstance, WSX_VERIFYCLIENTLICENSE);
  243. pWsx->pWsxQueryLicense = (PWSX_QUERYLICENSE)
  244. GetProcAddress(hDllInstance, WSX_QUERYLICENSE);
  245. pWsx->pWsxGetLicense = (PWSX_GETLICENSE)
  246. GetProcAddress(hDllInstance, WSX_GETLICENSE);
  247. pWsx->pWsxWinStationLogonAnnoyance = (PWSX_WINSTATIONLOGONANNOYANCE)
  248. GetProcAddress(hDllInstance, WSX_WINSTATIONLOGONANNOYANCE);
  249. pWsx->pWsxWinStationGenerateLicense = (PWSX_WINSTATIONGENERATELICENSE)
  250. GetProcAddress(hDllInstance, WSX_WINSTATIONGENERATELICENSE);
  251. pWsx->pWsxWinStationInstallLicense = (PWSX_WINSTATIONINSTALLLICENSE)
  252. GetProcAddress(hDllInstance, WSX_WINSTATIONINSTALLLICENSE);
  253. pWsx->pWsxWinStationEnumerateLicenses = (PWSX_WINSTATIONENUMERATELICENSES)
  254. GetProcAddress(hDllInstance, WSX_WINSTATIONENUMERATELICENSES);
  255. pWsx->pWsxWinStationActivateLicense = (PWSX_WINSTATIONACTIVATELICENSE)
  256. GetProcAddress(hDllInstance, WSX_WINSTATIONACTIVATELICENSE);
  257. pWsx->pWsxWinStationRemoveLicense = (PWSX_WINSTATIONREMOVELICENSE)
  258. GetProcAddress(hDllInstance, WSX_WINSTATIONREMOVELICENSE);
  259. pWsx->pWsxWinStationSetPoolCount = (PWSX_WINSTATIONSETPOOLCOUNT)
  260. GetProcAddress(hDllInstance, WSX_WINSTATIONSETPOOLCOUNT);
  261. pWsx->pWsxWinStationQueryUpdateRequired = (PWSX_WINSTATIONQUERYUPDATEREQUIRED)
  262. GetProcAddress(hDllInstance, WSX_WINSTATIONQUERYUPDATEREQUIRED);
  263. pWsx->pWsxWinStationAnnoyanceThread = (PWSX_WINSTATIONANNOYANCETHREAD)
  264. GetProcAddress(hDllInstance, WSX_WINSTATIONANNOYANCETHREAD);
  265. pWsx->pWsxInitializeClientData = (PWSX_INITIALIZECLIENTDATA)
  266. GetProcAddress(hDllInstance, WSX_INITIALIZECLIENTDATA);
  267. pWsx->pWsxInitializeUserConfig = (PWSX_INITIALIZEUSERCONFIG)
  268. GetProcAddress(hDllInstance, WSX_INITIALIZEUSERCONFIG);
  269. pWsx->pWsxConvertPublishedApp = (PWSX_CONVERTPUBLISHEDAPP)
  270. GetProcAddress(hDllInstance, WSX_CONVERTPUBLISHEDAPP);
  271. pWsx->pWsxWinStationInitialize = (PWSX_WINSTATIONINITIALIZE)
  272. GetProcAddress(hDllInstance, WSX_WINSTATIONINITIALIZE);
  273. pWsx->pWsxWinStationReInitialize = (PWSX_WINSTATIONREINITIALIZE)
  274. GetProcAddress(hDllInstance, WSX_WINSTATIONREINITIALIZE);
  275. pWsx->pWsxWinStationRundown = (PWSX_WINSTATIONRUNDOWN)
  276. GetProcAddress(hDllInstance, WSX_WINSTATIONRUNDOWN);
  277. pWsx->pWsxDuplicateContext = (PWSX_DUPLICATECONTEXT)
  278. GetProcAddress(hDllInstance, WSX_DUPLICATECONTEXT);
  279. pWsx->pWsxCopyContext = (PWSX_COPYCONTEXT)
  280. GetProcAddress(hDllInstance, WSX_COPYCONTEXT);
  281. pWsx->pWsxClearContext = (PWSX_CLEARCONTEXT)
  282. GetProcAddress(hDllInstance, WSX_CLEARCONTEXT);
  283. pWsx->pWsxVirtualChannelSecurity = (PWSX_VIRTUALCHANNELSECURITY)
  284. GetProcAddress(hDllInstance, WSX_VIRTUALCHANNELSECURITY);
  285. pWsx->pWsxIcaStackIoControl = (PWSX_ICASTACKIOCONTROL)
  286. GetProcAddress(hDllInstance, WSX_ICASTACKIOCONTROL);
  287. pWsx->pWsxBrokenConnection = (PWSX_BROKENCONNECTION)
  288. GetProcAddress(hDllInstance, WSX_BROKENCONNECTION);
  289. pWsx->pWsxLogonNotify = (PWSX_LOGONNOTIFY)
  290. GetProcAddress(hDllInstance, WSX_LOGONNOTIFY);
  291. pWsx->pWsxSetErrorInfo = (PWSX_SETERRORINFO)
  292. GetProcAddress(hDllInstance, WSX_SETERRORINFO);
  293. pWsx->pWsxSendAutoReconnectStatus = (PWSX_SENDAUTORECONNECTSTATUS)
  294. GetProcAddress(hDllInstance, WSX_SENDAUTORECONNECTSTATUS);
  295. pWsx->pWsxEscape = (PWSX_ESCAPE)
  296. GetProcAddress(hDllInstance, WSX_ESCAPE);
  297. return(pWsx);
  298. LoadWsx_ErrorReturn:
  299. LocalFree(pWsx);
  300. return(NULL);
  301. }
  302. /*******************************************************************************
  303. *
  304. * FindWinStationExtensionDll
  305. *
  306. * Perform initialization of Window Station Extensions
  307. *
  308. * ENTRY:
  309. * nothing
  310. *
  311. * EXIT:
  312. * nothing
  313. *
  314. ******************************************************************************/
  315. PWSEXTENSION
  316. FindWinStationExtensionDll( PWSTR pszWsxDll, ULONG WdFlag )
  317. {
  318. PLIST_ENTRY Head, Next;
  319. PWSEXTENSION pWsx = NULL;
  320. ICASRVPROCADDR IcaSrvProcAddr;
  321. RtlEnterCriticalSection( &WsxLoadLock );
  322. RtlEnterCriticalSection( &WsxListLock );
  323. Head = &WsxListHead;
  324. for ( Next = Head->Flink; Next != Head; Next = Next->Flink ) {
  325. pWsx = CONTAINING_RECORD( Next, WSEXTENSION, Links );
  326. if ( !_wcsicmp( pszWsxDll, pWsx->WsxDLL ) ){
  327. break;
  328. }
  329. }
  330. RtlLeaveCriticalSection( &WsxListLock );
  331. if ( Next != Head ) {
  332. RtlLeaveCriticalSection( &WsxLoadLock );
  333. return( pWsx );
  334. }
  335. /*
  336. * Load winstation extensions dll
  337. */
  338. if ( (pWsx = _LoadWsxDll( pszWsxDll )) != NULL ) {
  339. KdPrintEx((DPFLTR_TERMSRV_ID, DPFLTR_TRACE_LEVEL, "TERMSRV: FindWinStationExtensionDll(%S) succeeded\n", pszWsxDll ));
  340. IcaSrvProcAddr.cbProcAddr =
  341. (ULONG) sizeof(ICASRVPROCADDR);
  342. IcaSrvProcAddr.pNotifySystemEvent =
  343. (PICASRV_NOTIFYSYSTEMEVENT) NotifySystemEvent;
  344. IcaSrvProcAddr.pSendWinStationMessage =
  345. (PICASRV_SENDWINSTATIONMESSAGE) _SendWinStationMessage;
  346. IcaSrvProcAddr.pGetContextForLogonId =
  347. (PICASRV_GETCONTEXTFORLOGONID) _GetContextForLogonId;
  348. IcaSrvProcAddr.pWinStationEnumCallBack =
  349. (PICASRV_WINSTATIONENUMCALLBACK) _WinStationEnumCallback;
  350. // initialize dll support procs
  351. if ( pWsx->pWsxInitialize( &IcaSrvProcAddr ) ) {
  352. RtlEnterCriticalSection( &WsxListLock );
  353. InsertHeadList( &WsxListHead, &pWsx->Links );
  354. RtlLeaveCriticalSection( &WsxListLock );
  355. } else {
  356. LocalFree( pWsx );
  357. pWsx = NULL;
  358. KdPrintEx((DPFLTR_TERMSRV_ID, DPFLTR_ERROR_LEVEL, "TERMSRV: FindWinStationExtensionDll(%S) failed\n", pszWsxDll ));
  359. }
  360. }
  361. else {
  362. KdPrintEx(( DPFLTR_TERMSRV_ID, DPFLTR_ERROR_LEVEL, "TERMSRV: FindWinStationExtensionDll(%S) failed\n", pszWsxDll ));
  363. }
  364. RtlLeaveCriticalSection( &WsxLoadLock );
  365. /*
  366. * Create the thread which will monitor the condition of the
  367. * WinFrame Licenses and if necessary send Annoyance Messages.
  368. */
  369. if ( pWsx && pWsx->pWsxWinStationAnnoyanceThread ) {
  370. DWORD ThreadId;
  371. HANDLE ThreadHandle;
  372. ThreadHandle = CreateThread( NULL,
  373. 0,
  374. (LPTHREAD_START_ROUTINE)pWsx->pWsxWinStationAnnoyanceThread,
  375. NULL,
  376. THREAD_SET_INFORMATION,
  377. &ThreadId );
  378. if(ThreadHandle )
  379. NtClose( ThreadHandle );
  380. }
  381. return( pWsx );
  382. }
  383. /*******************************************************************************
  384. *
  385. * WsxStackIoControl
  386. *
  387. * Callback routine called from ICAAPI.DLL to issue StackIoControl calls.
  388. *
  389. * ENTRY:
  390. * nothing
  391. *
  392. * EXIT:
  393. * nothing
  394. *
  395. ******************************************************************************/
  396. NTSTATUS
  397. WsxStackIoControl(
  398. IN PVOID pContext,
  399. IN HANDLE pStack,
  400. IN ULONG IoControlCode,
  401. IN PVOID pInBuffer,
  402. IN ULONG InBufferSize,
  403. OUT PVOID pOutBuffer,
  404. IN ULONG OutBufferSize,
  405. OUT PULONG pBytesReturned )
  406. {
  407. PWINSTATION pWinStation = (PWINSTATION)pContext;
  408. NTSTATUS Status;
  409. TRACE((hTrace, TC_ICASRV, TT_API1,
  410. "TERMSRV: Enter WsxIcaIoControl, IoControlCode=%d\n",
  411. (IoControlCode >> 2) & 0xfff));
  412. if ( pWinStation &&
  413. pWinStation->pWsx &&
  414. pWinStation->pWsx->pWsxIcaStackIoControl ) {
  415. Status = pWinStation->pWsx->pWsxIcaStackIoControl(
  416. pWinStation->pWsxContext,
  417. pWinStation->hIca,
  418. pStack,
  419. IoControlCode,
  420. pInBuffer,
  421. InBufferSize,
  422. pOutBuffer,
  423. OutBufferSize,
  424. pBytesReturned );
  425. } else {
  426. Status = IcaStackIoControl(
  427. pStack,
  428. IoControlCode,
  429. pInBuffer,
  430. InBufferSize,
  431. pOutBuffer,
  432. OutBufferSize,
  433. pBytesReturned );
  434. }
  435. return( Status );
  436. }