> И вообще имхо никак не получить досовские вызовы. Потому > что если 9х оставляет обработчики прерываний досовские в > памяти то в NT их точно нет. А все вызовы из досовской > виртуальной машины транслируются в API.
Да вроде как ничего она не оставляет "досовского". Все через VxD. Из V86 все транслируется туда, апи (ты про kernel32 и т.п. ?) никак не находятся в промежутке. Этот вызов из win32 тоже транслируется к какому-нибудь IOS VxD через kernel32, в котором есть адреса, call/jmp на которые сразу переводит в нулевое кольцо. Этот вызов DeviceIoControl - просто обертка.
Возникла необходимость из win32 приложения вызывать ДОС прерывания, такие как int21h, 13h и др.
В MSDN есть пример с эмуляцией вызовов через int31h, но там используется функция GlobalDosAlloc, которая, вроде бы, исключена из поздних версий Windows.
Если кто-то уже сталкивался с аналогичной проблемой - просьба рассказать, как решили.
Всяческие ссылки по теме так же приветствуются.
Заранее спасибо всем ответившим.
DeviceIOControl15.02.04 01:08 Автор: Chingachguk <Chingachguk> Статус: Member
> Возникла необходимость из win32 приложения вызывать ДОС > прерывания, такие как int21h, 13h и др.
DeviceIOControl может быть использован, к примеру, для чтения секторов через псевдовызовы int 25/26:
.386
.model flat, stdcall
option casemap:none
; Эта константа взята с MSDN.
VWIN32_DIOC_DOS_DRIVEINFO EQU 6 ; Performs Interrupt 21h Function 730X commands.
; This value is supported in Windows 95 OEM Service Release 2 and later.
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
includelib \masm32\lib\kernel32.lib
include \masm32\include\user32.inc
includelib \masm32\lib\user32.lib
; Структура, в которой обычно передаются значения регистров ф-ции DeviceIOControl(kernel32)
; А уж она их передает какой-нибудь VxD
DIOCRegs STRUC
reg_EBX DD 0
reg_EDX DD 0
reg_ECX DD 0
reg_EAX DD 0
reg_EDI DD 0
reg_ESI DD 0
reg_Flags DD 0
DIOCRegs ENDS
; Структура для передачи параметров о чтении дисковых секторов (прерыванию int 25h, cx=0FFFFh
; прерыванию int 21h, ф-ция ax=7305h, etc):
; (из Ральфа Брауна) Format of disk read packet:
; Offset Size Description (Table 1884)
; 00h DWORD sector number
; 04h WORD number of sectors to read
; 06h DWORD transfer address
DiskReadPacket STRUC
SectorNumber dd 00h ; DWORD sector number
SectorsToRead dw 00h ; WORD number of sectors to read
TransferAddress dd 00h ; DWORD transfer address
DiskReadPacket ENDS
.data
; Оказывется, чтобы получить хендл для доступа
; к дискам под 95 надо сделать так:
; hDevice = CreateFile("\\\\.\\vwin32",...
VxDFileName db '\\.\vwin32',0 ; Имя VxD
; Имена сообщений (для MessageBox)
AppName db "DeviceIoControl",0
Success db "The VxD is successfully loaded!",0
Failure db "The VxD is not loaded!",0
Unload db "The VxD is now unloaded!",0
; Переменные для чтения/записи секторов
; Объявляем группу переменных (как структуру DIOCRegs)
DeviceIOCallStructure DIOCRegs <>
CallParams DiskReadPacket <,,offset Buffer>
Buffer db 512 dup(0) ; read/write buffer for sector
CB dd 0 ; Unknown buffer for DeviceIOControl
; Отладочные сообщения, выводимые через MessageBox
MsgErrDeviceIO db "Error at DeviceIOControl execution ! ;)",0
MsgErrReadSector db "Raising Error ???????? at read sector ! ;)",0
MsgDeviceIOControl db "DeviceIOControl example: read disk sector",0
MsgOk db "Sector number ???????? at Drive ???????? contain: ???????? at begin and ???????? at the end.",0
.data?
; Хендл открытой VxD (vwin32)
hVxD dd ?
.code
start:
; Device IO Control
; Открываем "VxD"
invoke CreateFile,addr VxDFileName,0,0,0,0,FILE_FLAG_DELETE_ON_CLOSE,0
cmp eax,INVALID_HANDLE_VALUE
jz @@VxDNotOpen
; Сохраняем ID открытой VxD
mov hVxD,eax
; Выдаем сообщение о том, что она(VxD) открыта
invoke MessageBox,NULL,addr Success,addr AppName,MB_OK+MB_ICONINFORMATION
; Формируем пакет для чтения сектора
mov CallParams.SectorNumber,0 ; Номер сектора
mov CallParams.SectorsToRead,1 ; Число секторов
; Формируем структуру для вызова сервиса VxD через DeviceIOControl
mov DeviceIOCallStructure.reg_EAX,7305h ; DOS Abs_Disk_Read
mov DeviceIOCallStructure.reg_EBX,offset CallParams ; = (DWORD)&dio;
mov DeviceIOCallStructure.reg_ECX,-1 ; use DISKIO struct
mov DeviceIOCallStructure.reg_ESI,0 ; Read (for write - 1)
mov DeviceIOCallStructure.reg_EDX,0 ; Drive Number = 0=Default,1="A",2="B"...
; Вызываем DeviceIOControl
push NULL
push offset CB
push size DeviceIOCallStructure
push offset DeviceIOCallStructure
push size DeviceIOCallStructure
push offset DeviceIOCallStructure
push VWIN32_DIOC_DOS_DRIVEINFO
push hVxD
call DeviceIoControl
; Проверка на ошибку. Если ошибка, то eax = 0
test eax,eax
jnz @@NoDeviceIoControlError
; Ошибка при вызове DeviceIoControl
invoke MessageBox,NULL,addr MsgErrDeviceIO,NULL,MB_OK+MB_ICONERROR
jmp @@ResultDone
@@NoDeviceIoControlError:
; Надо проверить возращенное значение "регистра" флагов в структуре DeviceIOCallStructure
test DeviceIOCallStructure.reg_Flags,1h ; error if carry flag set
jz @@NoReadSectorError
; Ошибка выполнения ф-ции чтения сектора
mov eax,DeviceIOCallStructure.reg_EAX
mov edi,offset MsgErrReadSector+14
call HexChar
invoke MessageBox,NULL,addr MsgErrReadSector,NULL,MB_OK+MB_ICONERROR
jmp @@ResultDone
@@NoReadSectorError:
; Show 3 word for control
call OutResult ; Покажем р-ты чтения сектора
@@ResultDone:
invoke CloseHandle,hVxD
invoke MessageBox,NULL,addr Unload,addr AppName,MB_OK+MB_ICONINFORMATION
jmp @@DeviceIODone
@@VxDNotOpen:
invoke MessageBox,NULL,addr Failure,NULL,MB_OK+MB_ICONERROR
@@DeviceIODone:
jmp @@AllDone
@@AllDone:
invoke ExitProcess,NULL
OutResult proc
mov eax,CallParams.SectorNumber
mov edi,offset MsgOk+14
call HexChar
mov eax,DeviceIOCallStructure.reg_EDX
mov edi,offset MsgOk+32
call HexChar
mov eax,dword ptr Buffer[0]
mov edi,offset MsgOk+50
call HexChar
mov eax,dword ptr Buffer[512-4]
mov edi,offset MsgOk+72
call HexChar
invoke MessageBox,NULL,addr MsgOk,addr MsgDeviceIOControl,MB_OK+MB_ICONINFORMATION
ret
OutResult endp
HexChar proc
pushad
cld
mov ecx,8
mov ebx,offset TabHex
@GetHex:
rol eax,4
push eax
and al,0fh
xlat
stosb
pop eax
loop @GetHex
popad
ret
TabHex db '0123456789abcdef'
HexChar endp
end start
Все хорошо но в NTях это не будет работать15.02.04 01:42 Автор: Killer{R} <Dmitry> Статус: Elderman
И вообще имхо никак не получить досовские вызовы. Потому что если 9х оставляет обработчики прерываний досовские в памяти то в NT их точно нет. А все вызовы из досовской виртуальной машины транслируются в API.
Да вроде речь про 98 ?15.02.04 09:28 Автор: Chigachguk Статус: Незарегистрированный пользователь
> И вообще имхо никак не получить досовские вызовы. Потому > что если 9х оставляет обработчики прерываний досовские в > памяти то в NT их точно нет. А все вызовы из досовской > виртуальной машины транслируются в API.
Да вроде как ничего она не оставляет "досовского". Все через VxD. Из V86 все транслируется туда, апи (ты про kernel32 и т.п. ?) никак не находятся в промежутке. Этот вызов из win32 тоже транслируется к какому-нибудь IOS VxD через kernel32, в котором есть адреса, call/jmp на которые сразу переводит в нулевое кольцо. Этот вызов DeviceIoControl - просто обертка.