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.

556 lines
12 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. //
  65. // External variables
  66. //
  67. extern HANDLE hAcdG;
  68. extern IMPERSONATION_INFO ImpersonationInfoG;
  69. extern CRITICAL_SECTION csRasG;
  70. extern HKEY hkeyCUG;
  71. extern CRITICAL_SECTION csDisabledAddressesLockG;
  72. DWORD
  73. PnpRegister(
  74. IN BOOL fRegister);
  75. BOOLEAN
  76. WINAPI
  77. InitAcsDLL(
  78. HINSTANCE hinstDLL,
  79. DWORD fdwReason,
  80. LPVOID lpvReserved
  81. )
  82. /*++
  83. DESCRIPTION
  84. Initialize the implicit connection DLL. Dynamically load rasapi32.dll
  85. and rasman.dll, and initialize miscellaneous other things.
  86. ARGUMENTS
  87. hinstDLL:
  88. fdwReason:
  89. lpvReserved:
  90. RETURN VALUE
  91. Always TRUE.
  92. --*/
  93. {
  94. switch (fdwReason) {
  95. case DLL_PROCESS_ATTACH:
  96. if (hinstDllG == NULL)
  97. hinstDllG = hinstDLL;
  98. break;
  99. case DLL_THREAD_ATTACH:
  100. case DLL_THREAD_DETACH:
  101. break;
  102. case DLL_PROCESS_DETACH:
  103. break;
  104. }
  105. return TRUE;
  106. }
  107. DWORD
  108. AcsInitialize()
  109. {
  110. NTSTATUS status;
  111. DWORD dwErr, dwcDevices = 0;
  112. WSADATA wsaData;
  113. UNICODE_STRING nameString;
  114. IO_STATUS_BLOCK ioStatusBlock;
  115. OBJECT_ATTRIBUTES objectAttributes;
  116. DWORD dwThreadId;
  117. RasAutoDebugInit();
  118. //
  119. // Initialize winsock.
  120. //
  121. dwErr = WSAStartup(MAKEWORD(2,0), &wsaData);
  122. if (dwErr) {
  123. RASAUTO_TRACE1("AcsInitialize: WSAStartup failed (dwErr=%d)", dwErr);
  124. return dwErr;
  125. }
  126. //
  127. // Load icmp.dll.
  128. //
  129. LoadIcmpDll();
  130. //
  131. // Initialize TAPI.
  132. //
  133. dwErr = TapiInitialize();
  134. if (dwErr) {
  135. RASAUTO_TRACE1("AcsInitialize: TapInitialize failed (dwErr=%d)", dwErr);
  136. return dwErr;
  137. }
  138. g_hLogEvent = RouterLogRegister(L"RASAUTO");
  139. if(NULL == g_hLogEvent)
  140. {
  141. dwErr = GetLastError();
  142. RASAUTO_TRACE1("AcsInitialize: RouterLogRegister failed 0x%x", dwErr);
  143. return dwErr;
  144. }
  145. //
  146. // Initialize the name of the implicit
  147. // connection device.
  148. //
  149. RtlInitUnicodeString(&nameString, ACD_DEVICE_NAME);
  150. //
  151. // Initialize the object attributes.
  152. //
  153. InitializeObjectAttributes(
  154. &objectAttributes,
  155. &nameString,
  156. OBJ_CASE_INSENSITIVE,
  157. (HANDLE)NULL,
  158. (PSECURITY_DESCRIPTOR)NULL);
  159. //
  160. // Open the automatic connection device.
  161. //
  162. status = NtCreateFile(
  163. &hAcdG,
  164. FILE_READ_DATA|FILE_WRITE_DATA,
  165. &objectAttributes,
  166. &ioStatusBlock,
  167. NULL,
  168. FILE_ATTRIBUTE_NORMAL,
  169. FILE_SHARE_READ|FILE_SHARE_WRITE,
  170. FILE_OPEN_IF,
  171. 0,
  172. NULL,
  173. 0);
  174. if (status != STATUS_SUCCESS) {
  175. RASAUTO_TRACE1(
  176. "AcsInitialize: NtCreateFile failed (status=0x%x)",
  177. status);
  178. return ERROR_BAD_DEVICE;
  179. }
  180. //
  181. // Create the event that userinit.exe signals
  182. // when a new user logs into the workstation.
  183. // Note we have to create a security descriptor
  184. // to make this event accessible by a normal user.
  185. //
  186. dwErr = InitSecurityAttribute();
  187. if (dwErr) {
  188. RASAUTO_TRACE1(
  189. "AcsInitialize: InitSecurityAttribute failed (dwErr=0x%x)",
  190. dwErr);
  191. return dwErr;
  192. }
  193. //
  194. // Create the events that are used for login/logout
  195. // notification. userinit.exe signals RasAutodialNewLogonUser
  196. // winlogon signals RasAutodialLogoffUser, and rasauto.dll
  197. // signals RasAutodialLogoffUserDone when it has completed
  198. // flushing HKEY_CURRENT_USER.
  199. //
  200. hNewLogonUserG = CreateEvent(&SecurityAttributeG, FALSE, FALSE, L"RasAutodialNewLogonUser");
  201. if (hNewLogonUserG == NULL) {
  202. RASAUTO_TRACE("AcsInitialize: CreateEvent (new user) failed");
  203. return GetLastError();
  204. }
  205. hNewFusG = CreateEvent(&SecurityAttributeG, FALSE, FALSE, NULL);
  206. if (hNewFusG == NULL) {
  207. RASAUTO_TRACE("AcsInitialize: CreateEvent (FUS) failed");
  208. return GetLastError();
  209. }
  210. hPnpEventG= CreateEvent(&SecurityAttributeG, FALSE, FALSE, NULL);
  211. if (hPnpEventG == NULL) {
  212. RASAUTO_TRACE("AcsInitialize: CreateEvent (hPnpEventG) failed");
  213. return GetLastError();
  214. }
  215. hLogoffUserG = CreateEvent(&SecurityAttributeG, FALSE, FALSE, L"RasAutodialLogoffUser");
  216. if (hLogoffUserG == NULL) {
  217. RASAUTO_TRACE("AcsInitialize: CreateEvent (logoff) failed");
  218. return GetLastError();
  219. }
  220. hLogoffUserDoneG = CreateEvent(&SecurityAttributeG, FALSE, FALSE, L"RasAutodialLogoffUserDone");
  221. if (hLogoffUserDoneG == NULL) {
  222. RASAUTO_TRACE("AcsInitialize: CreateEvent (logoff done) failed");
  223. return GetLastError();
  224. }
  225. //
  226. // Create an event to tell us when to dial the shared connection
  227. //
  228. hSharedConnectionG = CreateEventA(&SecurityAttributeG, FALSE, FALSE, RAS_AUTO_DIAL_SHARED_CONNECTION_EVENT);
  229. if (hSharedConnectionG == NULL) {
  230. RASAUTO_TRACE("AcsInitialize: CreateEvent failed");
  231. return GetLastError();
  232. }
  233. //
  234. // Create an event to give to rasapi32 to let
  235. // us know when a new RAS connection has been
  236. // created or destroyed.
  237. //
  238. hConnectionEventG = CreateEvent(NULL, FALSE, FALSE, NULL);
  239. if (hConnectionEventG == NULL) {
  240. RASAUTO_TRACE("AcsInitialize: CreateEvent failed");
  241. return GetLastError();
  242. }
  243. //
  244. // Create the event all threads wait
  245. // that notify them of termination.
  246. //
  247. hTerminatingG = CreateEvent(NULL, TRUE, FALSE, NULL);
  248. if (hTerminatingG == NULL) {
  249. RASAUTO_TRACE("AcsInitialize: CreateEvent failed");
  250. return GetLastError();
  251. }
  252. //
  253. // Initialize impersonation structures
  254. //
  255. dwErr = InitializeImpersonation();
  256. if (dwErr) {
  257. RASAUTO_TRACE1(
  258. "AcsInitialize: InitializeImpersonation failed (dwErr=0x%x)",
  259. dwErr);
  260. return dwErr;
  261. }
  262. //
  263. // Create critical section that protects the
  264. // RAS module structures.
  265. //
  266. InitializeCriticalSection(&csRasG);
  267. InitializeCriticalSection(&csDisabledAddressesLockG);
  268. //
  269. // Create a thread to manage the addresses stored
  270. // in the registry.
  271. //
  272. if (!InitializeAddressMap()) {
  273. RASAUTO_TRACE("AcsInitialize: InitializeAddressMap failed");
  274. return ERROR_OUTOFMEMORY; // just guessing
  275. }
  276. if (!InitializeNetworkMap()) {
  277. RASAUTO_TRACE("AcsInitialize: InitializeNetworkMap failed");
  278. return ERROR_OUTOFMEMORY; // just guessing
  279. }
  280. hAddressMapThreadG = CreateThread(
  281. NULL,
  282. 10000L,
  283. (LPTHREAD_START_ROUTINE)AcsAddressMapThread,
  284. 0,
  285. 0,
  286. &dwThreadId);
  287. if (hAddressMapThreadG == NULL) {
  288. RASAUTO_TRACE1(
  289. "AcsInitialize: CreateThread failed (error=0x%x)",
  290. GetLastError());
  291. return GetLastError();
  292. }
  293. // XP 364593
  294. //
  295. // Register for pnp not. Ignore the return value -- if we error, then
  296. // we simply wont react when a lan adapter comes/goes. It's not worth
  297. // letting that stop us.
  298. //
  299. PnpRegister(TRUE);
  300. return ERROR_SUCCESS;
  301. } // AcsInitialize
  302. VOID
  303. AcsTerminate()
  304. {
  305. //
  306. // Signal other threads to exit.
  307. // The main service controller
  308. // thread AcsDoService() will
  309. // call WaitForAllThreads().
  310. //
  311. SetEvent(hTerminatingG);
  312. } // AcsTerminate
  313. VOID
  314. WaitForAllThreads()
  315. {
  316. RASAUTO_TRACE("WaitForAllThreads: waiting for all threads to terminate");
  317. //
  318. // Wait for them to exit.
  319. //
  320. WaitForSingleObject(hAddressMapThreadG, INFINITE);
  321. //
  322. // Unload icmp.dll.
  323. //
  324. UnloadIcmpDll();
  325. //
  326. // Cleanup.
  327. //
  328. // PrepareForLongWait();
  329. CloseHandle(hAddressMapThreadG);
  330. RASAUTO_TRACE("WaitForAllThreads: all threads terminated");
  331. }
  332. VOID
  333. AcsCleanupUser()
  334. /*++
  335. DESCRIPTION
  336. Unload all resources associated with the currently
  337. logged-in user.
  338. ARGUMENTS
  339. None.
  340. RETURN VALUE
  341. None.
  342. --*/
  343. {
  344. if(NULL != hkeyCUG)
  345. {
  346. NtClose(hkeyCUG);
  347. hkeyCUG = NULL;
  348. }
  349. } // AcsCleanupUser
  350. VOID
  351. AcsCleanup()
  352. /*++
  353. DESCRIPTION
  354. Unload all resources associated with the entire
  355. service.
  356. ARGUMENTS
  357. None.
  358. RETURN VALUE
  359. None.
  360. --*/
  361. {
  362. //
  363. // Stop receiving pnp events
  364. //
  365. PnpRegister(FALSE);
  366. //
  367. // Unload per-user resources.
  368. //
  369. AcsCleanupUser();
  370. //
  371. // We're terminating. Wait for the
  372. // other threads.
  373. //
  374. WaitForAllThreads();
  375. //
  376. // Shutdown TAPI.
  377. //
  378. TapiShutdown();
  379. //
  380. // We've terminated. Free resources.
  381. //
  382. CloseHandle(hAcdG);
  383. //
  384. // For now, unload rasman.dll only when
  385. // we are about to go away.
  386. //
  387. //
  388. // Close all event handles
  389. //
  390. if(NULL != hNewLogonUserG)
  391. {
  392. CloseHandle(hNewLogonUserG);
  393. hNewLogonUserG = NULL;
  394. }
  395. if(NULL != hNewFusG)
  396. {
  397. CloseHandle(hNewFusG);
  398. hNewFusG = NULL;
  399. }
  400. if(NULL != hPnpEventG)
  401. {
  402. CloseHandle(hPnpEventG);
  403. hPnpEventG = NULL;
  404. }
  405. if(NULL != hLogoffUserG)
  406. {
  407. CloseHandle(hLogoffUserG);
  408. hLogoffUserG = NULL;
  409. }
  410. if(NULL != hLogoffUserDoneG)
  411. {
  412. CloseHandle(hLogoffUserDoneG);
  413. hLogoffUserDoneG = NULL;
  414. }
  415. if(NULL != hSharedConnectionG)
  416. {
  417. CloseHandle(hSharedConnectionG);
  418. hSharedConnectionG = NULL;
  419. }
  420. if(NULL != hConnectionEventG)
  421. {
  422. CloseHandle(hConnectionEventG);
  423. hConnectionEventG = NULL;
  424. }
  425. if(NULL != hTerminatingG)
  426. {
  427. CloseHandle(hTerminatingG);
  428. hTerminatingG = NULL;
  429. }
  430. if(NULL != hAutodialRegChangeG)
  431. {
  432. CloseHandle(hAutodialRegChangeG);
  433. hAutodialRegChangeG = NULL;
  434. }
  435. if(NULL != g_hLogEvent)
  436. {
  437. RouterLogDeregister(g_hLogEvent);
  438. g_hLogEvent = NULL;
  439. }
  440. {
  441. LONG l;
  442. l = InterlockedDecrement(&g_lRasAutoRunning);
  443. {
  444. // DbgPrint("RASAUTO: AcsCleanup - lrasautorunning=%d\n", l);
  445. }
  446. ASSERT(l == 0);
  447. }
  448. //
  449. // Revert impersonation before cleaning up
  450. //
  451. RevertImpersonation();
  452. //
  453. // Cleanup impersonation structures
  454. //
  455. CleanupImpersonation();
  456. //
  457. // Uninitialize addressmap
  458. //
  459. UninitializeAddressMap();
  460. DeleteCriticalSection(&csDisabledAddressesLockG);
  461. //
  462. // UninitializeNetworkmap
  463. //
  464. UninitializeNetworkMap();
  465. RasAutoDebugTerm();
  466. UnloadRasDlls();
  467. } // AcsCleanup