Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hello:

I've been trying for the last few days to access a hard disk in windows and be able to read in raw format (a la dd).

I've tried many ways and somewhat been successful but not good enough. I tried forking dd and then read its output, but on large disks the buffer just grows too much and the program dies. I need to be able to control the buffer, so I guees I must open the file in perl without using an external program.

I have been trying using the Win32API, but without success. The following code works on a normal file, but not when i try to open a partition or a physical disk. The Function OsFHandleOpen just dies saying wrong parameter. Any ideas on how can i fix this, or some other way to read the raw disk in perl?



use Win32API::File 0.08 qw( :ALL );

$winHandle= createFile( "//./c:", "r") or die "$^E\n";
OsFHandleOpen( FILE, $winHandle, "r" ) or die " $^E\n";

while(<FILE>){
print "$_\n";
}
  • Comment on Reading a physical disk in windows as a File

Replies are listed 'Best First'.
Re: Reading a physical disk in windows as a File
by BrowserUk (Patriarch) on Sep 03, 2002 at 21:51 UTC

    I doubt you will find a module to allow you access to the correct api's to read disks in their raw format. I haven't looked, so I may be wrong on that.

    As you already have a utility to do it, I would suggest the easiest way is to persue your notion of forking dd and reading it that way. Instead of trying to read the whole thing into memory as a line, use the method of setting $/=\nn, to control the amount you read from the pipe to dd.

    See perlman:perlvar, search for $INPUT_RECORD_SEPARATOR, and read the second piece of sample code and its surrounding paragraph for a full explaination.

    Out of interest, is 'dd' the MKSToolkit version?


    Well It's better than the Abottoire, but Yorkshire!
      It's Win32::API.

        True. That would give him access to the native api's. If he knows which ones to call, what parameters to pass, how to manipulate perl vars into their C counterparts and back again, that would work.

        Seems a lot of work to avoid typing local $/=\4096 or whatever buffersize he is comfortable with.

        I'd also be wary of doing anything complicated given dada's warning:

        this simplicistic approach doesn't by any mean address any issue, and leave a lot of work on the programmers side; you have to pack() and unpack() data as C wants it, you have to know the structures you're using, and so on. it's not recommended to use Win32::API for complex tasks; think about writing an XS extension for that.


        Well It's better than the Abottoire, but Yorkshire!
Re: Reading a physical disk in windows as a File
by John M. Dlugosz (Monsignor) on Sep 03, 2002 at 21:59 UTC
    If you open the "file" that way, you must read only multiples of a blocksize (in my experience, 512 bytes for anything except 2048 for a CD). The <FILE> is not going to do that. Perhaps read or sysread? I'd go with a Win32::API import of ReadFile and not try to map the OS handle to Perl's system.

Re: Reading a physical disk in windows as a File
by flounder99 (Friar) on Sep 04, 2002 at 11:09 UTC
    cygwin creates /dev/fdxx and /dev/hdxx under NT/2K. These devices don't show up under ls but they work using dd. (I have used it to create floppy images)

    --

    flounder

      It's just a matter of translating /dev/fd01 to \\.\A: and so on.