News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

which api to obtain drive name

Started by azdps, May 23, 2009, 02:11:01 PM

Previous topic - Next topic

azdps

i need to obtain the drive name. the same name that is displayed in device manager when you view the devices listed. i'm able to obtain the drive volume just fine.

evlncrn8

think you need to use IOCTL_STORAGE_QUERY_PROPERTY on the drive
google for it, and the structs should be there (msdn).. the vendorid, revision etc
is what you're after, if NULL, there isn't an entry, if there is an entry its
the start of the struct + the dword from the entry = the data you want...

note: you might need some access rights / privileges to get this information,
in most cases all you need is GENERIC_READ access to the drives...

in the cases of cd/dvd drives, for scsi based units, the vendor id is not present..

either way, do some experiments, but that info should set you on the right track

fearless

;**************************************************************************
; Get drive information, drive type, bus type etc
; Uses DeviceIOControl function to retrieve this information and store
; in a STORAGE_DEVICE_DESCRIPTOR structure

; hDrive - handle to previously opened drive
;
; lpdwDevDesc - dword value pointing to STORAGE_DEVICE_DESCRIPTOR buffer
;
;**************************************************************************
GetDriveInformation PROC hDrive:DWORD, lpdwDevDesc:DWORD
    LOCAL notuse:dword
LOCAL Query:STORAGE_PROPERTY_QUERY
mov Query.PropertyId,StorageDeviceProperty 
mov Query.QueryType,PropertyStandardQuery
invoke   DeviceIoControl,hDrive,IOCTL_STORAGE_QUERY_PROPERTY,addr Query, sizeof Query, lpdwDevDesc,512,addr notuse, NULL
ret
GetDriveInformation ENDP


;**************************************************************************
; Opens the specified logical drive letter and returns a handle to it for
; use with DeviceIOControl functions.
;
; Drive name can be retrieved from
; GetLogicalDriveStrings() or QueryDosDevice() functions
; thus function will prepend "\\.\" if it doesnt exist and will remove the
; trailing end \ if already exists.
;
; Can except the following drive examples:
; C:
; C:\
; PHYSICALDRIVE0
; \\.\C:
;
;**************************************************************************
OpenDrive PROC dwDriveName:DWORD

LOCAL hLogicalDrive:DWORD
LOCAL szDriveRootBuffer[12]:BYTE
LOCAL szDriveNameBuffer[MAX_PATH]:BYTE
LOCAL nDriveNameBufferLength:DWORD

mov esi, dwDriveName
Invoke lstrlen, dwDriveName
mov nDriveNameBufferLength, eax
add esi, eax
dec esi
xor eax, eax
mov ebx, nDriveNameBufferLength
mov al, byte ptr [esi]

.IF al == "\"
.ELSE
inc ebx
.ENDIF
Invoke lstrcpyn, Addr szDriveRootBuffer, dwDriveName, ebx
mov esi, dwDriveName
mov eax, dword ptr [esi]
.IF eax != 1546542172d ; \\.\ = 4388103
Invoke lstrcpy, Addr szDriveNameBuffer, CTEXT("\\.\")
Invoke szCatStr, Addr szDriveNameBuffer, Addr szDriveRootBuffer
.else
Invoke lstrcpy, Addr szDriveNameBuffer, Addr szDriveRootBuffer
.endif

invoke CreateFile, Addr szDriveNameBuffer, NULL, NULL, NULL, OPEN_EXISTING, NULL, NULL
mov hLogicalDrive,eax
.IF eax != INVALID_HANDLE_VALUE
; PrintText 'Opened drive for information'
.ELSE
; PrintText 'Failed to open drive for information'
.ENDIF
ret
OpenDrive endp



You could then do something like the following, i use an array of a structure to store all relevant info into:


LOCAL DevDesc[512]:byte ; DeviceIO DevDesc information
LOCAL nProductVendorSplit:DWORD

Invoke OpenDrive, Addr szDriveRoot ; open the drive
.IF eax != INVALID_HANDLE_VALUE
mov hDrive, eax
Invoke GetDriveInformation, hDrive, Addr DevDesc ; get deviceio information into our structure


; Get vendor and product id offsets
; if product id > 0 and vendor id = 0 then IDE type and need to parse vendor from product string bug
mov eax,[DevDesc.STORAGE_DEVICE_DESCRIPTOR.VendorIdOffset]
mov ebx,[DevDesc.STORAGE_DEVICE_DESCRIPTOR.ProductIdOffset]

.if eax == 0 && ebx > 0 ; bug, so parse out

mov nProductVendorSplit, 0
mov eax,[DevDesc.STORAGE_DEVICE_DESCRIPTOR.ProductIdOffset]
xor ecx, ecx
lea edx, DevDesc
add edx, eax


VendorProductSplit:

xor eax, eax
mov al, byte ptr [edx]

.if eax == 20h || eax == 0 ; stop here
inc ecx
mov nProductVendorSplit, ecx

.else
inc ecx
inc edx
jmp VendorProductSplit
.endif 

mov esi, dwDriveMatrixArrayOffset ; array to store drive info to
lea ebx, [esi].DRIVE_MATRIX_RECORD.szDriveVendorName ; i use a structure to store info in here
mov eax,[DevDesc.STORAGE_DEVICE_DESCRIPTOR.ProductIdOffset]
lea edx, DevDesc
add edx, eax
Invoke lstrcpyn, ebx, edx, nProductVendorSplit


mov esi, dwDriveMatrixArrayOffset ; this is my array to store drive info to
lea ebx, [esi].DRIVE_MATRIX_RECORD.szDriveDeviceName ; store devicename in my user defined structure
mov eax,[DevDesc.STORAGE_DEVICE_DESCRIPTOR.ProductIdOffset]
lea edx, DevDesc
add edx, eax
add edx, nProductVendorSplit
Invoke lstrcpy, ebx, edx
.else

; Save Vender Name
mov esi, dwDriveMatrixArrayOffset
lea ebx, [esi].DRIVE_MATRIX_RECORD.szDriveVendorName
mov eax,[DevDesc.STORAGE_DEVICE_DESCRIPTOR.VendorIdOffset]
lea edx, DevDesc
add edx, eax
Invoke lstrcpy, ebx, edx

; Save Device Name
mov esi, dwDriveMatrixArrayOffset
lea ebx, [esi].DRIVE_MATRIX_RECORD.szDriveDeviceName
mov eax,[DevDesc.STORAGE_DEVICE_DESCRIPTOR.ProductIdOffset]
lea edx, DevDesc
add edx, eax
Invoke lstrcpy, ebx, edx

.endif


This is my structure i use, which i fill by calling Invoke BuildDriveMatrix, Addr DriveMatrixArray, part of which is shown above, i define it as DriveMatrixArray DRIVE_MATRIX_RECORD 26 dup (<>) and just pass the builddrivematrix function the addr of the array, so it will fill in all the info i am looking for:

DRIVE_MATRIX_RECORD struct ; 332 bytes long
szDriveRootName db 4 dup (0)
szDriveVendorName db 32 dup (0)
szDriveDeviceName db 128 dup (0)
szDriveProductRevision db 32 dup (0)
szDriveSerialNumber db 32 dup (0)
szDriveVolumeName db 32 dup (0)
szDriveFileSystem db 32 dup (0)
dwDriveType dd 0
dwDriveBusType dd 0
dwDriveDeviceNo dd 0
dwDriveDeviceType dd 0
qwDriveTotalBytes dd 0,0
qwDriveTotalFreeBytes dd 0,0
qwDriveTotalUsedBytes dd 0,0
DRIVE_MATRIX_RECORD ends


Also here is the structures and data for deviceio stuff:



StorageDeviceProperty equ 0
PropertyStandardQuery equ 0

STORAGE_PROPERTY_QUERY struct
PropertyId dd 0
QueryType dd 0
AdditionalParameters dd 0       
STORAGE_PROPERTY_QUERY ends

STORAGE_DEVICE_DESCRIPTOR struct
Version dd 0   
theSize dd 0   
DeviceType db 0   
DeviceTypeModifier db 0   
RemovableMedia db 0   
CommandQueueing db 0   
VendorIdOffset dd 0   
ProductIdOffset dd 0   
ProductRevisionOffset dd 0   
SerialNumberOffset dd 0   
BusType dd 0   
RawPropertiesLength dd 0   
RawDeviceProperties dd 0   
STORAGE_DEVICE_DESCRIPTOR ends



Hope that helps give you a few pointers.
ƒearless

azdps

excellent examples fearless. i'm having a problem with IOCTL_STORAGE_QUERY_PROPERTY though. when i assemble i get the following error: undefined symbol : IOCTL_STORAGE_QUERY_PROPERTY

azdps

I looked at WinIoCtl.h file and saw that its defined but i'm having a hard time defining it in .asm file. i have it as:

IOCTL_STORAGE_QUERY_PROPERTY equ CTL_CODE(IOCTL_STORAGE_BASE, 0x0500, METHOD_BUFFERED, FILE_ANY_ACCESS)

but its not working. how do you properly define it?

fearless

Im in work at the mo, but ill have a look when i get home and check for you. Probably after 7.30ish my local time.
ƒearless

ToutEnMasm


fearless

I have this defined in my file, most from header files and some from google searching on particular structure or deviceio constants and possibly other sources.

CTL_CODE MACRO DeviceType:=<0>, Function:=<0>, Method:=<0>, Access:=<0>
        EXITM %(((DeviceType) SHL 16) OR ((Access) SHL 14) OR ((Function) SHL 2) OR (Method))
ENDM

;///////////////////////////////////////////////////////////////////////////////////////////////
;
; Device Types
;
;///////////////////////////////////////////////////////////////////////////////////////////////
FILE_DEVICE_DOESNT_EXIST equ -1h ; Virtual Devices
FILE_DEVICE_VIRTUAL equ -1h ; Virtual Devices
FILE_DEVICE_8042_PORT           equ 00000027h
FILE_DEVICE_ACPI                equ 00000032h
FILE_DEVICE_BATTERY             equ 00000029h
FILE_DEVICE_BEEP                equ 00000001h
FILE_DEVICE_BUS_EXTENDER        equ 0000002ah
FILE_DEVICE_CD_ROM              equ 00000002h
FILE_DEVICE_CD_ROM_FILE_SYSTEM  equ 00000003h
FILE_DEVICE_CHANGER             equ 00000030h
FILE_DEVICE_CONTROLLER          equ 00000004h
FILE_DEVICE_DATALINK            equ 00000005h
FILE_DEVICE_DFS                 equ 00000006h
FILE_DEVICE_DFS_FILE_SYSTEM     equ 00000035h
FILE_DEVICE_DFS_VOLUME          equ 00000036h
FILE_DEVICE_DISK                equ 00000007h
FILE_DEVICE_DISK_FILE_SYSTEM    equ 00000008h
FILE_DEVICE_DVD                 equ 00000033h
FILE_DEVICE_FILE_SYSTEM         equ 00000009h
FILE_DEVICE_FIPS                equ 0000003ah
FILE_DEVICE_FULLSCREEN_VIDEO    equ 00000034h
FILE_DEVICE_INPORT_PORT         equ 0000000ah
FILE_DEVICE_KEYBOARD            equ 0000000bh
FILE_DEVICE_KS                  equ 0000002fh
FILE_DEVICE_KSEC                equ 00000039h
FILE_DEVICE_MAILSLOT            equ 0000000ch
FILE_DEVICE_MASS_STORAGE        equ 0000002dh
FILE_DEVICE_MIDI_IN             equ 0000000dh
FILE_DEVICE_MIDI_OUT            equ 0000000eh
FILE_DEVICE_MODEM               equ 0000002bh
FILE_DEVICE_MOUSE               equ 0000000fh
FILE_DEVICE_MULTI_UNC_PROVIDER  equ 00000010h
FILE_DEVICE_NAMED_PIPE          equ 00000011h
FILE_DEVICE_NETWORK             equ 00000012h
FILE_DEVICE_NETWORK_BROWSER     equ 00000013h
FILE_DEVICE_NETWORK_FILE_SYSTEM equ 00000014h
FILE_DEVICE_NETWORK_REDIRECTOR  equ 00000028h
FILE_DEVICE_NULL                equ 00000015h
FILE_DEVICE_PARALLEL_PORT       equ 00000016h
FILE_DEVICE_PHYSICAL_NETCARD    equ 00000017h
FILE_DEVICE_PRINTER             equ 00000018h
FILE_DEVICE_SCANNER             equ 00000019h
FILE_DEVICE_SCREEN              equ 0000001ch
FILE_DEVICE_SERENUM             equ 00000037h
FILE_DEVICE_SERIAL_MOUSE_PORT   equ 0000001ah
FILE_DEVICE_SERIAL_PORT         equ 0000001bh
FILE_DEVICE_SMARTCARD           equ 00000031h
FILE_DEVICE_SMB                 equ 0000002eh
FILE_DEVICE_SOUND               equ 0000001dh
FILE_DEVICE_STREAMS             equ 0000001eh
FILE_DEVICE_TAPE                equ 0000001fh
FILE_DEVICE_TAPE_FILE_SYSTEM    equ 00000020h
FILE_DEVICE_TERMSRV             equ 00000038h
FILE_DEVICE_TRANSPORT           equ 00000021h
FILE_DEVICE_UNKNOWN             equ 00000022h
FILE_DEVICE_VDM                 equ 0000002ch
FILE_DEVICE_VIDEO               equ 00000023h
FILE_DEVICE_VIRTUAL_DISK        equ 00000024h
FILE_DEVICE_WAVE_IN             equ 00000025h
FILE_DEVICE_WAVE_OUT            equ 00000026h

;///////////////////////////////////////////////////////////////////////////////////////////////
;
; Bus Types - Used to identify bus type field in STORAGE_DEVICE_DESCRIPTOR structure
;
;///////////////////////////////////////////////////////////////////////////////////////////////
BusTypeUnknown equ 0h
BusTypeScsi equ 1h
BusTypeAtapi equ 2h ; Hard drives
BusTypeAta equ 3h ; CD/DVD drives
BusType1394 equ 4h
BusTypeSsa equ 5h
BusTypeFibre equ 6h
BusTypeUsb equ 7h ; USB drives
BusTypeRAID equ 8h
BusTypeMaxReserved equ 7Fh


;///////////////////////////////////////////////////////////////////////////////////////////////
;
; Define the method codes for how buffers are passed for I/O and FS controls
;
;///////////////////////////////////////////////////////////////////////////////////////////////
METHOD_BUFFERED                 equ 0
METHOD_IN_DIRECT                equ 1
METHOD_OUT_DIRECT               equ 2
METHOD_NEITHER                  equ 3


;///////////////////////////////////////////////////////////////////////////////////////////////
;
; Define the access check value for any access
;
; The FILE_READ_ACCESS and FILE_WRITE_ACCESS constants are also defined in ntioapi.h as
; FILE_READ_DATA and FILE_WRITE_DATA. The values for these constants *MUST* always be in sync.
;///////////////////////////////////////////////////////////////////////////////////////////////
FILE_ANY_ACCESS equ 0
FILE_READ_ACCESS equ 1
FILE_WRITE_ACCESS equ 2



IOCTL_STORAGE_BASE equ FILE_DEVICE_MASS_STORAGE ;from ntddstor.inc
IOCTL_STORAGE_QUERY_PROPERTY equ CTL_CODE(IOCTL_STORAGE_BASE, 500h, METHOD_BUFFERED, FILE_ANY_ACCESS)
IOCTL_STORAGE_GET_MEDIA_SERIAL_NUMBER equ 2D0C10h
ƒearless

dedndave

either WinIOCtl.h isn't getting pulled in or the equate isn't (is it defined in a macro ?)

MS docs say it is here.....

        Include Ntddstor.h


PBrennick

I get the ioctl values from Donkey's constants.inc (WinExplorer.exe, etc.)

You can just add the equate to your source though in the following manner;

IOCTL_STORAGE_QUERY_PROPERTY equ 02D1400h

Paul
The GeneSys Project is available from:
The Repository or My crappy website

azdps

thanks its all working now. wonder if hutch plans on adding those to the masm32 includes.

PBrennick

Why not ask him to? He generally adds what people seem to need so as to keep the size of the file as small as possible.  :thumbu

Paul
The GeneSys Project is available from:
The Repository or My crappy website

drizz

The truth cannot be learned ... it can only be recognized.

PBrennick

Hey Drizz,

I forgot all about the four-f stuff. Very useful for certain things.
Donkey is pretty darn thorough, though, and his stuff works for me.

Paul
The GeneSys Project is available from:
The Repository or My crappy website

UtillMasm

Donkey has move to GoASM...

anybody post the WinExplorer Source (Masm32 Version)?