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.

899 lines
29 KiB

  1. /*++
  2. Copyright (c) 1990 Microsoft Corporation
  3. Module Name:
  4. top.c
  5. Abstract:
  6. This module contains the NT/Win32 Top threads Meter
  7. Author:
  8. Another Mark Lucovsky (markl) / Lou Perazzoli (loup) production 5-Aug-1991
  9. Revision History:
  10. --*/
  11. #include "perfmtrp.h"
  12. #include <stdlib.h>
  13. #define BUFFER_SIZE 64*1024
  14. #define CPU_THREAD 0
  15. #define CPU_PROCESS 1
  16. #define FAULTS 2
  17. #define WORKING_SET 3
  18. #define CONTEXT_SWITCHES 4
  19. #define SYSTEM_CALLS 5
  20. PUCHAR g_pLargeBuffer1 = NULL;
  21. PUCHAR g_pLargeBuffer2 = NULL;
  22. DWORD g_dwBufSize1;
  23. DWORD g_dwBufSize2;
  24. WCHAR *NoNameFound = L"No Name Found";
  25. UCHAR *StateTable[] = {
  26. "Initialized",
  27. "Ready",
  28. "Running",
  29. "Standby",
  30. "Terminated",
  31. "Wait:",
  32. "Transition",
  33. "Unknown",
  34. "Unknown",
  35. "Unknown",
  36. "Unknown",
  37. "Unknown"
  38. };
  39. UCHAR *WaitTable[] = {
  40. "Executive",
  41. "FreePage",
  42. "PageIn",
  43. "PoolAllocation",
  44. "DelayExecution",
  45. "Suspended",
  46. "UserRequest",
  47. "Executive",
  48. "FreePage",
  49. "PageIn",
  50. "PoolAllocation",
  51. "DelayExecution",
  52. "Suspended",
  53. "UserRequest",
  54. "EventPairHigh",
  55. "EventPairLow",
  56. "LpcReceive",
  57. "LpcReply",
  58. "Spare1",
  59. "Spare2",
  60. "Spare3",
  61. "Spare4",
  62. "Spare5",
  63. "Spare6",
  64. "Spare7",
  65. "Spare8",
  66. "Spare9",
  67. "Unknown",
  68. "Unknown",
  69. "Unknown",
  70. "Unknown"
  71. };
  72. UCHAR *Empty = " ";
  73. PSYSTEM_PROCESS_INFORMATION
  74. FindMatchedProcess (
  75. IN PSYSTEM_PROCESS_INFORMATION ProcessToMatch,
  76. IN PUCHAR SystemInfoBuffer,
  77. IN PULONG Hint
  78. );
  79. PSYSTEM_THREAD_INFORMATION
  80. FindMatchedThread (
  81. IN PSYSTEM_THREAD_INFORMATION ThreadToMatch,
  82. IN PSYSTEM_PROCESS_INFORMATION MatchedProcess
  83. );
  84. typedef struct _TOPCPU {
  85. LARGE_INTEGER TotalTime;
  86. PSYSTEM_PROCESS_INFORMATION ProcessInfo;
  87. PSYSTEM_PROCESS_INFORMATION MatchedProcess;
  88. ULONG Value;
  89. } TOPCPU, *PTOPCPU;
  90. TOPCPU TopCpu[1000];
  91. int
  92. __cdecl main( argc, argv )
  93. int argc;
  94. char *argv[];
  95. {
  96. NTSTATUS Status;
  97. int i,j;
  98. ULONG DelayTimeMsec;
  99. ULONG DelayTimeTicks;
  100. COORD dest,cp;
  101. SMALL_RECT Sm;
  102. CHAR_INFO ci;
  103. CONSOLE_SCREEN_BUFFER_INFO sbi;
  104. KPRIORITY SetBasePriority;
  105. INPUT_RECORD InputRecord;
  106. HANDLE ScreenHandle;
  107. BOOLEAN Active;
  108. DWORD NumRead;
  109. SMALL_RECT Window;
  110. PSYSTEM_THREAD_INFORMATION Thread;
  111. PSYSTEM_THREAD_INFORMATION MatchedThread;
  112. PUCHAR PreviousBuffer;
  113. PUCHAR CurrentBuffer;
  114. PUCHAR TempBuffer;
  115. ULONG Hint;
  116. ULONG Offset1;
  117. int num;
  118. int Type;
  119. ULONG ContextSwitches;
  120. PSYSTEM_PROCESS_INFORMATION CurProcessInfo;
  121. PSYSTEM_PROCESS_INFORMATION MatchedProcess;
  122. LARGE_INTEGER LARGE_ZERO={0,0};
  123. LARGE_INTEGER Ktime;
  124. LARGE_INTEGER Utime;
  125. LARGE_INTEGER TotalTime;
  126. TIME_FIELDS TimeOut;
  127. PTOPCPU PTopCpu;
  128. BOOLEAN bToggle = TRUE;
  129. PDWORD pdwBufSize = NULL;
  130. NTSTATUS status;
  131. SetBasePriority = (KPRIORITY) 12;
  132. status = NtSetInformationProcess(
  133. NtCurrentProcess(),
  134. ProcessBasePriority,
  135. (PVOID) &SetBasePriority,
  136. sizeof(SetBasePriority)
  137. );
  138. if (!NT_SUCCESS(status)) {
  139. printf("Cannot set process priority\n");
  140. return 0;
  141. }
  142. GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE),&sbi);
  143. DelayTimeMsec = 2500;
  144. DelayTimeTicks = DelayTimeMsec * 10000;
  145. Window.Left = 0;
  146. Window.Top = 0;
  147. Window.Right = 79;
  148. Window.Bottom = 23;
  149. dest.X = 0;
  150. dest.Y = 23;
  151. ci.Char.AsciiChar = ' ';
  152. ci.Attributes = sbi.wAttributes;
  153. SetConsoleWindowInfo(GetStdHandle(STD_OUTPUT_HANDLE),
  154. TRUE,
  155. &Window
  156. );
  157. cp.X = 0;
  158. cp.Y = 0;
  159. Sm.Left = 0;
  160. Sm.Top = 0;
  161. Sm.Right = 79;
  162. Sm.Bottom = 22;
  163. ScrollConsoleScreenBuffer(
  164. GetStdHandle(STD_OUTPUT_HANDLE),
  165. &Sm,
  166. NULL,
  167. dest,
  168. &ci
  169. );
  170. SetConsoleCursorPosition(
  171. GetStdHandle(STD_OUTPUT_HANDLE),
  172. cp
  173. );
  174. printf( " %% Pid Tid Pri Key Start Address ImageName\n");
  175. printf( "___________________________________________________________________\n");
  176. cp.X = 0;
  177. cp.Y = 2;
  178. Sm.Left = 0;
  179. Sm.Top = 2;
  180. Sm.Right = 79;
  181. Sm.Bottom = 22;
  182. ScreenHandle = GetStdHandle (STD_INPUT_HANDLE);
  183. // allocate space for the buffer
  184. g_dwBufSize1 = BUFFER_SIZE;
  185. g_dwBufSize2 = BUFFER_SIZE;
  186. g_pLargeBuffer1 = ( PUCHAR )malloc( sizeof( UCHAR ) * g_dwBufSize1 );
  187. if( g_pLargeBuffer1 == NULL )
  188. {
  189. return 0;
  190. }
  191. g_pLargeBuffer2 = ( PUCHAR )malloc( sizeof( UCHAR ) * g_dwBufSize2 );
  192. if( g_pLargeBuffer2 == NULL )
  193. {
  194. return 0;
  195. }
  196. retry0:
  197. Status = NtQuerySystemInformation(
  198. SystemProcessInformation,
  199. g_pLargeBuffer1,
  200. g_dwBufSize1,
  201. NULL
  202. );
  203. if( Status == STATUS_INFO_LENGTH_MISMATCH )
  204. {
  205. g_dwBufSize1 *= 2;
  206. if( g_pLargeBuffer1 != NULL )
  207. {
  208. free( g_pLargeBuffer1 );
  209. }
  210. g_pLargeBuffer1 = ( PUCHAR )malloc( sizeof( UCHAR ) * g_dwBufSize1 );
  211. if( g_pLargeBuffer1 == NULL )
  212. {
  213. return 0;
  214. }
  215. }
  216. if ( !NT_SUCCESS(Status) ) {
  217. printf("Query Failed %lx\n",Status);
  218. goto retry0;
  219. }
  220. Sleep(DelayTimeMsec);
  221. retry01:
  222. NtSetInformationProcess(
  223. NtCurrentProcess(),
  224. ProcessBasePriority,
  225. (PVOID) &SetBasePriority,
  226. sizeof(SetBasePriority)
  227. );
  228. Status = NtQuerySystemInformation(
  229. SystemProcessInformation,
  230. g_pLargeBuffer2,
  231. g_dwBufSize2,
  232. NULL
  233. );
  234. if( Status == STATUS_INFO_LENGTH_MISMATCH )
  235. {
  236. g_dwBufSize2 *= 2;
  237. if( g_pLargeBuffer2 != NULL )
  238. {
  239. free( g_pLargeBuffer2 );
  240. }
  241. g_pLargeBuffer2 = ( PUCHAR )malloc( sizeof( UCHAR ) * g_dwBufSize2 );
  242. if( g_pLargeBuffer2 == NULL )
  243. {
  244. if( g_pLargeBuffer1 != NULL )
  245. {
  246. free( g_pLargeBuffer1 );
  247. }
  248. return 0;
  249. }
  250. }
  251. if ( !NT_SUCCESS(Status) ) {
  252. printf("Query Failed %lx\n",Status);
  253. goto retry01;
  254. }
  255. PreviousBuffer = &g_pLargeBuffer1[0];
  256. CurrentBuffer = &g_pLargeBuffer2[0];
  257. Active = TRUE;
  258. Type = CPU_PROCESS;
  259. while(TRUE) {
  260. waitkey:
  261. while (PeekConsoleInput (ScreenHandle, &InputRecord, 1, &NumRead) && NumRead != 0) {
  262. if (!ReadConsoleInput (ScreenHandle, &InputRecord, 1, &NumRead)) {
  263. break;
  264. }
  265. if (InputRecord.EventType == KEY_EVENT) {
  266. switch (InputRecord.Event.KeyEvent.uChar.AsciiChar) {
  267. case 'q':
  268. case 'Q':
  269. {
  270. if( CurrentBuffer != NULL )
  271. {
  272. free( CurrentBuffer );
  273. }
  274. if( PreviousBuffer != NULL )
  275. {
  276. free( PreviousBuffer );
  277. }
  278. ExitProcess(0);
  279. }
  280. break;
  281. case 'p':
  282. case 'P':
  283. Active = FALSE;
  284. break;
  285. case 'c':
  286. case 'C':
  287. Type = CPU_PROCESS;
  288. break;
  289. case 'f':
  290. case 'F':
  291. Type = FAULTS;
  292. break;
  293. case 's':
  294. case 'S':
  295. Type = CONTEXT_SWITCHES;
  296. break;
  297. case 't':
  298. case 'T':
  299. Type = CPU_THREAD;
  300. break;
  301. case 'w':
  302. case 'W':
  303. Type = WORKING_SET;
  304. break;
  305. default:
  306. Active = TRUE;
  307. break;
  308. }
  309. }
  310. }
  311. if ( !Active ) {
  312. goto waitkey;
  313. }
  314. ScrollConsoleScreenBuffer(
  315. GetStdHandle(STD_OUTPUT_HANDLE),
  316. &Sm,
  317. NULL,
  318. dest,
  319. &ci
  320. );
  321. SetConsoleCursorPosition(
  322. GetStdHandle(STD_OUTPUT_HANDLE),
  323. cp
  324. );
  325. //
  326. // Calculate top CPU users and display information.
  327. //
  328. //
  329. // Cross check previous process/thread info against current
  330. // process/thread info.
  331. //
  332. Offset1 = 0;
  333. num = 0;
  334. Hint = 0;
  335. TotalTime = LARGE_ZERO;
  336. while (TRUE) {
  337. if (num >= sizeof(TopCpu) / sizeof(TopCpu[0])) {
  338. break;
  339. }
  340. CurProcessInfo = (PSYSTEM_PROCESS_INFORMATION)&CurrentBuffer[Offset1];
  341. //
  342. // Find the corresponding process in the previous array.
  343. //
  344. MatchedProcess = FindMatchedProcess (CurProcessInfo,
  345. PreviousBuffer,
  346. &Hint);
  347. switch (Type) {
  348. case CPU_PROCESS:
  349. case CPU_THREAD:
  350. if (MatchedProcess == NULL) {
  351. TopCpu[num].TotalTime = Ktime;
  352. TopCpu[num].TotalTime.QuadPart =
  353. TopCpu[num].TotalTime.QuadPart +
  354. Utime.QuadPart;
  355. TotalTime.QuadPart = TotalTime.QuadPart +
  356. TopCpu[num].TotalTime.QuadPart;
  357. TopCpu[num].ProcessInfo = CurProcessInfo;
  358. TopCpu[num].MatchedProcess = NULL;
  359. num += 1;
  360. } else {
  361. Ktime.QuadPart = CurProcessInfo->KernelTime.QuadPart -
  362. MatchedProcess->KernelTime.QuadPart;
  363. Utime.QuadPart = CurProcessInfo->UserTime.QuadPart -
  364. MatchedProcess->UserTime.QuadPart;
  365. if ((Ktime.QuadPart != 0) ||
  366. (Utime.QuadPart != 0)) {
  367. TopCpu[num].TotalTime = Ktime;
  368. TopCpu[num].TotalTime.QuadPart =
  369. TopCpu[num].TotalTime.QuadPart +
  370. Utime.QuadPart;
  371. TotalTime.QuadPart = TotalTime.QuadPart +
  372. TopCpu[num].TotalTime.QuadPart;
  373. TopCpu[num].ProcessInfo = CurProcessInfo;
  374. TopCpu[num].MatchedProcess = MatchedProcess;
  375. num += 1;
  376. }
  377. }
  378. if (CurProcessInfo->NextEntryOffset == 0) {
  379. for (i=0;i<num;i++) {
  380. PTopCpu = &TopCpu[i];
  381. Ktime.QuadPart =
  382. PTopCpu->ProcessInfo->KernelTime.QuadPart +
  383. PTopCpu->ProcessInfo->UserTime.QuadPart;
  384. RtlTimeToTimeFields ( &Ktime, &TimeOut);
  385. printf( "%4ld%% %p %7ld %7ld %7ld %3ld:%02ld:%02ld.%03ld %ws\n",
  386. (PTopCpu->TotalTime.LowPart*100)/TotalTime.LowPart,
  387. PTopCpu->ProcessInfo->UniqueProcessId,
  388. PTopCpu->ProcessInfo->PageFaultCount,
  389. PTopCpu->ProcessInfo->WorkingSetSize,
  390. PTopCpu->ProcessInfo->PrivatePageCount,
  391. TimeOut.Hour,
  392. TimeOut.Minute,
  393. TimeOut.Second,
  394. TimeOut.Milliseconds,
  395. (PTopCpu->ProcessInfo->ImageName.Buffer != NULL) ?
  396. PTopCpu->ProcessInfo->ImageName.Buffer :
  397. NoNameFound);
  398. Thread = (PSYSTEM_THREAD_INFORMATION)(TopCpu[i].ProcessInfo + 1);
  399. if (Type == CPU_THREAD) {
  400. for (j = 0;
  401. j < (int)TopCpu[i].ProcessInfo->NumberOfThreads;
  402. j++) {
  403. if (TopCpu[i].MatchedProcess == NULL) {
  404. MatchedThread = NULL;
  405. } else {
  406. MatchedThread = FindMatchedThread (
  407. Thread,
  408. TopCpu[i].MatchedProcess
  409. );
  410. }
  411. if (MatchedThread == NULL) {
  412. Ktime.QuadPart =
  413. Thread->KernelTime.QuadPart +
  414. Thread->UserTime.QuadPart;
  415. } else {
  416. Ktime.QuadPart =
  417. Thread->KernelTime.QuadPart -
  418. MatchedThread->KernelTime.QuadPart;
  419. Utime.QuadPart =
  420. Thread->UserTime.QuadPart -
  421. MatchedThread->UserTime.QuadPart;
  422. Ktime.QuadPart =
  423. Ktime.QuadPart +
  424. Utime.QuadPart;
  425. }
  426. if (Ktime.LowPart != 0) {
  427. printf(" %4ld%% TID%p Cs %5ld\n",
  428. (Ktime.LowPart*100)/TotalTime.LowPart,
  429. Thread->ClientId.UniqueThread,
  430. Thread->ContextSwitches);
  431. }
  432. Thread += 1;
  433. }
  434. }
  435. }
  436. }
  437. break;
  438. case FAULTS:
  439. if (MatchedProcess == NULL) {
  440. TopCpu[num].Value = CurProcessInfo->PageFaultCount;
  441. TopCpu[num].ProcessInfo = CurProcessInfo;
  442. num += 1;
  443. } else {
  444. TopCpu[num].Value = CurProcessInfo->PageFaultCount -
  445. MatchedProcess->PageFaultCount;
  446. if (TopCpu[num].Value != 0) {
  447. TopCpu[num].ProcessInfo = CurProcessInfo;
  448. num += 1;
  449. }
  450. }
  451. if (CurProcessInfo->NextEntryOffset == 0) {
  452. for (i=0;i<num;i++) {
  453. PTopCpu = &TopCpu[i];
  454. Ktime.QuadPart =
  455. PTopCpu->ProcessInfo->KernelTime.QuadPart +
  456. PTopCpu->ProcessInfo->UserTime.QuadPart;
  457. RtlTimeToTimeFields ( &Ktime, &TimeOut);
  458. printf( "Pf: %4ld %p %7ld %7ld %7ld %3ld:%02ld:%02ld.%03ld %ws\n",
  459. PTopCpu->Value,
  460. PTopCpu->ProcessInfo->UniqueProcessId,
  461. PTopCpu->ProcessInfo->PageFaultCount,
  462. PTopCpu->ProcessInfo->WorkingSetSize,
  463. PTopCpu->ProcessInfo->PrivatePageCount,
  464. TimeOut.Hour,
  465. TimeOut.Minute,
  466. TimeOut.Second,
  467. TimeOut.Milliseconds,
  468. (PTopCpu->ProcessInfo->ImageName.Buffer != NULL) ?
  469. PTopCpu->ProcessInfo->ImageName.Buffer :
  470. NoNameFound);
  471. }
  472. }
  473. break;
  474. case WORKING_SET:
  475. if (MatchedProcess == NULL) {
  476. TopCpu[num].Value = CurProcessInfo->PageFaultCount;
  477. TopCpu[num].ProcessInfo = CurProcessInfo;
  478. num += 1;
  479. } else {
  480. if (CurProcessInfo->WorkingSetSize !=
  481. MatchedProcess->WorkingSetSize) {
  482. TopCpu[num].Value =
  483. (ULONG)(CurProcessInfo->WorkingSetSize - MatchedProcess->WorkingSetSize);
  484. TopCpu[num].ProcessInfo = CurProcessInfo;
  485. num += 1;
  486. }
  487. }
  488. if (CurProcessInfo->NextEntryOffset == 0) {
  489. for (i=0;i<num;i++) {
  490. PTopCpu = &TopCpu[i];
  491. Ktime.QuadPart =
  492. PTopCpu->ProcessInfo->KernelTime.QuadPart +
  493. PTopCpu->ProcessInfo->UserTime.QuadPart;
  494. RtlTimeToTimeFields ( &Ktime, &TimeOut);
  495. printf( "Ws: %4ld %p %7ld %7ld %7ld %3ld:%02ld:%02ld.%03ld %ws\n",
  496. PTopCpu->Value,
  497. PTopCpu->ProcessInfo->UniqueProcessId,
  498. PTopCpu->ProcessInfo->PageFaultCount,
  499. PTopCpu->ProcessInfo->WorkingSetSize,
  500. PTopCpu->ProcessInfo->PrivatePageCount,
  501. TimeOut.Hour,
  502. TimeOut.Minute,
  503. TimeOut.Second,
  504. TimeOut.Milliseconds,
  505. (PTopCpu->ProcessInfo->ImageName.Buffer != NULL) ?
  506. PTopCpu->ProcessInfo->ImageName.Buffer :
  507. NoNameFound);
  508. }
  509. }
  510. break;
  511. case CONTEXT_SWITCHES:
  512. Thread = (PSYSTEM_THREAD_INFORMATION)(CurProcessInfo + 1);
  513. TopCpu[num].Value = 0;
  514. if (MatchedProcess == NULL) {
  515. for (j = 0; j < (int)CurProcessInfo->NumberOfThreads; j++ ) {
  516. TopCpu[num].Value += Thread->ContextSwitches;
  517. Thread += 1;
  518. }
  519. if (TopCpu[num].Value != 0) {
  520. TopCpu[num].ProcessInfo = CurProcessInfo;
  521. TopCpu[num].MatchedProcess = NULL;
  522. num += 1;
  523. }
  524. } else {
  525. for (j = 0; j < (int)CurProcessInfo->NumberOfThreads; j++ ) {
  526. MatchedThread = FindMatchedThread (
  527. Thread,
  528. MatchedProcess
  529. );
  530. if (MatchedThread == NULL) {
  531. TopCpu[num].Value += Thread->ContextSwitches;
  532. } else {
  533. TopCpu[num].Value +=
  534. Thread->ContextSwitches - MatchedThread->ContextSwitches;
  535. }
  536. Thread += 1;
  537. }
  538. if (TopCpu[num].Value != 0) {
  539. TopCpu[num].ProcessInfo = CurProcessInfo;
  540. TopCpu[num].MatchedProcess = MatchedProcess;
  541. num += 1;
  542. }
  543. }
  544. if (CurProcessInfo->NextEntryOffset == 0) {
  545. for (i=0;i<num;i++) {
  546. PTopCpu = &TopCpu[i];
  547. Ktime.QuadPart =
  548. PTopCpu->ProcessInfo->KernelTime.QuadPart +
  549. PTopCpu->ProcessInfo->UserTime.QuadPart;
  550. RtlTimeToTimeFields ( &Ktime, &TimeOut);
  551. printf( "Cs: %4ld %p %7ld %7ld %7ld %3ld:%02ld:%02ld.%03ld %ws\n",
  552. PTopCpu->Value,
  553. PTopCpu->ProcessInfo->UniqueProcessId,
  554. PTopCpu->ProcessInfo->PageFaultCount,
  555. PTopCpu->ProcessInfo->WorkingSetSize,
  556. PTopCpu->ProcessInfo->PrivatePageCount,
  557. TimeOut.Hour,
  558. TimeOut.Minute,
  559. TimeOut.Second,
  560. TimeOut.Milliseconds,
  561. (PTopCpu->ProcessInfo->ImageName.Buffer != NULL) ?
  562. PTopCpu->ProcessInfo->ImageName.Buffer :
  563. NoNameFound);
  564. Thread = (PSYSTEM_THREAD_INFORMATION)(TopCpu[i].ProcessInfo + 1);
  565. for (j = 0;
  566. j < (int)TopCpu[i].ProcessInfo->NumberOfThreads;
  567. j++) {
  568. ContextSwitches = 0;
  569. if (TopCpu[i].MatchedProcess == NULL) {
  570. MatchedThread = NULL;
  571. } else {
  572. MatchedThread = FindMatchedThread (
  573. Thread,
  574. TopCpu[i].MatchedProcess
  575. );
  576. }
  577. if (MatchedThread == NULL) {
  578. ContextSwitches = Thread->ContextSwitches;
  579. } else {
  580. ContextSwitches =
  581. Thread->ContextSwitches -
  582. MatchedThread->ContextSwitches;
  583. }
  584. if (ContextSwitches != 0) {
  585. printf("\t TID%p Cs %5ld%+3ld\n",
  586. Thread->ClientId.UniqueThread,
  587. Thread->ContextSwitches,
  588. ContextSwitches);
  589. }
  590. Thread += 1;
  591. }
  592. }
  593. }
  594. break;
  595. default:
  596. break;
  597. } //end switch
  598. if (CurProcessInfo->NextEntryOffset == 0) {
  599. break;
  600. }
  601. Offset1 += CurProcessInfo->NextEntryOffset;
  602. } //end while
  603. /*
  604. two snapshot buffers are maintained and swapped around
  605. since these buffers are now dynamic keep the bufsize in
  606. sync
  607. */
  608. TempBuffer = PreviousBuffer;
  609. PreviousBuffer = CurrentBuffer;
  610. CurrentBuffer = TempBuffer;
  611. pdwBufSize = bToggle ? &g_dwBufSize1 : &g_dwBufSize2;
  612. bToggle = !bToggle;
  613. retry1:
  614. Sleep(DelayTimeMsec);
  615. NtSetInformationProcess(
  616. NtCurrentProcess(),
  617. ProcessBasePriority,
  618. (PVOID) &SetBasePriority,
  619. sizeof(SetBasePriority)
  620. );
  621. Status = NtQuerySystemInformation(
  622. SystemProcessInformation,
  623. ( PVOID)CurrentBuffer,
  624. *pdwBufSize,
  625. NULL
  626. );
  627. if( Status == STATUS_INFO_LENGTH_MISMATCH )
  628. {
  629. *pdwBufSize *= 2;
  630. if( CurrentBuffer != NULL )
  631. {
  632. free( CurrentBuffer );
  633. }
  634. CurrentBuffer = ( PUCHAR )malloc( sizeof( UCHAR ) * ( *pdwBufSize ) );
  635. if( CurrentBuffer == NULL )
  636. {
  637. if( PreviousBuffer != NULL )
  638. {
  639. free( PreviousBuffer );
  640. }
  641. return 0;
  642. }
  643. }
  644. if ( !NT_SUCCESS(Status) ) {
  645. printf("Query Failed %lx\n",Status);
  646. goto retry1;
  647. }
  648. }
  649. return(0);
  650. }
  651. PSYSTEM_PROCESS_INFORMATION
  652. FindMatchedProcess (
  653. IN PSYSTEM_PROCESS_INFORMATION ProcessToMatch,
  654. IN PUCHAR SystemInfoBuffer,
  655. IN OUT PULONG Hint
  656. )
  657. /*++
  658. Routine Description:
  659. This procedure finds the process which corresponds to the ProcessToMatch.
  660. It returns the address of the matching Process, or NULL if no
  661. matching process was found.
  662. Arguments:
  663. ProcessToMatch - Supplies a pointer to the target thread to match.
  664. SystemInfoBuffer - Supples a pointer to the system information
  665. buffer in which to locate the process.
  666. Hint - Supplies and returns a hint for optimizing the searches.
  667. Return Value:
  668. Address of the corresponding Process or NULL.
  669. --*/
  670. {
  671. PSYSTEM_PROCESS_INFORMATION Process;
  672. ULONG Offset2;
  673. Offset2 = *Hint;
  674. while (TRUE) {
  675. Process = (PSYSTEM_PROCESS_INFORMATION)&SystemInfoBuffer[Offset2];
  676. if ((Process->UniqueProcessId ==
  677. ProcessToMatch->UniqueProcessId) &&
  678. ((Process->CreateTime.QuadPart ==
  679. ProcessToMatch->CreateTime.QuadPart))) {
  680. *Hint = Offset2 + Process->NextEntryOffset;
  681. return(Process);
  682. }
  683. Offset2 += Process->NextEntryOffset;
  684. if (Offset2 == *Hint) {
  685. *Hint = 0;
  686. return(NULL);
  687. }
  688. if (Process->NextEntryOffset == 0) {
  689. if (*Hint == 0) {
  690. return(NULL);
  691. }
  692. Offset2 = 0;
  693. }
  694. }
  695. }
  696. PSYSTEM_THREAD_INFORMATION
  697. FindMatchedThread (
  698. IN PSYSTEM_THREAD_INFORMATION ThreadToMatch,
  699. IN PSYSTEM_PROCESS_INFORMATION MatchedProcess
  700. )
  701. /*++
  702. Routine Description:
  703. This procedure finds thread which corresponds to the ThreadToMatch.
  704. It returns the address of the matching thread, or NULL if no
  705. matching thread was found.
  706. Arguments:
  707. ThreadToMatch - Supplies a pointer to the target thread to match.
  708. MatchedProcess - Supples a pointer to the process which contains
  709. the target thread. The thread information
  710. must follow this process, i.e., this block was
  711. obtain from a NtQuerySystemInformation specifying
  712. PROCESS_INFORMATION.
  713. Return Value:
  714. Address of the corresponding thread from MatchedProcess or NULL.
  715. --*/
  716. {
  717. PSYSTEM_THREAD_INFORMATION Thread;
  718. ULONG i;
  719. Thread = (PSYSTEM_THREAD_INFORMATION)(MatchedProcess + 1);
  720. for (i = 0; i < MatchedProcess->NumberOfThreads; i++) {
  721. if ((Thread->ClientId.UniqueThread ==
  722. ThreadToMatch->ClientId.UniqueThread) &&
  723. ((Thread->CreateTime.QuadPart ==
  724. ThreadToMatch->CreateTime.QuadPart))) {
  725. return(Thread);
  726. }
  727. Thread += 1;
  728. }
  729. return(NULL);
  730. }