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.

496 lines
9.1 KiB

  1. /*++
  2. Copyright (c) 2000-2001 Microsoft Corporation
  3. Module Name:
  4. dll.c
  5. Abstract:
  6. Domain Name System (DNS) API
  7. Dnsapi.dll basic DLL infrastructure (init, shutdown, etc)
  8. Author:
  9. Jim Gilroy (jamesg) April 2000
  10. Revision History:
  11. --*/
  12. #include "local.h"
  13. //
  14. // Global Definitions
  15. //
  16. HINSTANCE g_hInstanceDll;
  17. //
  18. // Initialization level
  19. //
  20. DWORD g_InitLevel = 0;
  21. //
  22. // General purpose CS
  23. // Protects init and any other small scale uses
  24. //
  25. CRITICAL_SECTION g_GeneralCS;
  26. //
  27. // Initialization and cleanup
  28. //
  29. BOOL
  30. startInit(
  31. VOID
  32. )
  33. /*++
  34. Routine Description:
  35. Minimum DLL init at process attach.
  36. Arguments:
  37. None
  38. Return Value:
  39. TRUE if successful.
  40. FALSE otherwise.
  41. --*/
  42. {
  43. //
  44. // DCR_PERF: simplified init -- simple Interlock
  45. // then all external calls, must test the flag
  46. // if not set do the real init (then set flag)
  47. //
  48. // note: init function itself must have a dumb
  49. // wait to avoid race; this can be as simple
  50. // as sleep\test loop
  51. //
  52. // multilevel init:
  53. // have a bunch of levels of init
  54. // - query (registry stuff)
  55. // - update
  56. // - secure update
  57. //
  58. // call would add the init for the level required
  59. // this would need to be done under a lock to
  60. // test, take lock, retest
  61. //
  62. // could either take one CS on all inits (simple)
  63. // or init only brings stuff on line
  64. //
  65. InitializeCriticalSection( &g_GeneralCS );
  66. // for debug, note that we've gotten this far
  67. g_InitLevel = INITLEVEL_BASE;
  68. // tracing init
  69. Trace_Initialize();
  70. //
  71. // DCR_PERF: fast DLL init
  72. //
  73. // currently initializing everything -- like we did before
  74. // once we get init routines (macro'd) in interfaces we
  75. // can drop this
  76. //
  77. return DnsApiInit( INITLEVEL_ALL );
  78. }
  79. BOOL
  80. DnsApiInit(
  81. IN DWORD InitLevel
  82. )
  83. /*++
  84. Routine Description:
  85. Initialize the DLL for some level of use.
  86. The idea here is to avoid all the init and registry
  87. reading for processes that don't need it.
  88. Only insure initialization to the level required.
  89. Arguments:
  90. InitLevel -- level of initialization required.
  91. Return Value:
  92. TRUE if desired initialization is successful.
  93. FALSE otherwise.
  94. --*/
  95. {
  96. //
  97. // DCR_PERF: simplified init -- simple Interlock
  98. // then all external calls, must test the flag
  99. // if not set do the real init (then set flag)
  100. //
  101. // note: init function itself must have a dumb
  102. // wait to avoid race; this can be as simple
  103. // as sleep\test loop
  104. //
  105. // multilevel init:
  106. // have a bunch of levels of init
  107. // - query (registry stuff)
  108. // - update
  109. // - secure update
  110. //
  111. // call would add the init for the level required
  112. // this would need to be done under a lock to
  113. // test, take lock, retest
  114. //
  115. // could either take one CS on all inits (simple)
  116. // or init only brings stuff on line
  117. //
  118. //
  119. // check if already initialized to required level
  120. // => if there we're done
  121. //
  122. // note: could check after lock for MT, but not
  123. // unlikely and not much perf benefit over
  124. // individual checks
  125. //
  126. if ( (g_InitLevel & InitLevel) == InitLevel )
  127. {
  128. return( TRUE );
  129. }
  130. EnterCriticalSection( &g_GeneralCS );
  131. //
  132. // heap
  133. //
  134. Heap_Initialize();
  135. #if DBG
  136. //
  137. // init debug logging
  138. // - do for any process beyond simple attach
  139. //
  140. // start logging with log filename generated to be
  141. // unique for this process
  142. //
  143. // do NOT put drive specification in the file path
  144. // do NOT set the debug flag -- the flag is read from the dnsapi.flag file
  145. //
  146. if ( !(g_InitLevel & INITLEVEL_DEBUG) )
  147. {
  148. CHAR szlogFileName[ 30 ];
  149. sprintf(
  150. szlogFileName,
  151. "dnsapi.%d.log",
  152. GetCurrentProcessId() );
  153. Dns_StartDebug(
  154. 0,
  155. "dnsapi.flag",
  156. NULL,
  157. szlogFileName,
  158. 0 );
  159. g_InitLevel = INITLEVEL_DEBUG;
  160. }
  161. #endif
  162. //
  163. // general query service
  164. // - need registry info
  165. // - need adapter list info (servlist.c)
  166. //
  167. // DCR: even query level doesn't need full registry info
  168. // if either queries through cache OR gets netinfo from cache
  169. //
  170. // note: do NOT initialize winsock here
  171. // WSAStartup() in dll init routine is strictly verboten
  172. //
  173. if ( (InitLevel & INITLEVEL_QUERY) &&
  174. !(g_InitLevel & INITLEVEL_QUERY) )
  175. {
  176. DNS_STATUS status;
  177. //
  178. // Init registry lookup
  179. //
  180. status = Reg_ReadGlobalsEx( 0, NULL );
  181. if ( status != ERROR_SUCCESS )
  182. {
  183. ASSERT( FALSE );
  184. goto Failed;
  185. }
  186. //
  187. // net failure caching
  188. //
  189. InitializeCriticalSection( &g_NetFailureCS );
  190. g_NetFailureTime = 0;
  191. g_NetFailureStatus = ERROR_SUCCESS;
  192. //
  193. // init CS to protect adapter list global
  194. //
  195. InitNetworkInfo();
  196. //
  197. // set the query timeouts
  198. //
  199. Dns_InitQueryTimeouts();
  200. // indicate query init complete
  201. g_InitLevel |= INITLEVEL_QUERY;
  202. DNSDBG( INIT, ( "Query\\Config init is complete.\n" ));
  203. }
  204. //
  205. // registration services
  206. //
  207. if ( (InitLevel & INITLEVEL_REGISTRATION) &&
  208. !(g_InitLevel & INITLEVEL_REGISTRATION) )
  209. {
  210. InitializeCriticalSection( &g_RegistrationListCS );
  211. InitializeCriticalSection( &g_QueueCS );
  212. InitializeCriticalSection( &g_RegistrationThreadCS );
  213. g_InitLevel |= INITLEVEL_REGISTRATION;
  214. DNSDBG( INIT, ( "Registration init is complete.\n" ));
  215. }
  216. //
  217. // secure update?
  218. // - init security CS
  219. // note, this already has built in protection -- it doesn't init
  220. // the package, just the CS, which protects package init
  221. //
  222. if ( (InitLevel & INITLEVEL_SECURE_UPDATE) &&
  223. !(g_InitLevel & INITLEVEL_SECURE_UPDATE ) )
  224. {
  225. Dns_StartSecurity( TRUE );
  226. g_InitLevel |= INITLEVEL_SECURE_UPDATE;
  227. DNSDBG( INIT, ( "Secure update init is complete.\n" ));
  228. }
  229. //
  230. // clear global CS
  231. //
  232. LeaveCriticalSection( &g_GeneralCS );
  233. return( TRUE );
  234. Failed:
  235. LeaveCriticalSection( &g_GeneralCS );
  236. return( FALSE );
  237. }
  238. VOID
  239. cleanupForExit(
  240. VOID
  241. )
  242. /*++
  243. Routine Description:
  244. Cleanup for DLL unload.
  245. Cleanup memory and handles dnsapi.dll allocated.
  246. Arguments:
  247. None.
  248. Return Value:
  249. None.
  250. --*/
  251. {
  252. //
  253. // unload security packages used by secure dynamic update.
  254. //
  255. if ( g_InitLevel & INITLEVEL_SECURE_UPDATE )
  256. {
  257. Dns_TerminateSecurityPackage();
  258. }
  259. //
  260. // registration stuff
  261. //
  262. if ( g_InitLevel & INITLEVEL_REGISTRATION )
  263. {
  264. DeleteCriticalSection( &g_QueueCS );
  265. DeleteCriticalSection( &g_RegistrationListCS );
  266. DeleteCriticalSection( &g_RegistrationThreadCS );
  267. }
  268. //
  269. // query stuff
  270. //
  271. if ( g_InitLevel & INITLEVEL_QUERY )
  272. {
  273. //
  274. // clean up Server/Net Adapter lists
  275. //
  276. CleanupNetworkInfo();
  277. Dns_CacheSocketCleanup();
  278. Dns_CleanupWinsock();
  279. if ( g_pwsRemoteResolver )
  280. {
  281. FREE_HEAP( g_pwsRemoteResolver );
  282. }
  283. DeleteCriticalSection( &g_NetFailureCS );
  284. }
  285. //
  286. // unload IP Help
  287. //
  288. IpHelp_Cleanup();
  289. //
  290. // tracing
  291. //
  292. Trace_Cleanup();
  293. //
  294. // cleanup heap
  295. //
  296. Heap_Cleanup();
  297. //
  298. // kill general CS
  299. //
  300. DeleteCriticalSection( &g_GeneralCS );
  301. g_InitLevel = 0;
  302. }
  303. //
  304. // Main dnsapi.dll routines
  305. //
  306. __declspec(dllexport)
  307. BOOL
  308. WINAPI
  309. DnsDllInit(
  310. IN HINSTANCE hInstance,
  311. IN DWORD Reason,
  312. IN PVOID pReserved
  313. )
  314. /*++
  315. Routine Description:
  316. Dll attach entry point.
  317. Arguments:
  318. hinstDll -- instance handle of attach
  319. Reason -- reason for attach
  320. DLL_PROCESS_ATTACH, DLL_PROCESS_DETACH, etc.
  321. Reserved -- unused
  322. Return Value:
  323. TRUE if successful.
  324. FALSE on error.
  325. --*/
  326. {
  327. //
  328. // on process attach
  329. // - disable thread notifications
  330. // - save instance handle
  331. // - do minimum DLL initialization
  332. //
  333. if ( Reason == DLL_PROCESS_ATTACH )
  334. {
  335. if ( ! DisableThreadLibraryCalls( hInstance ) )
  336. {
  337. return( FALSE );
  338. }
  339. g_hInstanceDll = hInstance;
  340. return startInit();
  341. }
  342. //
  343. // on process detach
  344. // - cleanup IF pReserved==NULL which indicates detach due
  345. // to FreeLibrary
  346. // - if process is exiting do nothing
  347. //
  348. if ( Reason == DLL_PROCESS_DETACH
  349. &&
  350. pReserved == NULL )
  351. {
  352. cleanupForExit();
  353. }
  354. return TRUE;
  355. }
  356. //
  357. // End dll.c
  358. //