Студопедия

КАТЕГОРИИ:


Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748)

Файловые сисиемы Windows




Разрядное приложение в 64-разрядной среде

Разрядная архитектура

Win64-код объединяет в себе основные возможности 32-разрядного кода, а также включает изменения, связанные с повышением разрядности. В распоряжении программиста оказываются:

¾ 64-разрядные указатели;

¾ 64-разрядные типы данных;

¾ 32-разрядные типы данных;

¾ интерфейс Win64 API.

Обратите внимание, что 32-разрядные типы данных не исчезли при повышении разрядности платформы (как было с 16-разрядными типами данных при переходе к Win32). Это связано с тем, что даже в 64-разрядных приложениях в большинстве случаев переменные не требуют объема памяти в 8 байт, поэтому использование 64-разрядных типов в таких случаях оказалось бы крайне неэффективным. Операционной системе пришлось бы дописывать нули в старшие разряды, чтобы увеличить размер данных до 8 байт (такие данные к тому же очень неудобно считывать). Это привело бы к снижению производительности.

Иная участь постигла 32-разрядные указатели: они полностью исчезли. Дело в том, что использование 32-разрядных указателей накладывает ограничение на объем адресуемой памяти. Например, одним из главных преимуществ плоской модели памяти (она является основной для программирования 32-разрядных приложений для платформы NT), использующей 32-разрядные указатели, является возможность создания сегментов объемом до 4 Гбайт. Новые 64-разрядные указатели обеспечивают возможность адресации до 16 Тбайт памяти (1 Тбайт = 1012 Мбайт). Современными бизнес-приложениями этот объем вполне востребован.

Функции в Win64 API претерпели незначительные изменения. Только названия некоторых из них были изменены так, чтобы отразить принадлежность к 64-разрядной платформе. В большинстве случаев изменениям подверглись лишь типы параметров, являющихся аргументами вызова функций. Все остальные преимущества (возможность отказаться от использования файлов подкачки и т. д.) связаны либо с увеличившимся объемом адресации, либо с новыми типами данных.

Если бы 32-разрядные приложения работали в 64-разрядной среде так же эффективно, как в <родной>, не было бы никакого смысла не только писать эту статью, но и создавать 64-разрядный компилятор. Действительно, производительность 32-разрядных приложений при работе на 64-разрядной платформе существенно снижается. Это связано с тем, что для запуска 32-разрядного приложения операционной системе приходится выполнять ряд подготовительных действий: увеличивать все 32-разрядные указатели до размера в 8 байт, преобразовывать вызовы API-функций, заменять типы 32-разрядных данных на 64-разрядные.

Здесь следует остановиться и подробнее рассмотреть вопрос о преобразовании данных. Win64 допускает использование и 32-, и 64-разрядных данных. Поэтому когда операционная система встречает 32-разрядные данные в 32-разрядном приложении, она должна ответить на вопрос: <Преобразовать ли эти данные в 64-разрядные или оставить, как есть?> Делается это для того, чтобы оптимизировать работу приложения. Если операционная система встретит 32-разрядные данные в 64-разрядном приложении, то не обратит на них внимания, так как платформа Win64 допускает использование 32-разрядных типов данных. Преобразование 32-разрядных данных в 64-разрядные осуществляется точно так же, как и преобразование 32-разрядных указателей, - дописыванием нулей в старшие разряды. Очевидно, что на выполнение всех этих операций тратится масса системных ресурсов, и, как результат, производительность снижается. Это особенно заметно при работе 32-разрядных драйверов на 64-разрядной платформе. В связи с тем, что драйверы являются связующим звеном между оборудованием и операционной системой, именно они используются наиболее интенсивно.

Для работы с 64-разрядным кодом понадобятся компилятор, линкер и несколько подключаемых библиотек. Все это есть в последних дистрибутивах SDK и DDK. Прежде всего, необходимо рассмотреть макросы и директивы компилятора, предназначенные для 64-разрядного кода:

¾ _WIN64 - 64-разрядная платформа;

¾ _WIN32 - 32-разрядная платформа (для совместимости с 32-разрядной платформой);

¾ _WIN16 - 16-разрядная платформа.

¾ Также компилятор имеет встроенные предопределенные макросы, специфичные для различных архитектур процессоров:

¾ _M_IA64 - 64-разрядная архитектура Intel;

¾ _M_IX86 - 32-разрядная архитектура Intel;

¾ _M_ALPHA_64 - 64-разрядная архитектура Alpha;

¾ _M_ALPHA32 - 32-разрядная архитектура Alpha;

¾ _M_ALPHA - архитектура Alpha, либо 32-разрядная, либо 64-разрядная.

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

Теперь есть возможность создавать приложения, работающие и на 32-, и на 64-разрядной платформах. Здесь есть, однако, немало подводных камней. Следует быть очень внимательным - например, следующий код был вполне пригоден для <старых> приложений, но не для 64-разрядной платформы:

#ifdef _WIN32 // Win32 код...#else // А здесь неясно, какой код следует далее: 64- или 16-разрядный......#endifИ этот код не является корректным:#ifdef _WIN16 // Win16 код...#else // То же самое: 32- или 64-разрядный код?...#endif

Чтобы исправить этот код, нужно после #else добавить макросы _WIN32 или _WIN64. Просто придется привыкнуть к тому, что теперь код бывает трех (а не двух, как раньше) <видов>, поэтому использование директивы #else в привычных конструкциях приведет к неоднозначности (хотя 16-разрядных приложений становится все меньше и меньше, поддержка этой платформы в современных компиляторах остается).

Теперь рассмотрим новые типы данных. Их можно условно разделить на три группы:

¾ целочисленные типы явного представления (fixed-precision integer types);

¾ целочисленные типы, представленные указателями (pointer-precision integer types);

¾ типы специальных указателей (specific-precision pointer types).

Описания этих типов находятся в файле basetsd.h (входящем в состав DDK/SDK) и приведены в Таблице 1.

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

...#ifdef _WIN32 // Win32 код...

под 32-разрядным кодом подразумевается использование 32-разрядных типов данных. Именно для переменных этой платформы служит тип int32. То же касается и других целочисленных типов явного представления, имеющих размер 32 разряда.

Второй вид (целочисленные типы, представленные указателями) имеет свою особенность: размер данных каждого такого типа зависит от платформы, на которой исполняется приложение. Именно поэтому многие из этих типов названы интегральными. Они сочетают в себе свойства 32- и 64-разрядных типов. Эти типы можно сравнить с виртуальными функциями и поздним связыванием из объектно-ориентированного программирования, так как в обоих случаях среда исполнения определяет конкретные свойства элементов только во время исполнения приложения, а не компиляции (в этом и заключается позднее связывание). Эти типы данных позволяют создавать приложения, одинаково хорошо работающие на 32- и 64-разрядной платформах.

Далее следуют указатели. При работе с ними надо соблюдать осторожность: необходимо учитывать разрядность данных, которые адресуются указателем, и помнить, что 32-разрядные указатели в 64-разрядном коде всегда расширяются операционной системой до нужного размера.

Следующие функции Win64 (Helper Functions) отвечают за преобразование одного типа в другой (эти inline-функции определены в Basetsd.h). Смысл многих из них понятен из определения прототипов, к остальным требуются объяснения:

¾ unsigned long HandleToUlong(const void *h);

¾ long HandleToLong(const void *h);

¾ void *LongToHandle(const long h);

¾ unsigned long PtrToUlong(const void *p);

¾ unsigned int PtrToUint(const void *p);

¾ unsigned short PtrToUshort(const void *p);

¾ long PtrToLong(const void *p);

¾ int PtrToInt(const void *p);

¾ short PtrToShort(const void *p);

¾ void * IntToPtr(const int i) расширяет знаком (sign-extends) значение типа int;

¾ void * UIntToPtr(const unsigned int ui) расширяет нулем (zero-extends) значение типа unsigned int;

¾ void * LongToPtr(const long l) расширяет знаком (sign-extends) значение типа long;

¾ void * ULongToPtr(const unsigned long ul) расширяет нулем (zero-extends) значение типа unsigned long.

Теперь рассмотрим изменения в Win64 API. Как уже отмечалось, лишь некоторые функции Win64 API были изменены. Для того чтобы перевести 32-разрядный код в 64-разрядный, следует использовать новые функции оконного класса (Window class). Если в private-данных окна или класса есть указатели, необходимо задействовать следующие новые функции: GetClassLongPtr, GetWindowLongPtr, SetClassLongPtr, SetWindowLongPtr. Эти функции могут работать и на 32- и на 64-разрядной платформе, но для компиляции требуют 64-разрядного компилятора.

Также необходимо, чтобы указатели и дескрипторы (handles), входящие в private-данные класса, могли использовать новые 64-разрядные функции. Нужно иметь в виду, что следующие элементы в Winuser.h во время 64-разрядной компиляции не определены:

¾ GWL_WNDPROC, GWL_HINSTANCE,¾ GWL_HWDPARENT, GWL_USERDATA.

Вместо них в Winuser.h определены следующие новые элементы:

¾ GWLP_WNDPROC, GWLP_HINSTANCE,¾ GWLP_HWNDPARENT, GWLP_USERDATA, GWLP_ID.

Например, следующий код вызовет ошибку компиляции:

¾ SetWindowLong(hWnd,¾ GWL_WNDPROC, (LONG)MyWndProc);

Его нужно изменить так:

¾ SetWindowLongPtr(hWnd, GWLP_WNDPROC,¾ (LONG_PTR)MyWndProc);

Обращаю внимание читателей на следующий момент. Прежде чем делать cbWndExtra членом структуры WNDCLASS, необходимо убедиться, что для указателя имеется достаточно памяти. Например, если зарезервировано sizeof(DWORD) байт для адресуемой переменной, следует зарезервировать sizeof(DWORD_PTR) байт.

Теперь вернемся к новым 64-разрядным API-функциям. Все они объявлены в Winuser.h, включены в Windows.h и используют User32.lib.

1. GetClassLongPtr. GetClassLongPtr возвращает значение из структуры WNDCLASSEX, которое связано с определенным окном. Если вы возвращаете указатель или дескриптор окна (handle), эта функция в точности повторяет GetClassLong. Но чтобы написать код, работающий под двумя платформами (32- и 64-разрядной), нужно использовать только GetClassLongPtr. Вот ее определение:

ULONG_PTR GetClassLongPtr(HWND hWnd, // указатель на окноint nIndex // смещение возвращаемого значения).

Было бы нецелесообразно описывать все аргументы, так как они в точности повторяют параметры 32-разрядной функции GetClassLong (и, следовательно, доступны в любой справке по Win32 API).

2. GetWindowLongPtr. Здесь та же картина, что и в предыдущем случае. Эта функция является заменой <старой> функции GetWindowLong и служит лишь для совместимости двух платформ (а значит, и для создания кросс-платформенных приложений). Функция GetWindowLongPtr возвращает дескриптор окна и значение из экстрапамяти окна по указанному смещению. Вот ее определение:

LONG_PTR GetWindowLongPtr(HWND hWnd, // указатель на окноint nIndex // смещение возвращаемого значения).

3. SetClassLongPtr. Функция SetClassLong заменяет определенные значения по заданным смещениям в экстрапамяти класса или WNDCLASSEX-структуры на значения того класса, к которому принадлежит данное окно. Во многом эта функция похожа на SetClassLong, но она является межплатформенной.

ULONG_PTR SetClassLongPtr(HWND hWnd, // указатель на окноint nIndex, // указатель на значение, которое надо поменятьLONG_PTR dwNewLong // новое значение);

4. SetWindowLongPtr. Функция SetWindowLongPtr меняет атрибуты окон. Она также записывает определенные значения (по определенным смещениям) в экстрапамять окна. Эта функция является интегральным (в смысле объединения двух платформ) аналогом SetWindowLong.

LONG_PTR SetWindowLongPtr(HWND hWnd, // указатель на окноint nIndex, // смещение, куда записывать значениеLONG_PTR dwNewLong // новое значение).

 

Лекция 2. Использование файловой системы и функций символьного ввода-вывода в Windows.

Основные вопросы: файловые системы Windows, правила именования файлов, операции открытия, чтение и записи в файл, закрытие файла, управление файлами и каталогами.

 

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

Файловая система связывает носитель информации с одной стороны и API для доступа к файлам — с другой. Когда прикладная программа обращается к файлу, она не имеет никакого представления о том, каким образом расположена информация в конкретном файле, так же, как и на каком физическом типе носителя (CD, жёстком диске, магнитной ленте, блоке флеш-памяти или другом) он записан. Всё, что знает программа — это имя файла, его размер и атрибуты. Эти данные она получает от драйвера файловой системы. Именно файловая система устанавливает, где и как будет записан файл на физическом носителе (например, жёстком диске).

С точки зрения операционной системы (ОС), весь диск представляет собой набор кластеров (как правило, размером 512 байт и больше). Драйверы файловой системы организуют кластеры в файлы и каталоги (реально являющиеся файлами, содержащими список файлов в этом каталоге). Эти же драйверы отслеживают, какие из кластеров в настоящее время используются, какие свободны, какие помечены как неисправные.

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

Основные функции любой файловой системы нацелены на решение следующих задач:

¾ именование файлов;

¾ программный интерфейс работы с файлами для приложений;

¾ отображения логической модели файловой системы на физическую организацию хранилища данных;

¾ организация устойчивости файловой системы к сбоям питания, ошибкам аппаратных и программных средств;

¾ содержание параметров файла, необходимых для правильного его взаимодействия с другими объектами системы (ядро, приложения и пр.).

В многопользовательских системах появляется ещё одна задача: защита файлов одного пользователя от несанкционированного доступа другого пользователя, а также обеспечение совместной работы с файлами, к примеру, при открытии файла одним из пользователей, для других этот же файл временно будет доступен в режиме «только чтение».

1. NTFS — это рекомендуемая файловая система для Windows 7. Она имеет множество преимуществ по сравнению с более ранней файловой системой FAT32, в том числе:

¾ возможность автоматического восстановления после некоторых ошибок, связанных с дисками;

¾ улучшенная поддержка для жестких дисков повышенного размера;

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




Поделиться с друзьями:


Дата добавления: 2014-01-13; Просмотров: 227; Нарушение авторских прав?; Мы поможем в написании вашей работы!


Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет



studopedia.su - Студопедия (2013 - 2024) год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! Последнее добавление




Генерация страницы за: 0.032 сек.