I'm using the test code below to obtain drive information to calculate the drive size. Is my code obtaining accurate information? If the information being obtained is accurate, how would I calculate drive size? I also read somewhere that IOCTL_DISK_GET_DRIVE_GEOMETRY has a 2gb limitation and IOCTL_DISK_GET_DRIVE_GEOMETRY_EX should be used instead. Also the IOCTL_DISK_GET_DRIVE_GEOMETRY_EX structure I defined has a nested structure and also I read on MSDN that the struture is also variable in size. I'm not sure if I handled it correctly.
.586
.model flat, stdcall
option casemap :none
include /masm32/include/windows.inc
include /masm32/include/kernel32.inc
include /masm32/include/user32.inc
include /masm32/include/masm32.inc
include /masm32/include/Setupapi.inc
include /masm32/include/debug.inc
includelib /masm32/lib/kernel32.lib
includelib /masm32/lib/user32.lib
includelib /masm32/lib/masm32.lib
includelib /masm32/lib/Setupapi.lib
includelib /masm32/lib/debug.lib
WinMain PROTO :DWORD,:DWORD,:DWORD,:DWORD
DISK_GEOMETRY struct
Cylinders dd ?
MediaType dd ?
TracksPerCylinder dd ?
SectorsPerTrack dd ?
BytesPerSector dd ?
DISK_GEOMETRY ends
DISK_GEOMETRY_EX struct
Geometry DISK_GEOMETRY <>
DiskSize dd ?
Data db 8 dup (?)
DISK_GEOMETRY_EX ends
.const
IOCTL_DISK_GET_DRIVE_GEOMETRY = 70000h
IOCTL_DISK_GET_DRIVE_GEOMETRY_EX = 700a0h
GUID_DEVINTERFACE_DISK TEXTEQU <{053f56307h,0b6bfh,011d0h,{094h,0f2h,000h,0a0h,0c9h,01eh,0fbh,08bh}}>
DISK_GUID GUID GUID_DEVINTERFACE_DISK
.data
DrivePath db "\\.\c:",0
.data?
hDrive HANDLE ?
returnSize dd ?
dg DISK_GEOMETRY_EX <<?>,?>
.code
start:
invoke RtlZeroMemory,addr dg,sizeof dg
invoke CreateFile,addr DrivePath,0,FILE_SHARE_WRITE,0,OPEN_EXISTING,0,0
mov hDrive,eax
invoke DeviceIoControl,hDrive,IOCTL_DISK_GET_DRIVE_GEOMETRY_EX,0,0,addr dg,sizeof DISK_GEOMETRY_EX,addr returnSize,0
.if eax == 0
invoke GetLastError
PrintHex eax
.endif
PrintDec dg.DiskSize
PrintDec dg.Geometry.Cylinders
PrintDec dg.Geometry.TracksPerCylinder
PrintDec dg.Geometry.SectorsPerTrack
PrintDec dg.Geometry.BytesPerSector
invoke CloseHandle,hDrive
invoke ExitProcess,0
end start
Quote from: azdps on November 05, 2012, 01:01:49 PM
Is my code obtaining accurate information?
No. I'd say the structures should be
DISK_GEOMETRY struct
Cylinders dq ?
MediaType dd ?
TracksPerCylinder dd ?
SectorsPerTrack dd ?
BytesPerSector dd ?
DISK_GEOMETRY ends
DISK_GEOMETRY_EX struct 8
Geometry DISK_GEOMETRY <>
DiskSize dq ?
Data db ?
DISK_GEOMETRY_EX ends
I have this little example
I made the changes you suggested japheth.
Does PrintDec in vkdebug work with qwords? I'm obtaining a 0 value in the debug window for dg.Geometry.Cylinders.
LARGE_INTEGER also appears to be a structure. Should I use the LARGE_INTEGER structure in place of dq?
Lets suppose I changed the code to the following:
DISK_GEOMETRY struct
Cylinders LARGE_INTEGER <>
MediaType dd ?
TracksPerCylinder dd ?
SectorsPerTrack dd ?
BytesPerSector dd ?
DISK_GEOMETRY ends
DISK_GEOMETRY_EX struct
Geometry DISK_GEOMETRY <>
DiskSize LARGE_INTEGER <>
Data db ?
DISK_GEOMETRY_EX ends
How should I define the following:
dg DISK_GEOMETRY_EX <<?>,?>
I really don't know how to deal with qwords so I'm having difficulty working with the return qword values. Hopefully I can figure this out quickly. Also thanks for that example hfheatherfox07. Actually will come in handy.
my apologies .... I have too much stuff on my PC ::)
This is exactly what you want .386
.model flat, stdcall
option casemap :none
include \MASM32\INCLUDE\windows.inc
include \MASM32\INCLUDE\user32.inc
include \MASM32\INCLUDE\kernel32.inc
includelib \MASM32\LIB\user32.lib
includelib \MASM32\LIB\kernel32.lib
FPUProc PROTO :QWORD,:DWORD
_DISK_EXTENT struct
DiskNumber DWORD ?
StartingOffset INT64 ?
ExtentLength INT64 ?
_DISK_EXTENT ends
_VOLUME_DISK_EXTENTS struct
NumberOfDiskExtents DWORD ?
Extents _DISK_EXTENT <>
_VOLUME_DISK_EXTENTS ends
_DISK_GEOMETRY struct
Cylinders INT64 ?
MediaType DWORD ?
TracksPerCylinder DWORD ?
SectorsPerTrack DWORD ?
BytesPerSector DWORD ?
_DISK_GEOMETRY ends
.data
PhysicalDrive0 db '\\.\PhysicalDrive0',0
NumberD db 'MediaType %u',13,10,'TracksPerCylinder %u',13,10,'SectorsPerTrack %u',13,10,'BytesPerSector %u',13,10,'Cylinders ',0
form db "error: %u", 0
perenos db 13,10,0
IOCTL_DISK_GET_DRIVE_GEOMETRY = 70000h
Mtype db 'Format is unknown',0
db 'A5.25" floppy, with 1.2MB and 512 bytes/sector.',0
db 'A3.5" floppy, with 1.44MB and 512 bytes/sector.',0
db 'A3.5" floppy, with 2.88MB and 512 bytes/sector.',0
db 'A3.5" floppy, with 20.8MB and 512 bytes/sector.',0
db 'A3.5" floppy, with 720KB and 512 bytes/sector.',0
db 'A5.25" floppy, with 360KB and 512 bytes/sector.',0
db 'A5.25" floppy, with 320KB and 512 bytes/sector.',0
db 'A5.25" floppy, with 320KB and 1024 bytes/sector.',0
db 'A5.25" floppy, with 180KB and 512 bytes/sector.',0
db 'A5.25" floppy, with 160KB and 512 bytes/sector.',0
db 'Removable media other than floppy.',0
db 'Fixed hard disk media.',0
db 'A3.5" floppy, with 120MB and 512 bytes/sector.',0
db 'A3.5" floppy, with 640KB and 512 bytes/sector.',0
db 'A5.25" floppy, with 640KB and 512 bytes/sector.',0
db 'A5.25" floppy, with 720KB and 512 bytes/sector.',0
db 'A3.5" floppy, with 1.2MB and 512 bytes/sector.',0
db 'A3.5" floppy, with 1.23MB and 1024 bytes/sector.',0
db 'A5.25" floppy, with 1.23MB and 1024 bytes/sector.',0
db 'A3.5" floppy, with 128MB and 512 bytes/sector.',0
db 'A3.5" floppy, with 230MB and 512 bytes/sector.',0
db 'An 8" floppy, with 256KB and 128 bytes/sector.',0
db 'A3.5" floppy, with 200MB and 512 bytes/sector. (HiFD).',0
db 'A3.5" floppy, with 240MB and 512 bytes/sector. (HiFD).',0
db 'A3.5" floppy, with 32MB and 512 bytes/sector.',0
baza dw 0,18,66,114,162,210,257,305,353,402,450,498,533,556,603,650,698,746,793,842,892,939,986,1033,1088,1143,1189
.data?
cw dd ?
data1 _DISK_GEOMETRY <>
buffer db 512 dup (?)
.code
start:
invoke CreateFile,addr PhysicalDrive0,GENERIC_READ,FILE_SHARE_READ OR FILE_SHARE_WRITE,0, OPEN_EXISTING,0,0
mov ebx, eax
invoke DeviceIoControl, ebx, IOCTL_DISK_GET_DRIVE_GEOMETRY,0,0,addr data1,sizeof data1, addr cw, 0
.if eax!=0
invoke wsprintf,ADDR buffer,addr NumberD, data1.MediaType, data1.TracksPerCylinder, data1.SectorsPerTrack, data1.BytesPerSector
invoke FPUProc, data1.Cylinders, addr buffer
invoke lstrcat, addr buffer, addr perenos
lea esi, baza
add esi, data1.MediaType
add esi, data1.MediaType
lea edi, Mtype
movzx eax, word ptr[esi]
add edi, eax
invoke lstrcat, addr buffer, edi
.else
invoke GetLastError
invoke wsprintf,ADDR buffer,addr form, eax
.endif
invoke MessageBox,0,ADDR buffer,0,MB_ICONASTERISK
invoke CloseHandle, ebx
invoke ExitProcess,0
FPUProc proc uses ebx Value:QWORD, String:DWORD
LOCAL CReg:REAL10
LOCAL FString[20]:BYTE
finit
fild qword ptr [Value];[data1.Cylinders]
fbstp CReg
lea esi,FString
add esi, 18
mov byte ptr[esi],0
lea edi,CReg
xor edx, edx
xor ebx, ebx
mov ecx, 9
next:
dec esi
dec esi
mov bl, byte ptr [edi]
shl ebx,4
add bh, 48
mov dl, bh
xor bh, bh
shr ebx, 4
add bl, 48
mov dh, bl
mov word ptr [esi], dx
inc edi
loop next
Next:
inc esi
cmp byte ptr [esi], 48
je Next
cmp byte ptr [esi], 0
jne NotZero
dec esi
NotZero:
invoke lstrcat, String, esi;addr FString
ret
FPUProc endp
end start
Quote from: azdps on November 05, 2012, 04:20:38 PM
Does PrintDec in vkdebug work with qwords?
Apparently it doesn't. You may use deb (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1018) instead. Full code attached, with Japheth's mods.
deb 4, "Disk", dg.DiskSize, dg.Geometry.Cylinders, dg.Geometry.TracksPerCylinder, dg.Geometry.SectorsPerTrack, dg.Geometry.BytesPerSector
Disk
dg.DiskSize 60011642880
dg.Geometry.Cylinders 7296
dg.Geometry.TracksPerCylinder 255
dg.Geometry.SectorsPerTrack 63
dg.Geometry.BytesPerSector 512
Excellent info. I'm up and running again and moving past this part of my code. I would also like to thank Raymond for his fpu library which came in handy for some of the calculations that i needed done.
NtCreateFile \\??\\PhysicalDrive0 --> IOCTL_DISK_GET_DRIVE_LAYOUT --> PARTITION_INFORMATION --> PartitionNumber
NtCreateFile \\Device\\Harddisk0\\Partition[PartitionNumber]\\ --> Volume Label + Serial Number
How get volume Letter?
http://www.masmforum.com/board/index.php?topic=13479.0
.while byte ptr [ebx] <= "Z"
invoke GetDriveType,ebx
.if eax == DRIVE_CDROM ; Here the drivetype you want ( cdrom harddisk cardreader etc.)
.endif
inc byte ptr [ebx]
.endw
(http://s017.radikal.ru/i424/1303/e9/3e3780c11cf0.png)
red arrow show column which I already made. left 2 and 3 column and disk name. in kernel mode
IOCTL_STORAGE_GET_DEVICE_NUMBER
http://msdn.microsoft.com/ru-RU/library/windows/desktop/bb968800%28v=vs.85%29.aspx