Конференция "WinAPI" » SYSTEM_THREADS [D7]
 
  • _bass (31.08.09 21:23) [0]
    По какой причине ZwQuerySystemInformation выводит не верную (на мой взгляд) информацию о потоках?

    Так вот описываю структуры :

    PClientID = ^TClientID;
    TClientID = packed record
    UniqueProcess:cardinal;
    UniqueThread:cardinal;
    end;

    PSYSTEM_THREADS = ^SYSTEM_THREADS;
    SYSTEM_THREADS = packed record
     KernelTime,
     UserTime,
     CreateTime: LARGE_INTEGER;
     WaitTime: dword;
     StartAddress: pointer;
     ClientId: TClientId;
     Priority,
     BasePriority,
     ContextSwitchCount: dword;
     State: dword;
     WaitReason: dword;
    end;

  • _bass (31.08.09 21:31) [1]
    Всмысле возвращает, а не выводит. Речь идет, напрмер, о идентификаторе.
  • Сергей М. © (31.08.09 21:41) [2]

    > не верную (на мой взгляд) информацию


    Полагаешь, что о твоём взгляде мы должны догадаться ?
  • _bass (31.08.09 21:48) [3]
    Я имею ввиду, что получаю не верные данные, потому что, наверное, не правильно их обрабатываю.
    В таком случае подскажите пожалуйста как вывести все ИД потоков процесса, например.
    Мой код -
    for i:=1 to Data^.ThreadCount do
     ShowMessage(IntToStr(Data^.Threads[i].ClientId.UniqueThread));

  • Rouse_ © (31.08.09 22:44) [4]
    У тебя тут Data неверная, да к тому-же непонятно как полученная.
    Можно что-то более понятное посмотреть?
  • _bass (31.08.09 23:11) [5]
    begin
     DSize := $4000;
     repeat
       DPtr := VirtualAlloc(nil, DSize, MEM_COMMIT or MEM_RESERVE, PAGE_READWRITE);
       if DPtr = nil then
         Exit;
       DStat := ZwQuerySystemInformation(5, DPtr, DSize, nil);
       if DStat = STATUS_INFO_LENGTH_MISMATCH then
       begin
           VirtualFree(DPtr, 0, MEM_RELEASE);
           DSize := DSize * 2;
       end;
     until DStat <> STATUS_INFO_LENGTH_MISMATCH;
     if DStat = STATUS_SUCCESS then  begin
       Data := DPtr;
       repeat
         if PChar(WideCharToString(Data^.ProcessName.Buffer))='procexp.exe' then
           for i := 1 to Data^.ThreadCount do
             Writeln(IntToStr(Data^.Threads[i].ClientId.UniqueThread));
         Data := Pointer(DWord(Data) + Data^.NextEntryDelta);
       until Data^.NextEntryDelta = 0;
     end;
     VirtualFree(DPtr, 0, MEM_RELEASE);
    end;

  • Rouse_ © (31.08.09 23:41) [6]
    На SystemProcessInformation динамический релок памяти избыточен. При коде  STATUS_INFO_LENGTH_MISMATCH она сама вернет нужный размер необходимой памяти.
    Посмотри вот этот пример, он достаточно хорошо показывает работу с потоками приложения: http://rouse.drkb.ru/winapi.php#pmm
  • _bass (01.09.09 15:23) [7]
    Как можно идентифицировать статические потоки в процессе?
  • Rouse_ © (01.09.09 16:28) [8]

    > Как можно идентифицировать статические потоки в процессе?

    Ну я же тебе код дал, смотри процедуру FillThreadsInfo
  • Сергей М. © (01.09.09 16:47) [9]

    > статические потоки


    Эт что еще за зверь ?
  • _bass (01.09.09 16:56) [10]
    Я имею ввиду, например, StartAddress. Он статический для каждого потока (я ошибаюсь?).
    В твоем коде я не увидел получения этой информации о потоке.
  • Rouse_ © (01.09.09 17:39) [11]

    > Я имею ввиду, например, StartAddress

    Он просто не выводится, но доступен в FillProcessList.
    на тебе демокод, раз уж настолько лениво самому разбираться.

    program ThreadList2;

    {$APPTYPE CONSOLE}

    {$R-}

    uses
     Windows,
     SysUtils;

    type
     PSYSTEM_THREADS = ^SYSTEM_THREADS;
     SYSTEM_THREADS  = record
       KernelTime: LARGE_INTEGER;
       UserTime: LARGE_INTEGER;
       CreateTime: LARGE_INTEGER;
       WaitTime: ULONG;
       StartAddress: Pointer;
       UniqueProcess: DWORD;
       UniqueThread: DWORD;
       Priority: Integer;
       BasePriority: Integer;
       ContextSwitchCount: ULONG;
       State: Longint;
       WaitReason: Longint;
     end;

     PSYSTEM_PROCESS_INFORMATION = ^SYSTEM_PROCESS_INFORMATION;
     SYSTEM_PROCESS_INFORMATION = packed record
       NextOffset: ULONG;
       ThreadCount: ULONG;
       Reserved1: array [0..5] of ULONG;
       CreateTime: FILETIME;
       UserTime: FILETIME;
       KernelTime: FILETIME;
       ModuleNameLength: WORD;
       ModuleNameMaxLength: WORD;
       ModuleName: PWideChar;
       BasePriority: ULONG;
       ProcessID: ULONG;
       InheritedFromUniqueProcessID: ULONG;
       HandleCount: ULONG;
       Reserved2 : array[0..1] of ULONG;
       PeakVirtualSize : ULONG;
       VirtualSize : ULONG;
       PageFaultCount : ULONG;
       PeakWorkingSetSize : ULONG;
       WorkingSetSize : ULONG;
       QuotaPeakPagedPoolUsage : ULONG;
       QuotaPagedPoolUsage : ULONG;
       QuotaPeakNonPagedPoolUsage : ULONG;
       QuotaNonPagedPoolUsage : ULONG;
       PageFileUsage : ULONG;
       PeakPageFileUsage : ULONG;
       PrivatePageCount : ULONG;
       ReadOperationCount : LARGE_INTEGER;
       WriteOperationCount : LARGE_INTEGER;
       OtherOperationCount : LARGE_INTEGER;
       ReadTransferCount : LARGE_INTEGER;
       WriteTransferCount : LARGE_INTEGER;
       OtherTransferCount : LARGE_INTEGER;
       ThreadInfo: array [0..0] of SYSTEM_THREADS;
     end;

     function NtQuerySystemInformation(
       SystemInformationClass: DWORD;
       SystemInformation : Pointer;
       SystemInformationLength : DWORD;
       var ReturnLength: DWORD
       ): DWORD; stdcall; external 'ntdll.dll';

    const
     SystemProcessesAndThreadsInformation = 5;
     STATUS_INFO_LENGTH_MISMATCH = $C0000004;
    var
     SystemInformation, Temp: PSYSTEM_PROCESS_INFORMATION;
     ReturnLength: DWORD;
     I: Integer;
    begin
     ReturnLength := SizeOf(SYSTEM_THREADS);
     // Запрашиваем размер требуемой памяти
     if NtQuerySystemInformation(
       SystemProcessesAndThreadsInformation,
       nil, 0, ReturnLength) <> STATUS_INFO_LENGTH_MISMATCH then Exit;
     if ReturnLength > 0 then
     begin
       // Выделяем память
       GetMem(SystemInformation, ReturnLength);
       try
         // Получаем список процессов
         if NtQuerySystemInformation(SystemProcessesAndThreadsInformation,
           SystemInformation, ReturnLength, ReturnLength) = 0 then
         begin
           // Бежим по списку и заносим каждый в список
           Temp := SystemInformation;
           repeat
             if Temp^.ModuleName = nil then
               writeln('System Idle Process, PID = 0')
             else
               writeln(String(Temp^.ModuleName), ', PID = ', Temp^.ProcessID);
             writeln('TheadIDs | StartAddr');
             writeln('=========|==========');
             for I := 0 to Temp^.ThreadCount - 1 do
               writeln(IntToHex(Temp^.ThreadInfo[I].UniqueThread, 8), ' | ',
                 IntToHex(Integer(Temp^.ThreadInfo[I].StartAddress), 8));
             writeln;
             writeln;
             Temp := Pointer(DWORD(Temp) + Temp^.NextOffset);
           until Temp^.NextOffset = 0;
         end;
       finally
         FreeMem(SystemInformation);
       end;
     end;
     readln;
    end.

  • _bass (01.09.09 18:12) [12]
    Благодарю!
  • pablov © (17.06.11 15:18) [13]
    Почему при  получении списка процессов через native api (NtQuerySystemInformation(); ZwQuerySystemInformation() ) не отображается последний запущенный процесс. Т.е. Temp^.NextOffset = 0, список запонен, а последнего поцесса в нем нет. Читал на каком-то форуме, что это баг и его легко обойти. Но я не могу догнать как Подскажите, умные головы ))
  • Rouse_ © (17.06.11 18:04) [14]
    Просто в этом примере не выводится самый последний. Т.е. когда Temp^.NextOffset = 0 это означает что сейчас получена самая последняя запись и ее тоже нужно вывести на экран, но происходит выход по условию.
    Перепиши вот так:

          // Бежим по списку и заносим каждый в список
          Temp := SystemInformation;
          while True do
          begin
            if Temp^.ModuleName = nil then
              writeln('System Idle Process, PID = 0')
            else
              writeln(String(Temp^.ModuleName), ', PID = ', Temp^.ProcessID);
            writeln('TheadIDs | StartAddr');
            writeln('=========|==========');
            for I := 0 to Temp^.ThreadCount - 1 do
              writeln(IntToHex(Temp^.ThreadInfo[I].UniqueThread, 8), ' | ',
                IntToHex(Integer(Temp^.ThreadInfo[I].StartAddress), 8));
            writeln;
            writeln;
            if Temp^.NextOffset = 0 then Break;
            Temp := Pointer(DWORD(Temp) + Temp^.NextOffset);
          end;

  • Игорь Шевченко © (17.06.11 21:37) [15]

    > Почему при  получении списка процессов через native api
    > (NtQuerySystemInformation(); ZwQuerySystemInformation()
    > ) не отображается последний запущенный процесс.


    отображается
  • pablov © (20.06.11 08:43) [16]
    Rouse_
    Спасибо, все получилось ))
 
Конференция "WinAPI" » SYSTEM_THREADS [D7]
Есть новые Нет новых   [134431   +11][b:0][p:0.004]