Get the summary for MaxProcessSummaries processes starting from the top of list + SkipCount. @param SkipCount - How many processes to skip in the list. @param ProcessSummaries - Caller-supplied array of process summaries that this function fills. @param MaxProcessSumaries - Maximum number of process summaries that the array allows for. @return The actual number of summaries returned. */
| 678 | @return The actual number of summaries returned. |
| 679 | */ |
| 680 | ULONG |
| 681 | ImageHistoryFilter::GetProcessHistorySummary ( |
| 682 | _In_ ULONG SkipCount, |
| 683 | _Inout_ PPROCESS_SUMMARY_ENTRY ProcessSummaries, |
| 684 | _In_ ULONG MaxProcessSummaries |
| 685 | ) |
| 686 | { |
| 687 | PPROCESS_HISTORY_ENTRY currentProcessHistory; |
| 688 | ULONG currentProcessIndex; |
| 689 | ULONG actualFilledSummaries; |
| 690 | NTSTATUS status; |
| 691 | |
| 692 | currentProcessIndex = 0; |
| 693 | actualFilledSummaries = 0; |
| 694 | |
| 695 | if (ImageHistoryFilter::destroying) |
| 696 | { |
| 697 | return 0; |
| 698 | } |
| 699 | |
| 700 | // |
| 701 | // Acquire a shared lock to iterate processes. |
| 702 | // |
| 703 | FltAcquirePushLockShared(&ImageHistoryFilter::ProcessHistoryLock); |
| 704 | |
| 705 | // |
| 706 | // Iterate histories for the MaxProcessSummaries processes after SkipCount processes. |
| 707 | // |
| 708 | if (ImageHistoryFilter::ProcessHistoryHead) |
| 709 | { |
| 710 | currentProcessHistory = RCAST<PPROCESS_HISTORY_ENTRY>(ImageHistoryFilter::ProcessHistoryHead->ListEntry.Flink); |
| 711 | while (currentProcessHistory && currentProcessHistory != ImageHistoryFilter::ProcessHistoryHead && actualFilledSummaries < MaxProcessSummaries) |
| 712 | { |
| 713 | if (currentProcessIndex >= SkipCount) |
| 714 | { |
| 715 | // |
| 716 | // Fill out the summary. |
| 717 | // |
| 718 | ProcessSummaries[actualFilledSummaries].EpochExecutionTime = currentProcessHistory->EpochExecutionTime; |
| 719 | ProcessSummaries[actualFilledSummaries].ProcessId = currentProcessHistory->ProcessId; |
| 720 | ProcessSummaries[actualFilledSummaries].ProcessTerminated = currentProcessHistory->ProcessTerminated; |
| 721 | |
| 722 | if (currentProcessHistory->ProcessImageFileName) |
| 723 | { |
| 724 | // |
| 725 | // Copy the image name. |
| 726 | // |
| 727 | status = RtlStringCbCopyUnicodeString(RCAST<NTSTRSAFE_PWSTR>(&ProcessSummaries[actualFilledSummaries].ImageFileName), MAX_PATH * sizeof(WCHAR), currentProcessHistory->ProcessImageFileName); |
| 728 | if (NT_SUCCESS(status) == FALSE) |
| 729 | { |
| 730 | DBGPRINT("ImageHistoryFilter!GetProcessHistorySummary: Failed to copy the image file name with status 0x%X.", status); |
| 731 | break; |
| 732 | } |
| 733 | } |
| 734 | actualFilledSummaries++; |
| 735 | } |
| 736 | currentProcessIndex++; |
| 737 | currentProcessHistory = RCAST<PPROCESS_HISTORY_ENTRY>(currentProcessHistory->ListEntry.Flink); |