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

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

Сейчас Microsoft поставляет операционные системы Windows с тремя ядрами. Каждое ядро оптимизировано под свои виды вычислительных задач. Microsoft пытается переманить разработчиков программного обеспечения на Windows-платформы, утверждая, что интерфейс прикладного программирования (application programming interface, APT) у каждой из них одинаков. Это означает лишь то, что, научившись писать Windows-приложения для одного ядра, Вы поймете, как сделать то же самое для остальных.
Поскольку я объясняю, как писать Windows-приложения на основе Windows API, то теоретически все, о чем Вы узнаете из моей книги, применимо ко всем трем ядрам. На самом деле они сильно отличаются друг от друга, и поэтому одни и те же функции соответствующих операционных систем реализованы по-разному. Скажем так: базовые концепции одинаковы, но детали могут различаться.

Сегодняшние Windows-платформы
Windows 2000 рассчитана на рабочие станции и серверы, а также на применение в центрах обработки данных Отказоустойчива - плохо написанные программы не могут привести к краху системы. Защищена - несанкционированный доступ к ресурсам (например, файлам или принтерам), управляемым этой системой, невозможен. Богатый набор средств и утилит для администрирования системы в масштабах организации.

Вы тоже можете это сделать
О'кэй, я показал, как функции Windows сообщают об ошибках. Microsoft позволяет Вам использовать этот механизм и в собственных функциях. Допустим, Вы пишете функцию, к которой будут обращаться другие программы. Вызов этой функции может по какой-либо причине завершиться неудачно, и Вам тоже нужно сообщать об ошибках. С этой целью Вы просто устанавливаете код последней ошибки в потоке и возвращаете значение FALSE, INVALID_HANDLE_VALUE, NULL или что-то другое, более подходящее в Вашем случае.

Наборы символов
Настоящей проблемой при локализации всегда были операции с различными наборами символов. Годами, кодируя текстовые строки как последовательности однобайтовых символов с нулем в конце, большинство программистов так к этому привыкло, что это стало чуть ли не второй их натурой. Вызываемая нами функция strlen возвращает количество символов в заканчивающемся нулем массиве однобайтовых символов.

Что такое объект ядра
Каждый объект ядра — на самом деле просто блок памяти, выделенный ядром и доступный только ему. Этот блок представляет собой структуру данных, в элементах которой содержится информация об объекте. Некоторые элементы (дескриптор защиты, счетчик числа пользователей и др.) присутствуют во всех объектах, но большая их часть специфична для объектов конкретного типа.

Ваше первое Windows-приложение
Windows поддерживает два типа приложений: основанные на графическом интерфей се (graphical user interface, GUI) и консольные (console user interface, CUI) V приложе ний первого типа внешний интерфейс чисто графический GUI-приложения создают окна, имеют меню, взаимодействуют с пользователем через диалоговые окна и вооб ще пользуются всей стандартной "Windows'oвской" начинкой.

Определение ограничений, налагаемых на процессы в задании
Создав задание, Вы обычно строите "песочницу" (набор ограничений) для включае мых в него процессов. Ограничения бывают нескольких видов: базовые и расширенные базовые ограничения — не дают процессам в задании монопольно захватывать системные ресурсы; базовые ограничения по пользовательскому интерфейсу (UI) — блокируют возможность его изменения;

В каких случаях потоки создаются
Поток (thread) определяет последовательность исполнения кода в процессе. При инициализации процесса система всегда создает первичный поток Начинаясь со стартовою кодц из библиотеки С/С++, который в свою очередь вызывает входную функцию (WinMain, wWinMain, main или wmain) из Вашей программы, он живет до того момента, когда входная функция возвращает управление стартовому коду и тот вызывает функцию ExitProcess. Большинство приложений обходится единственным, первичным потоком

Приостановка и возобновление потоков
В объекте ядра "поток" имеется переменная — счетчик числа простоев данного по тока При вызове CreateProcess или CreateThread он инициализируется значением, равным 1, которое запрещает системе выделять новому потоку процессорное время. Та кая схема весьма разумна: сразу после создания поток не готов к выполнению, ему нужно время для инициализации.

Атомарный доступ: семейство Inferlockect-функций
Я объявил глобальную переменную g_n и инициализировал ее нулевым значени ем. Теперь представьте, что я создал два потока: один выполняет ThreadFunc1, дру гой — ThreadFunc2 Код этих функций идентичен: обе увеличивают значение глобаль ной переменной g_x па 1. Поэтому Вы, наверное, подумали: когда оба потока завер шат свою работу, значение g_x будет равно 2. Так ли это? Может быть.

Wait-функции
Wait-функции позволяют потоку в любой момент приостановиться и ждать освобож дения какого-либо объекта ядра. Из всего семейства этих функций чаще всего исполь зуется WaitForSingleObject: DWORD WaitForSingleObject( HANDLE hObject, DWORD dwMilliseconds);

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

Сценарий 1: асинхронный вызов функций
Допустим, у Вас есть серверный процесс с основным потоком, который ждет клиен тский запрос. Получив его, он порождает отдельный поток для обработки этого зап роса Тем самым основной поток освобождается для приема следующего клиентского запроса. Такой сценарий типичен в клиент-серверных приложениях.

Работа с волокнами
Во-первых, потоки в Windows реализуются на уровне ядра операционной системы, которое отлично осведомлено об их существовании и "коммутирует» их в соответ ствии с созданным Microsoft алгоритмом В то жс время волокня реализованы на уров не кода пользовательского режима, ядро ничего не знает о них, и процессорное вре мя распределяется между волокнами по алгоритму, определяемому Вами.

Виртуальное адресное пространство процесса
В Windows 2000 память, принадлежащая собственно операционной системе, тоже скрыта от любого выполняемого потока. Иными словами, ни один поток не может случайно повредить ее данные. А в Windows 98 последнее, увы, не реализовано, и есть вероятность, что выполняемый поток, случайно получив доступ к данным операционной системы, тем самым нарушит ее нормальную работу.

Системная информация
Многие параметры операционной системы (размер страницы, гранулярность выделения памяти и др) зависят от используемого в компьютере процессора Поэтому нельзя жестко «зашивать» их значения в исходный код пpoгpaмм Эту информацию надо считывать в момент инициализации процесса с помощью функции GetSystemfnfo

Резервирование региона в адресном пространстве
Для большинства программистов возможность выбора конкретного адреса резер вируемого региона — нечто совершенно новое Вспомните, как это делалось раньше операционная система просто находила подходящий по размеру блок памяти, выделяла этот блок и возвращала его адрес Но поскольку каждый процесс владеет собственным адресным пространством, у Вас появляется возможность указывать операционной системе желательный базовый адрес резервируемого региона

Стек потока в Windows 98
Блок перед стеком предназначен для перехвата его переполнения, а блок после стска — для перехвата обращений к несуществующим областям стека. Чтобы понять, какая польза от последнего блока, рассмотрим такой фрагмент кода

Проецирование в память EXE- и DLL-файлов
При вызове из потока функции CreateProcess система действует так: Отыскивает ЕХЕ-файл, указанный при вызове CreateProcess. Если файл не най ден, новый процесс не создастся, а функция возвращает FALSE. Создает новый объект ядра «процесс» Создает адресное пространство нового процесса

Стандартная куча процесса
При инициализации процесса система создает в его адресном пространстве стандарт ную кучу (process's default heap) Ее размер по умолчанию — 1 Мб Но система позволяет увеличивать этот размер, для чего надо указать компоновщику при сборке программы ключ /HEAP

DLL и адресное пространство процесса
Зачастую создать DLL проще, чем приложение, потому что она является лишь набором автономных функций, пригодных для использования любой программой, причем в DLL обычно нет кода, предназначенного для обработки циклов выборки сообщений или создания окон DLL представляет собой набор модулей исходного кода, в каждом из которых содержится определенное число функций, вызываемых приложением (исполняемым файлом) или другими DLL.

Явная загрузка DLL и связывание идентификаторов
Чтобы поток мог вызвать функцию из DLL-модуля, последний надо спроецировать на адресное пространство процесса, которому принадлежит этот поток Делается это двумя способами. Первый состоит в том, что код Вашего приложения просто ссылается на идентификаторы, содержащиеся в DLL, и гем самым заставляет загрузчик неявно загружать (и связывать) нужную DLL при запуске приложения



Динамическая локальная память потока
Каждый флаг выполняемого в системе процесса может находиться в состоянии FREE или INUSE, указывая, свободна или занята данная область локальной памяти потока (TLS-область). Microsoft гарантируетдоступность по крайней мере TLS_MINIMUM_AVAILABLE битовых флагов. Идентификатор TLS_MINIMUM_AVAILABLE определен в файле WinNT.h как 64. Но в Windows 2000 этот флаговый массив вмещает свыше 1000 элементов!

Пример внедрения DLL
Допустим, Вы хотите создать подкласс от экземпляра окна, порожденного другим процессом. Это, как Вы помните, позволит изменять поведение окна Все, что от Вас для этого требуется, — вызвать функцию SetWindowLongPtr, чтобы заменить адрес оконной процедуры в блоке памяти, принадлежащем окну, новым — указывающим на Вашу функцию WndProc.

Примеры использования обработчиков завершения
Поскольку при использовании SEH компилятор и операционная система вместе контролируют выполнение Вашего кода, то лучший, на мой взгляд, способ продемонстрировать работу SEH — изучать исходные тексты программ и рассматривать порядок выполнения операторов в каждом из примеров

Примеры использования фильтров и обработчиков исключений
В отличие от обработчиков завершения (рассмотренных в предыдущей главе), фильтры и обработчики исключений выполняются непосредственно операционной системой — нагрузка на компилятор при этом минимальна. В следующих разделах я расскажу, как обычно выполняются блоки try-except, как и когда операционная система проверяет фильтры исключений и в каких случаях она выполняет код обработчиков исключений.

Отладка по запросу
Windows позволяет подключать отладчик к любому процессу в любой момент времени — эта функциональность называется отладкой по запросу (just-in-time debugging). В этом разделе я расскажу, кяк она работает Щелкнув кнопку Cancel, Вы сообщаете функции UnhandledExceptionFilter о том, что хотиге начать отладку процесса.

Очередь сообщений потока
Как я уже говорил, одна из главных целей Windows — предоставить всем приложениям отказоустойчивую среду. Для этого любой поток должен выполняться в такой среде, где он может считать себя единственным. Точнее, у каждого потока должны быть очереди сообщений, полностью независимые от других потоков. Кроме того, для каждого потока нужно смоделировать среду, позволяющую ему самостоятельно управлять фокусом ввода с клавиатуры, активизировать окна, захватывать мышь и т. д

Поток необработанного ввода
Общая схема модели аппаратного ввода в системе показана на 27-1. При запуске система создает себе особый поток необработанного ввода (raw input thread, RIT) и системную очередь аппаратного ввода (system hardware input queue, SHIQ). RIT и SHIQ — это фундамент, на котором построена вся модель аппаратного ввода.

Путеводитель по написанию вирусов под Win32

Серия туториалов "Путеводитель по написанию вирусов под Win32" предназначена для сугубо образовательных целей. По крайней мере именно это было целью перевода: предоставить людям информацию о формате PE-файла, работе операционной системы, таких полезных технологиях, как полиморфизм и многом другом, что может потребоваться кодеру в его нелегком пути к постижению дао программирования. То, как читатели используют эту информацию, остается на их совести.

IMAGE_FILE_HEADER

Настройка Windows с использованием реестра 2003

Ну, что, очередной раз решили включить компьютер и полазить в Интернет? Ну и как компьютер грузится? Медленно? И при этом жужжит винчестером как майский жук? Ничего удивительного. А что у вас грузится каждый раз при старте системы? Как не знаю?! Тогда пора просвещаться, а заодно проверим, нет ли где хитрых троянов, нагло ворующих пароли от Интернет.
Сперва выясним, как Windows узнает о программах, которые надо запустить во время старта системы. Всего есть три места, где хранятся эти сведения: папка Автозагрузка из меню "Пуск", файл win.ini и реестр. Ну, с Автозагрузкой все понятно - это наиболее простое и доступное место для запуска программ, а вот на win.ini и реестре стоит остановиться поподробнее.
Начнем, пожалуй, с файла. Хоть Microsoft и усиленно призывает разработчиков хранить все настройки в реестре, отказываясь от INI-файлов, уверяет пользователей в том, что эти файлы оставлены только для совместимости со старыми программами, тем не менее, сами продолжают ими пользоваться. Сам файл находится в каталоге, где установлена операционная система. Откройте его любым текстовым редактором. В самом начале файла вы увидите раздел [windows]. В этом разделе есть два параметра, отвечающие за автоматическую загрузку программ - load и run. Обычно они пустые, но если там есть какая-то запись, обязательно проверьте, что за программу она запускает, и не затесалось ли туда что-то вроде kernel16.exe :).

Что скрывается в автозагрузке?
Сперва откройте раздел HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion. Найдите там подразделы Run, RunOnce, RunOnceEx, RunServices, RunServicesOnce. В этих разделах есть строковые ключи (некоторые разделы пустые), отвечающие за запуск программ. Название ключа может быть произвольным, а в качестве значения у них указывается запускаемая программа, если надо - то с параметрами.

Windows Script Host (WSH) - файлы и папки
Windows Script Host, или сокращенно WSH, является одной из интереснейших тем, рассматриваемых при работе с Windows. Именно благодаря скриптам, написанным на языке JScript или VBScript, можно существенно облегчить свой труд на компьютере, избавиться от массы рутинной работы, автоматизировать многие операции и процессы, да и просто поприкалываться над друзьями.

Windows Script Host (WSH) - теория, реестр
Когда компьютеры были большими, а программы были маленькими, основной операционной системой большинства домашних компьютеров была DOS. Компьютерщиков в то время было немного и были они все люди занятые, поэтому для выполнения каких-то постоянно повторяющихся действий были придуманы и использовались bat-файлы (или, как они еще называются, пакетные файлы).

Особенности реестра
Реестр Windows NT очень похож на реестр Windows 9x, но существует ряд существенных отличий, основным из которых является организация корневых разделов. Хотя в окне редактора реестра видны шесть разделов, но реально, раздел HKEY_DYN_DATA недоступен. Все остальные разделы по своей сути не отличаются от аналогичных в Windows 9х

Запрещение запуска программ
Материалы этой статьи, я думаю, очень пригодятся начальникам, которым надо быть твердо уверенным, что их подчиненные на компьютере работают только с нужными программами, а не гоняют в игрушки, когда этого никто не видит. Так что НИЗАЧТО не показывайте им ее :). Также она будет весьма интересна многим админам.

Создание локальных учетных записей пользователей и групп
Создание учетных записей и групп занимает важное место в обеспечении безопасности Windows XP, поскольку, назначая им права доступа, администратор получает возможность ограничить пользователей в доступе к конфиденциальной информации компьютерной сети, разрешить или запретить им выполнение в сети определенного действия, например архивацию данных или завершение работы компьютера.

Нулевое администрирование Windows (ZAW)
Эффективное управление рабочей средой настольных систем — главная и наиболее трудоемкая задача администратора сети или специалиста по информационным технологиям. Средства администрирования призваны помочь техническому персоналу планировать, размещать, эффективно поддерживать и централизованно управлять распределенной вычислительной средой.

Средства мониторинга и оптимизации
В системе Windows XP сохранено известное по Windows NT 4.0 средство мониторинга производительности — Диспетчер задач, который предоставляет информацию о программах и процессах, запущенных на компьютере, и отображает наиболее общие показатели производительности процессов.