Voici le code qui vous donne accès à tous les secteurs d'un disque.
Notez que le moteur de recherche n'est absolument pas optimisé pour la vitesse, c'est un jouet amusant...
Code : Tout sélectionner
;Disk read code 2024-01-07
EnableExplicit ;Varaible must be declared
#PB_Compiler_ExecutableFormat = #PB_Compiler_Executable
#PB_Compiler_IsMainFile = 1
#BlockSize = 512
#SECURITY_NT_AUTHORITY = 005
#IOCTL_DISK_GET_DRIVE_GEOMETRY = $00070000
#FILE_DEVICE_DISK = $07
#IOCTL_DISK_BASE = #FILE_DEVICE_DISK
#METHOD_BUFFERED = 0
#FILE_READ_ACCESS = $01
#IOCTL_DISK_GET_LENGTH_INFO = $7405C
#FSCTL_ALLOW_EXTENDED_DASD_IO = $00090083
#AppName = "Disk read"
#StaticDisk = 101
#StaticDiskCount = 102
#StaticBlockCount = 103
#StaticCyl = 104
#StaticHead = 105
#StaticSect = 106
#StaticMeg = 107
#StaticSearchStatus = 108
#StaticDiskIdPart = 109
#StaticPhysical = 110
#StaticLogical = 111
#ComboDisk = 201
#ButtonRead = 301
#ButtonSearchPrev = 303
#ButtonSearchNext = 304
#ButtonStop = 305
#EditLogicalBlock = 401
#EditHex = 402
#EditSearch = 403
#OptionPhysical = 501
#OptionLogical = 502
#UpDownHBlockIndex = 601
Macro LoWord(WordWord) : (WordWord&$ffff) : EndMacro ;ControlId = LoWord(wParam)
Macro HiWord(WordWord) : ((WordWord>>16)&$ffff) : EndMacro ;Action = HiWord(wParam)
Macro MakeDword(WordLo, WordHi) : ((WordHi<<16)+WordLo) : EndMacro ;resultvar = MAK(datatype, loworderval, highorderval)
Macro GetLBA(LBA)
sBuffer = Space(SendMessage_(hEditLogicalBlock, #WM_GETTEXTLENGTH, 0, 0))
SendMessage_(hEditLogicalBlock, #WM_GETTEXT, Len(sBuffer) + 1, @sBuffer)
LBA = Val(sBuffer)
If LBA > BlockCount - 1 : LBA = BlockCount - 1 : EndIf
If LBA < 0 : LBA = 0 : EndIf
SendMessage_(hUpDown, #UDM_SETPOS32, 0, UpDownStartPosition + LBA)
EndMacro
Structure DISK_GEOMETRY
Cylinders.q
MediaType.l ;0 unknown, 11 RemovableMedia, 12 FixedMedia, else floppy
TracksPerCylinder.l
SectorsPerTrack.l
BytesPerSector.l
EndStructure
Structure GET_LENGTH_INFORMATION
Length.q
EndStructure
;_____________________________________________________________________________
Procedure.s FileDeviceTypeText(dwDevType.l)
;From a number, return a string describing the device
Protected sDevType.s
Select dwDevType
Case $00000027 : sDevType = "8042_port" ; #FILE_DEVICE_8042_PORT
Case $00000032 : sDevType = "Acpi" ; #FILE_DEVICE_ACPI
Case $00000029 : sDevType = "Battery" ; #FILE_DEVICE_BATTERY
Case $00000001 : sDevType = "Beep" ; #FILE_DEVICE_BEEP
Case $0000002a : sDevType = "Bus-extender" ; #FILE_DEVICE_BUS_EXTENDER
Case $00000002 : sDevType = "Cd-rom" ; #FILE_DEVICE_CD_ROM
Case $00000003 : sDevType = "Cd-rom-file-system" ; #FILE_DEVICE_CD_ROM_FILE_SYSTEM
Case $00000030 : sDevType = "Changer" ; #FILE_DEVICE_CHANGER
Case $00000004 : sDevType = "Controller" ; #FILE_DEVICE_CONTROLLER
Case $00000005 : sDevType = "Datalink" ; #FILE_DEVICE_DATALINK
Case $00000006 : sDevType = "Dfs" ; #FILE_DEVICE_DFS
Case $00000035 : sDevType = "Dfs-file-system" ; #FILE_DEVICE_DFS_FILE_SYSTEM
Case $00000036 : sDevType = "Dfs-volume" ; #FILE_DEVICE_DFS_VOLUME
Case $00000007 : sDevType = "Disk" ; #FILE_DEVICE_DISK
Case $00000008 : sDevType = "Disk-file-system" ; #FILE_DEVICE_DISK_FILE_SYSTEM
Case $00000033 : sDevType = "Dvd" ; #FILE_DEVICE_DVD
Case $00000009 : sDevType = "File-system" ; #FILE_DEVICE_FILE_SYSTEM
Case $0000003a : sDevType = "Fips" ; #FILE_DEVICE_FIPS
Case $00000034 : sDevType = "Fullscreen-video" ; #FILE_DEVICE_FULLSCREEN_VIDEO
Case $0000000a : sDevType = "Inport-port" ; #FILE_DEVICE_INPORT_PORT
Case $0000000b : sDevType = "Keyboard" ; #FILE_DEVICE_KEYBOARD
Case $0000002f : sDevType = "Ks" ; #FILE_DEVICE_KS
Case $00000039 : sDevType = "Ksec" ; #FILE_DEVICE_KSEC
Case $0000000c : sDevType = "Mailslot" ; #FILE_DEVICE_MAILSLOT
Case $0000002d : sDevType = "Mass-storage" ; #FILE_DEVICE_MASS_STORAGE
Case $0000000d : sDevType = "Midi-in" ; #FILE_DEVICE_MIDI_IN
Case $0000000e : sDevType = "Midi-out" ; #FILE_DEVICE_MIDI_OUT
Case $0000002b : sDevType = "Modem" ; #FILE_DEVICE_MODEM
Case $0000000f : sDevType = "Mouse" ; #FILE_DEVICE_MOUSE
Case $00000010 : sDevType = "Multi-unc-provider" ; #FILE_DEVICE_MULTI_UNC_PROVIDER
Case $00000011 : sDevType = "Named-pipe" ; #FILE_DEVICE_NAMED_PIPE
Case $00000012 : sDevType = "Network" ; #FILE_DEVICE_NETWORK
Case $00000013 : sDevType = "Network-browser" ; #FILE_DEVICE_NETWORK_BROWSER
Case $00000014 : sDevType = "Network-file-system" ; #FILE_DEVICE_NETWORK_FILE_SYSTEM
Case $00000028 : sDevType = "Network-redirector" ; #FILE_DEVICE_NETWORK_REDIRECTOR
Case $00000015 : sDevType = "Null" ; #FILE_DEVICE_NULL
Case $00000016 : sDevType = "Parallel-port" ; #FILE_DEVICE_PARALLEL_PORT
Case $00000017 : sDevType = "Physical-netcard" ; #FILE_DEVICE_PHYSICAL_NETCARD
Case $00000018 : sDevType = "Printer" ; #FILE_DEVICE_PRINTER
Case $00000019 : sDevType = "Scanner" ; #FILE_DEVICE_SCANNER
Case $0000001c : sDevType = "Screen" ; #FILE_DEVICE_SCREEN
Case $00000037 : sDevType = "Serenum" ; #FILE_DEVICE_SERENUM
Case $0000001a : sDevType = "Serial-mouse-port" ; #FILE_DEVICE_SERIAL_MOUSE_PORT
Case $0000001b : sDevType = "Serial-port" ; #FILE_DEVICE_SERIAL_PORT
Case $00000031 : sDevType = "Smartcard" ; #FILE_DEVICE_SMARTCARD
Case $0000002e : sDevType = "Smb" ; #FILE_DEVICE_SMB
Case $0000001d : sDevType = "Sound" ; #FILE_DEVICE_SOUND
Case $0000001e : sDevType = "Streams" ; #FILE_DEVICE_STREAMS
Case $0000001f : sDevType = "Tape" ; #FILE_DEVICE_TAPE
Case $00000020 : sDevType = "Tape-file-system" ; #FILE_DEVICE_TAPE_FILE_SYSTEM
Case $00000038 : sDevType = "Termsrv" ; #FILE_DEVICE_TERMSRV
Case $00000021 : sDevType = "Transport" ; #FILE_DEVICE_TRANSPORT
Case $00000022 : sDevType = "Unknown" ; #FILE_DEVICE_UNKNOWN
Case $0000002c : sDevType = "Vdm" ; #FILE_DEVICE_VDM
Case $00000023 : sDevType = "Video" ; #FILE_DEVICE_VIDEO
Case $00000024 : sDevType = "Virtual-disk" ; #FILE_DEVICE_VIRTUAL_DISK
Case $00000025 : sDevType = "Wave-in" ; #FILE_DEVICE_WAVE_IN
Case $00000026 : sDevType = "Wave-out" ; #FILE_DEVICE_WAVE_OUT
Case $00000040 : sDevType = "Wpd" ; #FILE_DEVICE_WPD
Default : sDevType = "Unknown" + Str(dwDevType)
EndSelect
ProcedureReturn(sDevType)
EndProcedure
;_____________________________________________________________________________
Procedure.l IsUserAdmin()
;Check id Admin right are granted
Protected NtAuthority.SID_IDENTIFIER_AUTHORITY
Protected *FunctionPointer
Protected pSidAdministrator.i
Protected IsMember.l
;IsUserAnAdmin api may not be there in future Windows release, so doing it the following way.
NtAuthority\value[5] = #SECURITY_NT_AUTHORITY ;SECURITY_NT_AUTHORITY = 5
If AllocateAndInitializeSid_(@NtAuthority, 2, #SECURITY_BUILTIN_DOMAIN_RID,
#DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, @pSidAdministrator)
If OpenLibrary(125, "AdvApi32.dll")
*FunctionPointer = GetFunction(125, "CheckTokenMembership")
CallFunctionFast(*FunctionPointer, #Null, pSidAdministrator, @IsMember)
EndIf
CloseLibrary(125)
FreeSid_(pSidAdministrator)
EndIf
ProcedureReturn(IsMember)
EndProcedure
;_____________________________________________________________________________
Macro CreateControls
;Macro to declutter main window loop
;Get font
NonClient\cbSize = SizeOf(NONCLIENTMETRICS)
SystemParametersInfo_(#SPI_GETNONCLIENTMETRICS, SizeOf(NONCLIENTMETRICS), @NonClient, 0)
LogicalFont = NonClient\lfMessageFont
hFont = CreateFontIndirect_(LogicalFont) ;Usually "Segoe UI", 9
;Create controls...
hFrame01 = CreateWindowEx_(0, "Button", "", #WS_CHILD | #WS_VISIBLE | #BS_GROUPBOX | #BS_LEFT | #BS_TOP,
7, 0, 689, 109, hWnd, -1, hInstance, 0)
SendMessage_(hFrame01, #WM_SETFONT, hFont, 0)
hStaticPhysical = CreateWindowEx_(0, "Static", "Physical", #WS_CHILD | #WS_VISIBLE | #SS_NOTIFY,
28, 11, 50, 17, hWnd, #StaticPhysical, hInstance, 0)
SendMessage_(hStaticPhysical, #WM_SETFONT, hFont, 0)
hOptionPhysical = CreateWindowEx_(0, "Button", "&Physical", #WS_CHILD | #WS_VISIBLE | #WS_GROUP |
#WS_TABSTOP | #BS_AUTORADIOBUTTON | #BS_LEFT | #BS_VCENTER,
12, 11, 14, 16, hWnd, #OptionPhysical, hInstance, 0)
hStaticLogical = CreateWindowEx_(0, "Static", "Logical", #WS_CHILD | #WS_VISIBLE | #SS_NOTIFY,
98, 11, 50, 17, hWnd, #StaticLogical, hInstance, 0)
SendMessage_(hStaticLogical, #WM_SETFONT, hFont, 0)
hOptionLogical = CreateWindowEx_(0, "Button", "&Logical", #WS_CHILD | #WS_VISIBLE |
#BS_AUTORADIOBUTTON | #BS_LEFT | #BS_VCENTER,
82, 11, 14, 16, hWnd, #OptionLogical, hInstance, 0)
hStaticDiskFound = CreateWindowEx_(0, "Static", "Disk found: ", #WS_CHILD | #WS_VISIBLE,
12, 34, 105, 17, hWnd, #StaticDiskCount, hInstance, 0)
SendMessage_(hStaticDiskFound, #WM_SETFONT, hFont, 0)
hStaticHardDisk = CreateWindowEx_(0, "Static", "Hard Disk", #WS_CHILD | #WS_VISIBLE,
12, 58, 80, 17, hWnd, -1, hInstance, 0)
SendMessage_(hStaticHardDisk, #WM_SETFONT, hFont, 0)
hComboDisk = CreateWindowEx_(0, "ComboBox", "", #WS_CHILD | #WS_VISIBLE | #WS_TABSTOP | #CBS_DROPDOWNLIST |
#CBS_SORT | #CBS_HASSTRINGS, 100, 54, 54, 160, hWnd, #ComboDisk, hInstance, 0)
SendMessage_(hComboDisk, #WM_SETFONT, hFont, 0)
hStaticBlock = CreateWindowEx_(0, "Static", "Block: 1,953,520,065", #WS_CHILD | #WS_VISIBLE | #SS_NOTIFY,
175, 13, 158, 17, hWnd, #StaticBlockCount, hInstance, 0)
SendMessage_(hStaticBlock, #WM_SETFONT, hFont, 0)
hStaticMeg = CreateWindowEx_(0, "Static", "Bytes: 1,000,202,273,280", #WS_CHILD | #WS_VISIBLE | #SS_NOTIFY,
175, 32, 158, 17, hWnd, -1, hInstance, 0)
SendMessage_(hStaticMeg, #WM_SETFONT, hFont, 0)
hStaticDiskIdPart = CreateWindowEx_(0, "Static", "", #WS_CHILD | #WS_VISIBLE | #SS_CENTERIMAGE |
#SS_NOTIFY, 175, 51, 193, 18, hWnd, -1, hInstance, 0)
SendMessage_(hStaticDiskIdPart, #WM_SETFONT, hFont, 0)
hStaticCyl = CreateWindowEx_(0, "Static", "Cyl : 121,601", #WS_CHILD | #WS_VISIBLE |
#SS_NOTIFY, 376, 13, 140, 17, hWnd, -1, hInstance, 0)
SendMessage_(hStaticCyl, #WM_SETFONT, hFont, 0)
hStaticHead = CreateWindowEx_(0, "Static", "Head: 255", #WS_CHILD | #WS_VISIBLE |
#SS_NOTIFY, 376, 32, 140, 17, hWnd, -1, hInstance, 0)
SendMessage_(hStaticHead, #WM_SETFONT, hFont, 0)
hStaticSect = CreateWindowEx_(0, "Static", "Sect: 63", #WS_CHILD | #WS_VISIBLE |
#SS_NOTIFY, 376, 51, 140, 17, hWnd, -1, hInstance, 0)
SendMessage_(hStaticSect, #WM_SETFONT, hFont, 0)
hEditSearch = CreateWindowEx_(#WS_EX_CLIENTEDGE, "Edit", "", #WS_CHILD | #WS_VISIBLE | #WS_TABSTOP |
#ES_AUTOHSCROLL, 175, 71, 226, 21, hWnd, #EditSearch, hInstance, 0)
SendMessage_(hEditSearch, #WM_SETFONT, hFont, 0)
SendMessage_(hEditSearch, #EM_SETCUEBANNER, 1, "Cheap search for ansi text")
hButtonPrev = CreateWindowEx_(0, "Button", "Prev", #WS_CHILD | #WS_VISIBLE | #WS_TABSTOP,
403, 71, 35, 21, hWnd, #ButtonSearchPrev, hInstance, 0)
SendMessage_(hButtonPrev, #WM_SETFONT, hFont, 0)
hButtonNext = CreateWindowEx_(0, "Button", "Next", #WS_CHILD | #WS_VISIBLE | #WS_TABSTOP,
438, 71, 35, 21, hWnd, #ButtonSearchNext, hInstance, 0)
SendMessage_(hButtonNext, #WM_SETFONT, hFont, 0)
hButtonStop = CreateWindowEx_(0, "Button", "Stop", #WS_CHILD | #WS_VISIBLE | #WS_TABSTOP,
473, 71, 35, 21, hWnd, #ButtonStop, hInstance, 0)
SendMessage_(hButtonStop, #WM_SETFONT, hFont, 0)
hStaticLogicalBlock = CreateWindowEx_(0, "Static", "LogicalBlock", #WS_CHILD | #WS_VISIBLE,
525, 13, 68, 17, hWnd, -1, hInstance, 0)
SendMessage_(hStaticLogicalBlock, #WM_SETFONT, hFont, 0)
hEditLogicalBlock = CreateWindowEx_(0, "Edit", "4294967294", #WS_CHILD | #WS_VISIBLE | #WS_TABSTOP |
#ES_CENTER | #ES_NUMBER, 525, 32, 79, 15, hWnd, -1, hInstance, 0)
SendMessage_(hEditLogicalBlock, #WM_SETFONT, hFont, 0)
hButtonRead = CreateWindowEx_(0, "Button", "Read", #WS_CHILD | #WS_VISIBLE | #WS_TABSTOP,
613, 28, 70, 24, hWnd, #ButtonRead, hInstance, 0)
SendMessage_(hButtonRead, #WM_SETFONT, hFont, 0)
hUpDown = CreateWindowEx_(0, "MsCtls_UpDown32", "", #WS_CHILD | #WS_VISIBLE | #UDS_HORZ,
534, 60, 63, 28, hWnd, -1, hInstance, 0)
SendMessage_(hUpDown, #WM_SETFONT, hFont, 0)
hStaticSearchStatus = CreateWindowEx_(0, "Static", "Status: ", #WS_CHILD | #WS_VISIBLE,
12, 86, 158, 19, hWnd, #StaticSearchStatus, hInstance, 0)
SendMessage_(hStaticSearchStatus, #WM_SETFONT, hFont, 0)
hEditHex = CreateWindowEx_(#WS_EX_CLIENTEDGE, "Edit", "0123", #WS_CHILD | #WS_VISIBLE |
#WS_TABSTOP | #ES_MULTILINE | #ES_WANTRETURN | #ES_READONLY |
#ES_NOHIDESEL, 5, 118, 688, 553, hWnd, #EditHex, hInstance, 0)
hFixedFont = CreateFont_(16, 0, ;Height, Width usually 0,
0, 0, ;Escapement(angle), Orientation
0, 0, 0, 0, ;Bold, Italic, Underline, Strikethru
0, #OUT_TT_PRECIS, #CLIP_DEFAULT_PRECIS, #DEFAULT_QUALITY, #FF_DONTCARE,
"Courier New") ;Fixed font
SendMessage_(hEditHex, #WM_SETFONT, hFixedFont, 0)
EndMacro
;_____________________________________________________________________________
Procedure.q GetLogicalDiskBlockCount(sLogicalDisk.s)
;Get number of LBA LogicalBlockAddress on logical disk, aka "C:\"
Protected FreeBytesForUser.q
Protected UserDiskSize.q
Protected FreeByteOnDisk.q
Protected ByteOnDisk.GET_LENGTH_INFORMATION
Protected OldErrMode.l
Protected zLogicalDisk.s{8}
Protected hDisk.i
Protected BytesReturned.l
OldErrMode = SetErrorMode_(#SEM_FAILCRITICALERRORS) ;Prevent pop-up dialogs if device is not present or loaded
zLogicalDisk = "\\.\" + Left(sLogicalDisk, 2) ;Logical disk as "\\.\C:"
hDisk = CreateFile_(zLogicalDisk, #GENERIC_READ, #FILE_SHARE_READ |
#FILE_SHARE_WRITE, 0, #OPEN_EXISTING, 0, 0)
If hDisk <> #INVALID_HANDLE_VALUE
If DeviceIoControl_(hDisk, #IOCTL_DISK_GET_LENGTH_INFO, #Null, 0,
@ByteOnDisk, SizeOf(ByteOnDisk), @BytesReturned, #Null)
EndIf
CloseHandle_(hDisk)
EndIf
SetErrorMode_(OldErrMode)
If ByteOnDisk\Length
ProcedureReturn(ByteOnDisk\Length / #BlockSize)
EndIf
EndProcedure
;_____________________________________________________________________________
Procedure.l GetPhysicalDiskId(pBuffer.i, BufferLen.l)
;Get physical disk count and id, id are not always consecutive
Protected DiskGeometry.DISK_GEOMETRY
Protected sBuffer.s
Protected sPadZero.s
Protected sPhysicalDiskList.s
Protected PhysicalDiskIndex.l
Protected PhysicalDiskCount.l
Protected hDevice.i
Protected ReturnedSize.l
While 1
;Need to be Admin
hDevice = CreateFile_("\\.\PhysicalDrive" + Str(PhysicalDiskIndex), ;Could be a HD, flash, CdRom, etc.
#GENERIC_READ, #FILE_SHARE_READ | #FILE_SHARE_WRITE, 0, #OPEN_EXISTING, 0, 0)
If hDevice = #INVALID_HANDLE_VALUE
Break ;No more devices
Else
If DeviceIoControl_(hDevice, #IOCTL_DISK_GET_DRIVE_GEOMETRY, 0, ;Will be TRUE if device is a disk / have media inserted
0, @DiskGeometry, SizeOf(DISK_GEOMETRY), @ReturnedSize, 0)
sPadZero = "0" : If PhysicalDiskIndex > 9 : sPadZero = "" : EndIf
sPhysicalDiskList = sPhysicalDiskList + sPadZero + Str(PhysicalDiskIndex) + ":" ;Disk are zero based, Result example: "00:01:04:06"
PhysicalDiskCount = PhysicalDiskCount + 1
EndIf
CloseHandle_(hDevice)
PhysicalDiskIndex = PhysicalDiskIndex + 1
EndIf
Wend
If PhysicalDiskCount
sPhysicalDiskList = Left(sPhysicalDiskList, Len(sPhysicalDiskList) - 1) ;Remove last ":", example: "00:01:04:06:"
sBuffer = Left(sPhysicalDiskList, BufferLen) ;Respect buffer lenght
Else
sBuffer = ""
EndIf
PokeS(pBuffer, sBuffer, PhysicalDiskCount * 3)
ProcedureReturn(PhysicalDiskCount)
EndProcedure
;_____________________________________________________________________________
Procedure.l GetVolumeInfo(zDisk.s)
;Check if volume have a media available via GetVolumeInformation()
Protected.s{21} zVolumeName
Protected.s{21} zFileSystem
Protected.l VolumeSerialNumber
Protected.l FileNameMaxLen
Protected.l FileSystemFlag
If GetVolumeInformation_(zDisk, zVolumeName, 20, VolumeSerialNumber,
FileNameMaxLen, FileSystemFlag, zFileSystem, 20) = #False
;"No disk/media inserted !"
Else
ProcedureReturn(#True) ;Media inserted
EndIf
EndProcedure
;______________________________________________________________________________
Procedure.l GetLogicalDiskId(pBuffer.i, BufferLen.l)
;Get disk drive letters designer, aka "C:\, D:\, H:\"
Protected sLogicalDiskList.s
Protected sLogicalFixedDiskList.s
Protected sBuffer.s
Protected LogicalDiskIndex.l
Protected LogicalDiskCount.l
Protected LogicalFixedDiskCount.l
Protected LogicalDiskListLen.l
Protected zDrive.s{4}
sLogicalDiskList = Space(26 * 4 + 1)
LogicalDiskListLen = GetLogicalDriveStrings_(Len(sLogicalDiskList), @sLogicalDiskList) ;Aka C:\<NULL>D:\<NULL>R:\<NULL><NULL>
If LogicalDiskListLen <= BufferLen ;Success
LogicalDiskCount = LogicalDiskListLen / 4
For LogicalDiskIndex = 0 To LogicalDiskCount - 1
zDrive = PeekS(@sLogicalDiskList + LogicalDiskIndex * 8, 3) ;Aka C:\<NULL>D:\<NULL>R:\<NULL><NULL>
Select GetDriveType_(zDrive)
Case #DRIVE_UNKNOWN
Case #DRIVE_NO_ROOT_DIR
;CASE #DRIVE_REMOTE
Case #DRIVE_CDROM
Case #DRIVE_RAMDISK
;CASE #DRIVE_REMOVABLE
Case #DRIVE_FIXED, #DRIVE_REMOVABLE
If GetVolumeInfo(zDrive) ;Is there a media inserted
sLogicalFixedDiskList = sLogicalFixedDiskList + zDrive
LogicalFixedDiskCount = LogicalFixedDiskCount + 1
EndIf
EndSelect
Next
sBuffer = sLogicalFixedDiskList
Else ;sBuffer is too small, LogicalDiskListLen is the required size
sBuffer = ""
EndIf
PokeS(pBuffer, sBuffer, LogicalFixedDiskCount * 4)
ProcedureReturn(LogicalFixedDiskCount)
EndProcedure
;_____________________________________________________________________________
Procedure.l CloseDisk(phDisk.i)
;Clean up and close an open disk handle
CloseHandle_(PeekI(phDisk.i))
PokeI(phDisk, 0)
ProcedureReturn(GetLastError_())
EndProcedure
;_____________________________________________________________________________
Procedure.l OpenPhysicalDisk(PhysicalDiskId.l, WritePermission.l)
;Get an handle to work with a physical disk
Protected zDisk.s{20}
zDisk = ReplaceString(zDisk, " ", Chr(0))
zDisk = "\\.\PhysicalDrive" + Str(PhysicalDiskId) ;Physical disk aka "\\.\PhysicalDrive0"
If WritePermission ;Read & Write
ProcedureReturn(CreateFile_(zDisk, #GENERIC_READ | #GENERIC_WRITE,
#FILE_SHARE_READ | #FILE_SHARE_WRITE, 0, #OPEN_EXISTING, 0, 0))
Else ;Read only
ProcedureReturn(CreateFile_(zDisk, #GENERIC_READ,
#FILE_SHARE_READ | #FILE_SHARE_WRITE, 0, #OPEN_EXISTING, 0, 0))
EndIf
EndProcedure
;_____________________________________________________________________________
Procedure.q GetPhysicalDiskBlockCount(hDisk.l)
;Get number of LBA LogicalBlockAddress on physical disk via an open handle
Protected DiskGeometry.DISK_GEOMETRY
Protected OldErrMode.l
Protected ReturnedSize.l
OldErrMode = SetErrorMode_(#SEM_FAILCRITICALERRORS) ;Prevent pop-up dialogs if device is not present or loaded
If DeviceIoControl_(hDisk, #IOCTL_DISK_GET_DRIVE_GEOMETRY, 0,
0, @DiskGeometry, SizeOf(DISK_GEOMETRY), @ReturnedSize, 0 )
;Cyl = DISK_GEOMETRY\Cylinders
;Head = DISK_GEOMETRY\TracksPerCylinder
;Sect = DISK_GEOMETRY\SectorsPerTrack
;LB = DISK_GEOMETRY\Cyl * DiskGeometry\Head * DiskGeometry\Sect
ProcedureReturn(DiskGeometry\Cylinders * DiskGeometry\TracksPerCylinder * DiskGeometry\SectorsPerTrack)
EndIf
SetErrorMode_(OldErrMode)
EndProcedure
;_____________________________________________________________________________
Procedure.l GetPhysicalDiskGeometry(hDisk.i, pDiskGeometry.i) ;DISK_GEOMETRY)
;Get a physical disk Cyl, Head, Sect, and logical block number
Protected ReturnedSize.l
If DeviceIoControl_(hDisk, #IOCTL_DISK_GET_DRIVE_GEOMETRY, 0,
0, pDiskGeometry, SizeOf(DISK_GEOMETRY), @ReturnedSize, 0)
;Cyl = DISK_GEOMETRY\Cylinders
;Head = DISK_GEOMETRY\TracksPerCylinder
;Sect = DISK_GEOMETRY\SectorsPerTrack
;LB = DISK_GEOMETRY\Cyl * DiskGeo\Head * DiskGeo\Sect
ProcedureReturn(#True)
EndIf
EndProcedure
;_____________________________________________________________________________
Procedure.i OpenLogicalDisk(sLogicalDisk.s, WritePermission.l, hStaticDiskIdPart.i)
;Get an handle to work with a volume logical disk, aka D:\
Protected StorageDevice.STORAGE_DEVICE_NUMBER
Protected zDisk.s{8}
Protected hDisk.i
Protected BytesReturned.l
zDisk = "\\.\" + Left(sLogicalDisk, 2) ;Logical disk aka "\\.\C:"
If WritePermission ;Read & Write
hDisk = CreateFile_(zDisk, #GENERIC_READ | #GENERIC_WRITE,
#FILE_SHARE_READ | #FILE_SHARE_WRITE, 0, #OPEN_EXISTING, 0, 0)
Else ;Read only
hDisk = CreateFile_(zDisk, #GENERIC_READ,
#FILE_SHARE_READ | #FILE_SHARE_WRITE, 0, #OPEN_EXISTING, 0, 0 )
EndIf
;Remarks: A call using the FSCTL_ALLOW_EXTENDED_DASD_IO control code should only be used with great caution
; by programmers familiar with the underlying structure of a hard disk drive and file system.
; Improper use or inaccurate checking in subsequent write operations to the partition
; can result in damage to data on the partition, or destruction of the entire partition.
; The FSCTL_ALLOW_EXTENDED_DASD_IO control code is used to signal the file system driver
; not to perform any I/O boundary checks on read or write calls made with the specified handle.
; FSCTL_ALLOW_EXTENDED_DASD_IO allows access to hidden sectors, a part of the partition
; that might exist between the first sector of the partition (the boot parameter block)
; and the first useful sector of the partition. FSCTL_ALLOW_EXTENDED_DASD_IO also
; allows access to lost clusters, which might exist between the last useful cluster
; and the end of the partition.
DeviceIoControl_(hDisk, #FSCTL_ALLOW_EXTENDED_DASD_IO, #Null, 0,
#Null, 0, @BytesReturned, #Null)
If DeviceIoControl_(hDisk, #IOCTL_STORAGE_GET_DEVICE_NUMBER, #Null, 0, ;XP+
@StorageDevice, SizeOf(StorageDevice), @BytesReturned, #Null)
;Remember, disk start at 0, partition start at 1
SendMessage_(hStaticDiskIdPart, #WM_SETTEXT, 0,
FileDeviceTypeText(StorageDevice\DeviceType) +
", device" + Str(StorageDevice\DeviceNumber) +
", partition " + Str(StorageDevice\PartitionNumber))
Else
SendMessage_(hStaticDiskIdPart, #WM_SETTEXT, 0, "No device number info" )
EndIf
ProcedureReturn(hDisk)
EndProcedure
;_____________________________________________________________________________
Procedure.q DiskWrite(hDisk.i, BlockIndex.q, psBuffer.i, BufferLen.l)
;Disk write procedure
Protected FilePointer.q
Protected NewFilePointer.q
Protected BytesWritten.l
;Be carefull to not zap your disk if you implement and use this procedure
FilePointer = BlockIndex * #BlockSize
SetFilePointerEx_(hDisk, FilePointer, NewFilePointer, #FILE_BEGIN)
If WriteFile_(hDisk, psBuffer, BufferLen, @BytesWritten, 0)
ProcedureReturn(BytesWritten)
EndIf
EndProcedure
;_____________________________________________________________________________
Procedure.q DiskRead(hDisk.i, BlockIndex.q, psBuffer.i, BufferLen.l)
;Disk read procedure
Protected FilePointer.q
Protected NewFilePointer.q
Protected BytesReturned.l
FilePointer = BlockIndex * #BlockSize
SetFilePointerEx_(hDisk, FilePointer, NewFilePointer, #FILE_BEGIN)
If ReadFile_(hDisk, psBuffer, BufferLen, @BytesReturned, 0)
ProcedureReturn(BytesReturned)
EndIf
EndProcedure
;_____________________________________________________________________________
Procedure.s DataToHexView(pString.i, ReadCount.l) ;See D:\Dev\Pow\Bas\SRC\Hex\HexToStrGary03.bas
;Construct two digit hex line number, 16 bytes value in 2 digit hex, a ";"
;and text representation of those 16 bytes
;A dot replace non visible character
;Example: "30: 83 C6 10 49 74 19 38 2C 74 F6 A0 B5 07 B4 07 8B ; .ÆIt8,tö µ´."
Protected sBuffer.s
Protected LineNumber.l
Protected ChrIndex.l
Protected CharPos.l
Protected DataLen.l
Protected ChrPeek.a
DataLen = ReadCount
sBuffer = Chr(13) + Chr(10)
For LineNumber = 0 To DataLen - 1 Step 16
sBuffer = sBuffer + " " + Right("0" + Hex(LineNumber), 2) + ": "
For ChrIndex = 0 To 15 ;Aka "C6 10 49 74 19 38 2C 74 F6 A0 B5 07 B4 07 8B F0"
CharPos = LineNumber + ChrIndex
If CharPos <= DataLen
sBuffer = sBuffer + Right("0" + Hex(PeekA(pString + CharPos)), 2) + " " ;Hex part
EndIf
Next
;Example: "000000: 31 32 33 34 35 36 37 38 39 30 41 42 43 44 45 46 ; 1234567890ABCDEF"
sBuffer = sBuffer + "; " ;Used for a sector of 512 bytes
For ChrIndex = 1 To 16
CharPos = LineNumber + ChrIndex - 1
If CharPos <= DataLen
ChrPeek = PeekA(pString + CharPos - 0)
Select ChrPeek
Case 0,1,9,10,13,27,28,29,30,31,127 To 159
sBuffer = sBuffer + "."
Default
sBuffer = sBuffer + Chr(ChrPeek)
EndSelect
EndIf
Next
sBuffer = sBuffer + Chr(13) + Chr(10)
Next
ProcedureReturn(sBuffer)
EndProcedure
;_____________________________________________________________________________
Procedure.l EditSearch(hEditText.i, hEditSearch.i, Reverse.l)
;Simple, one way, case insensitive, and wide char
;Work by text via an edit control, caret position or selected text.
;SearchTextbox empty + no sel = do nothing
;SearchTextbox filled + no sel = find text from sel pos
;SearchTextbox empty + sel = copy sel to Search Textbox and find text (until crlf or max-char) from sel pos
;SearchTextbox filled + sel = copy sel to Search Textbox and find text (until crlf or max-char) from sel pos
Protected sToFind.s
Protected hEditTextMem.i, pEditTextMem.i, pFound.l
Protected SelStart.l, SelEnd.l, ToFindLen.l ;, Offset.l
hEditTextMem = SendMessage_(hEditText, #EM_GETHANDLE, 0, 0) ;Get the handle of text in memory
pEditTextMem = LocalLock_(hEditTextMem) ;Get the pointer to that text
ToFindLen = SendMessage_(hEditSearch, #WM_GETTEXTLENGTH, 0, 0)
sToFind = Space(ToFindLen)
SendMessage_(hEditSearch, #WM_GETTEXT, ToFindLen + 1, @sToFind)
SendMessage_(hEditText, #EM_GETSEL, @SelStart, @SelEnd)
If ToFindLen = 0 and SelStart <> SelEnd ;Some text is selected
sToFind = PeekS(pEditTextMem + SelStart * 2, SelEnd - SelStart, #PB_Unicode)
ToFindLen = Len(sToFind)
If FindString(sToFind, Chr(13)) : sToFind = Left(sToFind, FindString(sToFind, Chr(13)) - 1) : EndIf ;Optionnal limit sToFind
SendMessage_(hEditSearch, #WM_SETTEXT, 0, @sToFind)
EndIf
If ToFindLen
Protected TextLen.l = SendMessage_(hEditText, #WM_GETTEXTLENGTH, 0, 0)
If Reverse ;Search backward from the end
If SelStart = SelEnd ;No selection made so caret position
SelStart = SelStart - ToFindLen + 1
If SelStart < 0 : SelStart = TextLen : EndIf ;Caret is at the text end
EndIf ;Caret
pFound = StrRStrI_(pEditTextMem, pEditTextMem + SelStart * 2, @sToFind) ;Search text position backward
If pFound
SelStart = (pFound - pEditTextMem) / 2 ;pFound is zero if nothing found
SendMessage_(hEditText, #EM_SETSEL, SelStart, SelStart + ToFindLen)
Else
SelStart = 0
EndIf
Else ;Search forward ------------------------------------------------------------------------------------
If SelStart = SelEnd ;No selection made so caret position
SelStart = SelStart - ToFindLen
If SelStart = 0 : SelStart = -2 : EndIf ;Caret at the text beginning
EndIf ;Caret
pFound = StrStrI_(pEditTextMem + (SelStart + ToFindLen) * 2, @sToFind) ;Search text position
If pFound
SelStart = (pFound - pEditTextMem) / 2 ;pFound is zero if nothing found
SendMessage_(hEditText, #EM_SETSEL, SelStart, SelStart + ToFindLen)
Else
SelStart = 0
EndIf
EndIf
Else
SelStart = -1 ;No search text, nor selected text
EndIf
LocalUnlock_(hEditTextMem) ;LocalLock increments the lock count by one, use LocalUnlock to decrements when done.
ProcedureReturn(SelStart)
EndProcedure
;_____________________________________________________________________________
Procedure WndProc(hWnd, uMsg, wParam, lParam)
;Main callback procedure
Protected *pNotifyMessageUpDown.NM_UPDOWN
Protected *CreateStruct.CREATESTRUCT
Protected LogicalFont.LOGFONT
Protected NonClient.NONCLIENTMETRICS
Protected DiskGeometry.DISK_GEOMETRY
Protected hDC.i, sBuffer.s, BlockIndex.q, BlockSearchIndex.q
Protected UpDownAccellerationStepCount.l, ReadCount.l, Looper.l, ControlId.w, Action.w
Static hInstance.i, hFrame01.i, hCombo01.i, hButton01.i, hOptionPhysical.i, pSector.i
Static hOptionLogical.i, hStaticDiskFound.i, hStaticHardDisk.i, hComboDisk.i
Static hStaticBlock.i, hStaticMeg.i, hStaticDiskIdPart.i, hStaticCyl.i, hStaticHead.i
Static hStaticSect.i, hButtonPrev.i, hButtonNext.i, hStaticLogicalBlock.i, hEditLogicalBlock.i
Static hButtonRead.i, hUpDown.i, hStaticSearchStatus.i, hEditHex.i, hEditSearch.i, hFont.i, hFixedFont.i
Static hStaticPhysical.i, hStaticLogical.i, hEditBlockIndex.i, hBlueBrush.i, hButtonStop.i, hDisk.i
Static StartPos.l, PhysicalDisk.l, Disk.l, DiskCount.l, DiskError.l, UpDownValH.l, UpDownDeltaH.l, UpDownStartPosition.l
Static sDisk.s, BlockCount.q
Dim UpDownAccelleration.UDACCEL(7)
Select uMsg
Case #WM_CREATE
pSector = AllocateMemory(#BlockSize)
*CreateStruct = lParam ;Get hInstance from CreateWindowEx_()
hInstance = *CreateStruct\lpCreateParams
hBlueBrush = CreateSolidBrush_($c0320a)
CreateControls ;Macro for controls creation
;Sets the acceleration for the up-down control,
;after n seconds pushed, auto increment by nInc
UpDownStartPosition = 0 - 2147483648 + 1 ;Needed for 2 tb, LONG -2,147,483,648 to +2,147,483,647 (+1 so the control limit will be respected)
UpDownAccelleration(0)\nSec = 1 : UpDownAccelleration(0)\nInc = 1
UpDownAccelleration(1)\nSec = 2 : UpDownAccelleration(1)\nInc = 10
UpDownAccelleration(2)\nSec = 3 : UpDownAccelleration(2)\nInc = 100
UpDownAccelleration(3)\nSec = 4 : UpDownAccelleration(3)\nInc = 1000
UpDownAccelleration(4)\nSec = 5 : UpDownAccelleration(4)\nInc = 10000
UpDownAccelleration(5)\nSec = 6 : UpDownAccelleration(5)\nInc = 100000
UpDownAccelleration(6)\nSec = 7 : UpDownAccelleration(6)\nInc = 1000000
UpDownAccelleration(7)\nSec = 8 : UpDownAccelleration(7)\nInc = 10000000
UpDownAccellerationStepCount = 8
SendMessage_(hUpDown, #UDM_SETACCEL, UpDownAccellerationStepCount, @UpDownAccelleration(0))
;Click button programmatically to initiate
PostMessage_(hWnd, #WM_COMMAND, MakeDword(#StaticPhysical, #BN_CLICKED), hStaticPhysical)
ProcedureReturn(0)
Case #WM_COMMAND
ControlId = LoWord(wParam)
Action = HiWord(wParam)
Select ControlId
Case #OptionPhysical, #StaticPhysical
If (Action = #BN_CLICKED) Or (Action = 1) ;BN_CLICKED = STN_CLICKED = 0
If ControlId = #StaticPhysical
CheckDlgButton_(hWnd, #OptionPhysical, #BST_CHECKED)
CheckDlgButton_(hWnd, #OptionLogical, #BST_UNCHECKED)
EndIf
PhysicalDisk = IsDlgButtonChecked_(hWnd, #OptionPhysical) ;Set PhysicalDisk
BlockIndex = 0
SendMessage_(hEditLogicalBlock, #EM_SETSEL, 0, -1) ;Select all
SendMessage_(hEditLogicalBlock, #EM_REPLACESEL, #True, "00") ;Replace selection
SendMessage_(hComboDisk, #CB_RESETCONTENT, 0, 0)
sBuffer = Space(3 * 26)
DiskCount = GetPhysicalDiskId(@sBuffer, Len(sBuffer))
SendMessage_(hStaticDiskFound, #WM_SETTEXT, 0, "Disk found: " + Str(DiskCount))
If DiskCount = 0
MessageBox_(hWnd, "No disk fatal error", #AppName, #MB_OK | #MB_TOPMOST)
PostMessage_(hWnd, #WM_SYSCOMMAND, #SC_CLOSE, 0)
Else
For Looper = 1 To DiskCount ;example: "00:01:04:06"
SendMessage_(hComboDisk, #CB_ADDSTRING, Looper - 1, Mid(sBuffer, 1 + ((Looper - 1) * 3), 2))
Next
Disk = Val(Left(sBuffer, 2))
SendMessage_(hComboDisk, #CB_SETCURSEL, 0, 00)
EndIf
SendMessage_(hUpDown, #UDM_SETPOS32, 0, UpDownStartPosition) ;Reset to zero
BlockIndex = 0
SendMessage_(hEditLogicalBlock, #WM_SETTEXT, 0, FormatNumber(BlockIndex, 0, ".", ","))
PostMessage_(hWnd, #WM_COMMAND, MakeDword(#ComboDisk, #CBN_SELCHANGE), hComboDisk)
EndIf
Case #OptionLogical, #StaticLogical
If (Action = #BN_CLICKED) Or (Action = 1) ;BN_CLICKED = STN_CLICKED = 0
If LoWord(wParam) = #StaticLogical
CheckDlgButton_(hWnd, #OptionPhysical, #BST_UNCHECKED)
CheckDlgButton_(hWnd, #OptionLogical, #BST_CHECKED)
EndIf
PhysicalDisk = IsDlgButtonChecked_(hWnd, #OptionPhysical) ;Set PhysicalDisk
SendMessage_(hComboDisk, #CB_RESETCONTENT, 0, 0)
sBuffer = Space(3 * 26)
DiskCount = GetLogicalDiskId(@sBuffer, Len(sBuffer))
SendMessage_(hStaticDiskFound, #WM_SETTEXT, 0, "Disk found: " + Str(DiskCount))
If DiskCount = 0
MessageBox_(hWnd, "No disk fatal error!", #AppName, #MB_OK | #MB_TOPMOST)
PostMessage_(hWnd, #WM_SYSCOMMAND, #SC_CLOSE, 0)
Else
For Looper = 1 To DiskCount
SendMessage_(hComboDisk, #CB_ADDSTRING, Looper - 1, Mid(sBuffer, 1 + ((Looper - 1) * 3), 3))
Next
sDisk = Left(sBuffer, 3)
SendMessage_(hComboDisk, #CB_SETCURSEL, 0, 00)
EndIf
SendMessage_(hUpDown, #UDM_SETPOS32, 0, UpDownStartPosition) ;Reset to zero
BlockIndex = 0
SendMessage_(hEditLogicalBlock, #WM_SETTEXT, 0, FormatNumber(BlockIndex, 0, ".", ","))
PostMessage_(hWnd, #WM_COMMAND, MakeDword(#ComboDisk, #CBN_SELCHANGE), hComboDisk)
EndIf
Case #ComboDisk
If (Action = #CBN_SELCHANGE) Or (Action = 1)
If hDisk : CloseDisk(@hDisk) : EndIf
Disk = 0
BlockCount = 0
BlockIndex = 0
SendMessage_(hEditBlockIndex, #WM_SETTEXT, 0, Str(BlockIndex))
If PhysicalDisk
sBuffer = Space(SendMessage_(hComboDisk, #WM_GETTEXTLENGTH, 0, 0))
SendMessage_(hComboDisk, #WM_GETTEXT, Len(sBuffer) + 1, @sBuffer)
Disk = Val(sBuffer)
hDisk = OpenPhysicalDisk(Disk, #False) ;#FALSE for open in read only mode
BlockCount = GetPhysicalDiskBlockCount(hDisk)
If GetPhysicalDiskGeometry(hDisk, @DiskGeometry)
SendMessage_(hStaticCyl, #WM_SETTEXT, 0, "Cyl : " + FormatNumber(DiskGeometry\Cylinders, 0, ".", ","))
SendMessage_(hStaticHead, #WM_SETTEXT, 0, "Head: " + FormatNumber(DiskGeometry\TracksPerCylinder, 0, ".", ","))
SendMessage_(hStaticSect, #WM_SETTEXT, 0, "Sect: " + FormatNumber(DiskGeometry\SectorsPerTrack, 0, ".", ","))
SendMessage_(hStaticDiskIdPart, #WM_SETTEXT, 0, "")
EndIf
Else ;Logical disk
sDisk = Space(SendMessage_(hComboDisk, #WM_GETTEXTLENGTH, 0, 0))
SendMessage_(hComboDisk, #WM_GETTEXT, Len(sDisk) + 1, @sDisk)
hDisk = OpenLogicalDisk(sDisk, #False, hStaticDiskIdPart) ;#FALSE for open in read only mode
BlockCount = GetLogicalDiskBlockCount(sDisk)
SendMessage_(hStaticCyl, #WM_SETTEXT, 0, 0)
SendMessage_(hStaticHead, #WM_SETTEXT, 0, 0)
SendMessage_(hStaticSect, #WM_SETTEXT, 0, 0)
SendMessage_(hStaticDiskIdPart, #WM_SETTEXT, 0, 0)
EndIf
SendMessage_(hStaticMeg, #WM_SETTEXT, 0, "Bytes: " + FormatNumber(BlockCount * #BlockSize, 0, ".", ","))
SendMessage_(hUpDown, #UDM_SETRANGE32, UpDownStartPosition, UpDownStartPosition + BlockCount - 1)
SendMessage_(hUpDown, #UDM_SETPOS32, 0, UpDownStartPosition) ;Reset to zero
SendMessage_(hStaticBlock, #WM_SETTEXT, 0, "Block: " + FormatNumber(BlockCount, 0, ".", ","))
PostMessage_(hWnd, #WM_COMMAND, MakeDword(#ButtonRead, #BN_CLICKED), hButtonRead)
SendMessage_(hUpDown, #UDM_SETPOS32, 0, UpDownStartPosition) ;Reset to zero
BlockIndex = 0
SendMessage_(hEditLogicalBlock, #WM_SETTEXT, 0, FormatNumber(BlockIndex, 0, ".", ","))
EndIf
Case #StaticBlockCount
If (Action = #STN_DBLCLK) Or (Action = 1) ;Copy block count to logical block edit control
SendMessage_(hEditLogicalBlock, #WM_SETTEXT, 0, FormatNumber(BlockCount - 1, 0, ".", ","))
EndIf
Case #EditLogicalBlock
If (Action = #EN_CHANGE) Or (Action = 1)
GetLBA(BlockIndex) ;Read LBA edit control new value
EndIf
Case #ButtonRead, #IDOK
If (Action = #BN_CLICKED) Or (Action = 1)
If DiskError = #False
GetLBA(BlockIndex) ;Read LBA edit control
SendMessage_(hEditLogicalBlock, #WM_SETTEXT, 0, FormatNumber(BlockIndex, 0, ".", ","))
sBuffer = Space(#BlockSize) ;4096
ReadCount = DiskRead(hDisk, BlockIndex, @sBuffer, Len(sBuffer))
If ReadCount = 0
DiskError = #True
SendMessage_(hEditHex, #WM_SETTEXT, 0, 0)
MessageBox_(hWnd, "Disk error on block " + FormatNumber(BlockIndex, 0, ".", ","),
#AppName, #MB_ICONINFORMATION | #MB_OK)
DiskError = #False
Else
SendMessage_(hEditHex, #WM_SETTEXT, 0, DataToHexView(@sBuffer, ReadCount))
EndIf
EndIf
EndIf
Case #IDCANCEL ;Escape key
Static SearchStop.l
Static SearchStarted.l
SearchStop = #True
SendMessage_(hWnd, #WM_APP, 01, 0) ;Enable buttons
Case #ButtonStop
If (Action = #BN_CLICKED) Or (Action = 1)
SearchStop = #True
SendMessage_(hWnd, #WM_APP, 01, 0) ;Enable buttons
EndIf
Case #EditSearch
If (Action = #EN_CHANGE) Or (Action = 1)
GetLBA(BlockIndex)
EndIf
Case #ButtonSearchPrev, #ButtonSearchNext
If (Action = #BN_CLICKED) Or (Action = 1)
Protected Sector.s{#BlockSize}
Protected FoundPos.l
If SearchStarted
SearchStop = #True
Else
SearchStarted = #True
If DiskError = #False
GetLBA(BlockSearchIndex)
SendMessage_(hWnd, #WM_APP, 00, 0) ;Disable buttons
If ControlId = #ButtonSearchNext
Repeat ;For/Next won't work with quad under 32 bit as in FOR BlockSearchIndex = BlockSearchIndex TO BlockCount - 1
FoundPos = EditSearch(hEditHex, hEditSearch, #False) ;#False for forward search
SendMessage_(hStaticSearchStatus, #WM_SETTEXT, 0, "Searching " + FormatNumber(BlockSearchIndex, 0, ".", ","))
If FoundPos = -1 ;No search text, nor selected text
MessageBox_(hWnd, "No search text, nor selected text!", #AppName, #MB_OK | #MB_TOPMOST)
SearchStop = #False
SendMessage_(hWnd, #WM_APP, 01, 0) ;Enable buttons
Break
ElseIf FoundPos ;FoundPos >= 0
SendMessage_(hStaticSearchStatus, #WM_SETTEXT, 0, "Found in " + FormatNumber(BlockSearchIndex, 0, ".", ","))
SearchStarted = #False
SendMessage_(hWnd, #WM_APP, 01, 0) ;Enable buttons
Break
Else ;FoundPos = 0, none or no more found
BlockSearchIndex = BlockSearchIndex + 1
If BlockSearchIndex = BlockCount - 1 Or SearchStop ;SearchStop Or
SearchStop = #False
SendMessage_(hWnd, #WM_APP, 01, 0) ;Enable buttons
Break
EndIf
ReadCount = DiskRead(hDisk, BlockSearchIndex, @Sector, #BlockSize)
If ReadCount = 0
DiskError = #True
SendMessage_(hEditHex, #WM_SETTEXT, 0, 0)
MessageBox_(hWnd, "Disk error on block " + FormatNumber(BlockIndex, 0, ".", ","),
#AppName, #MB_OK | #MB_TOPMOST)
DiskError = #False
SearchStarted = #False
SendMessage_(hWnd, #WM_APP, 01, 0) ;Enable buttons
Break
Else ;Read disk successfull
SendMessage_(hEditHex, #WM_SETTEXT, 0, DataToHexView(@Sector, #BlockSize))
SendMessage_(hEditLogicalBlock, #WM_SETTEXT, 0, FormatNumber(BlockSearchIndex, 0, ".", ","))
BlockIndex = BlockSearchIndex
EndIf
EndIf
WindowEvent() ;Let window bread
ForEver
Else ;#ButtonSearchPrev clicked, going backward
Repeat ;For/Next won't work with quad under 32 bit as in FOR BlockSearchIndex = BlockSearchIndex TO BlockCount - 1
FoundPos = EditSearch(hEditHex, hEditSearch, #True) ;#True for reverse search
SendMessage_(hStaticSearchStatus, #WM_SETTEXT, 0, "Searching " + FormatNumber(BlockSearchIndex, 0, ".", ","))
If FoundPos = -1 ;No search text, nor selected text
MessageBox_(hWnd, "No search text, nor selected text!", #AppName, #MB_OK | #MB_TOPMOST)
SearchStop = #False
SendMessage_(hWnd, #WM_APP, 01, 0) ;Enable buttons
Break
ElseIf FoundPos ;Valid FoundPos >= 0
SendMessage_(hStaticSearchStatus, #WM_SETTEXT, 0, "Found in " + FormatNumber(BlockSearchIndex, 0, ".", ","))
SearchStarted = #False
SendMessage_(hWnd, #WM_APP, 01, 0) ;Enable buttons
Break
Else ;FoundPos = 0, none or no more found
SendMessage_(hStaticSearchStatus, #WM_SETTEXT, 0, "No found")
BlockSearchIndex = BlockSearchIndex - 1
If BlockSearchIndex = -1 Or SearchStop
SearchStop = #False
SendMessage_(hWnd, #WM_APP, 01, 0) ;Enable buttons
Break
EndIf
ReadCount = DiskRead(hDisk, BlockSearchIndex, @Sector, #BlockSize)
If ReadCount = 0
DiskError = #True
SendMessage_(hEditHex, #WM_SETTEXT, 0, 0)
MessageBox_(hWnd, "Disk error on block " + FormatNumber(BlockIndex, 0, ".", ","),
#AppName, #MB_OK | #MB_TOPMOST)
DiskError = #False
SearchStarted = #False
SendMessage_(hWnd, #WM_APP, 01, 0) ;Enable buttons
Break
Else ;Read disk successfull
SendMessage_(hEditHex, #WM_SETTEXT, 0, DataToHexView(@Sector, #BlockSize))
SendMessage_(hEditLogicalBlock, #WM_SETTEXT, 0, FormatNumber(BlockSearchIndex, 0, ".", ","))
BlockIndex = BlockSearchIndex
EndIf
EndIf
WindowEvent() ;Let window bread
ForEver
EndIf
EndIf
SearchStarted = #False
EndIf
EndIf
EndSelect
Case #WM_APP
If wParam ;Enable buttons
EnableWindow_(hButtonStop, #False)
EnableWindow_(hOptionPhysical, #True)
EnableWindow_(hOptionLogical, #True)
EnableWindow_(hComboDisk, #True)
EnableWindow_(hButtonPrev, #True)
EnableWindow_(hButtonNext, #True)
EnableWindow_(hEditLogicalBlock, #True)
EnableWindow_(hButtonRead, #True)
EnableWindow_(hEditSearch, #True)
EnableWindow_(hUpDown, #True)
Else ;Disable buttons
EnableWindow_(hButtonStop, #True)
EnableWindow_(hOptionPhysical, #False)
EnableWindow_(hOptionLogical, #False)
EnableWindow_(hComboDisk, #False)
EnableWindow_(hButtonPrev, #False)
EnableWindow_(hButtonNext, #False)
EnableWindow_(hEditLogicalBlock, #False)
EnableWindow_(hButtonRead, #False)
EnableWindow_(hEditSearch, #False)
EnableWindow_(hUpDown, #False)
EndIf
RedrawWindow_(hButtonStop, #Null, #Null, #RDW_INVALIDATE)
RedrawWindow_(hOptionPhysical, #Null, #Null, #RDW_INVALIDATE)
RedrawWindow_(hOptionLogical, #Null, #Null, #RDW_INVALIDATE)
RedrawWindow_(hComboDisk, #Null, #Null, #RDW_INVALIDATE)
RedrawWindow_(hButtonPrev, #Null, #Null, #RDW_INVALIDATE)
RedrawWindow_(hButtonNext, #Null, #Null, #RDW_INVALIDATE)
RedrawWindow_(hEditLogicalBlock, #Null, #Null, #RDW_INVALIDATE)
RedrawWindow_(hButtonRead, #Null, #Null, #RDW_INVALIDATE)
InvalidateRect_(hButtonRead, #Null, #True) : UpdateWindow_(hButtonRead)
RedrawWindow_(hEditSearch, #Null, #Null, #RDW_INVALIDATE)
RedrawWindow_(hUpDown, #Null, #Null, #RDW_INVALIDATE)
RedrawWindow_(hWnd, #Null, #Null, #RDW_INVALIDATE | #RDW_ALLCHILDREN)
Case #WM_NOTIFY
*pNotifyMessageUpDown = lParam ;NM_UPDOWN
If *pNotifyMessageUpDown\hdr\Code = #UDN_DELTAPOS
If *pNotifyMessageUpDown\hdr\HwndFrom = hUpDown
UpDownDeltaH = *pNotifyMessageUpDown\iDelta
EndIf
EndIf
Case #WM_VSCROLL, #WM_HSCROLL ;UpDownHBlockIndex
;nScrollCode = LO(INTEGER, wParam) ;Scroll bar value
;nPos = HI(INTEGER, wParam) ;Scroll box position
;hwndScrollBar = lParam ;Handle of scroll bar
;IF GetDlgCtrlID_(lParam) = #UpDownHBlockIndex
If lParam = hUpDown
Protected UpDownError.l
;GetLBA(BlockIndex) ;Read LBA edit control new value
UpDownValH = SendMessage_(lParam, #UDM_GETPOS32, #False, UpDownError)
SendMessage_(hEditLogicalBlock, #WM_SETTEXT, 0, FormatNumber(UpDownValH - UpDownStartPosition, 0, ".", ",")) ;-2147483648 ;Needed for 2 tb, LONG -2,147,483,648 to +2,147,483,647
PostMessage_(hWnd, #WM_COMMAND, MakeDword(#ButtonRead, #BN_CLICKED), hButtonRead)
EndIf
Case #WM_CTLCOLORSTATIC ;wParam is device context
SetTextColor_(WPARAM, #Yellow)
SetBkMode_(WPARAM, $c0320a)
ProcedureReturn(hBlueBrush)
Case #WM_CLOSE
PostMessage_(hWnd, #WM_QUIT, 0, 0)
Case #WM_DESTROY
;Clean-up
FreeMemory(pSector)
DeleteObject_(hFont)
DeleteObject_(hFixedFont)
DeleteObject_(hBlueBrush)
PostQuitMessage_(0)
EndSelect
ProcedureReturn(DefWindowProc_(hWnd, uMsg, wParam, lParam))
EndProcedure
;_____________________________________________________________________________
;Create main window
Define wce.WndClassEx
Define WindowSize.Sizel
Define msg.msg
Define AppName.s
Define hWnd.i
Define hInstance.i
AppName = "SectorReader"
hInstance = GetModuleHandle_(0)
Define AdminLevel.l = IsUserAdmin()
If AdminLevel = 0
MessageBox_(hWnd, "Must be run as Admin!", #AppName, #MB_OK | #MB_TOPMOST)
Else
wce\cbSize = SizeOf(WNDCLASSEX)
wce\STYLE = #CS_HREDRAW | #CS_VREDRAW
wce\lpfnWndProc = @WndProc()
wce\cbClsExtra = 0
wce\cbWndExtra = 0
wce\hInstance = hInstance
wce\hIcon = ExtractIcon_(GetModuleHandle_(""), "shell32.dll", 8)
wce\hIconSm = wce\hIcon
wce\hCursor = LoadCursor_(#Null, #IDC_ARROW)
wce\hbrBackground = CreateSolidBrush_($c0320a)
wce\lpszMenuName = 0
wce\lpszClassName = @AppName
RegisterClassEx_(@wce)
WindowSize\cx = 714
WindowSize\cy = 706
;Create a window using the registered class
hWnd = CreateWindowEx_(#WS_EX_CLIENTEDGE,
AppName, ;Window class name
AppName, ;Window caption
#WS_OVERLAPPED | #WS_BORDER | #WS_DLGFRAME | #WS_CAPTION | #WS_SYSMENU |
#WS_MINIMIZEBOX | #WS_CLIPSIBLINGS | #WS_VISIBLE,
(GetSystemMetrics_(#SM_CXSCREEN) - WindowSize\cx) / 2, ;Center position x
(GetSystemMetrics_(#SM_CYSCREEN) - WindowSize\cy) / 2, ;Centr position y
WindowSize\cx, ;x size
WindowSize\cy, ;y size
#HWND_DESKTOP, ;Parent window handle
0, ;Window menu handle
hInstance, ;Program instance handle
hInstance) ;Creation parameters
ShowWindow_(hWnd, #SW_SHOWDEFAULT)
UpdateWindow_(hWnd)
While GetMessage_(Msg, 0, 0, 0)
If IsDialogMessage_(hWnd, Msg) = #False
TranslateMessage_(Msg)
DispatchMessage_(Msg)
EndIf
Wend
EndIf
DestroyIcon_(wce\hIcon)
End msg\wParam
;_____________________________________________________________________________
;
; IDE Options = PureBasic 5.73 LTS (Windows - x86)
; CursorPosition = 1217
; FirstLine = 1203
; Folding = ----
; Markers = 1,190
; EnableAsm
; EnableXP
; EnableAdmin
; Executable = SectorReader.exe
; DisableDebugger
; CompileSourceDirectory
; EnableUnicode