Source code of Windows XP (NT5)
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.

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