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.

892 lines
22 KiB

  1. /*++
  2. Copyright (c) 1997-2000 Microsoft Corporation
  3. Module Name:
  4. HeapEventTracer.c
  5. Abstract:
  6. This file implements Event Tracing for Heap functions .
  7. --*/
  8. #include <nt.h>
  9. #include <ntrtl.h> // for ntutrl.h
  10. #include <nturtl.h> // for RTL_CRITICAL_SECTION in winbase.h/wtypes.h
  11. #include "wmiump.h"
  12. #include "evntrace.h"
  13. #include "ntdlltrc.h"
  14. #include "trcapi.h"
  15. #include "traceump.h"
  16. #include "tracelib.h"
  17. LONG NtdllTraceInitializeLock = 0;
  18. LONG NtdllLoggerLock = 0;
  19. PNTDLL_EVENT_HANDLES NtdllTraceHandles = NULL;
  20. BOOL bNtdllTrace = FALSE; // Flag determines that Tracing is enabled or disabled for this process.
  21. ULONG GlobalCounter = 0; // Used to determine that we have stale information about logger
  22. PWMI_LOGGER_INFORMATION gLoggerInfo = NULL;
  23. LONG TraceLevel = 0;
  24. extern LONG WmipLoggerCount;
  25. extern ULONG WmiTraceAlignment;
  26. extern BOOLEAN LdrpInLdrInit;
  27. extern PWMI_LOGGER_CONTEXT WmipLoggerContext;
  28. extern BOOLEAN EtwLocksInitialized;
  29. #define MAXSTR 1024
  30. #define BUFFER_STATE_FULL 2
  31. #define WmipIsLoggerOn() \
  32. (WmipLoggerContext != NULL) && \
  33. (WmipLoggerContext != (PWMI_LOGGER_CONTEXT) &WmipLoggerContext)
  34. #define WmipLockLogger() InterlockedIncrement(&WmipLoggerCount)
  35. #define WmipUnlockLogger() InterlockedDecrement(&WmipLoggerCount)
  36. NTSTATUS
  37. InitializeWmiHandles(PPNTDLL_EVENT_HANDLES ppWmiHandle)
  38. /*++
  39. Routine Description:
  40. This function does groundwork to start Tracing for Heap and Critcal Section.
  41. With the help of global lock NtdllTraceInitializeLock the function
  42. allocates memory for NtdllTraceHandles and initializes the various variables needed
  43. for heap and critical tracing.
  44. Arguments
  45. ppWmiHandle : OUT Pointer is set to value of NtdllTraceHandles
  46. Return Value:
  47. STATUS_SUCCESS
  48. STATUS_UNSUCCESSFUL
  49. --*/
  50. {
  51. NTSTATUS st = STATUS_UNSUCCESSFUL;
  52. PNTDLL_EVENT_HANDLES pWmiHandle = NULL;
  53. __try {
  54. WmipInitProcessHeap();
  55. pWmiHandle = (PNTDLL_EVENT_HANDLES)WmipAlloc(sizeof(NTDLL_EVENT_HANDLES));
  56. if(pWmiHandle){
  57. pWmiHandle->hRegistrationHandle = (TRACEHANDLE)INVALID_HANDLE_VALUE;
  58. pWmiHandle->pThreadListHead = NULL;
  59. //
  60. // Allocate TLS
  61. //
  62. pWmiHandle->dwTlsIndex = WmipTlsAlloc();
  63. if(pWmiHandle->dwTlsIndex == FAILED_TLSINDEX){
  64. WmipFree(pWmiHandle);
  65. } else {
  66. RtlInitializeCriticalSection(&pWmiHandle->CriticalSection);
  67. *ppWmiHandle = pWmiHandle;
  68. st = STATUS_SUCCESS;
  69. }
  70. }
  71. } __except (EXCEPTION_EXECUTE_HANDLER) {
  72. if(pWmiHandle !=NULL ) {
  73. WmipFree(pWmiHandle);
  74. pWmiHandle = NULL;
  75. }
  76. }
  77. return st;
  78. }
  79. void
  80. CleanOnThreadExit()
  81. /*++
  82. Routine Description:
  83. This function cleans up the Thread buffer and takes its node out of the Link list
  84. which contains information of all threads involved in tracing.
  85. --*/
  86. {
  87. PTHREAD_LOCAL_DATA pThreadLocalData = NULL;
  88. PWMI_BUFFER_HEADER pWmiBuffer;
  89. if(NtdllTraceHandles != NULL ){
  90. pThreadLocalData = (PTHREAD_LOCAL_DATA)WmipTlsGetValue(NtdllTraceHandles->dwTlsIndex);
  91. //
  92. // Remove the node from the Link List
  93. //
  94. if(pThreadLocalData != NULL ){
  95. RtlEnterCriticalSection(&NtdllTraceHandles->CriticalSection);
  96. __try {
  97. if(pThreadLocalData->BLink == NULL ){
  98. NtdllTraceHandles->pThreadListHead = pThreadLocalData->FLink;
  99. if(NtdllTraceHandles->pThreadListHead){
  100. NtdllTraceHandles->pThreadListHead->BLink = NULL;
  101. }
  102. } else {
  103. pThreadLocalData->BLink->FLink = pThreadLocalData->FLink;
  104. if(pThreadLocalData->FLink != NULL ){
  105. pThreadLocalData->FLink->BLink = pThreadLocalData->BLink;
  106. }
  107. }
  108. pWmiBuffer = pThreadLocalData->pBuffer;
  109. if(pWmiBuffer){
  110. WmipReleaseFullBuffer(pWmiBuffer);
  111. }
  112. pThreadLocalData->pBuffer = NULL;
  113. pThreadLocalData->ReferenceCount = 0;
  114. WmipFree(pThreadLocalData);
  115. WmipTlsSetValue(NtdllTraceHandles->dwTlsIndex, NULL);
  116. } __finally {
  117. RtlLeaveCriticalSection(&NtdllTraceHandles->CriticalSection);
  118. }
  119. }
  120. }
  121. }
  122. void
  123. CleanUpAllThreadBuffers(BOOLEAN Release)
  124. /*++
  125. Routine Description:
  126. This function cleans up the All Thread buffers and sets them to NULL. This
  127. function is called when the tracing is disabled for the process.
  128. --*/
  129. {
  130. PTHREAD_LOCAL_DATA pListHead;
  131. BOOL bAllClear = FALSE;
  132. PWMI_BUFFER_HEADER pWmiBuffer;
  133. int retry = 0;
  134. RtlEnterCriticalSection(&NtdllTraceHandles->CriticalSection);
  135. __try {
  136. while(bAllClear != TRUE && retry <= 10){
  137. bAllClear = TRUE;
  138. pListHead = NtdllTraceHandles->pThreadListHead;
  139. while(pListHead != NULL ){
  140. if(Release){
  141. pWmiBuffer = pListHead->pBuffer;
  142. if(pWmiBuffer){
  143. if(InterlockedIncrement(&(pListHead->ReferenceCount)) == 1){
  144. WmipReleaseFullBuffer(pWmiBuffer);
  145. pListHead->pBuffer = NULL;
  146. InterlockedDecrement(&(pListHead->ReferenceCount));
  147. } else {
  148. InterlockedDecrement(&(pListHead->ReferenceCount));
  149. bAllClear = FALSE;
  150. }
  151. }
  152. } else {
  153. pListHead->pBuffer = NULL;
  154. pListHead->ReferenceCount = 0;
  155. }
  156. pListHead = pListHead->FLink;
  157. }
  158. retry++;
  159. if(!bAllClear){
  160. WmipSleep(250);
  161. }
  162. }
  163. } __finally {
  164. RtlLeaveCriticalSection(&NtdllTraceHandles->CriticalSection);
  165. }
  166. }
  167. void
  168. ShutDownWmiHandles()
  169. /*++
  170. Routine Description:
  171. This function is called when the process is exiting. This cleans all the thread
  172. buffers and releases the memory allocated for NtdllTraceHandless.
  173. --*/
  174. {
  175. if(NtdllTraceHandles == NULL) return;
  176. bNtdllTrace = FALSE;
  177. RtlEnterCriticalSection(&NtdllTraceHandles->CriticalSection);
  178. __try {
  179. if(NtdllTraceHandles->hRegistrationHandle != (TRACEHANDLE)INVALID_HANDLE_VALUE){
  180. UnregisterTraceGuids(NtdllTraceHandles->hRegistrationHandle);
  181. }
  182. if(NtdllTraceHandles->pThreadListHead != NULL){
  183. PTHREAD_LOCAL_DATA pListHead, pNextListHead;
  184. pListHead = NtdllTraceHandles->pThreadListHead;
  185. while(pListHead != NULL ){
  186. if(pListHead->pBuffer != NULL){
  187. WmipReleaseFullBuffer(pListHead->pBuffer);
  188. pListHead->pBuffer = NULL;
  189. InterlockedDecrement(&(pListHead->ReferenceCount));
  190. }
  191. pNextListHead = pListHead->FLink;
  192. WmipFree(pListHead);
  193. pListHead = pNextListHead;
  194. }
  195. }
  196. WmipTlsFree(NtdllTraceHandles->dwTlsIndex);
  197. } __finally {
  198. RtlLeaveCriticalSection(&NtdllTraceHandles->CriticalSection);
  199. }
  200. RtlDeleteCriticalSection(&NtdllTraceHandles->CriticalSection);
  201. WmipFree(NtdllTraceHandles);
  202. NtdllTraceHandles = NULL;
  203. }
  204. NTSTATUS
  205. GetLoggerInfo(PWMI_LOGGER_INFORMATION LoggerInfo)
  206. {
  207. ULONG st = STATUS_UNSUCCESSFUL;
  208. WMINTDLLLOGGERINFO NtdllLoggerInfo;
  209. ULONG BufferSize;
  210. if(LoggerInfo == NULL) return st;
  211. NtdllLoggerInfo.LoggerInfo = LoggerInfo;
  212. NtdllLoggerInfo.LoggerInfo->Wnode.Guid = NtdllTraceGuid;
  213. NtdllLoggerInfo.IsGet = TRUE;
  214. st = WmipSendWmiKMRequest(
  215. NULL,
  216. IOCTL_WMI_NTDLL_LOGGERINFO,
  217. &NtdllLoggerInfo,
  218. sizeof(WMINTDLLLOGGERINFO),
  219. &NtdllLoggerInfo,
  220. sizeof(WMINTDLLLOGGERINFO),
  221. &BufferSize,
  222. NULL
  223. );
  224. return st;
  225. }
  226. BOOLEAN
  227. GetPidInfo(ULONG CheckPid, PWMI_LOGGER_INFORMATION LoggerInfo)
  228. {
  229. NTSTATUS st;
  230. BOOLEAN Found = FALSE;
  231. PTRACE_ENABLE_FLAG_EXTENSION FlagExt = NULL;
  232. st = GetLoggerInfo(LoggerInfo);
  233. if(NT_SUCCESS(st)){
  234. PULONG PidArray = NULL;
  235. ULONG count;
  236. FlagExt = (PTRACE_ENABLE_FLAG_EXTENSION) &LoggerInfo->EnableFlags;
  237. PidArray = (PULONG)(FlagExt->Offset + (PCHAR)LoggerInfo);
  238. for(count = 0; count < FlagExt->Length; count++){
  239. if(CheckPid == PidArray[count]){
  240. Found = TRUE;
  241. break;
  242. }
  243. }
  244. }
  245. return Found;
  246. }
  247. ULONG
  248. WINAPI
  249. NtdllCtrlCallback(
  250. WMIDPREQUESTCODE RequestCode,
  251. PVOID Context,
  252. ULONG *InOutBufferSize,
  253. PVOID Buffer
  254. )
  255. /*++
  256. Routine Description:
  257. This is WMI control callback function used at the time of registration.
  258. --*/
  259. {
  260. ULONG ret;
  261. ret = ERROR_SUCCESS;
  262. switch (RequestCode)
  263. {
  264. case WMI_ENABLE_EVENTS: //Enable Provider.
  265. {
  266. if(bNtdllTrace == TRUE) break;
  267. if(WmipIsLoggerOn()){
  268. bNtdllTrace = TRUE;
  269. break;
  270. }
  271. if(InterlockedIncrement(&NtdllLoggerLock) == 1){
  272. if( bNtdllTrace == FALSE ){
  273. BOOLEAN PidEntry = FALSE;
  274. PWMI_LOGGER_INFORMATION LoggerInfo = NULL;
  275. ULONG sizeNeeded = sizeof(WMI_LOGGER_INFORMATION)
  276. + (4 * MAXSTR * sizeof(WCHAR))
  277. + (MAX_PID + 1) * sizeof(ULONG);
  278. //
  279. // Check to see that this process is allowed to log events or not.
  280. //
  281. LoggerInfo = WmipAlloc(sizeNeeded);
  282. if(LoggerInfo){
  283. //
  284. // Check to see that this process is allowed to register or not.
  285. //
  286. RtlZeroMemory(LoggerInfo, sizeNeeded);
  287. if(GetPidInfo(WmipGetCurrentProcessId(), LoggerInfo)){
  288. LoggerInfo->LoggerName.Buffer = (PWCHAR)(((PUCHAR) LoggerInfo)
  289. + sizeof(WMI_LOGGER_INFORMATION));
  290. LoggerInfo->LogFileName.Buffer = (PWCHAR)(((PUCHAR) LoggerInfo)
  291. + sizeof(WMI_LOGGER_INFORMATION)
  292. + LoggerInfo->LoggerName.MaximumLength);
  293. LoggerInfo->InstanceCount = 0;
  294. LoggerInfo->InstanceId = WmipGetCurrentProcessId();
  295. TraceLevel = (LONG)LoggerInfo->Wnode.HistoricalContext;
  296. LoggerInfo->Wnode.HistoricalContext = 0;
  297. //Start Logger Here
  298. ret = WmipStartUmLogger(sizeNeeded,&sizeNeeded, &sizeNeeded,LoggerInfo);
  299. if(ret == ERROR_SUCCESS ){
  300. CleanUpAllThreadBuffers(FALSE);
  301. bNtdllTrace = TRUE;
  302. gLoggerInfo = LoggerInfo;
  303. InterlockedIncrement(&NtdllLoggerLock);
  304. } else {
  305. WmipFree(LoggerInfo);
  306. }
  307. }
  308. }
  309. }
  310. }
  311. InterlockedDecrement(&NtdllLoggerLock);
  312. break;
  313. }
  314. case WMI_DISABLE_EVENTS: //Disable Provider.
  315. {
  316. if( bNtdllTrace == TRUE ){
  317. ULONG WnodeSize,SizeUsed,SizeNeeded;
  318. bNtdllTrace = FALSE;
  319. while( InterlockedIncrement(&NtdllLoggerLock) != 1 ){
  320. WmipSleep(250);
  321. InterlockedDecrement(&NtdllLoggerLock);
  322. }
  323. if(!WmipIsLoggerOn()){
  324. InterlockedDecrement(&NtdllLoggerLock);
  325. break;
  326. }
  327. //
  328. // Now release thread buffer memory here.
  329. //
  330. CleanUpAllThreadBuffers(TRUE);
  331. WnodeSize = gLoggerInfo->Wnode.BufferSize;
  332. SizeUsed = 0;
  333. SizeNeeded = 0;
  334. WmipStopUmLogger(WnodeSize,
  335. &SizeUsed,
  336. &SizeNeeded,
  337. gLoggerInfo);
  338. if(gLoggerInfo){
  339. WmipFree(gLoggerInfo);
  340. gLoggerInfo = NULL;
  341. }
  342. InterlockedDecrement(&NtdllLoggerLock);
  343. }
  344. break;
  345. }
  346. default:
  347. {
  348. ret = ERROR_INVALID_PARAMETER;
  349. break;
  350. }
  351. }
  352. return ret;
  353. }
  354. ULONG
  355. RegisterNtdllTraceEvents()
  356. /*++
  357. Routine Description:
  358. This function registers the guids with WMI for tracing.
  359. Return Value:
  360. The return value of RegisterTraceGuidsA function.
  361. --*/
  362. {
  363. //Create the guid registration array
  364. NTSTATUS status;
  365. TRACE_GUID_REGISTRATION TraceGuidReg[] =
  366. {
  367. {
  368. (LPGUID) &HeapGuid,
  369. NULL
  370. },
  371. {
  372. (LPGUID) &CritSecGuid,
  373. NULL
  374. }
  375. };
  376. //Now register this process as a WMI trace provider.
  377. status = RegisterTraceGuidsA(
  378. (WMIDPREQUEST)NtdllCtrlCallback, // Enable/disable function.
  379. NULL, // RequestContext parameter
  380. (LPGUID)&NtdllTraceGuid, // Provider GUID
  381. 2, // TraceGuidReg array size
  382. TraceGuidReg, // Array of TraceGuidReg structures
  383. NULL, // Optional WMI - MOFImagePath
  384. NULL, // Optional WMI - MOFResourceName
  385. &(NtdllTraceHandles->hRegistrationHandle) // Handle required to unregister.
  386. );
  387. return status;
  388. }
  389. NTSTATUS
  390. InitializeAndRegisterNtdllTraceEvents()
  391. /*++
  392. Routine Description:
  393. This functions checks for global variable NtdllTraceHandles and if not set then calls
  394. fucntion InitializeWmiHandles to initialize it. NtdllTraceHandles contains handles used
  395. for Heap tracing. If NtdllTraceHandles is already initialized then a call is made to
  396. register the guids.
  397. Return Value:
  398. STATUS_SUCCESS
  399. STATUS_UNSUCCESSFUL
  400. --*/
  401. {
  402. NTSTATUS st = STATUS_UNSUCCESSFUL;
  403. if(NtdllTraceHandles == NULL){
  404. if(InterlockedIncrement(&NtdllTraceInitializeLock) == 1){
  405. st = InitializeWmiHandles(&NtdllTraceHandles);
  406. if(NT_SUCCESS(st)){
  407. st = RegisterNtdllTraceEvents();
  408. }
  409. }
  410. }
  411. return st;
  412. }
  413. NTSTATUS
  414. AllocateMemoryForThreadLocalData(PPTHREAD_LOCAL_DATA ppThreadLocalData)
  415. /*++
  416. Routine Description:
  417. This functions allcates memory for tls and adds it to Link list which
  418. contains informations of all threads involved in tracing.
  419. Arguments
  420. ppThreadLocalData : The OUT pointer to the tls.
  421. Return Value:
  422. STATUS_SUCCESS
  423. STATUS_UNSUCCESSFUL
  424. --*/
  425. {
  426. NTSTATUS st = STATUS_UNSUCCESSFUL;
  427. PTHREAD_LOCAL_DATA pThreadLocalData = NULL;
  428. pThreadLocalData = (PTHREAD_LOCAL_DATA)WmipAlloc(sizeof(THREAD_LOCAL_DATA));
  429. if(pThreadLocalData != NULL){
  430. if(WmipTlsSetValue(NtdllTraceHandles->dwTlsIndex, (LPVOID)pThreadLocalData) == TRUE){
  431. pThreadLocalData->pBuffer = NULL;
  432. pThreadLocalData->ReferenceCount = 0;
  433. RtlEnterCriticalSection(&NtdllTraceHandles->CriticalSection);
  434. if(NtdllTraceHandles->pThreadListHead == NULL ){
  435. pThreadLocalData->BLink = NULL;
  436. pThreadLocalData->FLink = NULL;
  437. } else {
  438. pThreadLocalData->FLink = NtdllTraceHandles->pThreadListHead;
  439. pThreadLocalData->BLink = NULL;
  440. NtdllTraceHandles->pThreadListHead->BLink = pThreadLocalData;
  441. }
  442. NtdllTraceHandles->pThreadListHead = pThreadLocalData;
  443. RtlLeaveCriticalSection(&NtdllTraceHandles->CriticalSection);
  444. st = STATUS_SUCCESS;
  445. }
  446. }
  447. if(!NT_SUCCESS(st) && pThreadLocalData != NULL){
  448. WmipFree(pThreadLocalData);
  449. pThreadLocalData = NULL;
  450. }
  451. *ppThreadLocalData = pThreadLocalData;
  452. return st;
  453. }
  454. void
  455. ReleaseBufferLocation(PTHREAD_LOCAL_DATA pThreadLocalData)
  456. {
  457. PWMI_BUFFER_HEADER pWmiBuffer;
  458. pWmiBuffer = pThreadLocalData->pBuffer;
  459. if(pWmiBuffer){
  460. PPERFINFO_TRACE_HEADER EventHeader = (PPERFINFO_TRACE_HEADER) (pWmiBuffer->SavedOffset
  461. + (PCHAR)(pWmiBuffer));
  462. EventHeader->Marker = PERFINFO_TRACE_MARKER;
  463. EventHeader->TS = WmipGetCycleCount();
  464. }
  465. InterlockedDecrement(&(pThreadLocalData->ReferenceCount));
  466. WmipUnlockLogger();
  467. }
  468. PCHAR
  469. ReserveBufferSpace(PTHREAD_LOCAL_DATA pThreadLocalData, PUSHORT ReqSize)
  470. {
  471. PWMI_BUFFER_HEADER TraceBuffer = pThreadLocalData->pBuffer;
  472. *ReqSize = (USHORT) ALIGN_TO_POWER2(*ReqSize, WmiTraceAlignment);
  473. if(TraceBuffer == NULL) return NULL;
  474. if(WmipLoggerContext->BufferSize - TraceBuffer->CurrentOffset < *ReqSize) {
  475. PWMI_BUFFER_HEADER NewTraceBuffer = NULL;
  476. NewTraceBuffer = WmipSwitchFullBuffer(TraceBuffer);
  477. if( NewTraceBuffer == NULL ){
  478. pThreadLocalData->pBuffer = NULL;
  479. return NULL;
  480. } else {
  481. pThreadLocalData->pBuffer = NewTraceBuffer;
  482. TraceBuffer = NewTraceBuffer;
  483. }
  484. }
  485. TraceBuffer->SavedOffset = TraceBuffer->CurrentOffset;
  486. TraceBuffer->CurrentOffset += *ReqSize;
  487. return (PCHAR)( TraceBuffer->SavedOffset + (PCHAR) TraceBuffer );
  488. }
  489. NTSTATUS
  490. AcquireBufferLocation(PVOID *ppEvent, PPTHREAD_LOCAL_DATA ppThreadLocalData, PUSHORT ReqSize)
  491. /*++
  492. Routine Description:
  493. This function is called from heap.c and heapdll.c whenever there is some
  494. Heap activity. It looks up the buffer location where the even can be written
  495. and gives back the pointer.
  496. Arguments:
  497. ppEvent - The pointer to pointer of buffer location
  498. ppThreadLocalData - The pointer to pointer of thread event storing struct.
  499. Return Value:
  500. STATUS_UNSUCCESSFUL if failed otherwise STATUS_SUCCESS
  501. --*/
  502. {
  503. NTSTATUS st = STATUS_SUCCESS;
  504. PWMI_BUFFER_HEADER pWmiBuffer;
  505. if( bNtdllTrace ){
  506. WmipLockLogger();
  507. if(WmipIsLoggerOn()){
  508. *ppThreadLocalData = (PTHREAD_LOCAL_DATA)WmipTlsGetValue(NtdllTraceHandles->dwTlsIndex);
  509. //
  510. //If there is no tls then create one here
  511. //
  512. if(*ppThreadLocalData == NULL ) {
  513. st = AllocateMemoryForThreadLocalData(ppThreadLocalData);
  514. }
  515. //
  516. //If the thread buffer is NULL then get it from logger.
  517. //
  518. if( NT_SUCCESS(st) && (*ppThreadLocalData)->pBuffer == NULL ){
  519. (*ppThreadLocalData)->pBuffer = WmipGetFullFreeBuffer();
  520. if((*ppThreadLocalData)->pBuffer == NULL){
  521. st = STATUS_UNSUCCESSFUL;
  522. }
  523. }
  524. if(NT_SUCCESS(st)){
  525. //
  526. //Check ReferenceCount. If is 1 then the cleaning process might be in progress.
  527. //
  528. pWmiBuffer = (*ppThreadLocalData)->pBuffer;
  529. if(pWmiBuffer){
  530. if(InterlockedIncrement(&((*ppThreadLocalData)->ReferenceCount)) == 1 ){
  531. *ppEvent = ReserveBufferSpace(*ppThreadLocalData, ReqSize );
  532. if(*ppEvent == NULL) {
  533. InterlockedDecrement(&((*ppThreadLocalData)->ReferenceCount));
  534. WmipUnlockLogger();
  535. }
  536. } else {
  537. InterlockedDecrement(&((*ppThreadLocalData)->ReferenceCount));
  538. }
  539. }
  540. }
  541. } else {
  542. WmipUnlockLogger();
  543. }
  544. } else if ( LdrpInLdrInit == FALSE && EtwLocksInitialized && NtdllTraceInitializeLock == 0 ){
  545. //
  546. // Make sure that process is not in initialization phase
  547. // Also we test for NtdllTraceInitializeLock. If is
  548. // greater than 0 then it was registered earlier so no
  549. // need to fire IOCTLS everytime
  550. //
  551. if((UserSharedData->TraceLogging >> 16) != GlobalCounter){
  552. PWMI_LOGGER_INFORMATION LoggerInfo = NULL;
  553. ULONG sizeNeeded = sizeof(WMI_LOGGER_INFORMATION)
  554. + (2 * MAXSTR * sizeof(TCHAR))
  555. + (MAX_PID + 1) * sizeof(ULONG);
  556. GlobalCounter = UserSharedData->TraceLogging >> 16;
  557. WmipInitProcessHeap();
  558. LoggerInfo = WmipAlloc(sizeNeeded);
  559. if(LoggerInfo != NULL){
  560. //
  561. // Check to see that this process is allowed to register or not.
  562. //
  563. if(GetPidInfo(WmipGetCurrentProcessId(), LoggerInfo)){
  564. st = InitializeAndRegisterNtdllTraceEvents();
  565. }
  566. WmipFree(LoggerInfo);
  567. }
  568. }
  569. }
  570. return st;
  571. }