Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Прямой доступ к диску из Win98

3.2K
14 марта 2003 года
GMR
3 / / 14.03.2003
Для выполнения дисковых функций используется DeviceIoControl, которая требует device handle в качестве 1-го параметра. Его (device handle) можно получить с помощью CreateFile, задав имя устройства в виде \\.\DeviceName, например, "\\\\.\\a:". К сожалению, это работает только под WinNT или 2000. Под Win98 выдается ошибка "Не найден требуемый файл", а если написать просто "a:", то выдается ошибка "Нет доступа".
Если кто знает, подскажите, пож., как преодолеть эту проблему.
Заранее благодарю.
424
22 марта 2003 года
(C)dragon
307 / / 04.12.2002
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

Этот пример компилится под Masm. Работает(Если немного поменять код) с дискетами и логическими дисками на чтение и запись, но вот до MBR ему не добраться.
384
06 апреля 2003 года
mikeshilkin
95 / / 20.04.2000
или на Си

typedef struct _DIOC_REGISTERS {
DWORD reg_EBX;
DWORD reg_EDX;
DWORD reg_ECX;
DWORD reg_EAX;
DWORD reg_EDI;
DWORD reg_ESI;
DWORD reg_Flags;
} DIOC_REGISTERS, *PDIOC_REGISTERS;

#define CARRY_FLAG 1

#pragma pack(1)
typedef struct _DISKIO {
DWORD dwStartSector; // starting logical sector number
WORD wSectors; // number of sectors
DWORD dwBuffer; // address of read/write buffer
} DISKIO, * PDISKIO;
#pragma pack()

/*------------------------------------------------------------------
ReadLogicalSectors (hDev, bDrive, dwStartSector, wSectors, lpSectBuff)

Purpose:
Reads sectors from a logical drive. Uses Int 25h.

Parameters:
hDev
Handle of VWIN32

bDrive
The MS-DOS logical drive number. 1 = A, 2 = B, 3 = C, etc.

dwStartSector
The first logical sector to read

wSectors
The number of sectors to read

lpSectBuff
The caller-supplied buffer that will contain the sector data

Return Value:
Returns TRUE if successful, or FALSE if failure.

Comments:
This function does not validate its parameters.
------------------------------------------------------------------*/
BOOL ReadLogicalSectors (BYTE bDrive,
DWORD dwStartSector,
WORD wSectors,
LPBYTE lpSectBuff)
{
BOOL fResult;
DWORD cb;
DIOC_REGISTERS reg = {0};
DISKIO dio = {0};
HANDLE hDevice;

hDevice = CreateFile("\\\\.\\vwin32",0, 0, NULL, 0, FILE_FLAG_DELETE_ON_CLOSE, NULL);

if (hDevice == (HANDLE) INVALID_HANDLE_VALUE)
return FALSE;

dio.dwStartSector = dwStartSector;
dio.wSectors = wSectors;
dio.dwBuffer = (DWORD)lpSectBuff;

reg.reg_EAX = bDrive - 1; // Int 25h drive numbers are 0-based.
reg.reg_EBX = (DWORD)&dio;
reg.reg_ECX = 0xFFFF; // use DISKIO struct

fResult = DeviceIoControl(hDevice, VWIN32_DIOC_DOS_INT25,
&reg, sizeof(reg),
&reg, sizeof(reg), &cb, 0);

// Determine if the DeviceIoControl call and the read succeeded.
fResult = fResult && !(reg.reg_Flags & CARRY_FLAG);
CloseHandle(hDevice);
return fResult;
}


/*------------------------------------------------------------------
WriteLogicalSectors (hDev, bDrive, dwStartSector, wSectors, lpSectBuff)

Purpose:
Writes sectors to a logical drive. Uses Int 26h

Parameters:
hDev
Handle of VWIN32

bDrive
The MS-DOS logical drive number. 1 = A, 2 = B, 3 = C, etc.

dwStartSector
The first logical sector to write

wSectors
The number of sectors to write

lpSectBuff
The caller-supplied buffer that contains the sector data

Return Value:
Returns TRUE if successful, or FALSE if failure.

Comments:
This function does not validate its parameters.
------------------------------------------------------------------*/
BOOL WriteLogicalSectors (HANDLE hDev,
BYTE bDrive,
DWORD dwStartSector,
WORD wSectors,
LPBYTE lpSectBuff)
{
BOOL fResult;
DWORD cb;
DIOC_REGISTERS reg = {0};
DISKIO dio = {0};

dio.dwStartSector = dwStartSector;
dio.wSectors = wSectors;
dio.dwBuffer = (DWORD)lpSectBuff;

reg.reg_EAX = bDrive - 1; // Int 26h drive numbers are 0-based.
reg.reg_EBX = (DWORD)&dio;
reg.reg_ECX = 0xFFFF; // use DISKIO struct

fResult = DeviceIoControl(hDev, VWIN32_DIOC_DOS_INT26,
&reg, sizeof(reg),
&reg, sizeof(reg), &cb, 0);

// Determine if the DeviceIoControl call and the write succeeded.
fResult = fResult && !(reg.reg_Flags & CARRY_FLAG);

return fResult;
}
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог