Запись на защищенный от записи
Таблица 3
19 | Запись на защищенный от записи диск |
20 | Задан неизвестный идентификатор устройства |
21 | Дисковод не готов |
22 | Неизвестная команда |
23 | Ошибка циклического кода проверки |
24 | Неправильная длина структуры запроса |
25 | Ошибка поиска |
26 | Неизвестен тип среды носителя данных |
27 | Сектор не найден |
28 | Кончилась бумага в принтере |
29 | Ошибка записи |
30 | Ошибка чтения |
31 | Общая ошибка |
32 | Нарушение разделения файла |
33 | Нарушение блокировки файла |
34 | Неправильная замена диска |
35 | FCB недоступен (слишком много блоков FCB) |
36 | Переполнился буфер разделения |
37 | Зарезервировано |
38 | Не завершена операция "Конец файла" |
39-49 | Зарезервировано |
50 | Сетевая функция не поддерживается |
51 | Удаленный компьютер "не слышит" |
52 | Дублирование имени в сети |
53 | Сетевое имя не найдено |
54 | Сеть занята |
55 | Сетевое устройство больше не существует |
56 | Превышен лимит команды сетевой BIOS |
57 | Ошибка в аппаратуре сетевого адаптера |
58 | Неправильный ответ из сети |
59 | Непредусмотренная ошибка сети |
60 | Несовместимый удаленный адаптер |
61 | Заполнена очередь печати |
62 | Для печатаемого файла недостаточно места |
63 | Печатающийся файл был удален |
64 | Сетевое имя было удалено |
65 | Доступ запрещен |
66 | Неправильный тип сетевого устройства |
67 | Сетевое имя не найдено |
68 | Превышен лимит сетевого имени |
69 | Превышен лимит сеанса сетевой BIOS |
70 | Временная пауза |
71 | Сетевой запрос отвергнут |
72 | Приостановлена печать или переадресация диска |
73-79 | Зарезервировано |
80 | Файл уже существует |
81 | Зарезервировано |
82 | Невозможно создать дескриптор в каталоге |
83 | Ошибка обработчика критических ошибок INT 24h |
84 | Слишком много переназначений |
85 | Двойное переназначение |
86 | Неправильный пароль |
87 | Неправильный параметр |
88 | Ошибка данных в сети |
89 | Нет такой функции в сети |
90 | Требуемый компонент системы не установлен |
Таблица 3
(0) 1 | type | тип блока MCB (M или Z) |
(+1) 2 | owner | параграф владельца блока ( если 0, то блок описывает сам себя) |
(+3) 2 | size | число параграфов в этом блоке (один параграф имеет размер 16 байт) |
(+5) 11 | reserve | зарезервировано |
Существует несколько удобных программ для просмотра списка блоков MCB. Вот какую информацию выдает программа MI.COM из пакета PCSHELL при запуске с параметром /A: Memory Info v5.8 Copyright 1989 Central Point Software, Inc. All rights reserved. Conventional memory. Total: 640k Largest executable program: 485k Type Paragraphs Bytes Owner ---- ---------- ----- ------------- Sys 0BA4-18C5h 53792 0008h < DOS > Free 18C7-18CFh 144 0000h < DOS > Env 18D1-18D2h 32 18D4h JYRKEYB Prog 18D4-1904h 784 18D4h JYRKEYB C:\DOS\JYRKEYB.COM C Prog 1906-1A69h 5696 1906h COMMAND Env 1A6B-1A7Dh 304 1906h COMMAND 1A7F-1A82h 64 1906h COMMAND Free 1A84-1A93h 256 0000h < DOS > Prog 1A95-1DD8h 13376 1A95h MOUSE Env 1DDA-1DEDh 320 1ED8h NS Prog 1DEF-1ED6h 3712 1DEFh SHELLB DOSSHELL Prog 1ED8-21EBh 12608 1ED8h NS f:\norton\NS.EXE Env 21ED-2200h 320 2202h NC Prog 2202-2527h 12896 2202h NC f:\norton\NC.EXESocha 2529-253Ch 320 253Eh COMMAND Prog 253E-26A1h 5696 253Eh COMMAND /a Env 26A3-26B5h 304 253Eh COMMAND Env 26B7-26CAh 320 26CCh MI Prog 26CC-9FFFh 485k 26CCh MI c:\dos\MI.COM /a
Программа сообщает размер оперативной памяти (640 К), максимальный размер выполняемой программы (485 К), затем выдает список блоков памяти с указанием типа, занимаемых параграфов памяти, размера в байтах и владельца блока памяти. Программа MI различает четыре типа блоков памяти:
системный (Sys), его владельцем является MS-DOS;
свободный (Free), обычно тоже принадлежит MS-DOS;
программный (Prog) - его занимает запущенная программа;
среда (Env) - содержит переменные среды MS-DOS.
Откуда MI берет информацию о типе блока памяти и имени программы? Системный блок распознается по занимаемым адресам, программный - по наличию правильного префикса программного сегмента (будет описан ниже). Блок переменных среды находится перед программным блоком и содержит кроме собственно переменных среды еще и полный путь файла запущенной программы. Если блок не системный, программный, или не является блоком среды и если в поле владельца этого блока записан ноль, программа отмечает такой блок памяти как свободный.
Видно, что для каждой запущенной программы создается два блока памяти - блок среды и программный блок. Среда формируется при загрузке операционной системы с помощью команд SET и содержит строки вида: LIB=D:\C600\LIB
Строки хранятся в формате ASCIIZ, т.е. закрыты двоичным нулем. Вся таблица переменных среды также закрыта двоичным нулем. После переменных среды в блоке памяти, отведенном для среды, содержится путь программного файла в формате ASCIIZ.
Блок памяти типа Prog (программный) независимо от формата загрузочного модуля (COM или EXE) начинается с префикса программного сегмента PSP, за которым следует сама программа.
Таким образом, при загрузке для программы выделяются блоки памяти, располагающиеся в следующей последовательности:
MCB для блока памяти переменных среды;
блок памяти переменных среды;
MCB программного блока памяти;
префикс программного сегмента PSP;
программный модуль.
Приведем фрагмент дампа оперативной памяти, полученные при отладке программы MI.COM с помощью отладчика Microsoft CodeView. Дамп памяти начинается с адреса 6D47:0000.
Первая строка дампа (смещение 000-00F) - это MCB блока памяти переменных среды. Это не последний блок памяти, поэтому MCB имеет тип M. В поле владельца блока памяти находятся нули, следовательно, MCB принадлежит сам себе. Поле длины содержит значение 0014 - это количество параграфов в блоке памяти переменных среды.
Со смещением 010 начинается блок переменных среды. Из дампа видно, что строки определения переменных среды закрыты двоичным нулем. Таблица переменных среды также закрыта нулем (смещение 13B). Со смещением 13C записано слово 0001 (количество слов в последующей строке), после которого расположен полный путь для файла запущенной программы. 000 4D00 0014 0000 0000 0000 0000 0000 0000 M............... 010 434F 4D53 5045 433D 433A 5C43 4F4D 4D41 COMSPEC=C:\COMMA 020 4E44 2E43 4F4D 0054 4D50 3D67 3A5C 7465 ND.COM.TMP=g:\te 030 6D70 0050 4154 483D 673A 5C3B 643A 5C71 mp.PATH=g:\;d:\q 040 6332 5C62 696E 3B65 3A5C 6336 3030 5C62 c2\bin;e:\c600\b 050 696E 623B 653A 5C63 3630 305C 6269 6E3B inb;e:\c600\bin; 060 633A 5C64 6F73 3B63 3A5C 6172 633B 663A c:\dos;c:\arc;f: 070 5C6E 6F72 746F 6E3B 653A 5C77 6F72 643B \norton;e:\word; 080 004C 4942 3D65 3A5C 7163 325C 4C49 4200 .LIB=e:\qc2\LIB. 090 494E 434C 5544 453D 673A 5C69 6E63 6C75 INCLUDE=g:\inclu 0A0 6465 3B65 3A5C 7163 325C 494E 434C 5544 de;e:\qc2\INCLUD 0B0 453B 653A 5C63 746F 6F6C 735C 696E 636C E;e:\ctools\incl 0C0 7564 653B 0048 454C 5046 494C 4553 3D65 ude;.HELPFILES=e 0D0 3A5C 4336 3030 5C48 454C 505C 2A2E 484C :\C600\HELP\*.HL 0E0 503B 0049 4E49 543D 653A 5C43 3630 305C P;.INIT=e:\C600\ 0F0 494E 4954 0044 4D41 4B45 3D67 3A5C 646D INIT.DMAKE=g:\dm 100 616B 653B 0056 4547 413D 653A 5C76 6567 ake;.VEGA=e:\veg 110 613B 004E 4152 4348 454C 503D 663A 5C61 a;.NARCHELP=f:\a 120 7263 5C6E 6172 633B 0048 454C 5050 4154 rc\narc;.HELPPAT 130 483D 643A 5C68 656C 703B 0000 0100 433A H=d:\help;....C: 140 5C44 4F53 5C6D 692E 636F 6D00 6D00 7016 \DOS\mi.com.m.p.
Далее начинается MCB прогаммного блока памяти (смещение 150). Это последний блок памяти, поэтому MCB имеет тип Z. Непосредственно за MCB располагается префикс программного сегмента PSP (смещение 160). Размер PSP - 256 байт, его формат будет описан ниже.
И, наконец, со смещением 260 расположена сама программа MI.COM. 150 5A00 00A3 3216 0000 6D69 0000 0000 0000 Z...2...mi...... 160 CD20 00A0 009A F0FE 1DF0 3D09 B22E 340A . ........=...4. 170 B22E 850E B22E CD26 FFFF FFFF FFFF FFFF .......&........ 180 FFFF FFFF FFFF FFFF FFFF FFFF 486D 92B3 ............Hm.. 190 FD4B 1400 1800 5D6D FFFF FFFF 0000 0000 .K....]m........ 1A0 0000 0000 0000 0000 0000 0000 0000 0000 ................ 1B0 CD21 CB00 0000 0000 0000 0000 0020 2020 .!........... 1C0 2020 2020 2020 2020 0000 0000 0020 2020 ..... 1D0 2020 2020 2020 2020 0000 0000 0000 0000 ........ 1E0 0320 2F61 0038 0F00 2C09 0001 0000 4005 . /a.8..,.....@. 1F0 7808 0000 9000 0100 04B3 0D07 ED2F 14B3 x............/.. 200 7501 4A36 0000 0000 0000 4003 A308 3F00 u.J6......@...?. 210 FD4B FD4B 0100 2ABA 0000 0000 026F 5718 .K.K..*......oW. 220 3800 0500 3800 CF08 DD26 2D09 FD4B FD4B 8...8....&-..K.K 230 E408 0000 4200 A308 3F00 FD4B FD4B E408 ....B...?..K.K.. 240 1304 0000 5718 C000 0500 C000 CE02 CE03 ....W........... 250 5718 8400 0500 8400 CE02 CE03 973A 92B3 W............:.. 260 E9BB 000D 0A4D 656D 6F72 7920 496E 666F .....Memory Info 270 2076 352E 380D 0A43 6F70 7972 6967 6874 v5.8..Copyright 280 2031 3938 3920 4365 6E74 7261 6C20 506F 1989 Central Po 290 696E 7420 536F 6674 7761 7265 2C20 496E int Software, In 2A0 632E 2020 416C 6C20 7269 6768 7473 2072 c. All rights r 2B0 6573 6572 7665 642E 0D0A 0A00 4279 2047 eserved.....By G 2C0 5744 2030 312F 3036 2F38 391A 2D2D 2D2D WD 01/06/89.---- 2D0 5041 5443 4820 4152 4541 2D2D 2D2D 2D2D PATCH AREA------ 2E0 2D2D FF90 5601 4102 0000 0290 5D6D 5C6D --..V.A.....]m\m
Префикс программного сегмента всегда создается при загрузке программы COM или EXE в память и имеет одинаковый формат для COM и EXE файлов:
Таблица 3
1 | неверный код подфункции; |
2 | файл запускаемой программы не найден; |
3 | путь не найден; |
4 | слишком много открытых файлов; |
5 | нет доступа; |
8 | нет памяти для загрузки программы; |
10 | длина блока среды больше 32 килобайт; |
11 | плохой формат запускаемого EXE-файла. |
Таблица 3
Бит | Назначение |
0 | Зарезервировано, бит должен быть равен 0 |
1 | 1 - драйвер поддерживает 32-битовую адресацию сектора (для версий DOS, начиная с 4.00 и более поздних); если установлен этот бит, поле номера сектора всех запросов является двойным словом, добавляемым в конец заголовка запроса, старое поле номера сектора должно содержать -1);
0 - используется 16-битовая адресация сектора |
2-5 | Эти биты зарезервированы и должны быть равны 0 |
6 | 1 - поддерживаются логические устройства (используется блочными драйверами для управления "виртуальными" флоппи-дисками, создаваемые драйвером DRIVER.SYS в DOS версии 3.2 и более поздних версиях);
0 - логические устройства для блочных драйверов не поддерживаются; |
7-10 | Эти биты зарезервированы и должны быть равны 0 |
11 | 1 - единица в этом бите означает, что драйвер поддерживает функцию проверки замены носителя данных в устройстве (например, замены дискеты); используется для DOS версий 3.00 и более поздних;
0 - для блочных устройств функция проверки замены носителя данных не поддерживается |
12 | Зарезервировано, бит должен быть равен 0 |
13 | 1 - драйвер не использует стандартное IBM-устройство, и необходимо выдать запрос на построение блока параметров BIOSBIOS BPB;
0 - используется IBM-устройство |
14 | 1 - поддерживаются функции IOCTL;
0 - функции IOCTL не поддерживаются |
15 | 1 - символьное устройство;
0 - блочное устройство |
После слова атрибутов драйвера находятся два очень важных поля: смещение программы стратегии драйвера strateg и смещение программы обработки прерывания interrupt.
Эти две программы используются DOS для организации обращения к драйверу. Для обращения к драйверу DOS формирует в своей области данных запрос, состоящий из заголовка стандартного формата и переменной части запроса, длина и формат которой зависят от типа запроса. После этого DOS считывает из заголовка драйвера значение смещения программы стратегии и передает ей управление, записав в регистры ES:BX адрес заголовка запроса.
Задача программы стратегии - запомнить этот адрес внутри тела драйвера для дальнейшего использования или организовать очередь запросов обслуживания.
Сразу после вызова программы стратегии DOS вызывает программу обработки прерываний, определив ее адрес из поля interrupt заголовка драйвера.
Программа обработки прерывания извлекает только что записанный программой стратегии адрес заголовка запроса и выполняет ту функцию, номер которой записан в запросе. Номер функции находится в заголовке запроса.
Результаты выполнения функции программа прерывания записывает в специально отведенные поля заголовка запроса, и на этом процедура обращения DOS к драйверу завершается.
Формат заголовка запроса будет приведен ниже, а сейчас покажем, как в заголовке драйвера задаются смещения программ стратегии и прерывания: strateg DW strateg_proc interrupt DW interrupt_proc
Последнее поле заголовка драйвера dev_name имеет различную интерпретацию для символьных и блочных устройств.
Для символьных устройств в этом поле должно располагаться выровненное по левому краю и дополненное до восьми символов пробелами имя устройства. Это имя будет использоваться для обращения к драйверу. Если Вы собираетесь заменить драйвер стандартного символьного устройства DOS на свой, Вы должны записать имя устройства заглавными буквами: dev_name DB 'AUX '
Для блочных устройств первый байт поля dev_name содержит количество устройств, обслуживаемых данным драйвером, остальные семь байтов не используются: dev_name DB 1 DB 7 dup(?)
Таким образом, мы выяснили, что драйвер содержит в самом начале заголовок, и где-то дальше должны располагаться программы стратегии и прерывания. (Не следует путать программу прерывания драйвера с программой обслуживания аппаратных или программных прерываний. Хотя программа прерывания драйвера немного похожа на обработчик программных прерываний, назначение этой программы и механизм ее использования совершенно другой).
Что еще может находиться в программе-драйвере?
Это могут быть области данных, используемые драйвером, и подпрограммы, вызываемые программами стратегии и прерывания. Иногда стандартные драйверы переназначают на себя некоторые вектора прерываний, и тогда они содержат в себе обработчики этих прерываний. В области памяти, отведенной операционной системой драйверу, может располагаться стек драйвера, если размер системного стека недостаточен.
На длину драйвера накладывается такое же ограничение, как и на длину COM-программ - 64 килобайта, то есть один сегмент.
Таблица 3
Бит | Назначение |
0 | Зарезервировано, бит должен быть равен 0 |
1 | 1 - драйвер поддерживает 32-битовую адресацию сектора (для версий DOS, начиная с 4.00 и более поздних); если установлен этот бит, поле номера сектора всех запросов является двойным словом, добавляемым в конец заголовка запроса, старое поле номера сектора должно содержать -1);
0 - используется 16-битовая адресация сектора |
2-5 | Эти биты зарезервированы и должны быть равны 0 |
6 | 1 - поддерживаются логические устройства (используется блочными драйверами для управления "виртуальными" флоппи-дисками, создаваемые драйвером DRIVER.SYS в DOS версии 3.2 и более поздних версиях);
0 - логические устройства для блочных драйверов не поддерживаются; |
7-10 | Эти биты зарезервированы и должны быть равны 0 |
11 | 1 - единица в этом бите означает, что драйвер поддерживает функцию проверки замены носителя данных в устройстве (например, замены дискеты); используется для DOS версий 3.00 и более поздних;
0 - для блочных устройств функция проверки замены носителя данных не поддерживается |
12 | Зарезервировано, бит должен быть равен 0 |
13 | 1 - драйвер не использует стандартное IBM-устройство, и необходимо выдать запрос на построение блока параметров BIOSBIOS BPB;
0 - используется IBM-устройство |
14 | 1 - поддерживаются функции IOCTL;
0 - функции IOCTL не поддерживаются |
15 | 1 - символьное устройство;
0 - блочное устройство |
После слова атрибутов драйвера находятся два очень важных поля: смещение программы стратегии драйвера strateg и смещение программы обработки прерывания interrupt.
Эти две программы используются DOS для организации обращения к драйверу. Для обращения к драйверу DOS формирует в своей области данных запрос, состоящий из заголовка стандартного формата и переменной части запроса, длина и формат которой зависят от типа запроса. После этого DOS считывает из заголовка драйвера значение смещения программы стратегии и передает ей управление, записав в регистры ES:BX адрес заголовка запроса.
Задача программы стратегии - запомнить этот адрес внутри тела драйвера для дальнейшего использования или организовать очередь запросов обслуживания.
Сразу после вызова программы стратегии DOS вызывает программу обработки прерываний, определив ее адрес из поля interrupt заголовка драйвера.
Программа обработки прерывания извлекает только что записанный программой стратегии адрес заголовка запроса и выполняет ту функцию, номер которой записан в запросе. Номер функции находится в заголовке запроса.
Результаты выполнения функции программа прерывания записывает в специально отведенные поля заголовка запроса, и на этом процедура обращения DOS к драйверу завершается.
Формат заголовка запроса будет приведен ниже, а сейчас покажем, как в заголовке драйвера задаются смещения программ стратегии и прерывания: strateg DW strateg_proc interrupt DW interrupt_proc
Последнее поле заголовка драйвера dev_name имеет различную интерпретацию для символьных и блочных устройств.
Для символьных устройств в этом поле должно располагаться выровненное по левому краю и дополненное до восьми символов пробелами имя устройства. Это имя будет использоваться для обращения к драйверу. Если Вы собираетесь заменить драйвер стандартного символьного устройства DOS на свой, Вы должны записать имя устройства заглавными буквами: dev_name DB 'AUX '
Для блочных устройств первый байт поля dev_name содержит количество устройств, обслуживаемых данным драйвером, остальные семь байтов не используются: dev_name DB 1 DB 7 dup(?)
Таким образом, мы выяснили, что драйвер содержит в самом начале заголовок, и где-то дальше должны располагаться программы стратегии и прерывания. (Не следует путать программу прерывания драйвера с программой обслуживания аппаратных или программных прерываний. Хотя программа прерывания драйвера немного похожа на обработчик программных прерываний, назначение этой программы и механизм ее использования совершенно другой).
Что еще может находиться в программе-драйвере?
Это могут быть области данных, используемые драйвером, и подпрограммы, вызываемые программами стратегии и прерывания. Иногда стандартные драйверы переназначают на себя некоторые вектора прерываний, и тогда они содержат в себе обработчики этих прерываний. В области памяти, отведенной операционной системой драйверу, может располагаться стек драйвера, если размер системного стека недостаточен.
На длину драйвера накладывается такое же ограничение, как и на длину COM-программ - 64 килобайта, то есть один сегмент.