Größe von PHYSICALDRIVE

Windowsspezifisches Forum , API ,..
Beiträge, die plattformübergreifend sind, gehören ins 'Allgemein'-Forum.
Marvin
Beiträge: 497
Registriert: 17.07.2005 14:42
Wohnort: Krikkit

Größe von PHYSICALDRIVE

Beitrag von Marvin »

Ich arbeite ja gerade (unter anderem) an Dateisystemen und beschäftige mich daher auch mit der Partitionierung. Damit es dem User möglichst einfach gemacht wird, das korrekte Laufwerk auszuwählen, wäre es schön, wenn ich ihm die größe des jeweiligen PhysicalDrives angeben könnte. Doch leider klappt das bei mir nicht. Ich habe die folgenden beiden Sachen schon ausprobiert:

Code: Alles auswählen

Procedure Lopd(hPhysicalDrive)
  ProcedureReturn GetFileSize_(hPhysicalDrive,0) ;Auch wenn ich einen Pointer
                                                 ;für lpFileSizeHigh angebe, klappt's nicht
EndProcedure
und

Code: Alles auswählen

Procedure Lopd(hPhysicalDrive)
  Protected ret,pos
  pos=SetFilePointer_(hPhysicalDrive,0,0,#FILE_CURRENT) ;Aktuelle Position
  ret=SetFilePointer_(hPhysicalDrive,0,0,#FILE_END) ;Größe der Datei
  SetFilePointer_(hPhysicalDrive,pos,0,#FILE_BEGIN) ;Vorherige Position
  ProcedureReturn ret
EndProcedure
Die Handles waren jedes Mal in Ordnung.

Vielen Dank im Voraus! :allright:
Benutzeravatar
bingo
Beiträge: 118
Registriert: 16.09.2004 18:33
Wohnort: thüringen
Kontaktdaten:

Beitrag von bingo »

paar routinen zur hilfe für xp/vista:

DRIVE_GEOMETRY...

Code: Alles auswählen

Structure DISK_GEOMETRY
   Cylinders.q
   MediaType.l  ;MEDIA_TYPE
   TracksPerCylinder.l
   SectorsPerTrack.l
   BytesPerSector.l 
EndStructure

Structure DISK_GEOMETRY_EX
pp1.DISK_GEOMETRY
DiskSize.q
byte.b[1];
EndStructure

pp.DISK_GEOMETRY_EX

#IOCTL_DISK_BASE                = 7  
#METHOD_BUFFERED                = 0
#FILE_ANY_ACCESS                = 0

Procedure.l CTL_CODE(DeviceType, Function, Method, Access)
  ProcedureReturn ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method)
EndProcedure

IOCTL_DISK_GET_DRIVE_GEOMETRY_EX = CTL_CODE(#IOCTL_DISK_BASE, $28, #METHOD_BUFFERED, #FILE_ANY_ACCESS) 


hDevice = CreateFile_("\\.\PhysicalDrive0", #GENERIC_READ,#FILE_SHARE_READ,0,#OPEN_EXISTING,0,0)

If hDevice

DeviceIoControl_(hDevice, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX,0,0,@pp,SizeOf(pp),@bytesret, 0)

EndIf

CloseHandle_(hDevice)

Debug  "size: " + Str(pp\Disksize / (1024*1024*1024)) + "gb"


Debug pp\pp1\cylinders
Debug pp\pp1\TracksPerCylinder
Debug pp\pp1\SectorsPerTrack
Debug pp\pp1\BytesPerSector
partition(en) löschen ... VORSICHT !!!

Code: Alles auswählen


#IOCTL_DISK_BASE                = 7  
#METHOD_BUFFERED                = 0
#FILE_ANY_ACCESS                = 0
#FILE_READ_ACCESS               = 1
#FILE_WRITE_ACCESS              = 2

Procedure.l CTL_CODE(DeviceType, Function, Method, Access)
  ProcedureReturn ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method)
EndProcedure

IOCTL_DISK_DELETE_DRIVE_LAYOUT = CTL_CODE(#IOCTL_DISK_BASE, $40, #METHOD_BUFFERED, #FILE_WRITE_ACCESS|#FILE_READ_ACCESS) 

;2. platte
hDevice = CreateFile_("\\.\PhysicalDrive1", #GENERIC_READ|#GENERIC_WRITE,#FILE_SHARE_READ|#FILE_SHARE_WRITE,0,#OPEN_EXISTING,0,0)

If hDevice

Debug DeviceIoControl_(hDevice,IOCTL_DISK_DELETE_DRIVE_LAYOUT,0,0,0,0,@ret,0)

Debug ret

EndIf

CloseHandle_(hDevice)
:wink:
1:0>1
Marvin
Beiträge: 497
Registriert: 17.07.2005 14:42
Wohnort: Krikkit

Beitrag von Marvin »

@bingo: 1000 Dank für dein erstes Beispiel! Genau das, was ich brauchte! :allright:
Und das mit den Partitionen mach' ich schon selbst...

@thorax: Ein paar Beispiele:

Code: Alles auswählen

;PhysicalDrive-Liste
NewList PhysicalDrives.b()
For Drive=0 To 9
  hFile=CreateFile_("\\.\PHYSICALDRIVE"+Str(Drive),#GENERIC_READ|#GENERIC_WRITE,#FILE_SHARE_READ|#FILE_SHARE_WRITE,0,#OPEN_EXISTING,#FILE_FLAG_NO_BUFFERING,0)
  If hFile>-1 ;Wenn das Drive nicht geöffnet werden kann...
    CloseHandle_(hFile)
    AddElement(PhysicalDrives())
    PhysicalDrives()=Drive
  EndIf
Next
In PhysicalDrives() sind dann die Nummern aller zu öffnenden PhysicalDrives gespeichert.

Ich kann bis jetzt leider nur mit primären Partitionen arbeiten:

Code: Alles auswählen

#PARTITION_UNUSED=$00 ;Unbenutzt
#PARTITION_FAT12=$01 ;FAT12 (für Disketten)
#PARTITION_FAT16_32M=$04 ;FAT16 (<= 32 MB size)
#PARTITION_DOS_EXTENDED=$05 ;Erweiterte Partition
#PARTITION_FAT16=$06 ;FAT16 (> 32 MB size)
#PARTITION_NTFS=$07 ;NTFS (kann auch HPFS sein)
#PARTITION_FAT32=$0B ;FAT32
#PARTITION_FAT32_LBA=$0C ;FAT32 im LBA-Modus
#PARTITION_FAT16_LBA=$0E ;FAT16 im LBA-Modus
#PARTITION_LINUX_SWAP=$82 ;Auslagerungspartition für Linux
#PARTITION_LINUX_NATIVE=$83 ;Linux-Partition (ReiserFS, ext2, ext3, etc.)
#PARTITION_LINUX_EXTENDED=$85 ;Erweiterte Partition für Linux
Procedure GetPartitionType(*MBR,PartNum) ;PartNum is number from 1 to 4
  ProcedureReturn PeekB(*MBR+430+(PartNum*16)+4)&$FF
EndProcedure
Procedure.s PartitionType2Name(type)
  Select type
    Case #PARTITION_UNUSED
      ProcedureReturn "---"
    Case #PARTITION_FAT12
      ProcedureReturn "FAT12"
    Case #PARTITION_FAT16_32M
      ProcedureReturn "FAT16 (<= 32 MB)"
    Case #PARTITION_DOS_EXTENDED
      ProcedureReturn "DOS extended"
    Case #PARTITION_FAT16
      ProcedureReturn "FAT16 (> 32 MB)"
    Case #PARTITION_NTFS
      ProcedureReturn "NTFS/HPFS"
    Case #PARTITION_FAT32
      ProcedureReturn "FAT32"
    Case #PARTITION_FAT32_LBA
      ProcedureReturn "FAT32 (LBA)"
    Case #PARTITION_FAT16_LBA
      ProcedureReturn "FAT16 (LBA)"
    Case #PARTITION_LINUX_SWAP
      ProcedureReturn "linux-swap"
    Case #PARTITION_LINUX_NATIVE
      ProcedureReturn "Linux native"
    Case #PARTITION_LINUX_EXTENDED
      ProcedureReturn "Linux extended"
    Default
      ProcedureReturn "??? (0x"+RSet(Hex(type),2,"0")+")"
  EndSelect
EndProcedure
Procedure OpenPhysicalDrive(PhysDrvNrm)
  ProcedureReturn CreateFile_("\\.\PHYSICALDRIVE"+Str(PhysDrvNrm),#GENERIC_READ|#GENERIC_WRITE,#FILE_SHARE_READ|#FILE_SHARE_WRITE,0,#OPEN_EXISTING,#FILE_FLAG_NO_BUFFERING,0)
EndProcedure
Procedure ClosePhysicalDrive(PhysDrvIdt)
  ProcedureReturn CloseHandle_(PhysDrvIdt)
EndProcedure
Procedure ReadPhysDrvData(PhysDrvIdt,memory,LengthToRead)
  Protected _
  ReadFile_(PhysDrvIdt,memory,LengthToRead,@_,0)
  ProcedureReturn _
EndProcedure
hFile=OpenPhysicalDrive(0)
If hFile>-1
  *mem=AllocateMemory(512)
  ReadPhysDrvData(hFile,*mem,512)
  Debug "Partition 1: "+PartitionType2Name(GetPartitionType(*mem,1))
  Debug "Partition 2: "+PartitionType2Name(GetPartitionType(*mem,2))
  Debug "Partition 3: "+PartitionType2Name(GetPartitionType(*mem,3))
  Debug "Partition 4: "+PartitionType2Name(GetPartitionType(*mem,4))
  ClosePhysicalDrive(hFile)
EndIf
End
Ein komplexes Codebeispiel wäre dann:

Code: Alles auswählen

#PARTITION_UNUSED=$00 ;Unbenutzt
#PARTITION_FAT12=$01 ;FAT12 (für Disketten)
#PARTITION_FAT16_32M=$04 ;FAT16 (<= 32 MB size)
#PARTITION_DOS_EXTENDED=$05 ;Erweiterte Partition
#PARTITION_FAT16=$06 ;FAT16 (> 32 MB size)
#PARTITION_NTFS=$07 ;NTFS (kann auch HPFS sein)
#PARTITION_FAT32=$0B ;FAT32
#PARTITION_FAT32_LBA=$0C ;FAT32 im LBA-Modus
#PARTITION_FAT16_LBA=$0E ;FAT16 im LBA-Modus
#PARTITION_LINUX_SWAP=$82 ;Auslagerungspartition für Linux
#PARTITION_LINUX_NATIVE=$83 ;Linux-Partition (ReiserFS, ext2, ext3, etc.)
#PARTITION_LINUX_EXTENDED=$85 ;Erweiterte Partition für Linux
Procedure GetPartitionType(*MBR,PartNum) ;PartNum is number from 1 to 4
  ProcedureReturn PeekB(*MBR+430+(PartNum*16)+4)&$FF
EndProcedure
Procedure.s PartitionType2Name(type)
  Select type
    Case #PARTITION_UNUSED
      ProcedureReturn "---"
    Case #PARTITION_FAT12
      ProcedureReturn "FAT12"
    Case #PARTITION_FAT16_32M
      ProcedureReturn "FAT16 (<= 32 MB)"
    Case #PARTITION_DOS_EXTENDED
      ProcedureReturn "DOS extended"
    Case #PARTITION_FAT16
      ProcedureReturn "FAT16 (> 32 MB)"
    Case #PARTITION_NTFS
      ProcedureReturn "NTFS/HPFS"
    Case #PARTITION_FAT32
      ProcedureReturn "FAT32"
    Case #PARTITION_FAT32_LBA
      ProcedureReturn "FAT32 (LBA)"
    Case #PARTITION_FAT16_LBA
      ProcedureReturn "FAT16 (LBA)"
    Case #PARTITION_LINUX_SWAP
      ProcedureReturn "linux-swap"
    Case #PARTITION_LINUX_NATIVE
      ProcedureReturn "Linux native"
    Case #PARTITION_LINUX_EXTENDED
      ProcedureReturn "Linux extended"
    Default
      ProcedureReturn "??? (0x"+RSet(Hex(type),2,"0")+")"
  EndSelect
EndProcedure
Procedure OpenPhysicalDrive(PhysDrvNrm)
  ProcedureReturn CreateFile_("\\.\PHYSICALDRIVE"+Str(PhysDrvNrm),#GENERIC_READ|#GENERIC_WRITE,#FILE_SHARE_READ|#FILE_SHARE_WRITE,0,#OPEN_EXISTING,#FILE_FLAG_NO_BUFFERING,0)
EndProcedure
Procedure ClosePhysicalDrive(PhysDrvIdt)
  ProcedureReturn CloseHandle_(PhysDrvIdt)
EndProcedure
Procedure ReadPhysDrvData(PhysDrvIdt,memory,LengthToRead)
  Protected _
  ReadFile_(PhysDrvIdt,memory,LengthToRead,@_,0)
  ProcedureReturn _
EndProcedure
Procedure EnumPhysicalDrives(ProcAddr)
  Protected _,hFile
  For _=0 To 9
    hFile=CreateFile_("\\.\PHYSICALDRIVE"+Str(_),#GENERIC_READ|#GENERIC_WRITE,#FILE_SHARE_READ|#FILE_SHARE_WRITE,0,#OPEN_EXISTING,#FILE_FLAG_NO_BUFFERING,0)
    If hFile>-1
      CloseHandle_(hFile)
      CallFunctionFast(ProcAddr,_)
    EndIf
  Next
EndProcedure
Procedure EnumDrives(Number)
  Protected hFile,*mem
  hFile=OpenPhysicalDrive(Number)
  *mem=AllocateMemory(512)
  ReadPhysDrvData(hFile,*mem,512)
  ClosePhysicalDrive(hFile)
  Debug "Examining PhysicalDrive "+Str(Number)
  Debug "Partition 1: "+PartitionType2Name(GetPartitionType(*mem,1))
  Debug "Partition 2: "+PartitionType2Name(GetPartitionType(*mem,2))
  Debug "Partition 3: "+PartitionType2Name(GetPartitionType(*mem,3))
  Debug "Partition 4: "+PartitionType2Name(GetPartitionType(*mem,4))
  Debug "------------------------------"
  FreeMemory(*mem)
EndProcedure
EnumPhysicalDrives(@EnumDrives())
End
Wie man den Volume-Namen herausfinden kann, weiß ich leider auch nicht... :|
Antworten