
- •1.1 Основы программирования в операционной системе Windows
- •1.1.1 Вызов функций api
- •1.1.2 Структура программы
- •1.2 Вопросы системного программирования в Windows
- •1.2.1 Страничная и сегментная адресация.
- •1.2.2 Адресное пространство процесса.
- •2.1 Управление процессами
- •2.2 Процессы и потоки в Windows
- •2.3 Создание процессов
- •2.4 Определение исполняемого образа и командной строки
- •2.5 Идентификация процессов
- •3.1 Создание потока. Функция CreateThread
- •3.2. Завершение потока
- •3.3 Другие функции работы с потоками
- •3.4 Структура context
- •3.5 Приоритеты потоков
- •4.1 Объект critical_section
- •4.2 Мьютексы
- •4.3 Семафоры
- •5.1 События
- •7.1 Кучи
- •7.2 Управление памятью кучи
- •Другие функции для работы с кучей
- •Резюме по управлению кучей
- •Отображение адресного пространства процесса в объекты отображения
- •Что такое импорт
- •Явная загрузка dll
- •Явное подключение экспортируемого идентификатора
- •10.1 Управление файлами и каталогами Создание и открытие файлов
- •10.2 Управление каталогами
- •10.3 Другие методы получения атрибутов файлов и каталогов
- •11.1 Блокировка файлов
- •11.2 Реестр
- •12.1 Стандартные устройства и консольный ввод-вывод
- •12.2 Асинхронный ввод-вывод и порты завершения
- •Параметры
- •Цели системы безопасности
- •Параметры
- •Аварийное завершение
- •Использование именованных каналов
- •Параметры
- •Наблюдение за сообщениями в именованном канале
- •Параметры
Явная загрузка dll
В любой момент поток может спроецировать DLL на адресное пространство процесса, вызвав одну из двух фунеций:
HINSTANCE LoadLibrary (PCTSTR pszDllPathName);
HINSTANCE LoadLibraryEx( PCTSTR pszDllPathName, HANDLE hFile,
DWORD dwFlags );
Обе функции ищут образ DLL-файла и пытаются спроецировать его на адресное пространство вызывающего процесса. Значение типа HINSTANCE, возвращаемое этими функциями, сообщает адрес виртуальной памяти, по которому спроецирован образ файда. При ошибке возвращается NULL (может посмотреть GetLastError).
Функция LoadLibraryEx: параметр hFile зарезервирован для использования в будуших версиях, и должен быть NULL. В параметре dwFlags можно передать либо 0, либо комбинацию флагов: DONT_RESOLVE_DLL_REFERENCES, LOAD_LIBRARY_AS _DATAFILE и LOAD_WITH_ALTERED_SEARCH_PATH
Явная выгрузка DLL
Если необходимость в DLL отпадает, ее можно выхрузить из адресного пространство процесса, вызвав функцию:
BOOL FreeLibrary (HINSTANCE hinstDll);
DLL можно выгрузить и с помощью другой функции:
VOID FreeLibraryAndExitThread ( HINSTANCE hinstDll, DWORD
dwExitCode);
Функции LoadLibrary и LoadLibraryEx увеличивают счетчик числа пользователей указанной библиотеки, а FreeLibrary и FreeLibraryAndExitThread его уменьшают. Так при первом вызове LoadLibrary для загрузки DLL система проецирует образ DLL-файла на адресного пространство вызывающего процесса и присваивает единицу счетчику числа пользователей этой DLL. Если поток того же процесса вызывает LoadLibrary для той же DLL еще раз, DLL больше не проецируется; система просто увеличивает счетчик числа ее пользователей.
Чтобы выгрузить DLL из адресного пространство процесса, FreeLibrary придется теперь вызывать дважды: первый вызов уменьшит счетчик до 1, второй – до 0. Обнаружив, что счетчик обнулен, система отключит DLL
Система поддерживает в каждом процессе свой счетчик DLL.
Чтобы определить спроецирована ли DLL на адресное пространство процесса, поток может вызвать функцию GetModuleHandle:
HINSTANCE GetModuleHandle(PCTSTR pszModuleName);
Например, следующий код загружает MyLib.dll, только если она еще не спроецирована на адресное пространство процесса:
HINSTANCE hinstDll=GetModuleHandle(“MyLib”);
if (hinstDll==NULL){
hinstDll=LoadLibrary(“MyLib”);
}
Если у нас имеется значение HINSTANCE для DLL, можно определить полное (вместе с путем) имя DLL или EXE с помощью GetModuleFileName:
DWORD GetModuleFileName( HINSTANCE hinstModule,
PTSTR pszPathName, DWORD cchPath);
Первый параметр этой функции – значение типа HINSTANCE нужной DLL (или EXE). Второй параметр, pszPathName, задает адрес буфера, в который она запишет полное имя файла. Третий – (cchPath) определяет размер буфера символах.
Явное подключение экспортируемого идентификатора
Поток получает адрес экспортируемого идентификатора из явно загружаемой DLL вызовом GetProcAddress:
FARPROC GetProcAddress( HINSTANCE hinstDll,
PCSTR pszSymbolName);
Параметр hinstDll – описатель, возвращенный LoadLibrary или GetModuleHandle и относящийся к DLL, которая содержит нужный идентификатор
Параметр pszSumbolName разрешается указывать в двух формах.
Во-первых, как адрес строки с нулевым символом в конце, содержащей имя интересующей нас функции:
FARPROC pfn = GetProcAddress ( hinstDll, ”SomeFuncInDll”);
Тип PCSTR указывает, что функция GetProcAddress принимает только ANSI строки. Идентификаторы функций и переменных в разделе экспорта DLL всегда хранятся как ASCII-строки
Вторая форма параметра pszSumbolName позволяет указывать порядковый номер нужной функции:
FARPROC pfn = GetProcAddress ( hinstDll, MAKEINTRESOURSE(2));
Здесь подразумевается, что нам известен порядковый номер (2) искомого идентификатора, присвоенный ему автором данной DLL. Microsoft не рекомендует пользоваться порядковыми номерами.
Функции ввода/вывода
В DLL может быть лишь одна функция ввода/вывода. Система вызывает ее в информационных целях, и обычно она используется DLL для инициализации и очистки ресурсов в конкеретных процессах и потоках. Если вашей DLL подобные уведомления не нужны, эту функцию можно не использовать (Пример – DLL, содержащая только ресурсы)
Пример использования функции:
BOOL WINAPI DllMain (HINSTANCE hinstDll, DWORD fdwReason,
PVOID fImpLoad){
switch (fwReason){
case DLL_PROCESS_ATTACH:
//DLL проецируется на адресное пространство процесса
break;
case DLL_THREAD_ATTACH:
//создается поток
break;
case DLL_THREAD_DETACH:
//поток корректно завершается
break;
case DLL_PROCESS_DETACH:
//DLL отключается от адресного пространство процесса
break;
}
return(TRUE); //используется только для DLL_PROCESS_ATTACH
Параметр hinstDll - описатель экземпляра DLL. (Виртуальный адрес проекции файла DLL на адресное пространство процесса)
Параметр fImpLoad – отличен от 0, если DLL загружена неявно, и равен 0, если DLL загружена явно.
Параметр fdwReason – сообщает о причине, по которой система вызвала эту функцию. Он принимает одно из значений: DLL_PROCESS_ATTACH, DLL_PROCESS_DETACH, DLL_THREAD_ATTACH, DLL_THREAD_DETACH
В документации Platform SDK утверждается, что DllMain должна выполнять лишь простые виды инициализации – настройку локальной памяти потока, создание объектов ядра, открытие файлов и т.д.
Из DllMain функции нельзя вызывать LoadLibrary(Ex) и FreeLibrary, так как это может привести к взаимной блокировке.
Нужно избегать обращений из DllMain к функциям, импортируемым их других DLL
Лекция 10. Тема: Использование файловой системы
Файлами обычно называют взаимосвязанные блоки данных на запоминающем устройстве, обозначенные именем, а в API Win32 файлами считают именованные каналы, ресурсы связи, дисковые устройства, потоки ввода или вывода на консоль или обычные файлы. По принципу организации все эти типы файлов являются одинаковыми, но отличаются друг от друга своими дополнительными свойствами и ограничениями. Файловые функции API Win32 позволяют приложениям получать доступ к файлам независимо от основополагающей файловой системы или типа устройства. Однака предоставляемые при этом возможности зависят от файловой системы, устройства или операционной системы.