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.

377 lines
8.6 KiB

  1. /*++
  2. Copyright (C) Microsoft Corporation, 1991 - 1999
  3. Module Name:
  4. initnt.cxx
  5. Abstract:
  6. This module contains the code used to initialize the RPC runtime. One
  7. routine gets called when a process attaches to the dll. Another routine
  8. gets called the first time an RPC API is called.
  9. Author:
  10. Michael Montague (mikemon) 03-May-1991
  11. Revision History:
  12. Kamen Moutafov (KamenM) Dec 99 - Feb 2000 - Support for cell debugging stuff
  13. --*/
  14. #include <precomp.hxx>
  15. #include <hndlsvr.hxx>
  16. #include <thrdctx.hxx>
  17. #include <rpccfg.h>
  18. #include <rc4.h>
  19. #include <randlib.h>
  20. #include <epmap.h>
  21. #include <CellHeap.hxx>
  22. #include <lpcpack.hxx>
  23. int RpcHasBeenInitialized = 0;
  24. RTL_CRITICAL_SECTION GlobalMutex;
  25. RPC_SERVER * GlobalRpcServer;
  26. BOOL g_fClientSideDebugInfoEnabled = FALSE;
  27. BOOL g_fServerSideDebugInfoEnabled = FALSE;
  28. BOOL g_fSendEEInfo = FALSE;
  29. LRPC_SERVER *GlobalLrpcServer = NULL;
  30. HINSTANCE hInstanceDLL ;
  31. EXTERN_C HINSTANCE g_hRpcrt4;
  32. DWORD gPageSize;
  33. DWORD gThreadTimeout;
  34. UINT gNumberOfProcessors;
  35. DWORD gAllocationGranularity;
  36. BOOL gfServerPlatform;
  37. ULONGLONG gPhysicalMemorySize; // in megabytes
  38. //
  39. // By default the non pipe arguments cannot be more than 4 Megs
  40. //
  41. DWORD gMaxRpcSize = 0x400000;
  42. DWORD gProrateStart = 0;
  43. DWORD gProrateMax = 0;
  44. DWORD gProrateFactor = 0;
  45. void *g_rc4SafeCtx = 0;
  46. extern "C" {
  47. BOOLEAN
  48. InitializeDLL (
  49. IN HINSTANCE DllHandle,
  50. IN ULONG Reason,
  51. IN PCONTEXT Context OPTIONAL
  52. )
  53. /*++
  54. Routine Description:
  55. This routine will get called: when a process attaches to this dll, and
  56. when a process detaches from this dll.
  57. Return Value:
  58. TRUE - Initialization successfully occurred.
  59. FALSE - Insufficient memory is available for the process to attach to
  60. this dll.
  61. --*/
  62. {
  63. NTSTATUS NtStatus;
  64. UNUSED(Context);
  65. switch (Reason)
  66. {
  67. case DLL_PROCESS_ATTACH:
  68. hInstanceDLL = DllHandle ;
  69. g_hRpcrt4 = DllHandle;
  70. GlobalMutex.DebugInfo = NULL;
  71. NtStatus = RtlInitializeCriticalSectionAndSpinCount(&GlobalMutex, PREALLOCATE_EVENT_MASK);
  72. if (NT_SUCCESS(NtStatus) == 0)
  73. {
  74. return(FALSE);
  75. }
  76. // initialize safe rc4 operations.
  77. if(!rc4_safe_startup( &g_rc4SafeCtx ))
  78. {
  79. (void) RtlDeleteCriticalSection(&GlobalMutex);
  80. return FALSE;
  81. }
  82. break;
  83. case DLL_PROCESS_DETACH:
  84. //
  85. // If shutting down because of a FreeLibrary call, cleanup
  86. //
  87. if (Context == NULL)
  88. {
  89. ShutdownLrpcClient();
  90. }
  91. if (GlobalMutex.DebugInfo != NULL)
  92. {
  93. NtStatus = RtlDeleteCriticalSection(&GlobalMutex);
  94. ASSERT(NT_SUCCESS(NtStatus));
  95. }
  96. if (g_rc4SafeCtx)
  97. rc4_safe_shutdown( g_rc4SafeCtx ); // free safe rc4 resources.
  98. break;
  99. case DLL_THREAD_DETACH:
  100. THREAD * Thread = RpcpGetThreadPointer();
  101. #ifdef RPC_OLD_IO_PROTECTION
  102. if (Thread)
  103. {
  104. Thread->UnprotectThread();
  105. }
  106. #else
  107. delete Thread;
  108. #endif
  109. break;
  110. }
  111. return(TRUE);
  112. }
  113. } //extern "C" end
  114. #ifdef NO_RECURSIVE_MUTEXES
  115. unsigned int RecursionCount = 0;
  116. #endif // NO_RECURSIVE_MUTEXES
  117. extern int InitializeRpcAllocator(void);
  118. extern RPC_STATUS ReadPolicySettings(void);
  119. const ULONG MEGABYTE = 0x100000;
  120. typedef struct tagBasicSystemInfo
  121. {
  122. DWORD m_dwPageSize;
  123. ULONGLONG m_dwPhysicalMemorySize;
  124. DWORD m_dwNumberOfProcessors;
  125. ULONG AllocationGranularity;
  126. BOOL m_fServerPlatform;
  127. } BasicSystemInfo;
  128. BOOL
  129. GetBasicSystemInfo (
  130. IN OUT BasicSystemInfo *basicSystemInfo
  131. )
  132. /*++
  133. Routine Description:
  134. Gets basic system information. We don't use the Win32 GetSystemInfo, because
  135. under NT it accesses the image header, which may not be available if the image
  136. was loaded from the network, and the network failed. Therefore, we need a function
  137. that accesses just what we need, and nothing else.
  138. Arguments:
  139. The basic system info structure.
  140. Return Value:
  141. 0 - failure
  142. non-0 - success.
  143. --*/
  144. {
  145. //
  146. // Query system info (for # of processors) and product type
  147. //
  148. SYSTEM_BASIC_INFORMATION BasicInfo;
  149. NTSTATUS Status;
  150. BOOL b;
  151. Status = NtQuerySystemInformation(
  152. SystemBasicInformation,
  153. &BasicInfo,
  154. sizeof(BasicInfo),
  155. NULL
  156. );
  157. if ( !NT_SUCCESS(Status) )
  158. {
  159. DbgPrintEx(DPFLTR_RPCPROXY_ID,
  160. DPFLTR_ERROR_LEVEL,
  161. "RPCTRANS: NtQuerySystemInformation failed: %x\n",
  162. Status);
  163. return 0;
  164. }
  165. basicSystemInfo->m_dwPageSize = BasicInfo.PageSize;
  166. basicSystemInfo->m_dwNumberOfProcessors = BasicInfo.NumberOfProcessors;
  167. basicSystemInfo->m_dwPhysicalMemorySize = ((BasicInfo.NumberOfPhysicalPages * (ULONGLONG) basicSystemInfo->m_dwPageSize) / MEGABYTE);
  168. basicSystemInfo->AllocationGranularity = BasicInfo.AllocationGranularity;
  169. NT_PRODUCT_TYPE type;
  170. b = RtlGetNtProductType(&type);
  171. if (b)
  172. {
  173. basicSystemInfo->m_fServerPlatform = (type != NtProductWinNt);
  174. return 1;
  175. }
  176. else
  177. {
  178. DbgPrintEx(DPFLTR_RPCPROXY_ID,
  179. DPFLTR_ERROR_LEVEL,
  180. "RpcGetNtProductType failed, usign default\n");
  181. return 0;
  182. }
  183. }
  184. RPC_STATUS
  185. PerformRpcInitialization (
  186. void
  187. )
  188. /*++
  189. Routine Description:
  190. This routine will get called the first time that an RPC runtime API is
  191. called. There is actually a race condition, which we prevent by grabbing
  192. a mutex and then performing the initialization. We only want to
  193. initialize once.
  194. Return Value:
  195. RPC_S_OK - This status code indicates that the runtime has been correctly
  196. initialized and is ready to go.
  197. RPC_S_OUT_OF_MEMORY - If initialization failed, it is most likely due to
  198. insufficient memory being available.
  199. --*/
  200. {
  201. if ( RpcHasBeenInitialized == 0 )
  202. {
  203. RequestGlobalMutex();
  204. if ( RpcHasBeenInitialized == 0 )
  205. {
  206. RPC_STATUS Status;
  207. BasicSystemInfo SystemInfo;
  208. BOOL b;
  209. b = GetBasicSystemInfo(&SystemInfo);
  210. if (!b)
  211. {
  212. ClearGlobalMutex();
  213. return RPC_S_OUT_OF_MEMORY;
  214. }
  215. gNumberOfProcessors = SystemInfo.m_dwNumberOfProcessors;
  216. gPageSize = SystemInfo.m_dwPageSize;
  217. gAllocationGranularity = SystemInfo.AllocationGranularity;
  218. gfServerPlatform = SystemInfo.m_fServerPlatform;
  219. gPhysicalMemorySize = SystemInfo.m_dwPhysicalMemorySize;
  220. // Should be something like 64kb / 4kb.
  221. ASSERT(gAllocationGranularity % gPageSize == 0);
  222. if (( InitializeRpcAllocator() != 0)
  223. || ( InitializeServerDLL() != 0 ))
  224. {
  225. ClearGlobalMutex();
  226. return(RPC_S_OUT_OF_MEMORY);
  227. }
  228. Status = InitializeEPMapperClient();
  229. if (Status != RPC_S_OK)
  230. {
  231. ClearGlobalMutex();
  232. return Status;
  233. }
  234. Status = ReadPolicySettings();
  235. if (Status != RPC_S_OK)
  236. {
  237. ClearGlobalMutex();
  238. return Status;
  239. }
  240. if (gfServerPlatform)
  241. {
  242. gThreadTimeout = 90*1000;
  243. }
  244. else
  245. {
  246. gThreadTimeout = 30*1000;
  247. }
  248. Status = InitializeCellHeap();
  249. if (Status != RPC_S_OK)
  250. {
  251. ClearGlobalMutex();
  252. return Status;
  253. }
  254. RpcHasBeenInitialized = 1;
  255. ClearGlobalMutex();
  256. if (LoadLibrary(RPC_CONST_SSTRING("rpcrt4.dll")) == 0)
  257. {
  258. return RPC_S_OUT_OF_MEMORY;
  259. }
  260. }
  261. else
  262. {
  263. ClearGlobalMutex();
  264. }
  265. }
  266. return(RPC_S_OK);
  267. }
  268. #ifdef DBG
  269. long lGlobalMutexCount = 0;
  270. #endif
  271. void
  272. GlobalMutexRequestExternal (
  273. void
  274. )
  275. /*++
  276. Routine Description:
  277. Request the global mutex.
  278. --*/
  279. {
  280. GlobalMutexRequest();
  281. }
  282. void
  283. GlobalMutexClearExternal (
  284. void
  285. )
  286. /*++
  287. Routine Description:
  288. Clear the global mutex.
  289. --*/
  290. {
  291. GlobalMutexClear();
  292. }