Code : Tout sélectionner
g=c800:5
Code : Tout sélectionner
g=c800:5
Ouaip !Ollivier a écrit :Ça me rappelle ceci :Exécution complètement obsolète aujourd'hui sous Debug.com pour faire un pré-formatage matériel (Esdi et Seagate STxxxx). Des centaines d'heures de formatage de disques durs de 55 méga. Ça doit sûrement parler à certains d'entre vous.Code : Tout sélectionner
g=c800:5
Code : Tout sélectionner
'-------------------------------------------------------------------------------------
'Cylinder start at zero, heads start at zero, and sectors at one but IOCTL_DISK_GET_DRIVE_GEOMETRY
'return CylinderCount, HeadCount, and SectorsCount so no need to add one.
'The math is TotalSectorCount = Cylinders * Heads(or Tracks) * SectorsByTrack
'But the main disparity reason reside somewhere else...
'
'IOCTL_DISK_GET_DRIVE_GEOMETRY/DISK_GEOMETRY will return CHS value that are depreciated
'by today standard. Becose of the way it was structured CHS is unable to give correct size
'for big disk, Microsoft is now using "Logical block adressing" or LBA wich is simply a sector number.
'The first LBA have number zero, unlike CHS where first sector is one.
'
'For a USB drive, since there is no mechanics, meaning no real cylinder, head, or sectorByTrack,
'the size don't have to fit exactly in a CHS sheme. So Microsoft took a simple approach
'for IOCTL_DISK_GET_DRIVE_GEOMETRY under modern Windows, always return 255 heads, always
'return 63 sectorsByTrack, always return 512 BytesPerSector and use the next formula
'to return calculated cylinder count...
'
'Cylinder = DiskSizeInBytes \ 255 * 63 * 512
'Note the "\" for integer division wich is not the same as "/" for Floating-point division.
'Here is what you got: 63 = 520,093,696 \ 255 * 63 * 512
'
'This way the cylinder count will always be small enough to stop legacy software to try to
'access a USB drive past the real end. They did not developped a sofisticated formula to get
'closer to the real size becose the main purpose is simply to protect.
'
'Now, to get the size of your USB stick, use IOCTL_DISK_GET_LENGTH_INFO/GET_LENGTH_INFORMATION
'as you did or use IOCTL_DISK_GET_DRIVE_GEOMETRY_EX/DISK_GEOMETRY_EX.
'The CHS geometry is still present for legacy purpose but there is also DiskSize
'as LARGE_INTEGER wich will give you the disk size in bytes.
'
'LbaCount = DiskSizeInByte / BytesBySector
'
'Now you can access any sector from zero to LbaCount - 1 using SetFilePointer/ReadFile.
'
'Note that modern hard disk work with 4096 bytes chunks, the main reason for the need
'of aligned partitions, but all this is transparent in the actual case.
'
'Note also that the old code posted at Disk sector Read-Write on any OS use
'the legacy CHS way and need to be updated.
'_____________________________________________________________________________
'This is a demo to show how to directly access
'a hard disk under any NT version of windows.
'Use it at your own risk, very easy to destroy the content of a hard-disk
'if you are not familiar with direct disk access.
'Accessing an NT system is fairly easy using CreateFile("\\.\PhysicalDrive0"...
'Thank to Semen Matusovski, William Burns and Lance Edmonds
'Pierre Bellisle
'_____________________________________________________________________________
#COMPILE EXE '#Win 9.07#
#REGISTER NONE
#DIM ALL
#INCLUDE "Win32Api.inc"
#INCLUDE "CommCtrl.inc"
#RESOURCE "SectorReader10.pbr" 'Set manifest to get admin right
GLOBAL hDlg AS DWORD
$AppName = "Direct disk read"
%LabelDisk = 101
%LabelDiskCount = 102
%LabelBlockCount = 103
%LabelCyl = 104
%LabelHead = 105
%LabelSect = 106
%LabelMeg = 107
%LabelStatus = 108
%ComboDisk = 201
%ButtonRead = 301
%ButtonTry = 302
%EditBlockIndex = 401
%EditHex = 402
%OptionPhysical = 501
%OptionLogical = 502
%UpDownH = 601
%SECURITY_NT_AUTHORITY = 005
%BlockSize = 512
%IOCTL_DISK_GET_DRIVE_GEOMETRY = &H00070000
%FILE_DEVICE_DISK = &h07 '%IOCTL_DISK_GET_LENGTH_INFO
%IOCTL_DISK_BASE = %FILE_DEVICE_DISK '%IOCTL_DISK_GET_LENGTH_INFO
%METHOD_BUFFERED = 0 '%IOCTL_DISK_GET_LENGTH_INFO
%FILE_READ_ACCESS = &h01 '%IOCTL_DISK_GET_LENGTH_INFO
%IOCTL_DISK_GET_LENGTH_INFO = &h7405C '%IOCTL_DISK_GET_LENGTH_INFO
%FSCTL_ALLOW_EXTENDED_DASD_IO = &H00090083 'CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 32, METHOD_NEITHER, FILE_ANY_ACCESS)
%Unknown = 00 'Format is unknown
%F5_1Pt2_512 = 01 '5.25", 1.2MB, 512 bytes/sector
%F3_1Pt44_512 = 02 '3.5", 1.44MB, 512 bytes/sector
%F3_2Pt88_512 = 03 '3.5", 2.88MB, 512 bytes/sector
%F3_20Pt8_512 = 04 '3.5", 20.8MB, 512 bytes/sector
%F3_720_512 = 05 '3.5", 720KB, 512 bytes/sector
%F5_360_512 = 06 '5.25", 360KB, 512 bytes/sector
%F5_320_512 = 07 '5.25", 320KB, 512 bytes/sector
%F5_320_1024 = 08 '5.25", 320KB, 1024 bytes/sector
%F5_180_512 = 09 '5.25", 180KB, 512 bytes/sector
%F5_160_512 = 10 '5.25", 160KB, 512 bytes/sector
%RemovableMedia = 11 'Removable media other than floppy
%FixedMedia = 12 'Fixed hard disk media
%F3_120M_512 = 13 '3.5", 120M Floppy
%F3_640_512 = 14 '3.5" , 640KB, 512 bytes/sector
%F5_640_512 = 15 '5.25", 640KB, 512 bytes/sector
%F5_720_512 = 16 '5.25", 720KB, 512 bytes/sector
%F3_1Pt2_512 = 17 '3.5" , 1.2Mb, 512 bytes/sector
%F3_1Pt23_1024 = 18 '3.5" , 1.23Mb, 1024 bytes/sector
%F5_1Pt23_1024 = 19 '5.25", 1.23MB, 1024 bytes/sector
%F3_128Mb_512 = 20 '3.5" MO 128Mb 512 bytes/sector
%F3_230Mb_512 = 21 '3.5" MO 230Mb 512 bytes/sector
%F8_256_128 = 22 '8", 256KB, 128 bytes/sector
%F3_200Mb_512 = 23 '3.5", 200M Floppy (HiFD)
%F3_240M_512 = 24 '3.5", 240Mb Floppy (HiFD)
%F3_32M_512 = 25 '3.5", 32Mb Floppy
TYPE GET_LENGTH_INFORMATION
Length AS QUAD
END TYPE
TYPE DISK_GEOMETRY
Cylinders AS QUAD
MediaType AS DWORD '0 unknown, 11 RemovableMedia, 12 FixedMedia, else floppy
TracksPerCylinder AS DWORD
SectorsPerTrack AS DWORD
BytesPerSector AS DWORD
END TYPE
DECLARE FUNCTION SetFilePointerEx LIB "Kernel32.dll" ALIAS "SetFilePointerEx" _
(BYVAL hFile AS DWORD, BYVAL liDistanceToMove AS QUAD, lpNewFilePointer AS QUAD, BYVAL dwMoveMethod AS DWORD) AS LONG
'_____________________________________________________________________________
FUNCTION IsUserLocalAdmin() AS LONG 'IsUserAnAdmin api may not be there in future Windows release, so doing it the safe way.
LOCAL NtAuthority AS SID_IDENTIFIER_AUTHORITY
LOCAL AdministratorsGroup AS LONG
LOCAL IsMember AS LONG
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, _
AdministratorsGroup) THEN
IF CheckTokenMembership(%NULL, BYVAL AdministratorsGroup, IsMember) THEN
FUNCTION = IsMember
END IF
FreeSid(BYVAL AdministratorsGroup)
END IF
END FUNCTION
'_____________________________________________________________________________
FUNCTION GeometryMediaTypeGet(BYVAL MediaType AS DWORD) EXPORT AS STRING
SELECT CASE MediaType
CASE %Unknown : FUNCTION = "Format is unknown"
CASE %F5_1Pt2_512 : FUNCTION = "A 5.25"" floppy, with 1.2MB and 512 bytes/sector."
CASE %F3_1Pt44_512 : FUNCTION = "A 3.5"" floppy, with 1.44MB and 512 bytes/sector."
CASE %F3_2Pt88_512 : FUNCTION = "A 3.5"" floppy, with 2.88MB and 512 bytes/sector."
CASE %F3_20Pt8_512 : FUNCTION = "A 3.5"" floppy, with 20.8MB and 512 bytes/sector."
CASE %F3_720_512 : FUNCTION = "A 3.5"" floppy, with 720KB and 512 bytes/sector."
CASE %F5_360_512 : FUNCTION = "A 5.25"" floppy, with 360KB and 512 bytes/sector."
CASE %F5_320_512 : FUNCTION = "A 5.25"" floppy, with 320KB and 512 bytes/sector."
CASE %F5_320_1024 : FUNCTION = "A 5.25"" floppy, with 320KB and 1024 bytes/sector."
CASE %F5_180_512 : FUNCTION = "A 5.25"" floppy, with 180KB and 512 bytes/sector."
CASE %F5_160_512 : FUNCTION = "A 5.25"" floppy, with 160KB and 512 bytes/sector."
CASE %RemovableMedia : FUNCTION = "Removable media other than floppy."
CASE %FixedMedia : FUNCTION = "Fixed hard disk media."
CASE %F3_120M_512 : FUNCTION = "A 3.5"" floppy, with 120MB and 512 bytes/sector."
CASE %F3_640_512 : FUNCTION = "A 3.5"" floppy, with 640KB and 512 bytes/sector."
CASE %F5_640_512 : FUNCTION = "A 5.25"" floppy, with 640KB and 512 bytes/sector."
CASE %F5_720_512 : FUNCTION = "A 5.25"" floppy, with 720KB and 512 bytes/sector."
CASE %F3_1Pt2_512 : FUNCTION = "A 3.5"" floppy, with 1.2MB and 512 bytes/sector."
CASE %F3_1Pt23_1024 : FUNCTION = "A 3.5"" floppy, with 1.23MB and 1024 bytes/sector."
CASE %F5_1Pt23_1024 : FUNCTION = "A 5.25"" floppy, with 1.23MB and 1024 bytes/sector."
CASE %F3_128Mb_512 : FUNCTION = "A 3.5"" floppy, with 128MB and 512 bytes/sector."
CASE %F3_230Mb_512 : FUNCTION = "A 3.5"" floppy, with 230MB and 512 bytes/sector."
CASE %F8_256_128 : FUNCTION = "An 8"" floppy, with 256KB and 128 bytes/sector."
CASE %F3_200Mb_512 : FUNCTION = "A 3.5"" floppy, with 200MB and 512 bytes/sector. (HiFD.)"
CASE %F3_240M_512 : FUNCTION = "A 3.5"" floppy, with 240MB and 512 bytes/sector. (HiFD.)"
CASE %F3_32M_512 : FUNCTION = "A 3.5"" floppy, with 32MB and 512 bytes/sector."
END SELECT
END FUNCTION
'_____________________________________________________________________________
FUNCTION MediaTypeGet(BYVAL MediaType AS DWORD) EXPORT AS STRING
SELECT CASE MediaType
CASE %DRIVE_UNKNOWN : FUNCTION = "DRIVE_UNKNOWN"
CASE %DRIVE_NO_ROOT_DIR : FUNCTION = "DRIVE_NO_ROOT_DIR"
CASE %DRIVE_REMOVABLE : FUNCTION = "DRIVE_REMOVABLE"
CASE %DRIVE_REMOTE : FUNCTION = "DRIVE_REMOTE"
CASE %DRIVE_CDROM : FUNCTION = "DRIVE_CDROM"
CASE %DRIVE_RAMDISK : FUNCTION = "DRIVE_RAMDISK"
CASE %DRIVE_FIXED : FUNCTION = "DRIVE_FIXED"
END SELECT
END FUNCTION
'_____________________________________________________________________________
FUNCTION GetVolumeInfo(zDisk AS ASCIIZ * 4)AS LONG
LOCAL zVolumeName AS ASCIIZ * 21
LOCAL zFileSystem AS ASCIIZ * 21
LOCAL VolumeSerialNumber AS DWORD
LOCAL FileNameMaxLen AS DWORD
LOCAL FileSystemFlag AS LONG
IF GetVolumeInformation(zDisk, _
zVolumeName, 20, _
VolumeSerialNumber, _
FileNameMaxLen, _
FileSystemFlag, _
zFileSystem, 20) = %FALSE THEN
ELSE
FUNCTION = %TRUE 'Media inserted
END IF
END FUNCTION
'_____________________________________________________________________________________
FUNCTION GetPhysicalDiskId(BYREF sBuffer AS STRING, BYVAL BufferLen AS DWORD) EXPORT AS DWORD
LOCAL DiskGeometry AS DISK_GEOMETRY
LOCAL sPhysicalDiskList AS STRING
LOCAL PhysicalDiskIndex AS DWORD
LOCAL PhysicalDiskCount AS DWORD
LOCAL hDevice AS DWORD
DO
hDevice = CreateFile("\\.\PhysicalDrive" & FORMAT$(PhysicalDiskIndex), _ 'Could be a HD, flash, CdRom, etc.
%GENERIC_READ, %FILE_SHARE_READ OR %FILE_SHARE_WRITE, BYVAL 0, %OPEN_EXISTING, 0, 0)
IF hDevice = %INVALID_HANDLE_VALUE THEN
EXIT DO 'No more devices
ELSE
IF DeviceIoControl(hDevice, %IOCTL_DISK_GET_DRIVE_GEOMETRY, BYVAL 0, _ 'Will be TRUE if device is a disk
BYVAL 0, BYVAL VARPTR(DiskGeometry), SIZEOF(DISK_GEOMETRY), 0, BYVAL 0 ) THEN
sPhysicalDiskList = sPhysicalDiskList & FORMAT$(PhysicalDiskIndex, "00") & ":" 'Disk are zero based, Result example: "00:01:04:06"
INCR PhysicalDiskCount
END IF
CloseHandle(hDevice)
INCR PhysicalDiskIndex
END IF
LOOP
IF PhysicalDiskCount THEN
sPhysicalDiskList = LEFT$(sPhysicalDiskList, -1) 'Remove last ":"
sBuffer = LEFT$(sPhysicalDiskList, BufferLen) 'Respect buffer lenght
ELSE
sBuffer = ""
END IF
FUNCTION = PhysicalDiskCount
END FUNCTION
'_____________________________________________________________________________
FUNCTION GetLogicalDiskId(BYREF sBuffer AS STRING, BYVAL BufferLen AS DWORD) EXPORT AS DWORD
LOCAL sLogicalDiskList AS STRING
LOCAL sLogicalFixedDiskList AS STRING
LOCAL LogicalDiskIndex AS DWORD
LOCAL LogicalDiskCount AS DWORD
LOCAL LogicalFixedDiskCount AS DWORD
LOCAL LogicalDiskListLen AS DWORD
LOCAL zDrive AS ASCIIZ * 4
sLogicalDiskList = NUL$(26 * 4 + 1)
LogicalDiskListLen = GetLogicalDriveStrings(LEN(sLogicalDiskList), BYVAL STRPTR(sLogicalDiskList)) 'C:\<NULL>D:\<NULL>R:\<NULL><NULL>
IF LogicalDiskListLen <= BufferLen THEN 'Success
REPLACE $NUL WITH "" IN sLogicalDiskList
LogicalDiskCount = LogicalDiskListLen / 4
FOR LogicalDiskIndex = 0 TO LogicalDiskCount - 1
zDrive = MID$(sLogicalDiskList, LogicalDiskIndex * 3 + 1, 3)
SELECT CASE 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) THEN 'Is there a media inserted
sLogicalFixedDiskList = sLogicalFixedDiskList & zDrive
INCR LogicalFixedDiskCount
END IF
END SELECT
NEXT
sBuffer = sLogicalFixedDiskList
ELSE 'sBuffer is too small, LogicalDiskListLen is the required size
sBuffer = ""
END IF
FUNCTION = LogicalFixedDiskCount
END FUNCTION
'_____________________________________________________________________________
FUNCTION GetPhysicalDiskGeometry(BYVAl hDisk AS DWORD, BYREF DiskGeometry AS DISK_GEOMETRY) EXPORT AS DWORD
'Does not work on USB FAT16
IF DeviceIoControl(hDisk, %IOCTL_DISK_GET_DRIVE_GEOMETRY, BYVAL 0, _
BYVAL 0, BYVAL VARPTR(DiskGeometry), SIZEOF(DISK_GEOMETRY), 0, BYVAL 0 ) THEN
FUNCTION = %TRUE
END IF
END FUNCTION
'_____________________________________________________________________________
FUNCTION OpenPhysicalDisk(BYVAL PhysicalDiskId AS DWORD, BYVAL WritePermission AS LONG) EXPORT AS DWORD
LOCAL zDisk AS ASCIIZ * 20
zDisk = "\\.\PhysicalDrive" & FORMAT$(PhysicalDiskId) 'Physical disk as "\\.\PhysicalDrive0"
IF WritePermission THEN 'Read & Write
FUNCTION = CreateFile(zDisk, %GENERIC_READ OR %GENERIC_WRITE, _
%FILE_SHARE_READ OR %FILE_SHARE_WRITE, BYVAL 0, %OPEN_EXISTING, 0, 0)
ELSE 'Read only
FUNCTION = CreateFile(zDisk, %GENERIC_READ, _
%FILE_SHARE_READ OR %FILE_SHARE_WRITE, BYVAL 0, %OPEN_EXISTING, 0, 0 )
END IF
END FUNCTION
'_____________________________________________________________________________
FUNCTION OpenLogicalDisk(BYVAL sLogicalDisk AS STRING, BYVAL WritePermission AS LONG) EXPORT AS DWORD
LOCAL zDisk AS ASCIIZ * 8
zDisk = "\\.\" & LEFT$(sLogicalDisk, 2) 'Logical disk as "\\.\C:"
IF WritePermission THEN 'Read & Write
FUNCTION = CreateFile(zDisk, %GENERIC_READ OR %GENERIC_WRITE, _
%FILE_SHARE_READ OR %FILE_SHARE_WRITE, BYVAL 0, %OPEN_EXISTING, 0, 0)
ELSE 'Read only
FUNCTION = CreateFile(zDisk, %GENERIC_READ, _
%FILE_SHARE_READ OR %FILE_SHARE_WRITE, BYVAL 0, %OPEN_EXISTING, 0, 0 )
END IF
END FUNCTION
'_____________________________________________________________________________
FUNCTION GetPhysicalDiskBlockCount(BYVAL hDisk AS DWORD) EXPORT AS QUAD
LOCAL DiskGeometry AS DISK_GEOMETRY
LOCAL OldErrMode AS LONG
'DeviceIoControl(BYVAL hDisk, %FSCTL_ALLOW_EXTENDED_DASD_IO, BYVAL %NULL, 0, _
' BYVAL %NULL, 0, BytesReturned, BYVAL %NULL)
'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.
OldErrMode = SetErrorMode(%SEM_FAILCRITICALERRORS) 'Prevent pop-up dialogs if device is not present or loaded
IF DeviceIoControl(hDisk, %IOCTL_DISK_GET_DRIVE_GEOMETRY, BYVAL 0, _
BYVAL 0, BYVAL VARPTR(DiskGeometry), SIZEOF(DISK_GEOMETRY), 0, BYVAL 0 ) THEN
FUNCTION = DiskGeometry.Cylinders * DiskGeometry.TracksPerCylinder * DiskGeometry.SectorsPerTrack
END IF
SetErrorMode(OldErrMode)
END FUNCTION
'_____________________________________________________________________________
FUNCTION GetLogicalDiskBlockCount(BYVAL sDisk AS STRING) EXPORT AS QUAD
LOCAL FreeBytesForUser AS QUAD 'Available to user
LOCAL UserDiskSize AS QUAD 'Available to user
LOCAL FreeByteOnDisk AS QUAD
LOCAL OldErrMode AS LONG
'DeviceIoControl(BYVAL hDisk, %FSCTL_ALLOW_EXTENDED_DASD_IO, BYVAL %NULL, 0, _ '
' BYVAL %NULL, 0, BytesReturned, BYVAL %NULL)
'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.
OldErrMode = SetErrorMode(%SEM_FAILCRITICALERRORS) 'Prevent pop-up dialogs if device is not present or loaded
GetDiskFreeSpaceEx(BYVAL STRPTR(sDisk), FreeBytesForUser, UserDiskSize, FreeByteOnDisk)
FUNCTION = UserDiskSize / %BlockSize
SetErrorMode(OldErrMode)
END FUNCTION
'_____________________________________________________________________________
FUNCTION DiskRead(BYVAL hDisk AS DWORD, BYVAL BlockIndex AS QUAD, BYREF sBuffer AS STRING, BYVAL BufferLen AS DWORD) EXPORT AS DWORD
LOCAL FilePointer AS QUAD
LOCAL NewFilePointer AS QUAD
LOCAL BytesReturned AS DWORD
FilePointer = BlockIndex * %BlockSize
SetFilePointerEx(hDisk, FilePointer, NewFilePointer, %FILE_BEGIN)
IF ReadFile(hDisk, BYVAL STRPTR(sBuffer), BufferLen, BytesReturned, BYVAL %NULL) THEN
FUNCTION = BytesReturned
END IF
END FUNCTION
'_____________________________________________________________________________
FUNCTION DiskWrite(BYVAL hDisk AS DWORD, BYVAL BlockIndex AS QUAD, BYREF sBuffer AS STRING, BYVAL BufferLen AS DWORD) EXPORT AS DWORD
LOCAL FilePointer AS QUAD
LOCAL NewFilePointer AS QUAD
LOCAL BytesWritten AS DWORD
FilePointer = BlockIndex * %BlockSize
SetFilePointerEx(hDisk, FilePointer, NewFilePointer, %FILE_BEGIN)
IF WriteFile(hDisk, BYVAL STRPTR(sBuffer), BufferLen, BytesWritten, BYVAL %NULL) THEN
FUNCTION = BytesWritten
END IF
END FUNCTION
'_____________________________________________________________________________
FUNCTION CloseDisk(BYREF hDisk AS DWORD) EXPORT AS DWORD
CloseHandle(hDisk)
FUNCTION = GetLastError()
hDisk = 0
END FUNCTION
'_____________________________________________________________________________
FUNCTION StringToHexView(sString AS STRING) AS STRING 'See D:\Basic\Bas\SRC\Hex\HexToStrGary03.bas
LOCAL sBuffer AS STRING
LOCAL LooperLine AS LONG
LOCAL LooperChar AS LONG
LOCAL CharPos AS LONG
LOCAL StringLen AS LONG
StringLen = LEN(sString)
FOR LooperLine = 0 TO StringLen - 1 STEP 16
sBuffer = sBuffer & HEX$(LooperLine, 4) & ": " 'Offset
FOR LooperChar = 1 TO 16 'Hex
CharPos = LooperLine + LooperChar
IF CharPos <= StringLen THEN
sBuffer = sBuffer & HEX$(ASC(sString, CharPos), 2) & $SPC
END IF
NEXT
'000000: 31 32 33 34 35 36 37 38 39 30 41 42 43 44 45 46 ; 1234567890ABCDEF
sBuffer = sBuffer & SPACE$(54 - (LEN(sBuffer) MOD 74)) & "; "
FOR LooperChar = 1 TO 16 'Ascii
CharPos = LooperLine + LooperChar
IF CharPos <= StringLen THEN
SELECT CASE ASC(sString, CharPos)
CASE 0, 1, 9, 10, 13, 27, 28, 29, 30, 31, _ '"Courier New"
127, 129, 140, 141, 143, 144, 152, 157
sBuffer = sBuffer & "."
CASE ELSE
sBuffer = sBuffer & MID$(sString, CharPos, 1)
END SELECT
END IF
NEXT
sBuffer = sBuffer & $CRLF
NEXT
FUNCTION = sBuffer
END FUNCTION
'______________________________________________________________________________
CALLBACK FUNCTION DlgProc()
LOCAL pNotifyMessageHeader AS NMHDR POINTER
LOCAL pNotifyMessageUpDown AS NM_UPDOWN POINTER
LOCAL MinMaxInfoPtr AS MINMAXINFO POINTER
DIM UpDownAccelleration(0 TO 7) AS UDACCEL
LOCAL DiskGeometry AS DISK_GEOMETRY
STATIC sLogicalDisk AS STRING
LOCAL sBuffer AS STRING
STATIC sDisk AS STRING
LOCAL BlockIndex AS QUAD
STATIC BlockCount AS QUAD
LOCAL UpDownAccellerationStepCount AS DWORD
STATIC hDisk AS DWORD
STATIC PhysicalDisk AS DWORD
STATIC Disk AS DWORD
STATIC DiskCount AS DWORD
STATIC DiskError AS LONG
LOCAL ReadCount AS LONG
LOCAL Looper AS LONG
STATIC UpDownValH AS LONG
STATIC UpDownDeltaH AS LONG
STATIC UpDownStartPosition AS LONG
SELECT CASE CBMSG
CASE %WM_INITDIALOG
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)
'Sets the acceleration for the up-down control
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
CONTROL SEND hDlg, %UpDownH, %UDM_SETACCEL, UpDownAccellerationStepCount, VARPTR(UpDownAccelleration(0))
PostMessage(hDlg, %WM_COMMAND, MAKDWD(%OptionPhysical, %BN_CLICKED), GetDlgItem(hDlg, %OptionPhysical))
CASE %WM_COMMAND
SELECT CASE LOWRD(CBWPARAM)
CASE %OptionLogical, %OptionPhysical
IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
BlockIndex = 0
CONTROL SET TEXT hDlg, %EditBlockIndex, "0"
CONTROL GET CHECK hDlg, %OptionPhysical TO PhysicalDisk
COMBOBOX RESET hDlg, %ComboDisk
IF PhysicalDisk THEN
sBuffer = NUL$(3 * 26)
DiskCount = GetPhysicalDiskId(sBuffer, LEN(sBuffer))
IF DiskCount = 0 THEN
MessageBox(hDlg, BYCOPY "No disk fatal error", BYCOPY $AppName, %MB_ICONINFORMATION OR %MB_OK)
PostMessage(hDlg, %WM_SYSCOMMAND, %SC_CLOSE, BYVAL 0)
ELSE
FOR Looper = 1 TO DiskCount
COMBOBOX ADD hDlg, %ComboDisk, PARSE$(sBuffer, ":", Looper)
NEXT
Disk = VAL(PARSE$(sBuffer, ":", 1)) 'Set to first disk, zero based
COMBOBOX SELECT hDlg, %ComboDisk, 1 'Set to first disk, zero based
END IF
ELSE 'OptionLogical
sBuffer = NUL$(3 * 26)
DiskCount = GetLogicalDiskId(sBuffer, LEN(sBuffer))
IF DiskCount = 0 THEN
MessageBox(hDlg, BYCOPY "No disk fatal error", BYCOPY $AppName, %MB_ICONINFORMATION OR %MB_OK)
PostMessage(hDlg, %WM_SYSCOMMAND, %SC_CLOSE, BYVAL 0)
ELSE
FOR Looper = 1 TO DiskCount
COMBOBOX ADD hDlg, %ComboDisk, PARSE$(sBuffer, "\", Looper) & "\"
NEXT
sDisk = PARSE$(sBuffer, "\", 1) & "\" 'Set to first disk,
COMBOBOX SELECT hDlg, %ComboDisk, 1
END IF
END IF
CONTROL SET TEXT hDlg, %LabelDiskCount, "Disk found: " & STR$(DiskCount)
PostMessage(hDlg, %WM_COMMAND, MAKDWD(%ComboDisk, %CBN_EDITCHANGE), GetDlgItem(hDlg, %ComboDisk))
END IF
CASE %ComboDisk
IF CBCTLMSG = %CBN_EDITCHANGE OR CBCTLMSG = 1 THEN
IF hDisk THEN CloseDisk(hDisk)
Disk = 0
BlockCount = 0
BlockIndex = 0
CONTROL SET TEXT hDlg, %EditBlockIndex, FORMAT$(BlockIndex) '"0"
IF PhysicalDisk THEN
CONTROL GET TEXT hDlg, %ComboDisk TO sBuffer
Disk = VAL(sBuffer)
hDisk = OpenPhysicalDisk(Disk, %FALSE) '%FALSE for open in read only mode
BlockCount = GetPhysicalDiskBlockCount(hDisk)
IF GetPhysicalDiskGeometry(hDisk, DiskGeometry) THEN
CONTROL SET TEXT hDlg, %LabelCyl, "Cyl : " & FORMAT$(DiskGeometry.Cylinders, "0,")
CONTROL SET TEXT hDlg, %LabelHead, "Head: " & FORMAT$(DiskGeometry.TracksPerCylinder)
CONTROL SET TEXT hDlg, %LabelSect, "Sect: " & FORMAT$(DiskGeometry.SectorsPerTrack)
END IF
ELSE 'Logical disk
COMBOBOX GET TEXT hDlg, %ComboDisk TO sDisk 'sLogicalDisk
hDisk = OpenLogicalDisk(sDisk, %FALSE) '%FALSE for open in read only mode
BlockCount = GetLogicalDiskBlockCount(sDisk)
CONTROL SET TEXT hDlg, %LabelCyl, ""
CONTROL SET TEXT hDlg, %LabelHead, ""
CONTROL SET TEXT hDlg, %LabelSect, ""
END IF
CONTROL SET TEXT hDlg, %LabelMeg, "Bytes: " & FORMAT$(BlockCount * %BlockSize, "0,")
CONTROL SEND hDlg, %UpDownH, %UDM_SETRANGE32, UpDownStartPosition, _ 'LONG -2,147,483,648 '
UpDownStartPosition + BlockCount - 1
CONTROL SEND hDlg, %UpDownH, %UDM_SETPOS32, 0, UpDownStartPosition 'Reset to start pos
CONTROL SET TEXT hDlg, %LabelBlockCount, "Block: " & FORMAT$(BlockCount, "0,")
DIALOG POST hDlg, %WM_COMMAND, %ButtonRead, %BN_CLICKED
END IF
CASE %EditBlockIndex
IF HIWRD(CBWPARAM) = %EN_CHANGE THEN
CONTROL GET TEXT hDlg, %EditBlockIndex TO sBuffer
BlockIndex = VAL(sBuffer)
IF BlockIndex > BlockCount - 1 THEN BlockIndex = BlockCount - 1
IF BlockIndex < 0 THEN BlockIndex = 0
CONTROL SEND hDlg, %UpDownH, %UDM_SETPOS32, 0, UpDownStartPosition + BlockIndex
END IF
CASE %ButtonRead, %IDOK
IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
IF DiskError = %FALSE THEN
CONTROL GET TEXT hDlg, %EditBlockIndex TO sBuffer
BlockIndex = VAL(sBuffer)
IF BlockIndex > BlockCount - 1 THEN BlockIndex = BlockCount - 1
IF BlockIndex < 0 THEN BlockIndex = 0
CONTROL SET TEXT hDlg, %EditBlockIndex, FORMAT$(BlockIndex)
CONTROL SEND hDlg, %UpDownH, %UDM_SETPOS32, 0, UpDownStartPosition + BlockIndex
sBuffer = NUL$(%BlockSize) '4096
ReadCount = DiskRead(hDisk, BlockIndex, sBuffer, LEN(sBuffer))
IF ReadCount = 0 THEN
DiskError = %TRUE
CONTROL SET TEXT hDlg, %EditHex, ""
MessageBox(hDlg, "Disk error on block " & FORMAT$(BlockIndex, "0,"), _
$AppName, %MB_ICONINFORMATION OR %MB_OK)
DiskError = %FALSE
ELSE
CONTROL SET TEXT hDlg, %EditHex, StringToHexView(sBuffer)
END IF
END IF
END IF
END SELECT
CASE %WM_NOTIFY
pNotifyMessageHeader = CBLPARAM
IF @pNotifyMessageHeader.Code = %UDN_DELTAPOS THEN
IF (@pNotifyMessageHeader.idFrom = %UpDownH) THEN
pNotifyMessageUpDown = CBLPARAM
UpDownDeltaH = @pNotifyMessageUpDown.iDelta
END IF
END IF
CASE %WM_VSCROLL, %WM_HSCROLL
IF GetDlgCtrlID(CBLPARAM) = %UpDownH THEN
LOCAL UpDownError AS LONG
UpDownValH = SendMessage(CBLPARAM, %UDM_GETPOS32, %FALSE, UpDownError) '+ UpDownStartPosition
CONTROL SET TEXT hDlg, %EditBlockIndex, FORMAT$(UpDownValH - UpDownStartPosition) '-2147483648 'Needed for 2 tb, LONG -2,147,483,648 to +2,147,483,647
DIALOG POST hDlg, %WM_COMMAND, %ButtonRead, %BN_CLICKED
END IF
CASE %WM_DESTROY
IF hDisk THEN CloseDisk(hDisk)
END SELECT
END FUNCTION
'_____________________________________________________________________________
FUNCTION PBMAIN()
LOCAL hFont AS DWORD
LOCAL hIconBig AS DWORD
LOCAL hIconSmall AS DWORD
LOCAL DiskGeometry AS DISK_GEOMETRY
LOCAL hDisk AS DWORD
LOCAL PhysicalDiskCount AS DWORD
LOCAL PhysicalDiskId AS DWORD
LOCAL LogicalDiskCount AS DWORD
LOCAL ReadCount AS DWORD
LOCAL BlockCount AS QUAD
LOCAL BlockIndex AS QUAD
LOCAL sDisk AS STRING
LOCAL sBuffer AS STRING
IF IsUserLocalAdmin = %FALSE THEN
MessageBox(%HWND_DESKTOP, "Please restart program as administrator.", $AppName & " - Error", %MB_OK)
ELSE
DIALOG FONT "Segoe UI", 9
DIALOG NEW %HWND_DESKTOP, $AppName & " for Windows NT/2000/XP/Vista/Seven/Eight/Ten",,, _
398, 360, %WS_CAPTION OR %WS_MINIMIZEBOX OR %WS_SYSMENU, 0 TO hDlg
CONTROL ADD FRAME, hDlg, -1, "", 02, 0, 394, 58, %BS_LEFT OR %BS_TOP, %WS_EX_LEFT
CONTROL ADD OPTION, hDlg, %OptionPhysical, "&Physical", 7, 6, 35, 9, %BS_LEFT OR %BS_VCENTER OR %WS_TABSTOP OR %WS_GROUP, %WS_EX_LEFT
CONTROL ADD OPTION, hDlg, %OptionLogical, "&Logical", 47, 6, 35, 9, %BS_LEFT OR %BS_VCENTER OR %WS_TABSTOP, %WS_EX_LEFT
CONTROL SET OPTION hDlg, %OptionPhysical, %OptionPhysical, %OptionLogical
CONTROL ADD LABEL, hDlg, %LabelDiskCount, "Disk found:", 7, 18, 60, 9
CONTROL ADD LABEL, hDlg, %LabelDisk, "Hard Disk", 7, 31, 50, 9
CONTROL ADD COMBOBOX, hDlg, %ComboDisk, , 57, 29, 31, 72, _
%CBS_DROPDOWNLIST OR %CBS_HASSTRINGS OR %CBS_SORT OR %WS_TABSTOP, %WS_EX_CLIENTEDGE OR %WS_EX_LEFT
CONTROL ADD LABEL, hDlg, %LabelBlockCount, "LB: 00000000", 100, 7, 90, 9, %SS_NOTIFY
CONTROL ADD LABEL, hDlg, %LabelMeg, "Meg: 00000000", 100, 17, 90, 9, %SS_NOTIFY
CONTROL ADD LABEL, hDlg, %LabelCyl, "Cylinder: 00000000", 215, 7, 80, 9, %SS_NOTIFY
CONTROL ADD LABEL, hDlg, %LabelHead, "Head: 00000", 215, 17, 80, 9, %SS_NOTIFY
CONTROL ADD LABEL, hDlg, %LabelSect, "Sector: 00000", 215, 27, 80, 9, %SS_NOTIFY
CONTROL ADD LABEL, hDlg, -1, "LogicalBlock", 300, 7, 90, 9
CONTROL ADD TEXTBOX, hDlg, %EditBlockIndex, "0", 300, 17, 45, 12
CONTROL ADD BUTTON, hDlg, %ButtonRead, "Read", 350, 16, 40, 13
CONTROL ADD "msctls_updown32", hDlg, %UpDownH, "", 305, 32, 0, 0, %WS_CHILD OR %WS_VISIBLE OR %UDS_HORZ
CONTROL SET SIZE hDlg, %UpDownH, 36, 15
CONTROL ADD LABEL, hDlg, %LabelStatus, "Status", 47, 46, 250, 9
CONTROL ADD TEXTBOX, hDlg, %EditHex, "", 3, 63, 393, 295, %WS_CHILD OR %WS_VISIBLE OR _
%WS_TABSTOP OR %WS_HSCROLL OR %WS_VSCROLL OR %ES_LEFT OR %ES_MULTILINE OR _
%ES_NOHIDESEL OR %ES_AUTOHSCROLL OR %ES_AUTOVSCROLL OR %ES_WANTRETURN, _
%WS_EX_CLIENTEDGE OR %WS_EX_LEFT OR %WS_EX_LTRREADING OR %WS_EX_RIGHTSCROLLBAR
hFont = 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, _
BYCOPY "Courier New") 'Consolas
SendDlgItemMessage(hDlg, %EditHex, %WM_SETFONT, hFont, %TRUE)
ExtractIconEx("shell32.dll", 8, BYVAL VARPTR(hIconBig), BYVAL VARPTR(hIconSmall), 1)
SetClassLong(hDlg, %GCL_HICONSM, hIconSmall) 'Set an icon
SetClassLong(hDlg, %GCL_HICON, hIconBig) 'Set an icon
SendMessage(hDlg, %WM_SETICON, %ICON_SMALL, hIconSmall)
SendMessage(hDlg, %WM_SETICON, %ICON_BIG, hIconBig)
DIALOG SHOW MODAL hDlg CALL DlgProc
DestroyIcon(hIconSmall)
DestroyIcon(hIconBig)
DeleteObject(hFont)
END IF
END FUNCTION
'_____________________________________________________________________________
'
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