Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
WIN32 API.DOC
Скачиваний:
28
Добавлен:
13.07.2019
Размер:
206.34 Кб
Скачать

Лекция 2

Объекты ядра

Существуют следующие объекты ядра ОС: процессы, потоки, каналы, мьютексы, проекции файлов, почтовые ящики, семафоры, события, файловые объекты. Они создаются функциями Win32. Структура этих объектов недоступна программам, поэтому работа с объектами ядра происходит посредством вызова функций Win32. С этой целью функции создания объекта возвращают так называемый описатель (handle) объекта. Например: function CreateThread(…): THandle;

Объекты ядра принадлежат не процессу, а самому ядру, поэтому каждый объект ядра имеет в своей структуре счетчик пользователей. Когда ваша программа разрушает объект, это не означает, что он будет уничтожен, так как в данный момент может использоваться другой программой. В этом случае счетчик пользователя объектов уменьшается на единицу.

Объекты ядра можно защитить дескриптором защиты, который описывает, кто создал объект и кто имеет права на доступ к нему. Практически все функции создания объектов содержат параметр типа

TSecurityAttributes = record

nLength: DWORD;

lpSecurityDescriptor: Pointer;

bInheritHandle: BOOL;

end;

В Windows 95 lpSecurityDescriptor не поддерживается.

При создании дочернего процесса наследование описателей из родительского процессе выполняется, если установлен bInheritHandle.

Закрытие объекта производится вызовом функции function CloseHandle( hObject :Thandle ):bool. После вызова CloseHandle Вы не сможете получить доступ к объекту, тем не менее, он может оставаться в памяти, если счетчик пользователей не обнулен. После завершения процесса ОС очищает таблицу описателей, освобождая ресурсы.

Существует функция, которая позволяет скопировать описатель объекта. Применяя данную функцию можно использовать один и тот же объект в разных процессах.

function DuplicateHandle(hSourceProcessHandle, hSourceHandle,

hTargetProcessHandle: THandle;

lpTargetHandle: PHandle; dwDesiredAccess: DWORD;

bInheritHandle: BOOL; dwOptions: DWORD): BOOL;

hSourceProcessHandle, hTargetProcessHandle - описатели процессов

hSourceHandle - описатель любого объекта ядра

lpTargetHandle - возвращается описатель скопированного объекта ядра

dwDesiredAccess - маска доступа к скопированному объекту

bInheritHandle - флаг наследования

dwOptions - DUPLICATE_CLOSE_SOURCE или DUPLICATE_SAME_ACCESS

DUPLICATE_SAME_ACCESS - игнорирует dwDesiredAccess и копирует условия доступа к объекту

DUPLICATE_CLOSE_SOURCE - после копирования закрывает описатель в процессе источнике.

Лекция 3

Процессы и потоки

  • Процесс - это экземпляр выполняемой программы. Процессу отводится 4 Гб адресного пространства. Процесс в Win32 является инертным, т.е. он ничего не выполняет, а только владеет адресным пространством, куда загружаются код и данные EXE файла и DLL библиотек.

Так как процессы инертны, чтобы выполнить код программы необходимо создать поток. У процесса потоков может быть несколько. Все они будут выполнять код программы "одновременно".

Чтобы все потоки работали, ОС выделяет каждому из них определенные отрезки времени, которые называются квантами. Время выделяется по принципу карусели.

Функция создания процесса

function CreateProcess(lpApplicationName: PChar;

lpCommandLine: PChar;

lpProcessAttributes, lpThreadAttributes: PSecurityAttributes;

bInheritHandles: BOOL;

dwCreationFlags: DWORD;

lpEnvironment: Pointer;

lpCurrentDirectory: PChar;

const lpStartupInfo: TStartupInfo;

var lpProcessInformation: TProcessInformation): BOOL;

Функция создает объект ядра - процесс, создает виртуальное адресное пространство 4 Гб, загружает в него код и данные EXE файла. Далее ОС создает объект ядра - первичный поток процесса. Первичный поток начинает работу со стартового кода. При удачном создании процесса функция вернет TRUE, иначе False. Код ошибки можно узнать, вызвав функцию function GetLastError: DWORD.

lpCommandLine - командная строка, содержащая имя выполняемого файла и параметры командной строки. Например, Pchar('notepad.exe myfile.txt'). Функция начинает искать заданный файл в следующем порядке:

  1. Каталог, содержащий EXE-файл вызывающего процесса

  2. Текущий каталог вызывающего процесса

  3. Системный каталог Windows

  4. Основной каталог Windows

  5. Каталоги, перечисленные в переменной окружения PATH

Все это произойдет, если в LpCommandLine не указан путь по EXE-файла и если lpApplicationName = nil. Если lpApplicationName - строка не пустая система считает, что в ней задано имя выполняемой программы, причем находящейся в текущем каталоге.

lpProcessAttributes, lpThreadAttributes - атрибуты защиты для процесса и первичного потока.

bInheritHandles - флаг наследования.

dwCreationFlags - определяет флаги, влияющие на то, как именно создается новый процесс.

DEBUG_PROCESS - позволяет родительскому процессу проводить отладку всех дочерних процесса. Родительский процесс уведомляется о наступлении определенных событий.

DEBUG_ONLY_THIS_PROCESS - позволяет родительскому процессу проводить отладку только прямого потомка

CREATE_SUSPENDED - приостанавливает выполнение первичного потока

DETACHED_PROCESS - ???

CREATE_NEW_CONSOLE - приводит к созданию нового консольного окна

CREATE_NO_WINDOW - не дает создавать консольное окно

CREATE_NEW_PROCESS_GROUP - ???

CREATE_DEFAULT_ERROR_MODE - запрещает наследования режимов обработки событий

CREATE_SEPARATE_WOW_VDM - используется для запуска 16 разрядных приложений в Windows NT. Заставляет открывать для процесса отдельную Virtual DOS-machine (VDM). В Windows 95 все DOS приложения выполняются в одной VDM.

CREATE_SHARED_WOW_VDM - имеет обратное действие.

CREATE_UNICODE_ENVIRONMENT - определяет, что переменные окружения содержат Unicode-символы. По умолчанию ANSI символы.

При создании процесса можно указать его класс приоритета:

NORMAL_PRIORITY_CLASS-

IDLE_PRIORITY_CLASS-

HIGH_PRIORITY_CLASS-

REALTIME_PRIORITY_CLASS-

lpEnvironment - Параметр указывает на блок памяти, хранящий строки переменных окружения нового процесса. Если nil - тогда переменные окружения наследуются от родительского процесса.

lpCurrentDirectory - позволяет установить текущий диск и каталог для создаваемого процесса. Если nil то текущий каталог и диск устанавливается такой же, как и у родительского процесса.

lpStartupInfo - элементы данной структуры определяют различные атрибуты при создании нового процесса. Обычно используются атрибуты по умолчанию, поэтому необходимо заполнить данную структуру нулями и записать в lpStartupInfo.cb размер структуры.

Пример:

Var si :TStartupInfo;

begin

ZeroMemory(@si,SizeOf(si));

si.cb:=SizeOf(si);

end;

lpProcessInformation - возвращает информацию о созданном процессе и его первичном потоке.

TProcessInformation = record

hProcess: THandle;

hThread: THandle;

dwProcessId: DWORD;

dwThreadId: DWORD;

end;

dwProcessId, dwThreadId - уникальные идентификаторы процесса и потока

Пример:

procedure TForm1.Button1Click(Sender: TObject);

var

si :TStartupInfo;

pi :TProcessInformation;

begin

ZeroMemory(@si,SizeOf(si));

si.cb:=SizeOf(si);

if not CreateProcess

(nil,

PChar('notepad.exe'),

nil, //lpProcessAttributes

nil, //lpThreadAttributes: PSecurityAttributes;

True, //bInheritHandles: BOOL;

NORMAL_PRIORITY_CLASS,//dwCreationFlags: DWORD;

nil, // lpEnvironment: Pointer;

nil, //lpCurrentDirectory: PChar;

si, //const lpStartupInfo: TStartupInfo;

pi)

then raise Exception.Create(SysErrorMessage(GetLastError));

LabelProcID.Caption:='ID процесса $'+IntToHex(pi.dwProcessId,32);

LabelThreadID.Caption:='ID потока $'+IntToHex(pi.dwThreadID,32);

// закрываем

if not CloseHandle(pi.hThread)

then raise Exception.Create(SysErrorMessage(GetLastError));

if not CloseHandle(pi.hProcess)

then raise Exception.Create(SysErrorMessage(GetLastError));

end;

Несколько полезных функций, относящихся к процессу.

function GetCommandLine: PChar; - возвращает командную строку процесса.

function GetEnvironmentVariable(lpName: PChar; lpBuffer: PChar; nSize: DWORD): DWORD; - выявляет присутствие переменной окружения lpName и записывает ее значение в lpBuffer. nSize- размер буфера. Функция возвращает кол-во скопированных символов или 0.

function SetEnvironmentVariable(lpName, lpValue: PChar): BOOL; - позволяет удалять, добавлять и модифицировать значение переменной lpName.

function GetCurrentDirectory(nBufferLength: DWORD; lpBuffer: PChar): DWORD;

function SetCurrentDirectory(lpPathName: PChar): BOOL; - получает и устанавливает текущий каталог процесса.

function GetCurrentProcess: THandle; - возвращает описатель текущего процесса

function GetCurrentProcessId: DWORD; - возвращает идентификатор текущего процесса

Завершить процесс можно тремя способами

  1. Один из потоков вызывает функцию procedure ExitProcess(uExitCode: UINT); uExitCode - код возврата.

  2. Поток другого процесса вызывает function TerminateProcess(hProcess: THandle; uExitCode: UINT): BOOL;

  3. Все потоки процесса умирают по своей воле.

Пример:

procedure TForm1.Button2Click(Sender: TObject);

begin

if not TerminateProcess(pi.hProcess,0)

then raise Exception.Create(SysErrorMessage(GetLastError));

if not CloseHandle(pi.hProcess)

then raise Exception.Create(SysErrorMessage(GetLastError));

end;

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]