Как низкоуровнево можно получить ПОЛНЫЙ размер харда? В MBR информация о разделах уже размеченных,соответсвенно полного размера харда я не получу тупо складывая размеры всех разделов....
T800 Какой нулевой сектор? MBR содержит таблицу разделов,как я понимаю уже размеченных и из них никак не узнать настоящего размера HDD...
Да что вы пристали то к этой MBR то? http://rsdn.ru/forum/asm/4646517.flat.aspx это тоже ваше что ли?
А вам на каком уровне надо? Например можно послать команду ATA IDENTIFY DEVICE. Есть еще и прерывание делающее это же. В винде через DeviceIoControl делается
AlexCasual, ты определись что тебе именно надо. Реальный размер диска, или тот что указан в файловой системе или MBR ? 1) Таблица разделов - там данные нереальный могут быть. 2) Нулевой сектор - всё зависит от файловой системы в разделе + данные могут быть нереальные. По этому необходимо сделать запросы к HDD напрямую через порты или как-нибудь через BIOS Extended CHS. К примеру погляди исходники трукрипта, там есть функция GetDriveGeometry
Понятно, что речь идет о "реальном размере диска". "РУЧНОЙ разбор файловых структур" можно и из-под винды делать. Ты лучше скажи, тебе нужно напрямую взаимодействовать с аппаратурой или можно использовать сервис ОС/драйверов. В любом случае и для винды, и для работы на голом железе ответы были даны. Только следует учитывать, что существует два вида размеров диска - пользовательский и заводской. Обычно используется пользовательский размер - слова 60-61 (28-разрядная адресация) или 100-103 (48-разрядная адресация) структуры, возвращаемой IDENTIFY DEVICE. Если нужен заводской размер, то для этого есть спец. команда READ NATIVE MAX ADDRESS (EXT).
1. Получаешь информацию о размеченных/занятых областях. 2. Получаешь геометрию диска, считаешь общий размер. 3. Сопоставляешь его с п.1 На каком этапе у Вас трудности?
Вот пример на FASM'е для сбора инфы о диске через API. Собственно ничего нового.. Но речь о том, как вычислить константы IOCTL, т.к. мой FASM-1.67 в упор отказывался компилить "DeviceIoControl", если в нём 'код операции' задаётся в текстовом виде, типа "IOCTL_Disk_Get_Drive_Geometry". Требует константу.. В итоге, выловил в гугле файл "MpuNTDeviceIOControl.pas", который цепляю в скрепке. В нём имеются базы и алго вычисления всех констант кодов операций. Вот вырезка из этого файла, и пример вычисления константы для "Get_Drive_Geometry": const: --------- IOCTL_DISK_GET_DRIVE_GEOMETRY = ( (IOCTL_DISK_BASE shl 16) or (FILE_ANY_ACCESS shl 14) or ($0000 shl 2) or METHOD_BUFFERED); IOCTL_DISK_GET_MEDIA_TYPES = ( (IOCTL_DISK_BASE shl 16) or (FILE_ANY_ACCESS shl 14) or ($0300 shl 2) or METHOD_BUFFERED); IOCTL_DISK_FORMAT_TRACKS = ( (IOCTL_DISK_BASE shl 16) or ((FILE_READ_ACCESS or FILE_WRITE_ACCESS) shl 14) or ($0006 shl 2) or METHOD_BUFFERED); Здесь видно, что нужны ещё 6 полей, которые описаны там-же: const: ---------- IOCTL_DISK_BASE = FILE_DEVICE_DISK; FILE_DEVICE_DISK = 00000007h; FILE_ANY_ACCESS = 0; FILE_READ_ACCESS = 00000001h; FILE_WRITE_ACCESS = 00000002h; METHOD_BUFFERED = 0. Подставив эти значения в алго первой врезки "IOCTL_DISK_GET_DRIVE_GEOMETRY" получаю в отладчике(GRDB) такое значение: --------------------------------------- GRDB version 1.7 Copyright (c) LADsoft History enabled ->a 0E85:0100 mov eax,7 0E85:0106 shl eax,10 0E85:010A mov ebx,0 0E85:0111 shl ebx,0Е 0E85:0115 mov ecx,0 0E85:011C shl ecx,2 0E85:0120 or eax,ebx 0E85:0123 or eax,ecx 0E85:0126 or eax,0 : EAX = 00070000h 0E85:012A -> Остальные коды операций вычисляются аналогично, в результате чего имею константы ниже, которые теперь можно подставить в FASM'овский код с "DeviceIoControl": 00070000h = IOCTL_DISK_GET_DRIVE_GEOMETRY 00070C00h = IOCTL_DISK_GET_MEDIA_TYPES 0007C018h = IOCTL_DISK_FORMAT_TRACKS Кстати, кое-что можно выловить и из СИ-шного хидера "winioctl.h", но там что-то мутное..
Код (ASM): ; DeviceIoControl: ;-------------------------- format PE console include 'win32ax.inc' include 'api\kernel32.inc' entry start section '.data' data readable writeable path db '\\.\PhysicalDrive0',0 ;устройство count dd 0 ;счётчик записаных байт opCode = 00070000h ;константа 'IOCTL_DISK_GET_DRIVE_GEOMETRY' align 16 ; делаем адрес буфера кратным 16 buff: ; DISK_GEOMETRY totalCyl dd 0,0 ; - Всего цилиндров (Large integer) mediaType dd 0 ; - Тип устройства trackCyl dd 0 ; - Треков в цилиндре secTrack dd 0 ; - Секторов в треке byteSec dd 0 ; - Байт в секторе ;---------------------------------------------- section '.code' code readable executable start: ;// Открываем устройство (диск) ---------- ; Константы функций лежат в файле: 'FASM\INCLUDE\EQUATES\kernel32.inc' invoke CreateFile, path,80000000h,1,0,3,0,0 or eax,eax jns @f ;EAX = -1, ошибка. cinvoke printf,<'Physical Drive ERROR!!!',0> jmp exit @@: push eax ;дескриптор устройства ;// Читаем геометрию диска -------------- invoke DeviceIoControl, eax,opCode,0,0,buff,32,count,0 pop eax invoke CloseHandle,eax ;закрыть устройство ;// Выводим 'DISK_GEOMETRY' ------------- cinvoke printf, <'Sector size : %d byte',10,0>,[byteSec] ; Считаем всего секторов mov eax,[trackCyl] imul eax,[secTrack] push eax mov ebx,[totalCyl] xor edx,edx ;EDX = старшая часть mul ebx ;EAX = младшая cinvoke printf, <'Total sectors : %d%d',10,0>,edx,eax ; Считаем общий объём диска pop eax imul eax,[byteSec] shr eax,10 ;EAX = один цилиндр в Кбайтах (EAX / 1024) imul eax,[totalCyl] shr eax,10 ;EAX = всего в Мбайтах cinvoke printf, <'---------------',10,\ 'HDD Capacity : %d Mb',0>,eax exit: cinvoke scanf invoke ExitProcess, 0 ;---------------------------------------------- section '.idata' import data readable library kernel32, 'kernel32.dll',\ msvcrt, 'msvcrt.dll' import msvcrt,\ printf, 'printf',\ scanf, 'scanf'
Ну и прицепом ещё пару строк.. Для получения инфы о памяти: Код (ASM): ;GlobalMemoryStatus ;------------------- format PE console include 'win32ax.inc' include 'api\kernel32.inc' entry start section '.data' data readable writeable buff dd 8 dup(0) ; буфер под структуру section '.code' code readable executable start: invoke GlobalMemoryStatus, buff ;// Всего физической памяти mov eax,[buff+8] shr eax,20 ;в Мбайтах cinvoke printf, <'MEMORY',10,'----------',10,'Total : %d Mb',10,0>,eax ;// Свободно физ.памяти mov eax,[buff+12] shr eax,20 ;в Мбайтах mov ebx,100 ;..и в процентах sub ebx,[buff+4] cinvoke printf, <'Free : %d Mb = %d%%',10,10,0>,eax,ebx ;// Файл подкачки mov eax,[buff+16] shr eax,20 cinvoke printf, <'PageFile',10,'----------',10,'Total : %d Mb',10,0>,eax mov eax,[buff+20] shr eax,20 cinvoke printf, <'Free : %d Mb',10,10,0>,eax ;// Виртуальной памяти mov eax,[buff+24] shr eax,20 cinvoke printf, <'Virtual',10,'----------',10,'Total : %d Mb',10,0>,eax mov eax,[buff+28] shr eax,20 cinvoke printf, <'Free : %d Mb',10,0>,eax cinvoke scanf invoke ExitProcess, 0 ;---------------------------------------------- section '.idata' import data readable library kernel32, 'kernel32.dll',\ msvcrt, 'msvcrt.dll' import msvcrt,\ printf, 'printf',\ scanf, 'scanf'
Читаем данные о разделах диска: Код (ASM): ;GetVolumeInformation ;-------------------------- format PE console include 'win32ax.inc' include 'api\kernel32.inc' entry start section '.data' data readable writeable PathName db 'C:\',0 ; выбираем раздел VolName db 16 dup(0) ; буфер под метку тома VolNameSize dd 0 ; ..(размер этого буфера) VolSN dd 0 ; серийник тома MaxLen dd 0 ; допустимая макс.длина имени файлов FSflags dd 0 ; флаги FS FSName db 16 dup(0) ; буфер под тип FS FSNameSize dd 0 ; ..(размер этого буфера) section '.code' code readable executable start: invoke GetVolumeInformation, PathName, VolName, 16,\ VolSN, MaxLen, FSflags, FSName, 16 cinvoke printf, PathName cinvoke printf, <' Volume Info',10,'----------------',10,\ 'Label : %s',10,0>,VolName cinvoke printf, <'Vol SN : %08X',10,0>,[VolSN] cinvoke printf, <'FSystem : %s',10,0>,FSName cinvoke printf, <'fName len: %d',10,0>,[MaxLen] cinvoke scanf invoke ExitProcess, 0 ;---------------------------------------------- section '.idata' import data readable library kernel32, 'kernel32.dll',\ msvcrt, 'msvcrt.dll' import msvcrt,\ printf, 'printf',\ scanf, 'scanf'