-
Итак, сразу прошу прощения за грязь в коде. Вариант черновой.
Есть код ( в принципе, спер из инета и ничего не переделывал особо, признаюсь честно ):function FillProcessesList(var slProcesses: TStringList;
aProcessName: String = '1cv7s.exe'): Boolean;
var
ret: NTSTATUS;
pBuffer, pCur: PSYSTEM_PROCESSES;
ReturnLength: DWORD;
i: Integer;
c: String;
ProcessName, PN: String;
begin
Result := False;
ReturnLength := 0;
// Запрашиваем размер требуемого буфера
ZwQuerySystemInformation(SystemProcessesAndThreadsInformation, nil, 0,
ReturnLength);
// Резервируем буфер
pBuffer := AllocMem(ReturnLength);
// Получаем информацию о процессах в буфер
ret := ZwQuerySystemInformation(SystemProcessesAndThreadsInformation, pBuffer,
ReturnLength, ReturnLength);
if ret = STATUS_SUCCESS then // Проверяем успешность выполнения запроса
begin
pCur := pBuffer; // Инициируем указатель на текущую структуру
i := 0; // Инициируем счетчик процессов. Его можно и не использовать.
// Проходим в цикле по всей цепочке структур
slProcesses.Clear;
repeat
begin
// Смотрим длину имени процесса и если оно не равно 0,
// то читаем строку из буфера, иначе – имя = <неизвестно>
if pCur.ProcessName.Length = 0 then
ProcessName := '<неизвестно>'
else
ProcessName := WideCharToString(pCur.ProcessName.Buffer);
// Добавляем инфу о процессе в TStringList
if ProcessName = aProcessName then
begin
inc(i); // Увеличиваем счетчик процессов.
{
Format('%s|%d|%s|%s', [pe.szExeFile, pe.th32ProcessID, c,
GetProcessUser(pe.th32ProcessID)])); }
c := GetWindowCaption(pCur.ProcessId);
PN := pCur.ProcessName.Buffer;
slProcesses.Add(
Format('%s|%d|%s|%s', [PN, pCur.ProcessId, c,
GetProcessAccount(pCur.ProcessId)]));
end;
// Вычисляем указатель на следующую структуру SYSTEM_PROCESSES
// Для этого к адресу этой структуру прибавляем смещение следующей
// из поля NextEntryDelta
pCur := Ptr(DWORD(pCur) + pCur.NextEntryDelta);
// Крутим цикл, пока есть следующая структура
end;
Result := True;
until pCur.NextEntryDelta = 0;
end;
FreeMem(pBuffer);
// form1.btnNotify.Caption := IntToStr(slProcesses.Count);
Вопрос вот в чем.
Почему когда ПЕРВЫЙ РАЗ вызываешь эту функцию, она отрабатывает корректно, и все процессы показывает, а все последующие вызовы теряет ровно 1 процесс (причем похоже тот, что был запущен последним)? Причем иногда таки при вызове функции процесс в списке появляется. Но с дикой задержкой (около минуты) - как это победить? Форум уже курил, но именно такой проблемы не нашел... -
Rouse_ © (22.06.13 21:33) [1]просто не выводится последняя запись, поправь алгоритм
-
p © (22.06.13 21:34) [2]type
PUNICODE_STRING = ^UNICODE_STRING;
UNICODE_STRING = record
Length: USHORT;
MaximumLength: USHORT;
Buffer: PWideChar;
end;
CLIENT_ID = record
UniqueProcess: THandle;
UniqueThread: THandle;
end;
PCLIENT_ID = ^CLIENT_ID;
KPRIORITY = Integer;
_KWAIT_REASON = (
Executive,
FreePage,
PageIn,
PoolAllocation,
DelayExecution,
Suspended,
UserRequest,
WrExecutive,
WrFreePage,
WrPageIn,
WrPoolAllocation,
WrDelayExecution,
WrSuspended,
WrUserRequest,
WrEventPair,
WrQueue,
WrLpcReceive,
WrLpcReply,
WrVirtualMemory,
WrPageOut,
WrRendezvous,
WrKeyedEvent,
WrTerminated,
WrProcessInSwap,
WrCpuRateControl,
WrCalloutStack,
WrKernel,
WrResource,
WrPushLock,
WrMutex,
WrQuantumEnd,
WrDispatchInt,
WrPreempted,
WrYieldExecution,
WrFastMutex,
WrGuardedMutex,
WrRundown,
MaximumWaitReason);
KWAIT_REASON = _KWAIT_REASON;
SYSTEM_THREADS = record
KernelTime: FILETIME;
UserTime: FILETIME;
CreateTime: FILETIME;
WaitTime: ULONG;
StartAddress: PVOID;
ClientId: CLIENT_ID;
Priority: KPRIORITY;
BasePriority: LONG;
ContextSwitches: ULONG;
ThreadState: ULONG;
WaitReason: KWAIT_REASON;
end;
SYSTEM_PROCESS_INFORMATION = record
NextEntryOffset: ULONG;
NumberOfThreads: ULONG;
WorkingSetPrivateSize: Int64;
HardFaultCount: ULONG;
NumberOfThreadsHighWatermark: ULONG;
CycleTime: ULONGLONG;
CreateTime: FILETIME;
UserTime: FILETIME;
KernelTime: FILETIME;
ImageName: UNICODE_STRING;
BasePriority: KPRIORITY;
UniqueProcessId: THandle;
InheritedFromUniqueProcessId: THandle;
HandleCount: ULONG;
SessionId: ULONG;
UniqueProcessKey: ULONG_PTR;
PeakVirtualSize: SIZE_T;
VirtualSize: SIZE_T;
PageFaultCount: ULONG;
PeakWorkingSetSize: SIZE_T;
WorkingSetSize: SIZE_T;
QuotaPeakPagedPoolUsage: SIZE_T;
QuotaPagedPoolUsage: SIZE_T;
QuotaPeakNonPagedPoolUsage: SIZE_T;
QuotaNonPagedPoolUsage: SIZE_T;
PagefileUsage: SIZE_T;
PeakPagefileUsage: SIZE_T;
PrivatePageCountp: SIZE_T;
ReadOperationCount: Int64;
WriteOperationCount: Int64;
OtherOperationCount: Int64;
ReadTransferCount: Int64;
WriteTransferCount: Int64;
OtherTransferCount: Int64;
Threads: array [0 .. 0] of SYSTEM_THREADS;
end;
PSYSTEM_PROCESS_INFORMATION = ^SYSTEM_PROCESS_INFORMATION;
type
NTSTATUS = System.LongInt;
const
STATUS_SUCCESS = NTSTATUS($00000000);
STATUS_INFO_LENGTH_MISMATCH = NTSTATUS($C0000004);
var
SystemInformation: PVOID;
SystemInformationLength: ULONG;
ReturnLength: ULONG;
PSPI: PSYSTEM_PROCESS_INFORMATION;
begin
SystemInformationLength := $400;
GetMem(SystemInformation, SystemInformationLength);
Result := NtQuerySystemInformation(SystemProcessesAndThreadsInformation, SystemInformation, SystemInformationLength, @ReturnLength);
if (Result = STATUS_INFO_LENGTH_MISMATCH) then
begin
while (Result = STATUS_INFO_LENGTH_MISMATCH) do
begin
FreeMem(SystemInformation);
SystemInformationLength := SystemInformationLength * 2;
GetMem(SystemInformation, SystemInformationLength);
Result := NtQuerySystemInformation(SystemProcessesAndThreadsInformation, SystemInformation, SystemInformationLength, @ReturnLength);
end;
end;
try
if Result = STATUS_SUCCESS then
begin
PSPI := PSYSTEM_PROCESS_INFORMATION(SystemInformation);
repeat
if PSPI^.UniqueProcessId = 0 then
ProcessName := 'System Idle Process';
else
ProcessName := PSPI^.ImageName.Buffer;
if PSPI^.NextEntryOffset = 0 then
Break;
PSPI := PSYSTEM_PROCESS_INFORMATION(DWORD(PSPI) + PSPI^.NextEntryOffset);
until
False;
end;
finally
if SystemInformation <> nil then
FreeMem(SystemInformation);
SystemInformation := nil;
end;
end; -
p © (22.06.13 21:36) [3]NtQuerySystemInformation(SystemInformationClass: ULONG; SystemInformation: PVOID; SystemInformationLength: ULONG; ReturnLength: PULONG): NTSTATUS;