|
|
| Посл.отвђт | Сообщенiе |
|
|
Дата: Дек 3, 2002 18:42:29 Как из-под Windows 9x читать данные с дисков независимо от файловой системе, которая на них используется? |
|
|
Дата: Дек 4, 2002 05:46:31 DeviceIoControl? |
|
|
Дата: Дек 4, 2002 09:30:05 Абсолютно согласен с P2M. Вот как я читал сектора: .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 |
|
|
Дата: Дек 4, 2002 11:09:15 А можно ли так писать в сектора(Например в Boot sector)? |
|
|
Дата: Дек 4, 2002 14:51:17 dragon Воин дзена Дата: Дек 4, 2002 11:09:15 А можно ли так писать в сектора(Например в Boot sector)? Можно, хотя я не пробовал ;) Вроде вот это: mov DeviceIOCallStructure.reg_ESI,0 ; Read (for write - 1) А вот в mbr так не запишшешь ;) |
|
|
Дата: Дек 4, 2002 15:33:08 Я пробывал читать с обычной дискеты нулевой сектор, параметр CB всё время получается 28, а в буфере сплошные нули. Тот же результат при чтении других секторов и при чиении с жесткого диска. Может в Windows Me программа не работает? Да, а что такое mbr? |
|
|
Дата: Дек 4, 2002 17:01:47 Я пробывал читать с обычной дискеты нулевой сектор Я не уверен, что она применима для чтения секторов дискеты. Для дискет я пользовался чем-то другим. параметр CB всё время получается 28, а в буфере сплошные нули. Тот же результат при чтении других секторов и при чиении с жесткого диска. Может в Windows Me программа не работает? Задай как у меня: mov CallParams.SectorNumber,0 ; Номер сектора Это будет означать чтение бут-сектора того раздела, на котором у тебя винда. У меня на 98-х (несколько компов все работало). Примерно так: (Messaege Box): SecNumber: 00000 at Drive 000000 contain 4d9058ed at begin and aa550000 at the end. Здесь видно типичное содержимое boot-сектора: короткий jmp в начале и маркер бута (aa55) в конце. Вообще, скомпили мой пример без модификации и запусти. Должно работать. Да, а что такое mbr? Мастер Бут Рекорд. Код, который первым получает управление при загрузке компа с винта. |
|
|
Дата: Дек 4, 2002 21:04:22 Я не могу скомпилить пример без модификации, переписываю его на TASM.(Вроде от этого ничего не меняется), или на C++. Всё то же самое - CB всё время 28, в буфер ничего не записывается ни при чтении с дискеты ни с жесткого диска. Может есть какой-нибудь другой способ чтения из Ring3? Из Ring0 можно работать с дисками, используя Vxd, но как читать оттуда, я не знаю(В опциях прерывания 13h буфер чтения указывается, смещение относительно CS, поэтому трудно указать правильный адрес буфера, а как работать через порты, вообще не понятно.) Да и не найти документации, как вызвать функцию Vxd из простого приложения. |
|
|
Дата: Дек 5, 2002 04:06:05 · Поправил: P2M dragon переписываю его на TASM Если есть возможность попробовать C/C++, то BUG: Int 21 Read/Write Track on Logical Drive Fails on OSR2 and Later Может есть какой-нибудь другой способ чтения Попробуйте PRB: DeviceIoControl Int 13h Does Not Support Hard Disks |
|
|
Дата: Дек 14, 2002 04:33:39 1) VXD-туториал в руки. 2) Вот такая шняга должна сработать: ; Выполнить код в режме v86 Push_Client_State VMMCall Begin_Nest_V86_Exec assume ebp:ptr Client_word_reg_struc mov edx,edi ;EDI[0-1] - смещение, EDI[2-3] - сегмент mov [ebp].Client_ax,201h ;} mov [ebp].Client_bx,dx ; } mov bx,CYLNUMBER mov cx,SECNUMBER ; 0-5 биты AX <- 0-5 биты CX ; 6-7 биты AX <- 8-9 биты BX ; 8-15 биты AX <- 0-7 биты BX ;1) mov al,bh ;} поместить 8-9 биты BX в 6-7 биты AX shl al,6 ;} ;2) and cl,00111111b ;обнулить 6-7 биты CX or al,cl ; поместить 0-5 биты CX в 0-5 биты AX ;3) mov ah,bl ;поместить 0-7 биты BX в 8-15 биты AX mov [ebp].Client_cx,ax ; } Заполнить Client_word_reg_struc для mov ah,HEADNUMBER mov al,80h mov [ebp].Client_dx,ax ; } чтения 0-го сектора shr edx,16 ; } mov [ebp].Client_es,dx ;} mov eax,13h VMMCall Exec_Int VMMCall End_Nest_Exec Pop_Client_State |
|
|
Дата: Янв 7, 2003 21:13:07 На С++ код по чтению и записи секторов с 13 прерыванием работает. #define VWIN32_DIOC_DOS_DRIVEINFO 6 //Performs Interrupt 21h Function 730X commands. This value is supported in Windows 95 OEM Service Release 2 and later. #define VWIN32_DIOC_DOS_INT13 4 //Performs Interrupt 13h commands #define VWIN32_DIOC_DOS_INT25 2 //Performs the Absolute Disk Read command (Interrupt 25h) #define VWIN32_DIOC_DOS_INT26 3 //Performs the Absolute Disk Write command (Interrupt 26h) #define VWIN32_DIOC_DOS_IOCTL 1 //Performs the specified MS-DOS device I/O control function (Interrupt 21h Function 4400h through 4411h) #define FUNC_DISK_FORMAT 5 #define FUNC_DISK_READ 2 #define FUNC_DISK_WRITE 3 #define FUNC_DISK_RESET 0 #define FUNC_DISK_STATUS 1 #define FUNC_DISK_VERIFY 4 #define SECTOR_SIZE 512 // Size, in bytes, of a disk sector #define CARRY_FLAG 0x0001 BOOL SimulateInt13(PDEVIOCTL_REGISTERS preg) { HANDLE hDevice; BOOL fResult; DWORD cb; hDevice = CreateFile("\\\\.\\vwin32", GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, (LPSECURITY_ATTRIBUTES) NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, (HANDLE) NULL); if (hDevice == (HANDLE) INVALID_HANDLE_VALUE) return FALSE; preg->reg_Flags = CARRY_FLAG; // assume error (carry flag is set) fResult = DeviceIoControl(hDevice, VWIN32_DIOC_DOS_INT13, preg, sizeof(DEVIOCTL_REGISTERS), preg, sizeof(DEVIOCTL_REGISTERS), &cb, 0); CloseHandle(hDevice); if (!fResult || (preg->reg_Flags & CARRY_FLAG)) // error if carry flag set return FALSE; return TRUE; } BOOL BiosDisk(BYTE bFunc, PDISK_INFO pDiskInfo) { DEVIOCTL_REGISTERS reg; BOOL fResult; reg.reg_EAX = MAKEWORD(pDiskInfo->nsectors, bFunc); // BIOS func, Sectors count # reg.reg_ECX = MAKEWORD(pDiskInfo->sector, pDiskInfo->track); // Cylinder #, Sector # reg.reg_EDX = MAKEWORD(pDiskInfo->drive, pDiskInfo->head); // Head #, Drive # reg.reg_EBX = (DWORD)pDiskInfo->buffer; // Offset of sector buffer fResult = SimulateInt13(®); if (fResult == TRUE) { pDiskInfo->sector = LOBYTE(reg.reg_ECX); pDiskInfo->track = HIBYTE(reg.reg_ECX); pDiskInfo->drive = LOBYTE(reg.reg_EDX); pDiskInfo->head = HIBYTE(reg.reg_EDX); } return fResult; } Можно использовать прерывание 21h 440D commands 41 function - write, 42 - format .... смотри MSDN там все написано. Или использоавть прерывание 25h, 26h. Или использоавть прерывание 21h, 730X commands Кто бы обьяснил чем эти методы отличаются? |
|
|
Дата: Янв 11, 2003 18:25:19 · Поправил: OxMDN А не подскажете как считать гибкий диск нестандартного формата (256 байт) под досом... только не отсылайте к докам плз ... я их уже порядком начитался :(( Не помогает А так же как отформатить под тот же дос тот же диск на тот же формат Почему то моя прога не помогает: cseg segment 'code' assume cs:cseg,ds:dseg include macro.mac main proc mov ax,dseg mov ds,ax ; reset controller mov ah,00h int 13h ; set media for formating mov ah,18h mov ch,tpd ; track per side mov cl,spt ; sector per track mov dl,0 ; disk num int 13h ; set buffer data for formating xor cx,cx mov cl,spt mov bx,0 ; offset of element in 4-th byte structure mov sci,1 ; struct element index mov dx,4 nextel: mov ah,trind mov finf[bx],ah ; track number mov ah,hind mov finf[bx+1],ah ; head number mov ah,sci mov finf[bx+2],ah ; sector index mov ah,bps mov finf[bx+3],ah ; code of sector length mov bx,dx add dx,4 inc sci ; inc sector index loop nextel wrblock finf 32 ; display array wrstr new_str ;format track xor cx,cx mov ch,trind ; track number mov dh,hind ; head number mov dl,0 ; disk number mov ax,ds mov es,ax mov bx,offset finf mov ah,05h int 13h ; exit program ou_p: mov ax,4c00h int 21h main endp cseg ends dseg segment ; vars for filling finf buffer bps db 2 ; byte per sector spt db 8 ; sector per track tpd db 40 ; track per side trind db 0 ; tr index hind db 0 ; head index sci db 0 ; sector index finf db 32 dup ('*') new_str db 10,13,24h dseg ends end main Заранее плз. |
|
|
Дата: Янв 12, 2003 21:15:31 По адресу 0000:007A находится байт, который отвечает за код размера сектора, попробуй поставить его в 1, и запусти процедуру чтения(ah=2). Если флаг переноса будет установлен, то значит сектор не 256 байт или диск повреждён. Но вообще я сомневаюсь, что Bios будет читать нестандартную дискету. Поэтому надо читать через порты. Алгоритм такой: Определяешь размер сектора функцией 01001010, и читаешь посекторно. Функцию определения размера сектора лучше вызывать для каждой дорожки, т.к. на каждой дорожке может быть свой размер сектора. |
|
|
Дата: Янв 13, 2003 15:41:55 а код РАБОЧИЙ прислать не можешь ?? Плззз malyshev_d@mail.ru |
|
Powered by miniBB 1.6 © 2001-2002
Время загрузки страницы (сек.): 0.061 |