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.

334 lines
7.0 KiB

  1. //==========================================================================
  2. // Copyright (c) 1995, Microsoft Corporation
  3. //
  4. // File: entry.c
  5. //
  6. // History:
  7. // t-abolag 06-21-95 Created.
  8. //
  9. // entry point for Routing Table API set
  10. //==========================================================================
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #include <time.h>
  14. #include <ctype.h>
  15. #ifndef CHICAGO
  16. #include <nt.h>
  17. #include <ntrtl.h>
  18. #include <nturtl.h>
  19. #endif
  20. #include <windows.h>
  21. #include <winsock.h>
  22. #include <string.h>
  23. #include <errno.h>
  24. #include <process.h>
  25. #include <malloc.h>
  26. #include <io.h>
  27. #include <winsvc.h>
  28. #include "ipinfo.h"
  29. #include "llinfo.h"
  30. #include "ntddtcp.h"
  31. #include "tdiinfo.h"
  32. #include "dhcpcapi.h"
  33. #include "routetab.h"
  34. #include "rtdefs.h"
  35. BOOL
  36. WINAPI
  37. LIBMAIN(
  38. IN HINSTANCE hInstance,
  39. IN DWORD dwReason,
  40. IN LPVOID lpvUnused
  41. )
  42. {
  43. BOOL bError = TRUE;
  44. switch(dwReason) {
  45. case DLL_PROCESS_ATTACH: {
  46. DEBUG_PRINT(("LIBMAIN: DLL_PROCESS_ATTACH\n"));
  47. //
  48. // we have no per-thread initialization,
  49. // so disable DLL_THREAD_{ATTACH,DETACH} calls
  50. //
  51. DisableThreadLibraryCalls(hInstance);
  52. //
  53. // initialize globals and background thread
  54. //
  55. bError = RTStartup((HMODULE)hInstance);
  56. break;
  57. }
  58. case DLL_PROCESS_DETACH: {
  59. //
  60. // if the background thread is around, tell it to clean up;
  61. // otherwise clean up ourselves
  62. //
  63. bError = RTShutdown((HMODULE)hInstance);
  64. break;
  65. }
  66. }
  67. DEBUG_PRINT(("LIBMAIN: <= %d\n", bError ));
  68. return bError;
  69. }
  70. //----------------------------------------------------------------------------
  71. // Function: RTStartup
  72. //
  73. // Handles initialization for DLL-wide data
  74. //----------------------------------------------------------------------------
  75. BOOL
  76. RTStartup(
  77. HMODULE hmodule
  78. )
  79. {
  80. HANDLE hThread;
  81. DWORD dwErr, dwThread;
  82. SECURITY_ATTRIBUTES saAttr;
  83. SECURITY_DESCRIPTOR sdDesc;
  84. CHAR szModule[MAX_PATH + 1];
  85. g_prtcfg = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*g_prtcfg));
  86. if (g_prtcfg == NULL){
  87. DEBUG_PRINT(("RTStartup: !HeapAlloc \n"));
  88. return FALSE;
  89. }
  90. do {
  91. //
  92. // We do a loadlibrary to increment the reference count
  93. // on this library, so that when the library is unloaded
  94. // by the application, our address-space doesn't disappear.
  95. // Instead, we signal the thread and then we cleanup
  96. // and call FreeLibraryAndExitThread to unload the DLL completely
  97. //
  98. GetModuleFileName(hmodule, szModule, MAX_PATH);
  99. hmodule = LoadLibrary(szModule);
  100. if (!hmodule) {
  101. DEBUG_PRINT(("RTStartup: !loadlibrary %s\n", szModule ));
  102. return FALSE;
  103. }
  104. //
  105. // Create the event signalled to tell the update thread to exit
  106. //
  107. g_rtCfg.hUpdateThreadExit = CreateEvent(NULL, FALSE, FALSE, NULL);
  108. if (g_rtCfg.hUpdateThreadExit == NULL) {
  109. DEBUG_PRINT(("RTStartup: !CreateEvent \n"));
  110. break;
  111. }
  112. //
  113. // Create the mutex which protects our tables
  114. //
  115. g_rtCfg.hRTMutex = CreateMutex(NULL, FALSE, NULL);
  116. if (g_rtCfg.hRTMutex == NULL) { break; }
  117. //
  118. // Load interface table now before any API functions are called
  119. //
  120. dwErr = RTGetTables(
  121. &g_rtCfg.lpIfTable, &g_rtCfg.dwIfCount,
  122. &g_rtCfg.lpIPAddressTable, &g_rtCfg.dwIPAddressCount
  123. );
  124. if (dwErr != 0) {
  125. DEBUG_PRINT(("RTStartup: !RTGetTables \n"));
  126. break;
  127. }
  128. //
  129. // Try to open the DHCP Global event
  130. //
  131. g_rtCfg.hDHCPEvent = DhcpOpenGlobalEvent();
  132. if (g_rtCfg.hDHCPEvent != NULL) {
  133. //
  134. // Start up the thread which updates the interface table
  135. // if IP addresses are changed
  136. //
  137. hThread = CreateThread(
  138. NULL, 0, (LPTHREAD_START_ROUTINE)RTUpdateThread,
  139. (LPVOID)hmodule, 0, &dwThread
  140. );
  141. if (hThread == NULL) {
  142. DEBUG_PRINT(("RTStartup: !CreateThread \n"));
  143. break;
  144. }
  145. g_rtCfg.dwUpdateThreadStarted = 1;
  146. CloseHandle(hThread);
  147. }
  148. return TRUE;
  149. } while(FALSE);
  150. //
  151. // If we reach here, something went wrong;
  152. // clean up and decrement the DLL reference count.
  153. //
  154. RTCleanUp();
  155. if (hmodule) {
  156. FreeLibrary(hmodule);
  157. }
  158. return FALSE;
  159. }
  160. //----------------------------------------------------------------------------
  161. // Function: RTShutdown
  162. //
  163. // Handles DLL-unload-time cleanup.
  164. //----------------------------------------------------------------------------
  165. BOOL
  166. RTShutdown(
  167. HMODULE hmodule
  168. )
  169. {
  170. //
  171. // If the background thread exists, allow it to clean up;
  172. // otherwise, handle cleanup ourselves.
  173. //
  174. if (g_rtCfg.dwUpdateThreadStarted) {
  175. //
  176. // Tell the thread to exit
  177. //
  178. SetEvent(g_rtCfg.hUpdateThreadExit);
  179. }
  180. else {
  181. //
  182. // Do the cleanup ourselves
  183. //
  184. RTCleanUp();
  185. FreeLibrary(hmodule);
  186. }
  187. return TRUE;
  188. }
  189. //----------------------------------------------------------------------------
  190. // Function: RTCleanUp
  191. //
  192. // This is called to free up resources used by the DLL.
  193. //----------------------------------------------------------------------------
  194. VOID
  195. RTCleanUp(
  196. )
  197. {
  198. //
  199. // Free memory for the interface table
  200. //
  201. if (g_rtCfg.lpIfTable != NULL) {
  202. HeapFree(GetProcessHeap(), 0, g_rtCfg.lpIfTable);
  203. }
  204. //
  205. // Free memory for the address table
  206. //
  207. if (g_rtCfg.lpIPAddressTable != NULL) {
  208. HeapFree(GetProcessHeap(), 0, g_rtCfg.lpIPAddressTable);
  209. }
  210. //
  211. // Close the event on which we receive IP-address-change notifications
  212. //
  213. if (g_rtCfg.hDHCPEvent != NULL) { CloseHandle(g_rtCfg.hDHCPEvent); }
  214. //
  215. // Close the mutex protecting our tables
  216. //
  217. if (g_rtCfg.hRTMutex != NULL) { CloseHandle(g_rtCfg.hRTMutex); }
  218. //
  219. // Close the handle signalled to tell the update-thread to exit
  220. //
  221. if (g_rtCfg.hUpdateThreadExit != NULL) {
  222. CloseHandle(g_rtCfg.hUpdateThreadExit);
  223. }
  224. //
  225. // Close our handle to the TCP/IP driver
  226. //
  227. if (g_rtCfg.hTCPHandle != NULL) { CloseHandle(g_rtCfg.hTCPHandle); }
  228. HeapFree(GetProcessHeap(), 0, g_prtcfg);
  229. }