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.

515 lines
13 KiB

  1. //*************************************************************
  2. //
  3. // File name: TSrv.c
  4. //
  5. // Description: Contains routines to support remote
  6. // terminals
  7. //
  8. // Microsoft Confidential
  9. // Copyright (c) Microsoft Corporation 1991-1997
  10. // All rights reserved
  11. //
  12. //*************************************************************
  13. #include <regapi.h>
  14. #include <TSrv.h>
  15. #include <TSrvTerm.h>
  16. #include <TSrvCom.h>
  17. #include <TSrvInfo.h>
  18. #include <TSrvVC.h>
  19. #include <McsLib.h>
  20. #include "stdio.h"
  21. #include "_tsrvinfo.h"
  22. #include <tlsapi.h>
  23. // Data declarations
  24. HINSTANCE g_hDllInstance = NULL; // DLL instance
  25. HANDLE g_hMainThread = NULL; // Main work thread
  26. HANDLE g_hReadyEvent = NULL; // Ready event
  27. BOOL g_fShutdown = FALSE; // TSrvShare shutdown flag
  28. HANDLE g_hIcaTrace; // system wide trace handle
  29. HANDLE g_MainThreadExitEvent = NULL;
  30. extern HANDLE g_hVCAddinChangeEvent;
  31. extern HKEY g_hAddinRegKey; // handle to Addins reg subkey
  32. #define CERTIFICATE_INSTALLATION_INTERVAL 900000
  33. LICENSE_STATUS GetServerCertificate(CERT_TYPE CertType,
  34. LPBYTE * ppbCertificate,
  35. LPDWORD pcbCertificate );
  36. //*************************************************************
  37. //
  38. // DllMain()
  39. //
  40. // Purpose: Dll entry point.
  41. //
  42. // Parameters: IN [hInstance] -- Dll hInstance.
  43. // IN [dwReason] -- Call reason
  44. // IN [lpReserved] -- Reserved.
  45. //
  46. // Return: TRUE if successful
  47. // FALSE if not
  48. //
  49. // History: 07-17-97 BrianTa Created
  50. //
  51. //*************************************************************
  52. BOOL WINAPI _CRT_INIT(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved);
  53. BOOL
  54. WINAPI
  55. TShareDLLEntry(
  56. IN HINSTANCE hInstance,
  57. IN DWORD dwReason,
  58. IN LPVOID lpReserved)
  59. {
  60. BOOL fSuccess;
  61. // DbgBreakPoint();
  62. TRACE((DEBUG_TSHRSRV_FLOW,
  63. "TShrSRV: DllMain entry\n"));
  64. TRACE((DEBUG_TSHRSRV_DEBUG,
  65. "TShrSRV: hInstance 0x%x, dwReason 0x%x\n",
  66. hInstance, dwReason));
  67. fSuccess = TRUE;
  68. switch (dwReason)
  69. {
  70. case DLL_PROCESS_ATTACH:
  71. if (!_CRT_INIT(hInstance, dwReason, lpReserved))
  72. return(FALSE);
  73. TRACE((DEBUG_TSHRSRV_NORMAL,
  74. "TShrSRV: DLL attach\n"));
  75. // Disable thread library calls and save off
  76. // the DLL instance handle
  77. DisableThreadLibraryCalls(hInstance);
  78. g_hDllInstance = hInstance;
  79. TSRNG_Initialize();
  80. //
  81. // init TShare util library.
  82. //
  83. if (TSUtilInit() != ERROR_SUCCESS)
  84. {
  85. fSuccess = FALSE;
  86. break;
  87. }
  88. //
  89. // invoke mcsmux library first.
  90. //
  91. if (!MCSDLLInit())
  92. {
  93. fSuccess = FALSE;
  94. break;
  95. }
  96. //
  97. // Invoke TShareSRV initialization
  98. //
  99. if (!TSRVStartup())
  100. {
  101. fSuccess = FALSE;
  102. break;
  103. }
  104. //
  105. // additional init routines go here.
  106. //
  107. break;
  108. case DLL_PROCESS_DETACH:
  109. TRACE((DEBUG_TSHRSRV_NORMAL,
  110. "TShrSRV: DLL deattach\n"));
  111. //
  112. // Invoke TShareSRV shutdown
  113. //
  114. TSRVShutdown();
  115. //
  116. // invoke mcsmux cleanup routine.
  117. //
  118. MCSDllCleanup();
  119. TSUtilCleanup();
  120. TSRNG_Shutdown();
  121. if (!_CRT_INIT(hInstance, dwReason, lpReserved))
  122. return(FALSE);
  123. break;
  124. default:
  125. TRACE((DEBUG_TSHRSRV_DEBUG,
  126. "TShrSRV: Unknown reason code\n"));
  127. break;
  128. }
  129. TRACE((DEBUG_TSHRSRV_FLOW,
  130. "TShrSRV: DllMain exit - 0x%x\n",
  131. fSuccess));
  132. return (fSuccess);
  133. }
  134. //*************************************************************
  135. //
  136. // TSRVStartup()
  137. //
  138. // Purpose: Performs startup processing.
  139. //
  140. // Parameters: void
  141. //
  142. // Return: TRUE if successful
  143. // FALSE if not
  144. //
  145. // Notes: This routine is called by DLLMain to perform the
  146. // most basic initialization
  147. //
  148. // History: 07-17-97 BrianTa Created
  149. //
  150. //*************************************************************
  151. BOOL
  152. TSRVStartup(void)
  153. {
  154. DWORD err;
  155. LONG rc;
  156. TRACE((DEBUG_TSHRSRV_FLOW,
  157. "TShrSRV: TSRVStartup entry\n"));
  158. g_hMainThread = NULL;
  159. g_MainThreadExitEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
  160. if( NULL == g_MainThreadExitEvent )
  161. {
  162. err = GetLastError();
  163. TRACE((DEBUG_TSHRSRV_FLOW,
  164. "TShrSRV: TSRVStartup exit - 0x%x\n",
  165. err));
  166. return FALSE;
  167. }
  168. rc = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  169. TSRV_VC_KEY,
  170. 0,
  171. KEY_READ,
  172. &g_hAddinRegKey);
  173. if (rc == ERROR_SUCCESS)
  174. {
  175. g_hVCAddinChangeEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
  176. if( NULL == g_hVCAddinChangeEvent )
  177. {
  178. //
  179. // This is not catastrophic, so we just trace and continue.
  180. //
  181. err = GetLastError();
  182. TRACE((DEBUG_TSHRSRV_ERROR,
  183. "TShrSRV: Failed to create VC Addin Change event - 0x%x\n",
  184. err));
  185. }
  186. }
  187. else
  188. {
  189. // This is not catastrophic either.
  190. TRACE((DEBUG_TSHRSRV_ERROR,
  191. "TShrSRV: Failed to open key %S, rc %d\n",
  192. TSRV_VC_KEY, rc));
  193. }
  194. g_hReadyEvent = CreateEvent(NULL, // security attributes
  195. FALSE, // manual-reset event
  196. FALSE, // initial state
  197. NULL); // event-object name
  198. TRACE((DEBUG_TSHRSRV_FLOW,
  199. "TShrSRV: TSRVStartup exit - 0x%x\n",
  200. g_hReadyEvent ? TRUE : FALSE));
  201. return (g_hReadyEvent ? TRUE : FALSE);
  202. }
  203. //*************************************************************
  204. //
  205. // TSRVShutdown()
  206. //
  207. // Purpose: Performs shutdown processing.
  208. //
  209. // Parameters: void
  210. //
  211. // Return: void
  212. //
  213. // History: 07-17-97 BrianTa Created
  214. //
  215. //*************************************************************
  216. void
  217. TSRVShutdown(void)
  218. {
  219. DWORD dwWaitStatus;
  220. TRACE((DEBUG_TSHRSRV_FLOW,
  221. "TShrSRV: TSRVShutdown entry\n"));
  222. // Denote that we are no longer ready to service any
  223. // new requests
  224. TSrvReady(FALSE);
  225. // If we were able to launch our main worker thread, then
  226. // we may need to terminate conferences, etc.
  227. if (g_hMainThread)
  228. {
  229. // Tell the system that we are terminating. This will cause
  230. // TSrvMainThread to exit once it has finished servicing all
  231. // outstanding posted work items.
  232. TSrvTerminating(TRUE);
  233. // Wait for TSrvMainThread to exit
  234. TRACE((DEBUG_TSHRSRV_NORMAL,
  235. "TShrSRV: Waiting for TSrvMainThread to exit\n"));
  236. SetEvent( g_MainThreadExitEvent );
  237. dwWaitStatus = WaitForSingleObject(g_hMainThread, 600000);
  238. if( WAIT_OBJECT_0 != dwWaitStatus )
  239. {
  240. //
  241. // The thread did not terminate within allowable time
  242. //
  243. TRACE((DEBUG_TSHRSRV_DEBUG,
  244. "TShrSRV: TSrvMainThread refused to exit, killing\n"));
  245. TerminateThread( g_hMainThread, 0 );
  246. }
  247. CloseHandle( g_hMainThread );
  248. g_hMainThread = NULL;
  249. CloseHandle( g_MainThreadExitEvent );
  250. g_MainThreadExitEvent = NULL;
  251. CloseHandle( g_hVCAddinChangeEvent );
  252. g_hVCAddinChangeEvent = NULL;
  253. if (g_hAddinRegKey)
  254. {
  255. RegCloseKey(g_hAddinRegKey);
  256. g_hAddinRegKey = NULL;
  257. }
  258. // Get the VC code to free its stuff
  259. TSrvTermVC();
  260. TLSShutdown();
  261. }
  262. else
  263. {
  264. TSrvTerminating(TRUE);
  265. }
  266. // Inform GCC we no longer want to be a Node Controller
  267. TSrvUnregisterNC();
  268. TRACE((DEBUG_TSHRSRV_FLOW,
  269. "TShrSRV: TSRVShutdown exit\n"));
  270. }
  271. //*************************************************************
  272. //
  273. // TSrvMainThread()
  274. //
  275. // Purpose: Main worker thread for TShareSRV.
  276. //
  277. // Parameters: void
  278. //
  279. // Return: 0
  280. //
  281. // Notes: This thread is spawned by DLLMain. It performs
  282. // the vast majority of TShareSRV initialization
  283. // and then waits for work items to be posted to it.
  284. //
  285. // History: 07-17-97 BrianTa Created
  286. //
  287. //*************************************************************
  288. DWORD
  289. WINAPI
  290. TSrvMainThread(LPVOID pvContext)
  291. {
  292. LPBYTE pX509Cert;
  293. DWORD dwX509CertLen;
  294. DWORD dwWaitStatus;
  295. LICENSE_STATUS Status;
  296. LARGE_INTEGER DueTime = {0,0};
  297. HANDLE rghWait[4] = {0};
  298. DWORD dwCount = 0;
  299. DWORD dwWaitExit = 0xFFFFFFFF;
  300. DWORD dwWaitVCAddin = 0xFFFFFFFF;
  301. TRACE((DEBUG_TSHRSRV_FLOW,
  302. "TShrSRV: TSrvMainThread entry\n"));
  303. if (TSrvInitialize())
  304. {
  305. TSrvReady(TRUE);
  306. TRACE((DEBUG_TSHRSRV_NORMAL,
  307. "TShrSRV: Entering TSrvMainThread worker loop\n"));
  308. if (g_MainThreadExitEvent)
  309. {
  310. dwWaitExit = WAIT_OBJECT_0 + dwCount;
  311. rghWait[dwCount] = g_MainThreadExitEvent;
  312. dwCount++;
  313. TRACE((DEBUG_TSHRSRV_DEBUG, "TShrSRV: Added exit event\n"));
  314. }
  315. if (g_hVCAddinChangeEvent)
  316. {
  317. //
  318. // The addin change notification was set up earlier, when we read
  319. // the addins information from the registry.
  320. //
  321. dwWaitVCAddin = WAIT_OBJECT_0 + dwCount;
  322. rghWait[dwCount] = g_hVCAddinChangeEvent;
  323. dwCount++;
  324. }
  325. while (1)
  326. {
  327. dwWaitStatus = WaitForMultipleObjects(dwCount,
  328. rghWait,
  329. FALSE,
  330. INFINITE);
  331. if( dwWaitExit == dwWaitStatus )
  332. {
  333. //
  334. // time to exit the thread
  335. //
  336. TRACE((DEBUG_TSHRSRV_NORMAL,
  337. "TShrSRV: TSrvMainThread got EXIT event\n"));
  338. break;
  339. }
  340. else if (dwWaitVCAddin == dwWaitStatus)
  341. {
  342. //
  343. // The Virtual Channel Addins registry key has changed.
  344. // We need to kick off a refresh of our data.
  345. //
  346. TRACE((DEBUG_TSHRSRV_WARN,
  347. "TShrSRV: TSrvMainThread got VC ADDINS CHANGED event\n"));
  348. TSrvGotAddinChangedEvent();
  349. }
  350. else
  351. {
  352. TS_ASSERT(dwWaitStatus == WAIT_FAILED);
  353. TRACE((DEBUG_TSHRSRV_DEBUG,
  354. "TShrSRV: Wait failed, so we'll just exit\n"));
  355. //
  356. // Wait failed, just bail
  357. //
  358. break;
  359. }
  360. }
  361. TSrvReady(FALSE);
  362. }
  363. TRACE((DEBUG_TSHRSRV_FLOW,
  364. "TShrSRV: TSrvMainThread exit - 0x%x\n",
  365. 0));
  366. return (0);
  367. }
  368. //*************************************************************
  369. //
  370. // TSrvInitialize()
  371. //
  372. // Purpose: Main routine for TSrvShare initialization
  373. //
  374. // Parameters: void
  375. //
  376. // Return: TRUE if successful
  377. // FALSE if not
  378. //
  379. // History: 07-17-97 BrianTa Created
  380. //
  381. //*************************************************************
  382. BOOL
  383. TSrvInitialize(void)
  384. {
  385. BOOL fSuccess;
  386. TRACE((DEBUG_TSHRSRV_FLOW,
  387. "TShrSRV: TSrvInitialize entry\n"));
  388. fSuccess = FALSE;
  389. // Initialize TSrvInfo data structs
  390. if (TSrvInitGlobalData())
  391. {
  392. if (TSrvInitVC())
  393. {
  394. // Register TShareSRV as GCC node controller
  395. if (TSrvRegisterNC())
  396. {
  397. if (ERROR_SUCCESS == TLSInit())
  398. {
  399. fSuccess = TRUE;
  400. }
  401. }
  402. }
  403. }
  404. TRACE((DEBUG_TSHRSRV_FLOW,
  405. "TShrSRV: TSrvInitialize exit - 0x%x\n", fSuccess));
  406. return (fSuccess);
  407. }