use Win32API::File qw /:Func :IOCTL_DISK_ :MEDIA_TYPE :Misc/;
use Data::Dumper;
use strict;
use warnings;
use diagnostics;
my $sDosDeviceName = [];
my $osTargetPath;
my @devices = Win32API::File::QueryDosDevice($sDosDeviceName, $osTargetPath, []) or die "Can't open: $^E\n";
print Dumper($sDosDeviceName);
#foreach (@devices) {
# print $_ . "\n";
#}
my $hObject = createFile( "//./PhysicalDrive3", "r", "rw")
or die "Can't open: $^E\n";
#Usage: Win32API::File::DeviceIoControl(hDevice, uIoControlCode, pInBuf, lInBuf, opOutBuf, lOutBuf, olRetBytes, pOverlapped)
my $opOutBuf;
my $olRetBytes;
Win32API::File::DeviceIoControl($hObject, IOCTL_DISK_GET_DRIVE_GEOMETRY, [], 0, $opOutBuf, [], $olRetBytes, []);
# Calculate the number of DISK_GEOMETRY structures returned:
my $cStructs = length($opOutBuf)/(4+4+4+4+4+4);
my @fields = unpack( "L l I L L L" x $cStructs, $opOutBuf );
my( @ucCylsLow, @ivcCylsHigh, @uMediaType, @uTracksPerCyl, @uSectsPerTrack, @uBytesPerSect ) = ();
print Dumper(@fields);
my $ucCylsLow = shift @fields;
my $ivcCylsHigh = shift @fields;
my $uMediaType = shift @fields;
my $uTracksPerCyl = shift @fields;
my $uSectsPerTrack = shift @fields;
my $uBytesPerSect = shift @fields;
if ($uMediaType eq FixedMedia) {
print "FixedMedia";
}
####
my ($opBuffer, $lBytes, $olBytesRead);
$lBytes = $uBytesPerSect;
my $bool = ReadFile( $hObject, $opBuffer, $lBytes, $olBytesRead, []);
####
my $ivOffset = 25096704;
my $uNewPos = SetFilePointer( $hObject, $ivOffset, [], FILE_CURRENT ); # change to use Win32API::File qw /:Func :IOCTL_DISK_ :MEDIA_TYPE :Misc/;
####
if ($bool) {
print $opBuffer . "\n";
}
else {
print "ERROR: $^E\n";
}