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.

736 lines
17 KiB

  1. /*++
  2. Copyright(c) 1995 Microsoft Corporation
  3. MODULE NAME
  4. init.c
  5. ABSTRACT
  6. Initialization for the implicit connection service.
  7. AUTHOR
  8. Anthony Discolo (adiscolo) 08-May-1995
  9. REVISION HISTORY
  10. --*/
  11. #define UNICODE
  12. #define _UNICODE
  13. #include <nt.h>
  14. #include <ntrtl.h>
  15. #include <nturtl.h>
  16. #include <stdlib.h>
  17. #include <windows.h>
  18. #include <stdio.h>
  19. #include <wchar.h>
  20. #include <winsock.h>
  21. #include <npapi.h>
  22. #include <ipexport.h>
  23. #include <ras.h>
  24. #include <rasman.h>
  25. #include <acd.h>
  26. #include <tapi.h>
  27. #define DEBUGGLOBALS
  28. #include <debug.h>
  29. #include <rasuip.h>
  30. #include "rasprocs.h"
  31. #include "table.h"
  32. #include "addrmap.h"
  33. #include "netmap.h"
  34. #include "imperson.h"
  35. #include "tapiproc.h"
  36. #include "access.h"
  37. #include "misc.h"
  38. #include "rtutils.h"
  39. //
  40. // Name of the event rasman.dll
  41. // signals whenever a connection
  42. // is created/destroyed.
  43. //
  44. #define CONNECTION_EVENT L"RasConnectionChangeEvent"
  45. //
  46. // Global variables
  47. //
  48. #if DBG
  49. DWORD AcsDebugG = 0x0; // flags defined in debug.h
  50. #endif
  51. DWORD dwModuleUsageG = 0;
  52. HANDLE hNewLogonUserG = NULL; // new user logged into the workstation
  53. HANDLE hNewFusG = NULL; // FUS caused a new user to get the console
  54. HANDLE hPnpEventG = NULL; // Pnp event notification
  55. HANDLE hLogoffUserG = NULL; // user logged off workstation
  56. HANDLE hLogoffUserDoneG = NULL; // HKEY_CURRENT_USER flushed
  57. HANDLE hTerminatingG = NULL; // service is terminating
  58. HANDLE hSharedConnectionG = NULL; // dial shared connection
  59. HANDLE hAddressMapThreadG = NULL; // AcsAddressMapThread()
  60. extern HANDLE hAutodialRegChangeG;
  61. HINSTANCE hinstDllG;
  62. LONG g_lRasAutoRunning = 0;
  63. HANDLE g_hLogEvent = NULL;
  64. DWORD g_dwCritSecFlags = 0;
  65. //
  66. // External variables
  67. //
  68. extern HANDLE hAcdG;
  69. extern IMPERSONATION_INFO ImpersonationInfoG;
  70. extern CRITICAL_SECTION csRasG;
  71. extern HKEY hkeyCUG;
  72. extern CRITICAL_SECTION csDisabledAddressesLockG;
  73. DWORD
  74. PnpRegister(
  75. IN BOOL fRegister);
  76. BOOLEAN
  77. WINAPI
  78. InitAcsDLL(
  79. HINSTANCE hinstDLL,
  80. DWORD fdwReason,
  81. LPVOID lpvReserved
  82. )
  83. /*++
  84. DESCRIPTION
  85. Initialize the implicit connection DLL. Dynamically load rasapi32.dll
  86. and rasman.dll, and initialize miscellaneous other things.
  87. ARGUMENTS
  88. hinstDLL:
  89. fdwReason:
  90. lpvReserved:
  91. RETURN VALUE
  92. Always TRUE.
  93. --*/
  94. {
  95. switch (fdwReason) {
  96. case DLL_PROCESS_ATTACH:
  97. if (hinstDllG == NULL)
  98. hinstDllG = hinstDLL;
  99. break;
  100. case DLL_THREAD_ATTACH:
  101. case DLL_THREAD_DETACH:
  102. break;
  103. case DLL_PROCESS_DETACH:
  104. break;
  105. }
  106. return TRUE;
  107. }
  108. DWORD
  109. AcsInitialize()
  110. {
  111. NTSTATUS status;
  112. DWORD dwErr, dwcDevices = 0;
  113. WSADATA wsaData;
  114. UNICODE_STRING nameString;
  115. IO_STATUS_BLOCK ioStatusBlock;
  116. OBJECT_ATTRIBUTES objectAttributes;
  117. DWORD dwThreadId;
  118. RasAutoDebugInit();
  119. do
  120. {
  121. hAcdG = NULL;
  122. g_dwCritSecFlags = 0;
  123. //
  124. // Initialize winsock.
  125. //
  126. dwErr = WSAStartup(MAKEWORD(2,0), &wsaData);
  127. if (dwErr) {
  128. RASAUTO_TRACE1("AcsInitialize: WSAStartup failed (dwErr=%d)",
  129. dwErr);
  130. break;
  131. }
  132. //
  133. // Load icmp.dll.
  134. //
  135. LoadIcmpDll();
  136. //
  137. // Initialize TAPI.
  138. //
  139. dwErr = TapiInitialize();
  140. if (dwErr)
  141. {
  142. RASAUTO_TRACE1("AcsInitialize: TapInitialize failed (dwErr=%d)",
  143. dwErr);
  144. break;
  145. }
  146. g_hLogEvent = RouterLogRegister(L"RASAUTO");
  147. if(NULL == g_hLogEvent)
  148. {
  149. dwErr = GetLastError();
  150. RASAUTO_TRACE1("AcsInitialize: RouterLogRegister failed 0x%x",
  151. dwErr);
  152. break;
  153. }
  154. //
  155. // Initialize the name of the implicit
  156. // connection device.
  157. //
  158. RtlInitUnicodeString(&nameString, ACD_DEVICE_NAME);
  159. //
  160. // Initialize the object attributes.
  161. //
  162. InitializeObjectAttributes(
  163. &objectAttributes,
  164. &nameString,
  165. OBJ_CASE_INSENSITIVE,
  166. (HANDLE)NULL,
  167. (PSECURITY_DESCRIPTOR)NULL);
  168. //
  169. // Open the automatic connection device.
  170. //
  171. status = NtCreateFile(
  172. &hAcdG,
  173. FILE_READ_DATA|FILE_WRITE_DATA,
  174. &objectAttributes,
  175. &ioStatusBlock,
  176. NULL,
  177. FILE_ATTRIBUTE_NORMAL,
  178. FILE_SHARE_READ|FILE_SHARE_WRITE,
  179. FILE_OPEN_IF,
  180. 0,
  181. NULL,
  182. 0);
  183. if (status != STATUS_SUCCESS)
  184. {
  185. RASAUTO_TRACE1(
  186. "AcsInitialize: NtCreateFile failed (status=0x%x)",
  187. status);
  188. dwErr = ERROR_BAD_DEVICE;
  189. break;
  190. }
  191. //
  192. // Create the event that userinit.exe signals
  193. // when a new user logs into the workstation.
  194. // Note we have to create a security descriptor
  195. // to make this event accessible by a normal user.
  196. //
  197. dwErr = InitSecurityAttribute();
  198. if (dwErr)
  199. {
  200. RASAUTO_TRACE1(
  201. "AcsInitialize: InitSecurityAttribute failed (dwErr=0x%x)",
  202. dwErr);
  203. break;
  204. }
  205. //
  206. // Create the events that are used for login/logout
  207. // notification. userinit.exe signals RasAutodialNewLogonUser
  208. // winlogon signals RasAutodialLogoffUser, and rasauto.dll
  209. // signals RasAutodialLogoffUserDone when it has completed
  210. // flushing HKEY_CURRENT_USER.
  211. //
  212. hNewLogonUserG = CreateEvent(&SecurityAttributeG,
  213. FALSE,
  214. FALSE,
  215. L"RasAutodialNewLogonUser");
  216. if (hNewLogonUserG == NULL)
  217. {
  218. RASAUTO_TRACE("AcsInitialize: CreateEvent (new user) failed");
  219. dwErr = GetLastError();
  220. break;
  221. }
  222. hNewFusG = CreateEvent(&SecurityAttributeG, FALSE, FALSE, NULL);
  223. if (hNewFusG == NULL)
  224. {
  225. RASAUTO_TRACE("AcsInitialize: CreateEvent (FUS) failed");
  226. dwErr = GetLastError();
  227. break;
  228. }
  229. hPnpEventG= CreateEvent(&SecurityAttributeG, FALSE, FALSE, NULL);
  230. if (hPnpEventG == NULL)
  231. {
  232. RASAUTO_TRACE("AcsInitialize: CreateEvent (hPnpEventG) failed");
  233. dwErr = GetLastError();
  234. break;
  235. }
  236. hLogoffUserG = CreateEvent(&SecurityAttributeG,
  237. FALSE,
  238. FALSE,
  239. L"RasAutodialLogoffUser");
  240. if (hLogoffUserG == NULL)
  241. {
  242. RASAUTO_TRACE("AcsInitialize: CreateEvent (logoff) failed");
  243. dwErr = GetLastError();
  244. break;
  245. }
  246. hLogoffUserDoneG = CreateEvent(&SecurityAttributeG,
  247. FALSE,
  248. FALSE,
  249. L"RasAutodialLogoffUserDone");
  250. if (hLogoffUserDoneG == NULL)
  251. {
  252. RASAUTO_TRACE("AcsInitialize: CreateEvent (logoff done) failed");
  253. dwErr = GetLastError();
  254. break;
  255. }
  256. //
  257. // Create an event to tell us when to dial the shared connection
  258. //
  259. hSharedConnectionG = CreateEventA(&SecurityAttributeG,
  260. FALSE,
  261. FALSE,
  262. RAS_AUTO_DIAL_SHARED_CONNECTION_EVENT);
  263. if (hSharedConnectionG == NULL)
  264. {
  265. RASAUTO_TRACE("AcsInitialize: CreateEvent failed");
  266. dwErr = GetLastError();
  267. break;
  268. }
  269. //
  270. // Create an event to give to rasapi32 to let
  271. // us know when a new RAS connection has been
  272. // created or destroyed.
  273. //
  274. hConnectionEventG = CreateEvent(NULL, FALSE, FALSE, NULL);
  275. if (hConnectionEventG == NULL)
  276. {
  277. RASAUTO_TRACE("AcsInitialize: CreateEvent failed");
  278. dwErr = GetLastError();
  279. break;
  280. }
  281. //
  282. // Create the event all threads wait
  283. // that notify them of termination.
  284. //
  285. hTerminatingG = CreateEvent(NULL, TRUE, FALSE, NULL);
  286. if (hTerminatingG == NULL)
  287. {
  288. RASAUTO_TRACE("AcsInitialize: CreateEvent failed");
  289. dwErr = GetLastError();
  290. break;
  291. }
  292. //
  293. // Initialize impersonation structures
  294. //
  295. dwErr = InitializeImpersonation();
  296. if (dwErr)
  297. {
  298. RASAUTO_TRACE1(
  299. "AcsInitialize: InitializeImpersonation failed (dwErr=0x%x)",
  300. dwErr);
  301. break;
  302. }
  303. //
  304. // Create critical section that protects the
  305. // RAS module structures.
  306. //
  307. RasInitializeCriticalSection(&csRasG, &dwErr);
  308. if(dwErr != ERROR_SUCCESS)
  309. {
  310. break;
  311. }
  312. g_dwCritSecFlags |= RASAUTO_CRITSEC_RASG;
  313. RasInitializeCriticalSection(&csDisabledAddressesLockG, &dwErr);
  314. if(dwErr != ERROR_SUCCESS)
  315. {
  316. break;
  317. }
  318. g_dwCritSecFlags |= RASAUTO_CRITSEC_DISABLEDADD;
  319. //
  320. // Create a thread to manage the addresses stored
  321. // in the registry.
  322. //
  323. if (!InitializeAddressMap())
  324. {
  325. RASAUTO_TRACE("AcsInitialize: InitializeAddressMap failed");
  326. dwErr = ERROR_OUTOFMEMORY;
  327. break;
  328. }
  329. if (!InitializeNetworkMap())
  330. {
  331. RASAUTO_TRACE("AcsInitialize: InitializeNetworkMap failed");
  332. dwErr = ERROR_OUTOFMEMORY;
  333. break;
  334. }
  335. hAddressMapThreadG = CreateThread(
  336. NULL,
  337. 10000L,
  338. (LPTHREAD_START_ROUTINE)AcsAddressMapThread,
  339. 0,
  340. 0,
  341. &dwThreadId);
  342. if (hAddressMapThreadG == NULL)
  343. {
  344. dwErr = GetLastError();
  345. RASAUTO_TRACE1(
  346. "AcsInitialize: CreateThread failed (error=0x%x)",
  347. dwErr);
  348. break;
  349. }
  350. // XP 364593
  351. //
  352. // Register for pnp not. Ignore the return value -- if we error,
  353. // then we simply wont react when a lan adapter comes/goes.
  354. // It's not worth letting that stop us.
  355. //
  356. PnpRegister(TRUE);
  357. return ERROR_SUCCESS;
  358. }
  359. while(FALSE);
  360. //
  361. // Cleanup in case of error.
  362. //
  363. TapiShutdown();
  364. if(g_dwCritSecFlags & RASAUTO_CRITSEC_RASG)
  365. {
  366. DeleteCriticalSection(&csRasG);
  367. g_dwCritSecFlags &= ~(RASAUTO_CRITSEC_RASG);
  368. }
  369. if(g_dwCritSecFlags & RASAUTO_CRITSEC_DISABLEDADD)
  370. {
  371. DeleteCriticalSection(&csDisabledAddressesLockG);
  372. g_dwCritSecFlags &= ~(RASAUTO_CRITSEC_DISABLEDADD);
  373. }
  374. if(NULL != g_hLogEvent)
  375. {
  376. RouterLogDeregister(g_hLogEvent);
  377. g_hLogEvent = NULL;
  378. }
  379. if(NULL != hAcdG)
  380. {
  381. CloseHandle(hAcdG);
  382. hAcdG = NULL;
  383. }
  384. if(NULL != hNewLogonUserG)
  385. {
  386. CloseHandle(hNewLogonUserG);
  387. hNewLogonUserG = NULL;
  388. }
  389. if(NULL != hNewFusG)
  390. {
  391. CloseHandle(hNewFusG);
  392. hNewFusG = NULL;
  393. }
  394. if(NULL != hPnpEventG)
  395. {
  396. CloseHandle(hPnpEventG);
  397. hPnpEventG = NULL;
  398. }
  399. if(NULL != hLogoffUserG)
  400. {
  401. CloseHandle(hLogoffUserG);
  402. hLogoffUserG = NULL;
  403. }
  404. if(NULL != hLogoffUserDoneG)
  405. {
  406. CloseHandle(hLogoffUserDoneG);
  407. hLogoffUserDoneG = NULL;
  408. }
  409. if(NULL != hSharedConnectionG)
  410. {
  411. CloseHandle(hSharedConnectionG);
  412. hSharedConnectionG = NULL;
  413. }
  414. if(NULL != hConnectionEventG)
  415. {
  416. CloseHandle(hConnectionEventG);
  417. hConnectionEventG = NULL;
  418. }
  419. if(NULL != hTerminatingG)
  420. {
  421. CloseHandle(hTerminatingG);
  422. hTerminatingG = NULL;
  423. }
  424. return dwErr;
  425. } // AcsInitialize
  426. VOID
  427. AcsTerminate()
  428. {
  429. //
  430. // Signal other threads to exit.
  431. // The main service controller
  432. // thread AcsDoService() will
  433. // call WaitForAllThreads().
  434. //
  435. SetEvent(hTerminatingG);
  436. } // AcsTerminate
  437. VOID
  438. WaitForAllThreads()
  439. {
  440. RASAUTO_TRACE("WaitForAllThreads: waiting for all threads to terminate");
  441. //
  442. // Wait for them to exit.
  443. //
  444. WaitForSingleObject(hAddressMapThreadG, INFINITE);
  445. //
  446. // Unload icmp.dll.
  447. //
  448. UnloadIcmpDll();
  449. //
  450. // Cleanup.
  451. //
  452. // PrepareForLongWait();
  453. CloseHandle(hAddressMapThreadG);
  454. RASAUTO_TRACE("WaitForAllThreads: all threads terminated");
  455. }
  456. VOID
  457. AcsCleanupUser()
  458. /*++
  459. DESCRIPTION
  460. Unload all resources associated with the currently
  461. logged-in user.
  462. ARGUMENTS
  463. None.
  464. RETURN VALUE
  465. None.
  466. --*/
  467. {
  468. if(NULL != hkeyCUG)
  469. {
  470. NtClose(hkeyCUG);
  471. hkeyCUG = NULL;
  472. }
  473. } // AcsCleanupUser
  474. VOID
  475. AcsCleanup()
  476. /*++
  477. DESCRIPTION
  478. Unload all resources associated with the entire
  479. service.
  480. ARGUMENTS
  481. None.
  482. RETURN VALUE
  483. None.
  484. --*/
  485. {
  486. //
  487. // Stop receiving pnp events
  488. //
  489. PnpRegister(FALSE);
  490. //
  491. // Unload per-user resources.
  492. //
  493. // AcsCleanupUser();
  494. //
  495. // We're terminating. Wait for the
  496. // other threads.
  497. //
  498. WaitForAllThreads();
  499. //
  500. // Shutdown TAPI.
  501. //
  502. TapiShutdown();
  503. //
  504. // We've terminated. Free resources.
  505. //
  506. CloseHandle(hAcdG);
  507. //
  508. // For now, unload rasman.dll only when
  509. // we are about to go away.
  510. //
  511. //
  512. // Close all event handles
  513. //
  514. if(NULL != hNewLogonUserG)
  515. {
  516. CloseHandle(hNewLogonUserG);
  517. hNewLogonUserG = NULL;
  518. }
  519. if(NULL != hNewFusG)
  520. {
  521. CloseHandle(hNewFusG);
  522. hNewFusG = NULL;
  523. }
  524. if(NULL != hPnpEventG)
  525. {
  526. CloseHandle(hPnpEventG);
  527. hPnpEventG = NULL;
  528. }
  529. if(NULL != hLogoffUserG)
  530. {
  531. CloseHandle(hLogoffUserG);
  532. hLogoffUserG = NULL;
  533. }
  534. if(NULL != hLogoffUserDoneG)
  535. {
  536. CloseHandle(hLogoffUserDoneG);
  537. hLogoffUserDoneG = NULL;
  538. }
  539. if(NULL != hSharedConnectionG)
  540. {
  541. CloseHandle(hSharedConnectionG);
  542. hSharedConnectionG = NULL;
  543. }
  544. if(NULL != hConnectionEventG)
  545. {
  546. CloseHandle(hConnectionEventG);
  547. hConnectionEventG = NULL;
  548. }
  549. if(NULL != hTerminatingG)
  550. {
  551. CloseHandle(hTerminatingG);
  552. hTerminatingG = NULL;
  553. }
  554. if(NULL != hAutodialRegChangeG)
  555. {
  556. CloseHandle(hAutodialRegChangeG);
  557. hAutodialRegChangeG = NULL;
  558. }
  559. if(NULL != g_hLogEvent)
  560. {
  561. RouterLogDeregister(g_hLogEvent);
  562. g_hLogEvent = NULL;
  563. }
  564. {
  565. LONG l;
  566. l = InterlockedDecrement(&g_lRasAutoRunning);
  567. {
  568. // DbgPrint("RASAUTO: AcsCleanup - lrasautorunning=%d\n", l);
  569. }
  570. ASSERT(l == 0);
  571. }
  572. //
  573. // Revert impersonation before cleaning up
  574. //
  575. RevertImpersonation();
  576. //
  577. // Cleanup impersonation structures
  578. //
  579. CleanupImpersonation();
  580. //
  581. // Uninitialize addressmap
  582. //
  583. UninitializeAddressMap();
  584. if(g_dwCritSecFlags & RASAUTO_CRITSEC_DISABLEDADD)
  585. {
  586. DeleteCriticalSection(&csDisabledAddressesLockG);
  587. g_dwCritSecFlags &= ~(RASAUTO_CRITSEC_DISABLEDADD);
  588. }
  589. //
  590. // UninitializeNetworkmap
  591. //
  592. UninitializeNetworkMap();
  593. RasAutoDebugTerm();
  594. UnloadRasDlls();
  595. if(g_dwCritSecFlags & RASAUTO_CRITSEC_RASG)
  596. {
  597. DeleteCriticalSection(&csRasG);
  598. g_dwCritSecFlags &= ~(RASAUTO_CRITSEC_RASG);
  599. }
  600. } // AcsCleanup