Создание эффективных WIN32-приложений с учетом специфики 64-разрядной версии Windows

Создание эффективных WIN32-приложений с учетом специфики 64-разрядной версии Windows

Сегодняшние Windows-платформы
Ядро Windows 2000
Ядро Windows 98
Ядро Windows CE
Завтрашние Windows-платформы (64-разрядная Windows 2000)
Что нового в четвертом издании
В этой книге нет ошибок

Содержимое компакт-диска и требования к системе



Создание эффективных WIN32-приложений с учетом специфики 64-разрядной версии Windows

Вы тоже можете это сделать
Программа-пример ErrorShow

Создание эффективных WIN32-приложений с учетом специфики 64-разрядной версии Windows

Наборы символов
Одно- и двухбайтовые наборы символов

Unicode: набор широких символов
Почему Unicode?
Windows 2000 и Unicode
Windows 98 и Unicode
Windows CE и Unicode
В чью пользу счет?
Unicode и СОМ
Как писать программу с использованием Unicode
Unicode и библиотека С

Типы данных, определенные в Windows для Unicode
Unicode- и ANSI-функции в Windows
Строковые функции Windows
Создание программ, способных использовать и ANSI, и Unicode
Ресурсы
Текстовые файлы

Перекодировка строк из Unicode в ANSI и обратно

Создание эффективных WIN32-приложений с учетом специфики 64-разрядной версии Windows

Что такое объект ядра
Учет пользователей объектов ядра
Защита
Таблица описателей объектов ядра
Создание объекта ядра

Закрытие объекта ядра
Совместное использование объектов ядра несколькими процессами
Наследование описателя объекта
Именованные объекты

Дублирование описателей объектов

Создание эффективных WIN32-приложений с учетом специфики 64-разрядной версии Windows

Ваше первое Windows-приложение

Описатель экземпляра процесса
Описатель предыдущего экземпляра процесса
Командная строка процесса
Переменные окружения
Привязка к процессорам
Режим обработки ошибок

Текущие диск и каталог для процесса
Текущие каталоги для процесса
Определение версии системы
Функция CreateProcess
Параметры pszApplicationName и pszCommandLine
Параметры psaProcess, psaThread и blnheritHandles
Параметр fdwCreate

Параметр pvEnvironment
Параметр pszCurDir
Параметр psiStartlnfo
Параметр ppiProclnfo

Завершение процесса
Возврат управления входной функцией первичного потока
Функция ExitProcess
Функция TerminateProcess
Когда все потоки процесса уходят
Что происходит при завершении процесса
Дочерние процессы
Запуск обособленных дочерних процессов

Перечисление процессов, выполняемых в системе
Программа-пример Processlnfo

Создание эффективных WIN32-приложений с учетом специфики 64-разрядной версии Windows

Определение ограничений, налагаемых на процессы в задании
Включение процесса в задание

Завершение всех процессов в задании
Получение статистической информации о задании
Уведомления заданий
Программа-пример JobLab

Создание эффективных WIN32-приложений с учетом специфики 64-разрядной версии Windows

В каких случаях потоки создаются

И в каких случаях потоки не создаются
Ваша первая функция потока
Функция CreateThread
Параметр psa
Параметр cbStack
Параметры pfnStartAddr и pvParam
Параметр fdwCreate
Параметр pdwThreadlD
Завершение потока
Возврат управления функцией потока

Функция ExitThread
Функция TerminateThread
Если завершается процесс
Что происходит при завершении потока
Кое-что о внутреннем устройстве потока
Некоторые соображения по библиотеке С/С++

Ой, вместо _beginthreadex я по ошибке вызвал CreateThread
Библиотечные функции, которые лучше не вызывать
Как узнать о себе
Преобразование псевдоописателя в настоящий описатель

Создание эффективных WIN32-приложений с учетом специфики 64-разрядной версии Windows


Приостановка и возобновление потоков
Приостановка и возобновление процессов
Функция Sleep
Переключение потоков
Определение периодов выполнения потока
Структура CONTEXT

Приоритеты потоков
Абстрагирование приоритетов
Программирование приоритетов

Динамическое изменение уровня приоритета потока
Подстройка планировщика для активного процесса
Программа-пример Scheduling Lab
Привязка потоков к процессорам

Создание эффективных WIN32-приложений с учетом специфики 64-разрядной версии Windows

Атомарный доступ: семейство Inferlockect-функций

Кэш-линии
Более сложные методы синхронизации потоков
Худшее, что можно сделать

Критические секции
Критические секции: важное дополнение
Критические секции и спин-блокировка
Критические секции и обработка ошибок
Несколько полезных приемов

Создание эффективных WIN32-приложений с учетом специфики 64-разрядной версии Windows

Wait-функции
Побочные эффекты успешного ожидания
События

Программа-пример Handshake
Ожидаемые таймеры
Ожидаемые таймеры и АРС-очередь
И еще кое-что о таймерах

Семафоры
Мьютексы
Отказ от объекта-мьютекса
Мьютексы и критические секции
Программа-пример Queue

Сводная таблица объектов, используемых для синхронизации потоков
Другие функции, применяемые в синхронизации потоков
Асинхронный ввод-вывод на устройствах
Функция WaitForlnputldle
Функция MsgWaitForMultipleObjects(Ex)
Функция WaitForDebugEvent
Функция SignalObjectAndWait

Создание эффективных WIN32-приложений с учетом специфики 64-разрядной версии Windows

Реализация критической секции: объект-оптекс

Программа-пример Optex
Создание инверсных семафоров и типов данных, безопасных в многопоточной среде
Программа-пример lnterlockedType
Синхронизация в сценарии "один писатель/группа читателей"

Программа-пример SWMRG
Реализация функции WaitForMultipleExpressions
Программа-пример WaitForMultExp

Создание эффективных WIN32-приложений с учетом специфики 64-разрядной версии Windows

Сценарий 1: асинхронный вызов функций

Сценарий 2: вызов функций через определенные интервалы времени
Программа-пример TimedMsgBox
Сценарий 3: вызов функций при освобождении отдельных объектов ядра
Сценарий 4; вызов функций по завершении запросов на асинхронный ввод-вывод
Работа с волокнами
Программа-пример Counter

Создание эффективных WIN32-приложений с учетом специфики 64-разрядной версии Windows

Виртуальное адресное пространство процесса
Как адресное пространство разбивается на разделы
Раздел для выявления нулевых указателей (Windows 2000 и Windows 98)
Раздел для совместимости с программами DOS и 16-разрядной Windows (только Windows 98)
Раздел для кода и данных пользовательского режима (Windows 2000 и Windows 98)

Закрытый раздел размером 64 Кб (только Windows 2000)
Раздел для общих MMF (только Windows 98)
Раздел для кода и данных режима ядра (Windows 2000 и Windows 98)
Регионы в адресном пространстве
Передача региону физической памяти
Физическая память и страничный файл
Физическая память в страничном файле не хранится

Атрибуты защиты
Защита типа «копирование при записи»
Специальные флаги атрибутов защиты
Подводя итоги
Блоки внутри регионов
Особенности адресного пространства в Windows 98

Выравнивание данных

Создание эффективных WIN32-приложений с учетом специфики 64-разрядной версии Windows

Системная информация
Программа-пример Syslnfo
Статус виртуальной памяти
Программа-пример VMStat

Определение состояния адресного пространства
Функция VMQuery
Программа-пример VMMap

Создание эффективных WIN32-приложений с учетом специфики 64-разрядной версии Windows

Резервирование региона в адресном пространстве
Передача памяти зарезервированному региону
Резервирование региона с одновременной передачей физической памяти

В какой момент региону передают физическую память
Возврат физической памяти и освобождение региона
В какой момент физическую память возвращают системе
Программа-пример VMAIloc
Изменение атрибутов защиты
Сброс содержимого физической памяти

Программа-пример MemReset
Программа-пример AWE

Создание эффективных WIN32-приложений с учетом специфики 64-разрядной версии Windows

Стек потока в Windows 98
Функция из библиотеки С/С++ для контроля стека

Программа-пример Summation

Создание эффективных WIN32-приложений с учетом специфики 64-разрядной версии Windows

Проецирование в память EXE- и DLL-файлов
Статические данные не разделяются несколькими экземплярами EXE или DLL
Статические данные разделяются несколькими экземплярами EXE или DLL

Программа-пример Applnst
Файлы данных, проецируемые в память
Метод 1: один файл, один буфер
Метод 2: два файла, один буфер
Метод 3: один файл, два буфера
Метод 4: один файл и никаких буферов
Использование проецируемых в память файлов
Этап1: создание или открытие объекта ядра «файл»
Этап 2: создание объекта ядра «проекция файла»

Этап 3: проецирование файловых данных на адресное пространство процесса
Этап 4: отключение файла данных от адресного пространства процесса
Этапы 5 и 6: закрытие объектов «проекция файла» и «файл»
Программа-пример FileRev

Обработка больших файлов
Проецируемые файлы и когерентность
Базовый адрес файла, проецируемого в память
Особенности проецирования файлов на разных платформах
Совместный доступ процессов к данным через механизм проецирования

Файлы, проецируемые на физическую память из страничного файла
Программа-пример MMFShare
Частичная передача физической памяти проецируемым файлам
Программа-пример MMFSparse

Создание эффективных WIN32-приложений с учетом специфики 64-разрядной версии Windows

Стандартная куча процесса
Дополнительные кучи в процессе
Защита компонентов
Более эффективное управление памятью

Локальный доступ
Исключение издержек, связанных с синхронизацией потоков
Быстрое освобождение всей памяти в куче
Создание дополнительной кучи
Выделение блока памяти из кучи
Изменение размера блока
Определение размера блока
Освобождение блока
Уничтожение кучи

Использование куч в программах на С++
Другие функции управления кучами

Создание эффективных WIN32-приложений с учетом специфики 64-разрядной версии Windows

DLL и адресное пространство процесса
Общая картина

Создание DLL-модуля
Что такое экспорт
Создание DLL для использования с другими средствами разработки (отличными от Visual C++)
Создание ЕХЕ-модуля
Что такое импорт
Выполнение ЕХЕ-модуля

Создание эффективных WIN32-приложений с учетом специфики 64-разрядной версии Windows

Явная загрузка DLL и связывание идентификаторов

Явная загрузка DLL
Явная выгрузка DLL
Явное подключение экспортируемого идентификатора
Функция входа/выхода
Уведомление DLL_PROCESS_ATTACH
Уведомление DLL_PROCESS_DETACH
Уведомление DLL_THREAD_ATTACH

Уведомление DLL_THREAD_DETACH
Как система упорядочивает вызовы DIIMain
Функция DllMain и библиотека С/С++
Отложенная загрузка DLL

Программа-пример DelayLoadApp
Переадресация вызовов функций
Известные DLL
Перенаправление DLL
Модификация базовых адресов модулей

Связывание модулей

Создание эффективных WIN32-приложений с учетом специфики 64-разрядной версии Windows

Динамическая локальная память потока
Использование динамической TLS
Статическая локальная память потока

Создание эффективных WIN32-приложений с учетом специфики 64-разрядной версии Windows

Пример внедрения DLL

Внедрение DLL c использованием реестра
Внедрение DLL с помощью ловушек
Утилита для сохранения позиций элементов на рабочем столе
Внедрение DLL с помощью удаленных потоков

Программа-пример lnjLib
Библиотека lmgWalk.dll
Внедрение троянской DLL
Внедрение DLL как отладчика
Внедрение кода в среде Windows 98 через проецируемый в память файл
Внедрение кода через функцию CreateProcess

Перехват API-вызовов: пример
Перехват API-вызовов подменой кода
Перехват API-вызовов с использованием раздела импорта
Программа-пример LastMsgBoxlnfo

Создание эффективных WIN32-приложений с учетом специфики 64-разрядной версии Windows

Примеры использования обработчиков завершения
Funcenstein1
Funcenstein2

Funcenstein3
Funcfurter1
Проверьте себя: FuncaDoodleDoo
Funcenstein4
Funcarama1
Funcarama2
Funcarama3
Funcarama4: последний рубеж
И еще о блоке finally

Funcfurter2
Программа-пример SEHTerm

Создание эффективных WIN32-приложений с учетом специфики 64-разрядной версии Windows

Примеры использования фильтров и обработчиков исключений
Funcmeister1
Funcmeister2
EXCEPTION_EXECUTE_HANDLER
Некоторые полезные примеры
Глобальная раскрутка

Остановка глобальной раскрутки
EXCEPTION_CONTINUE_EXECUTION
Будьте осторожны с EXCEPTION_CONTINUE_EXECUTION
EXCEPTION_CONTINUE_SEARCH
Функция GetExceptionCode
Функция GetExceptionlnformation

Программные исключения

Создание эффективных WIN32-приложений с учетом специфики 64-разрядной версии Windows

Отладка по запросу
Отключение вывода сообщений об исключении
Принудительное завершение процесса
Создание оболочки вокруг функции потока
Создание оболочки вокруг всех функций потоков

Автоматический вызов отладчика
Явный вызов функции UnhandledExceptionFilter
Функция UnhandledExceptionFilter изнутри
Исключения и отладчик
Программа-пример Spreadsheet
Исключения С++ и структурные исключения

Перехват структурных исключений в С++

Создание эффективных WIN32-приложений с учетом специфики 64-разрядной версии Windows

Очередь сообщений потока
Посылка асинхронных сообщений в очередь потока
Посылка синхронных сообщений окну

Пробуждение потока
Флаги состояния очереди
Алгоритм выборки сообщений из очереди потока
Пробуждение потока с использованием объектов ядра или флагов состояния очереди
Передача данных через сообщения

Программа-пример CopyData
Как Windows манипулирует с ANSI/Unicode-символами и строками

Создание эффективных WIN32-приложений с учетом специфики 64-разрядной версии Windows

Поток необработанного ввода
Локальное состояние ввода
Ввод с клавиатуры и фокус

Управление курсором мыши
Подключение к очередям виртуального ввода и переменным локального состояния ввода
Программа-пример LISLab

Программа-пример LISWatch

Содержание раздела