Здравствуйте. Проблема следующая: необходимо получить список всех потоков в Windows NT. Пишу я значит примерно следующий код: Код (Text): ............ typedef int (_stdcall *NtQuerySysInfPtr)(SYSTEM_INFORMATION_CLASS,PVOID,ULONG,PULONG); int _tmain(int argc, _TCHAR* argv[]) { NtQuerySysInfPtr NtQuerySysInformation = (NtQuerySysInfPtr)GetProcAddress(GetModuleHandle(L"ntdll.dll"),"NtQuerySystemInformation"); if(NtQuerySysInformation != NULL) { SYSTEM_PROCESS_INFORMATION Buffer[1000]; memset(Buffer,0,1000*sizeof( SYSTEM_PROCESS_INFORMATION )); ULONG cVar = 0; NtQuerySysInformation((SYSTEM_INFORMATION_CLASS)5/*SystemProcessInformation*/,(PVOID)Buffer,cVar,&cVar); DWORD Result = GetLastError(); printf("Error code is %d\n",Result); for(int i = 0;i <= 5;i++) printf("%d\n",Buffer[i].UniqueProcessId); ............................................ } else { ....... } } Результат: Error code is 0 и Buffer остался пустым. В чем может быть причина? И еще,в некоторых исходниках в сети NtQuerySystemInformation первым параметром передается SystemProcessAndThreadInformation. В Winternl.h структура SYSTEM_INFORMATION_CLASS определена следующим образом: Код (Text): typedef enum _SYSTEM_INFORMATION_CLASS { SystemBasicInformation = 0, SystemPerformanceInformation = 2, SystemTimeOfDayInformation = 3, SystemProcessInformation = 5, SystemProcessorPerformanceInformation = 8, SystemInterruptInformation = 23, SystemExceptionInformation = 33, SystemRegistryQuotaInformation = 37, SystemLookasideInformation = 45 } SYSTEM_INFORMATION_CLASS; и в ней нет значения SystemProcessAndThreadInformation. Жду Ваших соображений.
Как уже спросили -- какой статус возвращается? И что находится в переменной cVar после выполнения ф-ии?
что еще за NT_ERROR, нет такого статуса... какое значение то? http://source.winehq.org/source/include/ntstatus.h скорее всего размер буффера неподходящий... и еще: выделяйте память в куче, а не на стеке...
Rel Извиняюсь . На другую страницу посмотрел - STATUS_INFO_LENGTH_MISMATCH. Видимо размер буффера маловат. На счет стека учту. Обычно память там никогда не выделяю,а тем более такие объемы. Это меня переклинило видимо от Nt-функций. До этого сталкивался с ними только при крекинге,и то не часто. А если я попытаюсь выделить в стеке объем памяти,превосходящий размер стека или кучи что произойдет в процессе? Добавит ли память система автоматически ? Когда-то, около года назад,когда начинал на C программировать писал какую-то термодинамическую ерунду ради интереса и выделил интовый массив размером за 1000000. Тогда WINDOWS закрыла программу.
если вы используете кучу процесса (GetProcessHeap), то размер кучи будет увеличен при переполнении... если вы создаете отдельную кучу, то чтобы избежать проблем, при создании не фиксируйте ее размер... на стеке я бы не стал большие размеры резервировать...
Память выделил в куче,увеличил размер массива до 10000 - STATUS_INFO_LENGTH_MISMATCH и буффер пуст. Странно как-то структуры обнулил,импортируется функция вроде та что надо,процессов ну явно ни как не больше 10000. вообще ничего не понятно. Может Zw-функцию использовать?
И еще,пока не забыл,в своих рассуждениях я опираюсь на структуры: Код (Text): typedef struct _SYSTEM_THREADS { LARGE_INTEGER KernelTime; LARGE_INTEGER UserTime; LARGE_INTEGER CreateTime; ULONG WaitTime; PVOID StartAddress; CLIENT_ID ClientId; KPRIORITY Priority; KPRIORITY BasePriority; ULONG ContextSwitchCount; THREAD_STATE State; KWAIT_REASON WaitReason; } SYSTEM_THREADS, *PSYSTEM_THREADS; typedef struct _SYSTEM_PROCESSES { // Information Class 5 ULONG NextEntryDelta; ULONG ThreadCount; ULONG Reserved1[6]; LARGE_INTEGER CreateTime; LARGE_INTEGER UserTime; LARGE_INTEGER KernelTime; UNICODE_STRING ProcessName; KPRIORITY BasePriority; ULONG ProcessId; ULONG InheritedFromProcessId; ULONG HandleCount; ULONG Reserved2[2]; VM_COUNTERS VmCounters; IO_COUNTERS IoCounters; // Windows 2000 only SYSTEM_THREADS Threads[1]; } SYSTEM_PROCESSES, *PSYSTEM_PROCESSES; для начала получить список процессов,вывести в окно в какой - либо форме и далее выводить по команде для каждого из них диалог отображающий все его потоки. Но в структуре SYSTEM_PROCESSES массив элементов SYSTEM_THREADS имеет фиксированный размер,а именно 1. А как быть с остальными потоками?
Mika0x65 Замечательно ! Теперь пашет. По крайней мере структура уже не заполнена нулями. Да и PIDы вроде на реальные похожи. Потом протестить надо будет. Как я забыл в эту переменную размер буффера записать сам не знаю. В MSDN описалово этой ф-и перечитывал раза 4 ,а это нюанс продолбал.
он не имеет фиксированного размера... за систем_процесс идет N структур систем_тред, начиная с поля Threads... а написано так специально, чтобы это поле в языке си представляло собой указатель сам на себя, чтобы можно было обращаться к нему по индексу (Threads[t], где t - номер потока)... в принципе это тоже самое, что написать Threads[]... а поскольку таким вот образом структура систем_процесс получилась нефиксированного размера, то было введено поле смещения следующего эклемента относительно текущего (первый дворд в структуре)... и вообще, как я уже советовал, возьмите хедер из ddk, так проще, да и та структура, что вы привели не будет корректно работать на x64...
Rel Спасибо за ответы и рекомендации. Халявный DDK достану только в субботу,вот тогда и перепишу учитывая все вышесказанное.