Создание процессов в Windows, часть II BOOL CreateProcess ( LPCTSTR lpApplicationName, // имя исполняемого модуля LPTSTR lpCommandLine, // команда командной строки LPSECURITY_ATTRIBUTES lpProcessAttributes, // указатель на дескриптор безопасности процесса LPSECURITY_ATTRIBUTES lpThreadAttributes, // указатель на дескриптор безопасности потока BOOL bInheritHandles, // бит, управляющий наследованием дескрипторов DWORD dwCreationFlags, // флаги приоритета, консоли и т.д. LPVOID lpEnvironment, // строки окружения LPCTSTR lpCurrentDirectory, // имя текущей директории LPSTARTUPINFO lpStartupInfo, // описатель начального состояния окна LPPROCESS_INFORMATION lpProcessInformation // структура, содержащая информацию о процессе );
Descriptor – индекс записи в структуре данных на уровне ядра или сама эта запись. Handle – описатель (дескриптор) объекта, целое число, используемое при манипуляции объектом на уровне пользователя. В зависимости от объекта смысл значения этого целого числа различен. Файловый описатель (file handle, FILE* fp;) является указателем на структуру, содержащую поле имени файла, поле указателя на буфер потока ввода/вывода и т.д. Описатель модуля (module handle) равен базовому адресу данного исполняемого модуля в адресном пространстве процесса. В случае объекта ядра, его описатель преобразуется в указатель на этот объект диспетчером объектов.
typedef struct _STARTUPINFO { DWORD cb; LPTSTR lpReserved; LPTSTR lpDesktop; LPTSTR lpTitle; DWORD dwX; DWORD dwY; DWORD dwXSize; DWORD dwYSize; DWORD dwXCountChars; DWORD dwYCountChars; DWORD dwFillAttribute; DWORD dwFlags; WORD wShowWindow; WORD cbReserved2; LPBYTE lpReserved2; Структура STARTUPINFO, содержащая информацию о начальных свойствах окна:
HANDLE hStdInput; HANDLE hStdOutput; HANDLE hStdError; } STARTUPINFO, *LPSTARTUPINFO;
typedef struct _PROCESS_INFORMATION { HANDLE hProcess; // описатель процесса HANDLE hThread; // описатель потока DWORD dwProcessId;//глобальный идентификатор процесса DWORD dwThreadId; //глобальный идентификатор потока } PROCESS_INFORMATION; Структура PROCESS_INFORMATION, содержащая идентификаторы процесса и начального потока: BOOL TerminateProcess( HANDLE hProcess, // описатель процесса UINT uExitCode // код выхода ); Дескриптор (описатель) процесса может использоваться для манипулирования процессом, в частности он может использоваться для его прекращения:
#include void main( void ) { STARTUPINFO si; PROCESS_INFORMATION pi; //char* cmdLine="cmd /C dir"; //Задание процесса с использованием командной строки ZeroMemory( &si, sizeof(si) ); //Выделение памяти для si и ее инициализация нулями si.cb = sizeof(si); // инициализация первого поля структуры STARTUPINFO ZeroMemory( &pi, sizeof(pi) ); //Выделение памяти для pi и ее инициализация нулями Пример создания процесса в Windows:
// Запускается дочерний процесс if( !CreateProcess( "C:\\Windows\\notepad.exe", //Исполняемый модуль NULL, //cmdLine, // Командная строка не используется NULL, // Дескриптор процесса не наследуется NULL, // Дескриптор потока не наследуется FALSE, // Открытые дескрипторы родительского процесса не //наследуется CREATE_NO_WINDOW, // Не создавать окна (консольного окна) NULL, // Используются переменные окружения родителя NULL, // Используется текущая директория родителя &si, // Указатель на структуру STARTUPINFO &pi ) // Указатель на структуру PROCESS_INFORMATION )
{ printf("System error code: %i\n",GetLastError()); } //Ожидание окончания дочернего процесса WaitForSingleObject( pi.hProcess, INFINITE ); // Закрытие дескрипторов процесса и начального потока CloseHandle( pi.hProcess ); CloseHandle( pi.hThread ); } Упражнение 1: протестировать вызов функции CreateProcess с флагами, перечисленными в таблице: ФлагЗначение CREATE_NO_WINDOWНе создавать новое окно CREATE_NEW_CONSOLEСоздать новое консольное окно ABOVE_NORMAL_PRIORITY_CLASSПриоритет выше обычного IDLE_PRIORITY_CLASSФоновый приоритет HIGH_PRIORITY_CLASSВысший приоритет
Получение информации о процессах #include int main(){ DWORD pID; HANDLE pHndl; HMODULE* modHndls; DWORD b_alloc=8, b_needed; char modName[MAX_PATH]; int i; pID=GetCurrentProcessId(); pHndl=OpenProcess(PROCESS_ALL_ACCESS,FALSE,pID); Чтение информации из PCB (Process control block) возможно с помощью интерфейса PSAPI (Process Status API), реализация psapi.dll, заголовочный файл psapi.h
while(1){ modHndls=(HMODULE*)malloc(b_alloc); EnumProcessModules(pHndl,modHndls,b_alloc,&b_needed); printf("%u %u\n",pID,pHndl); printf("%u %u\n",b_alloc, b_needed); if(b_alloc>=b_needed) break; else{ free(modHndls); b_alloc*=2; }
for(i=0;i
C:\Users\ewgenij\Documents\СибГУТИ\2011- spring\Лекции\Лекция3\Лаб3> exe C:\Users\ewgenij\Documents\шс\2011- spring\Лекции\Лекция3\Лаб3\2.exe ntdll.dll C:\Windows\system32\ntdll.dll kernel32.dll C:\Windows\system32\kernel32.dll PSAPI.DLL C:\Windows\system32\PSAPI.DLL Замечание: …> cl filename.c kernel32.lib psapi.lib
Упражнение 2: запустите приложение Internet Explorer и с помощью функций EnumProcesses, OpenProcess, EnumProcessModules, GetModuleBaseName и GetModuleFileName определите все модули процесса и места расположения, соответствующих им файлов. BOOL EnumProcesses( DWORD *lpidProcess, // массив идентификаторов процессов DWORD cb, // размер массива DWORD *cbNeeded // количество необходимых байт );