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.

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