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.

441 lines
12 KiB

  1. /*++
  2. Copyright (c) 1995-1999 Microsoft Corporation
  3. Module Name:
  4. dllinit.c
  5. Abstract:
  6. This module contians the DLL attach/detach event entry point for
  7. the pdh.dll
  8. Author:
  9. Bob Watson (a-robw) Jul 95
  10. Revision History:
  11. --*/
  12. #include <windows.h>
  13. #include <assert.h>
  14. #include "pdhitype.h"
  15. #include "pdhidef.h"
  16. #include "pdhmsg.h"
  17. #include "strings.h"
  18. #include "pdhp.h"
  19. HANDLE ThisDLLHandle = NULL;
  20. WCHAR szStaticLocalMachineName[MAX_PATH] = {0};
  21. HANDLE hPdhDataMutex = NULL;
  22. HANDLE hPdhContextMutex = NULL;
  23. HANDLE hPdhHeap = NULL;
  24. HANDLE hEventLog = NULL;
  25. LONGLONG llRemoteRetryTime = RETRY_TIME_INTERVAL;
  26. BOOL bEnableRemotePdhAccess = TRUE;
  27. DWORD dwPdhiLocalDefaultDataSource = DATA_SOURCE_REGISTRY;
  28. LONG dwCurrentRealTimeDataSource = 0;
  29. BOOL bProcessIsDetaching = FALSE;
  30. LPWSTR
  31. GetStringResource (
  32. DWORD dwResId
  33. )
  34. {
  35. LPWSTR szReturnString = NULL;
  36. LPWSTR szTmpString = NULL;
  37. DWORD dwStrLen = (2048 * sizeof(WCHAR));
  38. szReturnString = (LPWSTR) G_ALLOC (dwStrLen);
  39. if (szReturnString != NULL) {
  40. dwStrLen /= sizeof(WCHAR);
  41. dwStrLen = LoadStringW (
  42. ThisDLLHandle,
  43. (UINT)dwResId,
  44. szReturnString,
  45. dwStrLen);
  46. if (dwStrLen > 0) {
  47. // then realloc down to the size used
  48. dwStrLen++; // to include the NULL
  49. dwStrLen *= sizeof (WCHAR);
  50. szTmpString = szReturnString;
  51. szReturnString = G_REALLOC (szReturnString, dwStrLen);
  52. if (szReturnString == NULL) {
  53. G_FREE(szTmpString);
  54. szTmpString = NULL;
  55. }
  56. } else {
  57. // free the memory since the look up failed
  58. G_FREE (szReturnString);
  59. szReturnString = NULL;
  60. }
  61. } //else allocation failed
  62. return szReturnString;
  63. }
  64. STATIC_BOOL
  65. PdhiOpenEventLog (
  66. HANDLE *phEventLogHandle
  67. )
  68. {
  69. HANDLE hReturn;
  70. BOOL bReturn;
  71. if ((hReturn = RegisterEventSourceW (
  72. NULL, // on the local machine
  73. cszAppShortName // for the PDH.DLL
  74. )) != NULL) {
  75. *phEventLogHandle = hReturn;
  76. bReturn = TRUE;
  77. } else {
  78. bReturn = FALSE;
  79. }
  80. return bReturn;
  81. }
  82. STATIC_BOOL
  83. PdhiGetRegistryDefaults ()
  84. {
  85. DWORD dwStatus;
  86. DWORD dwType, dwSize, dwValue;
  87. HKEY hKeyPDH;
  88. // the local data source is not initialized so use it
  89. dwStatus = RegOpenKeyExW (
  90. HKEY_LOCAL_MACHINE,
  91. cszPdhKey,
  92. 0L,
  93. KEY_READ,
  94. &hKeyPDH);
  95. if (dwStatus == ERROR_SUCCESS) {
  96. //
  97. // get the default null data source
  98. //
  99. dwValue = 0;
  100. dwType = 0;
  101. dwSize = sizeof (dwValue);
  102. dwStatus = RegQueryValueExW (
  103. hKeyPDH,
  104. cszDefaultNullDataSource,
  105. NULL,
  106. &dwType,
  107. (LPBYTE)&dwValue,
  108. &dwSize);
  109. if (!(dwStatus == ERROR_SUCCESS) || !(dwType == REG_DWORD)) {
  110. dwValue = DATA_SOURCE_REGISTRY;
  111. } else {
  112. // check the value for validity
  113. switch (dwValue) {
  114. case DATA_SOURCE_WBEM:
  115. case DATA_SOURCE_REGISTRY:
  116. // this is OK
  117. break;
  118. case DATA_SOURCE_LOGFILE:
  119. default:
  120. // these are not OK so insert default
  121. dwValue = DATA_SOURCE_REGISTRY;
  122. break;
  123. }
  124. }
  125. dwPdhiLocalDefaultDataSource = dwValue;
  126. //
  127. // get the retry timeout
  128. //
  129. dwValue = 0;
  130. dwType = 0;
  131. dwSize = sizeof (dwValue);
  132. dwStatus = RegQueryValueExW (
  133. hKeyPDH,
  134. cszRemoteMachineRetryTime,
  135. NULL,
  136. &dwType,
  137. (LPBYTE)&dwValue,
  138. &dwSize);
  139. if (!(dwStatus == ERROR_SUCCESS) || !(dwType == REG_DWORD)) {
  140. dwValue = 0;
  141. } else {
  142. // check the value for validity
  143. // must be 30 seconds or more yet no more than an hour
  144. if ((dwValue <= 30) || (dwValue > 3600)) {
  145. dwValue = 0;
  146. }
  147. }
  148. if (dwValue != 0) {
  149. // convert to 100NS units
  150. llRemoteRetryTime = dwValue * 10000000;
  151. } else {
  152. // use default
  153. llRemoteRetryTime = RETRY_TIME_INTERVAL;
  154. }
  155. //
  156. // get the remote access mode
  157. //
  158. dwValue = 0;
  159. dwType = 0;
  160. dwSize = sizeof (dwValue);
  161. dwStatus = RegQueryValueExW (
  162. hKeyPDH,
  163. cszEnableRemotePdhAccess,
  164. NULL,
  165. &dwType,
  166. (LPBYTE)&dwValue,
  167. &dwSize);
  168. if (!(dwStatus == ERROR_SUCCESS) || !(dwType == REG_DWORD)) {
  169. dwValue = TRUE;
  170. } else {
  171. // check the value for validity
  172. if (dwValue != 0) {
  173. dwValue = TRUE;
  174. }
  175. }
  176. bEnableRemotePdhAccess = (BOOL)dwValue;
  177. // close the registry key
  178. RegCloseKey (hKeyPDH);
  179. }
  180. return TRUE;
  181. }
  182. STATIC_BOOL
  183. PdhiCloseEventLog (
  184. HANDLE * phEventLogHandle
  185. )
  186. {
  187. BOOL bReturn;
  188. if (*phEventLogHandle != NULL) {
  189. bReturn = DeregisterEventSource (*phEventLogHandle);
  190. *phEventLogHandle = NULL;
  191. } else {
  192. // it's already closed so that's OK
  193. bReturn = TRUE;
  194. }
  195. return bReturn;
  196. }
  197. HRESULT
  198. PdhiPlaInitMutex()
  199. {
  200. HRESULT hr = ERROR_SUCCESS;
  201. BOOL bResult = TRUE;
  202. PSECURITY_DESCRIPTOR SD = NULL;
  203. SECURITY_ATTRIBUTES sa;
  204. PSID AuthenticatedUsers = NULL;
  205. PSID BuiltInAdministrators = NULL;
  206. PSID NetworkService = NULL;
  207. DWORD dwAclSize;
  208. ACL *Acl;
  209. SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
  210. bResult = AllocateAndInitializeSid(
  211. &NtAuthority,
  212. 2,
  213. SECURITY_BUILTIN_DOMAIN_RID,
  214. DOMAIN_ALIAS_RID_ADMINS,
  215. 0,0,0,0,0,0,
  216. &BuiltInAdministrators);
  217. if( !bResult ){goto cleanup;}
  218. bResult = AllocateAndInitializeSid(
  219. &NtAuthority,
  220. 1,
  221. SECURITY_AUTHENTICATED_USER_RID,
  222. 0,0,0,0,0,0,0,
  223. &AuthenticatedUsers);
  224. if( !bResult ){goto cleanup;}
  225. bResult = AllocateAndInitializeSid(
  226. &NtAuthority,
  227. 1,
  228. SECURITY_NETWORK_SERVICE_RID,
  229. 0,0,0,0,0,0,0,
  230. &NetworkService);
  231. if( !bResult ){goto cleanup;}
  232. dwAclSize = sizeof (ACL) +
  233. (3 * (sizeof (ACCESS_ALLOWED_ACE) - sizeof (ULONG))) +
  234. GetLengthSid(AuthenticatedUsers) +
  235. GetLengthSid(BuiltInAdministrators) +
  236. GetLengthSid(NetworkService);
  237. SD = (PSECURITY_DESCRIPTOR)G_ALLOC(SECURITY_DESCRIPTOR_MIN_LENGTH + dwAclSize);
  238. if( NULL == SD ){ goto cleanup; }
  239. ZeroMemory( SD, sizeof(SD) );
  240. Acl = (ACL *)((BYTE *)SD + SECURITY_DESCRIPTOR_MIN_LENGTH);
  241. bResult = InitializeAcl( Acl, dwAclSize, ACL_REVISION);
  242. if( !bResult ){goto cleanup;}
  243. bResult = AddAccessAllowedAce(Acl, ACL_REVISION, SYNCHRONIZE | GENERIC_READ, AuthenticatedUsers );
  244. if( !bResult ){goto cleanup;}
  245. bResult = AddAccessAllowedAce(Acl, ACL_REVISION, MUTEX_ALL_ACCESS , NetworkService );
  246. if( !bResult ){goto cleanup;}
  247. bResult = AddAccessAllowedAce(Acl, ACL_REVISION, GENERIC_ALL, BuiltInAdministrators );
  248. if( !bResult ){goto cleanup;}
  249. bResult = InitializeSecurityDescriptor(SD, SECURITY_DESCRIPTOR_REVISION);
  250. if( !bResult ){goto cleanup;}
  251. bResult = SetSecurityDescriptorDacl(SD, TRUE, Acl, FALSE);
  252. if( !bResult ){goto cleanup;}
  253. sa.nLength = sizeof(SECURITY_ATTRIBUTES);
  254. sa.lpSecurityDescriptor = SD;
  255. sa.bInheritHandle = FALSE;
  256. hPdhPlaMutex = CreateMutexW( &sa, FALSE, PDH_PLA_MUTEX );
  257. cleanup:
  258. if( hPdhPlaMutex == NULL || !bResult ){
  259. hr = GetLastError();
  260. }
  261. if( NULL != AuthenticatedUsers ){
  262. FreeSid(AuthenticatedUsers);
  263. }
  264. if( NULL != BuiltInAdministrators){
  265. FreeSid(BuiltInAdministrators);
  266. }
  267. if( NULL != NetworkService){
  268. FreeSid(NetworkService);
  269. }
  270. G_FREE(SD);
  271. return hr;
  272. }
  273. BOOL
  274. _stdcall
  275. PdhDllInitRoutine(
  276. IN HANDLE DLLHandle,
  277. IN DWORD Reason,
  278. IN LPVOID ReservedAndUnused
  279. )
  280. {
  281. BOOL bStatus;
  282. BOOL bReturn = TRUE;
  283. OSVERSIONINFOW os;
  284. ReservedAndUnused;
  285. switch(Reason) {
  286. case DLL_PROCESS_ATTACH:
  287. bProcessIsDetaching = FALSE;
  288. {
  289. DWORD dwBufferLength = 0;
  290. ThisDLLHandle = DLLHandle;
  291. // make sure this is the correct operating system
  292. memset (&os, 0, sizeof(os));
  293. os.dwOSVersionInfoSize = sizeof(os);
  294. bReturn = GetVersionExW (&os);
  295. if (bReturn) {
  296. // check for windows NT v4.0
  297. if (os.dwPlatformId != VER_PLATFORM_WIN32_NT) {
  298. // not WINDOWS NT
  299. bReturn = FALSE;
  300. } else if (os.dwMajorVersion < 4) {
  301. // it's windows NT, but an old one
  302. bReturn = FALSE;
  303. }
  304. } else {
  305. // unable to read version so give up
  306. }
  307. if (bReturn) {
  308. // disable thread init calls
  309. DisableThreadLibraryCalls (DLLHandle);
  310. // initialize the event log so events can be reported
  311. bStatus = PdhiOpenEventLog (&hEventLog);
  312. bStatus = PdhiGetRegistryDefaults ();
  313. // initialize the local computer name buffer
  314. if (szStaticLocalMachineName[0] == 0) {
  315. // initialize the computer name for this computer
  316. szStaticLocalMachineName[0] = BACKSLASH_L;
  317. szStaticLocalMachineName[1] = BACKSLASH_L;
  318. dwBufferLength = (sizeof(szStaticLocalMachineName) / sizeof(WCHAR)) - 2;
  319. GetComputerNameW (&szStaticLocalMachineName[2], &dwBufferLength);
  320. }
  321. hPdhDataMutex = CreateMutexW (NULL, FALSE, NULL);
  322. hPdhContextMutex = CreateMutexW(NULL, FALSE, NULL);
  323. hPdhHeap = HeapCreate (0, 0, 0);
  324. if (hPdhHeap == NULL) {
  325. // unable to create our own heap, so use the
  326. // process heap
  327. hPdhHeap = GetProcessHeap();
  328. assert (hPdhHeap != NULL);
  329. }
  330. PdhiPlaInitMutex();
  331. }
  332. }
  333. break;
  334. case DLL_PROCESS_DETACH:
  335. // close all pending loggers
  336. //
  337. bProcessIsDetaching = (ReservedAndUnused != NULL)
  338. ? (TRUE) : (FALSE);
  339. PdhiCloseAllLoggers();
  340. // walk down query list and close (at least disconnect) queries.
  341. PdhiQueryCleanup ();
  342. FreeAllMachines(bProcessIsDetaching);
  343. PdhiFreeAllWbemServers ();
  344. if (hPdhDataMutex != NULL) {
  345. bStatus = CloseHandle (hPdhDataMutex);
  346. assert (bStatus);
  347. hPdhDataMutex = NULL;
  348. }
  349. if (hPdhContextMutex != NULL) {
  350. bStatus = CloseHandle (hPdhContextMutex);
  351. assert (bStatus);
  352. hPdhContextMutex = NULL;
  353. }
  354. if (hPdhHeap != GetProcessHeap()) {
  355. HeapDestroy (hPdhHeap);
  356. hPdhHeap = NULL;
  357. }
  358. // lastly close the event log interface
  359. bStatus = PdhiCloseEventLog (&hEventLog);
  360. bReturn = TRUE;
  361. break ;
  362. case DLL_THREAD_ATTACH:
  363. case DLL_THREAD_DETACH:
  364. bReturn = TRUE;
  365. break;
  366. }
  367. return (bReturn);
  368. }