# #!/usr/bin/env perl use Win32::API; use Win32API::File qw /:Func :IOCTL_DISK_/; use Data::Dumper; use strict; use warnings; #use diagnostics; # HANDLE CreateFile( # LPCTSTR lpFileName, # DWORD dwDesiredAccess, # DWORD dwShareMode, # LPSECURITY_ATTRIBUTES lpSecurityAttributes, # DWORD dwCreationDisposition, # DWORD dwFlagsAndAttributes, # HANDLE hTemplateFile # ); # BOOL DeviceIoControl( # (HANDLE) hDevice, // handle to volume # IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, // dwIoControlCode # (LPVOID) lpInBuffer, // input buffer # (DWORD) nInBufferSize, // size of input buffer # (LPVOID) lpOutBuffer, // output buffer # (DWORD) nOutBufferSize, // size of output buffer # (LPDWORD) lpBytesReturned, // number of bytes returned # (LPOVERLAPPED) lpOverlapped // OVERLAPPED structure # ); # typedef struct _VOLUME_DISK_EXTENTS { # DWORD NumberOfDiskExtents; # DISK_EXTENT Extents[1]; # } VOLUME_DISK_EXTENTS, # *PVOLUME_DISK_EXTENTS; # typedef struct _DISK_EXTENT { # DWORD DiskNumber; # LARGE_INTEGER StartingOffset; # LARGE_INTEGER ExtentLength; # } DISK_EXTENT, # *PDISK_EXTENT; # DWORD = N ## Internal stuff my ($CloseHandle, $GetCurrentProcess, $OpenProcessToken, $LookupPrivilegeValue, $AdjustTokenPrivileges, $CreateFile, $ReadDirectoryChanges, $DeviceIoControl); sub FILE_LIST_DIRECTORY { 0x00000001 } sub FILE_SHARE_READ { 0x00000001 } sub FILE_SHARE_WRITE { 0x00000002 } sub OPEN_EXISTING { 3 } sub FILE_FLAG_BACKUP_SEMANTICS { 0x02000000 } sub IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS { 5636096 } sub FILE_READ_ATTRIBUTES { 0x0080 } sub FILE_NOTIFY_CHANGE_NAME { 0x00000003 } sub DWORD_SIZE { 4 } sub TOKEN_ADJUST_PRIVILEGES { 0x0020 } sub TOKEN_QUERY { 0x0008 } sub SE_BACKUP_NAME { 'SeBackupPrivilege' } sub SE_RESTORE_NAME { 'SeRestorePrivilege' } sub SE_CHANGE_NOTIFY_NAME { 'SeChangeNotifyPrivilege' } sub SE_PRIVILEGE_ENABLED { 2 } sub _InitializeAPI { my $kernel32 = 'kernel32.dll'; my $advapi32 = 'advapi32.dll'; $CloseHandle = new Win32::API($kernel32, 'CloseHandle', 'N', 'I') || die; $GetCurrentProcess = new Win32::API($kernel32, 'GetCurrentProcess', '', 'N') || die $^E; $OpenProcessToken = new Win32::API($advapi32, 'OpenProcessToken', 'NNP', 'I' ) || die $^E; $LookupPrivilegeValue = new Win32::API($advapi32, 'LookupPrivilegeValue', 'PPP', 'I') || die $^E; $AdjustTokenPrivileges = new Win32::API($advapi32, 'AdjustTokenPrivileges', 'NIPNPP', 'I') || die $^E; $CreateFile = new Win32::API($kernel32, 'CreateFileA', 'PNNPNNN', 'N') or die $^E; $ReadDirectoryChanges = new Win32::API($kernel32, 'ReadDirectoryChangesW', 'NPNINPPP', 'I') || die $^E +; $DeviceIoControl = new Win32::API($kernel32, 'DeviceIoControl', 'NPPNPNPP', 'I') || die $^E; } sub _EnablePrivileges { my $phToken = pack("L", 0); if($OpenProcessToken->Call($GetCurrentProcess->Call(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, $phToken)) { my $hToken = unpack("L", $phToken); _SetPrivilege($hToken, SE_BACKUP_NAME, 1); _SetPrivilege($hToken, SE_RESTORE_NAME, 1); _SetPrivilege($hToken, SE_CHANGE_NOTIFY_NAME, 1); $CloseHandle->Call($hToken); } #print "privileges altered\n"; } sub _SetPrivilege { my ($hToken, $pszPriv, $bSetFlag) = @_; my $iResult; my $pLuid = pack("Ll", 0, 0); if($LookupPrivilegeValue->Call("\x00\x00", $pszPriv, $pLuid)) { my $pPrivStruct = pack("LLlL", 1, unpack("Ll", $pLuid), (($bSetFlag)? SE_PRIVILEGE_ENABLED : 0) +); $iResult = (0 != $AdjustTokenPrivileges->Call($hToken, 0, $pPrivStruct, length($pPrivStr +uct), 0, 0)); } return ($iResult); } _InitializeAPI(); _EnablePrivileges(); my $hDevice; #my $dwIoControlCode = FSCTL_GET_RETRIEVAL_POINTERS; #my $lpInBuffer = pack("L", 0); my $lpInBuffer = []; my $nInBufferSize = 0; my $lpOutBuffer = 0; my $nOutBufferSize = 0; my $lpBytesReturned = 0; my $lpOverlapped = []; #$hDevice = createFile( "//./PhysicalDrive1", "r", "rw") # or die "Can't open: $^E\n"; #my $path = "//./D:/Snap1.gif"; #my $path = "D:/Snap1.gif"; my $path = "D:/"; $hDevice = $CreateFile->Call($path, FILE_LIST_DIRECTORY, FILE_SHARE_READ | FILE_SHARE_W +RITE, 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0) || die $^E; my $nBufferLength = 1024; #1024 * DWORD_SIZE; my $pBuffer = "\x00" x $nBufferLength; my $pBytesReturned = pack("L", 0); # my $iResult = $ReadDirectoryChanges->Call($hDevice, # $pBuffer, # $nBufferLength, # 1, # FILE_NOTIFY_CHANGE_NAME +, # $pBytesReturned, # 0, 0) || die $^E; # my $bytesReturned = unpack("L", $pBytesReturned); #print Dumper($iResult); print Dumper($hDevice); #if ($iResult < 1) { # print Win32::GetLastError() . "\n"; # print $^E . "\n"; # exit; #} if ($hDevice < 1) { print $^E . "\n"; exit; } #$hDevice = unpack("L", $hDevice); #print $hDevice . "\n"; #Win32API::File::DeviceIoControl($hDevice, # IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, # 0, # [], # $lpOutBuffer, # $nOutBufferSize, # $lpBytesReturned, # 0, # ) || die $^E; my $iResult2 = $DeviceIoControl->Call($hDevice, IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, 0, [], $lpOutBuffer, $nOutBufferSize, $lpBytesReturned, 0, ) || die $^E; print Dumper($lpOutBuffer); print Dumper($nOutBufferSize); my $pBytesReturned2 = pack("L", 0); my $bytesReturned2 = unpack("L", $pBytesReturned2); my @results = (); print $bytesReturned2 . "\n"; __END__ if ($bytesReturned > 0) { my ($NextEntryOffset, $Action, $FileNameLength, $FileName); while (1) { my ($NextEntryOffset, $Action, $FileNameLength) = unpack("LLL" +, $pBuffer); (undef, undef, undef, $FileName) = unpack("LLLa$FileNameLength +", $pBuffer); $FileName = pack "C*", unpack "S*", $FileName; push @results, $Action => $FileName; last if($NextEntryOffset <= 0); $pBuffer = substr($pBuffer, $NextEntryOffset); } } #print Win32::GetLastError();
In reply to From File to at Sectors on harddrive (Windows) by Ace128
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |