Solved

Direct reading of disk sectors

Posted on 1998-10-21
24
463 Views
Last Modified: 2010-04-06
I need to read a hard disk sector by sector using Delphi3
under W95. The disk is not the W95 system disk - the idea
is that it will be added by using a "slot-in" disk caddy.
It will have a dos partition on it but also non-dos ones
which I also need to read.
I have seen references to Vwin32.vxd and Ints 25h and 26h
but how do you access them? Any code snippets etc would be
very useful.
0
Comment
Question by:jellison
  • 10
  • 8
  • 6
24 Comments
 
LVL 20

Expert Comment

by:Madshi
ID: 1343575
Run "win32.help". Choose from the index listing "Calling DeviceIoControl on Windows 95". This is all I can tell you. Sorry - have no sources...

Regards, Madshi.
0
 
LVL 5

Accepted Solution

by:
inter earned 200 total points
ID: 1343576
Hi,
to open physical disks or partition (not for logical ones) you can use win32
CreateFile win32 API call. The follwing call opens the drive A, just change the drive letter for your needs, to open the first physical drive change
\\.\A: to \\.\PHYSICALDRIVE0


function LowLevel: boolean;
var
  fh: THandle;
  i: integer;
  SPos: integer;
begin
  Result := false;
  fh := CreateFile('\\.\A:', GENERIC_READ or GENERIC_WRITE,
    FILE_SHARE_READ or FILE_SHARE_WRITE, nil,
    OPEN_EXISTING, 0, 0);
  if fh > 0 then
  begin
    try
      //seek to begining of the drive
      FileSeek(fh, 0, 0);
      // *************** DO YOUR OPS HERE ***********
      Result := true;
    finally
      // close the disk
      CloseHandle(fh);
    end;
  end
  else
    ShowMessage('Cannot open drive');
end;

regards, igor
0
 
LVL 20

Expert Comment

by:Madshi
ID: 1343577
Sorry, Igor...

your code will definitely not work with Win95!    :-(

Regards, Madshi.
0
 
LVL 5

Expert Comment

by:inter
ID: 1343578
Ok, I'll dig up the 95 code tomorrow,
c.u. igor
0
 
LVL 1

Author Comment

by:jellison
ID: 1343579
Igor,
Following your answer I looked at the Win32 Help & it does suggest that using a filename
of \\.\PHYSICALDRIVEn will work with W95 although, as you said, logical partitions won't.
I did try it to see what happened but all I got was a "cannot open" result - so I guess
Madshi is right.
I look forward to your W95 solution.
Regards, JohnE.
0
 
LVL 1

Author Comment

by:jellison
ID: 1343580
Igor,
Are you getting anywhere with the problem?  Following your comments I have been
experimenting with the \\.\vwin32 as documented in the Win32 help file. I have managed
to read floppy disk sectors but can't get anything to read the HD? Very frustrating.

Regards, JohnE

0
 
LVL 20

Expert Comment

by:Madshi
ID: 1343581
Jellison,

how about posting your floppy disk source code here?
Then perhaps we can find out why it doesn't work with HD.

Regards, Madshi.
0
 
LVL 5

Expert Comment

by:inter
ID: 1343582
I am back again,
since I have no 95 I try to code it on my mind post it, then you test it and comment...etc..
OK?
0
 
LVL 5

Expert Comment

by:inter
ID: 1343583
Yes man, the win95 lowlevel HD operations are troublesome. But it would be much easier if you only want to READ from drive, so do you need to WRITE something on harddisk?
0
 
LVL 1

Author Comment

by:jellison
ID: 1343584
Yes, I only need to read. The writing is being done by another system. I will then remove
the drive, put it into my PC and try to read it.

JohnE
0
 
LVL 5

Expert Comment

by:inter
ID: 1343585
Hi,
The following code compiles without error but I can not run it on NT...Supply a buffer to the read sector and sector to be read (the buffer should be at least 512 bytes and test to see if it can read the data...). I just conduct the example from several sources so I AM REALLY NOT SURE but I am sure this is the way...


const
  VWIN32_DIOC_DOS_INT13 = 4;      //do not use this it requires thunking
  VWIN32_DIOC_DOS_INT25 = 2;      //Performs the Absolute Disk Read command (Interrupt 25h).
  VWIN32_DIOC_DOS_INT26 = 3;      //Performs the Absolute Disk Write command (Interrupt 25h).
  VWIN32_DIOC_DOS_IOCTL = 1;      //Performs the specified MS-DOS device I/O control function                         //(Interrupt 21h Function 4400h through 4411h).

type
 PDIOC_REGISTERS = ^TDIOC_REGISTERS;
 TDIOC_REGISTERS = packed record
    reg_EBX,
    reg_EDX,
    reg_ECX,
    reg_EAX,
    reg_EDI,
    reg_ESI,
    reg_Flags : DWORD;
 end;

function ReadSector(nSector : DWORD; var inBuffer : Pointer):boolean;
var
  hDevice : THandle;
  reg     : TDIOC_REGISTERS;
  cb      : DWORD;
const
  DRIVE_C = 2;  // Drive C:
begin
  hDevice := CreateFile('\\.\vwin32',
    0, 0, nil, 0, FILE_FLAG_DELETE_ON_CLOSE, 0);

  reg.reg_EAX := DRIVE_C;          // which drive
  reg.reg_EBX := DWORD(inBuffer);         // pointer to input buffer
  reg.reg_ECX := 1;                // how many sectors to read
  reg.reg_EDX := nSector;          // read which sector
  reg.reg_Flags := 0;              // no error


  Result := DeviceIoControl(hDevice,
    VWIN32_DIOC_DOS_INT25,
    @reg, sizeof(reg),
    @reg, sizeof(reg),
    cb, nil);

  Result := Result and ((reg.reg_Flags and $0001) = 0);

  CloseHandle(hDevice);
end;

regards, igor (wow man who says delphi is not a tool for real programmers ;-)

0
 
LVL 5

Expert Comment

by:inter
ID: 1343586
Wait............!!!!!!!!!!!!!!!!!
I strongly suggest you to change DRIVE_C = 0 to test the routines on floppy. If every thing ok test is on harddisk..........
0
Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

 
LVL 1

Author Comment

by:jellison
ID: 1343587
Igor,

Good grief. I know more about HD drives than I ever wanted to - & I still can't make it
work. I tried Int25 and it works BUT it only supports the old bios read and is therefore
restricted to 528Mb because of the limits on sector/head/cylinder values. There is an
extended version of the call by setting CX to $FFFF but that is limited to 2Gb. I need
more and the only place I can find support for bigger drives is in extended Int13 calls
with functions $41 to $48. These address drives with Logical Block Addressing and
support huge block numbers.
Now, despite your comment re thunking (which I don't really understand) I tried some
Int13 calls using Vwin32. The strange thing is that the install check function ($41)
returns a valid response from the floppy drive (drive 0) although when I try to read it
(Func $42) I get an invalid seek. Perhaps that's to do with thunking.
When I try the install check on my HD however (drive $80 - a 4Gb drive in LBA mode
as far as the bios is concerned) it returns an invalid response. I am suspecting 3 things:
1. It's failing because of thunking
2. W95 needs some sort of lock on the HD before it will allow access
3. My bios isn't up to the job.
Before I check on (3) I would be grateful for your comments on (1) and (2).

Thanks,

JohnE
0
 
LVL 5

Expert Comment

by:inter
ID: 1343588
So, lets try to proceed in the following order(fm easy to hard)
1 - try to lock hd
2 - try to write thunk between our 32 bit process and 16 bit subsystem dlls (this is the basic explanation of thunking)
sorry, i can not be here for long try to dig it up tomorrow(sorry again I should go)
regards, igor
0
 
LVL 20

Expert Comment

by:Madshi
ID: 1343589
To lock/unlock the drive, call DeviceIOControl with VWIN32_DIOC_DOS_IOCTL and

            reg.reg_EAX:=$440D;                        // IOCTL for block devices
            reg.reg_EBX:=ord(drive)-ord('A')+1;        // zero-based drive ID
            reg.reg_ECX:=$084A;
            reg.reg_EDX:=0;

To unlock it again, call:

            reg.reg_EAX:=$440D;                        // IOCTL for block devices
            reg.reg_EBX:=ord(drive)-ord('A')+1;        // zero-based drive ID
            reg.reg_ECX:=$086A;

Regards, Madshi.
0
 
LVL 5

Expert Comment

by:inter
ID: 1343590
Thanks man,
here for a while....
0
 
LVL 1

Author Comment

by:jellison
ID: 1343591
Ok.. after much experimentation:

I think I have the vwin32 interface sorted out for everything but Int13 calls. I can get
successful locks on any physical drive using ECX := $084B and unlock it with
ECX := $086B. If I lock a drive then do an Int13 with AH=$41, BX=$55AA, DL=Drive
number that should tell me whether the IBM/MS extensions are valid for that drive.
If I set the drive to 0 (the A drive) the install check returns saying the extensions are
installed with bit flags indicating that I can use the IBM/MS extended functions and
that removable media extensions are valid too. If I set the drive to $80 (the HD) then I
can lock and unlock it but the extensions install check returns an error??
Theory - could this be because of thunking?  If the drive number is not being passed to
the Int function properly then 00 might work but anything else is scrambling the bits?
I have tried it on two separate machines with different bios's and HD's with exactly the same results so I don't think it's a bios problem.
So what's thunking?

Regards,

JohnE
0
 
LVL 5

Expert Comment

by:inter
ID: 1343592
The thunking is a mechanism to call 16bit DLL functions from within your 32 bit native code.

|32 bit APP|---->|16 bit thunk DLL|----->|16 bit DLL that performs the required operations|

You may ask why we can not call the required functions directly from 32 bit APP. For int 13 we should call DPMI functions which is not allowed by the design of the Win95. So we can only call then in asm from 16 bit code. There are several methods of thunking but the best way for win95 is to use so called 'flat thunking' with the 'undocumented' method. I have long ago learn this from one of the friends. If we use that undocumented function exported by kernel32 (callled QT_Thunk) we do not need to write 16 bit thunkDLL. So what should we do is:

1 - Create 16 bit DLL that calls the DPMI and emulates int 13 call
2 - Link that dll into our 32 bit app with QT_Thunk

Questions:
1 - Do you have 16 bit compiler (such as delphi 1.x, BC 4.5) etc...?
2 - Do you have any questions regarding the mechanism?

regards, igor (please do not disapointed we can make this out but I have no 16 bit compiler by now)
0
 
LVL 1

Author Comment

by:jellison
ID: 1343593
Igor,

Sorry for the delay in reply but I think the server crashed and then the net was impossibly
slow yesterday. Anyway - I do have Delphi1 and even an old TP6 somewhere but I would
like to take a step back before launching into thunking.
Where did you get the info that the Int13  calls need thunking? I have been posting a few
questions around and looking at web sites & help files, and you are the only one who has said it's required. Having said that, you have also given the most time & effort to solving the problem so please don't take it as a crticism - I just want to be sure before spending a lot of time, effort (and I suspect pain) on thunking.
Regards,
JohnE
0
 
LVL 20

Expert Comment

by:Madshi
ID: 1343594
You don't need thunking to call int13 in 32bit windows. You just CANNOT call int13 in 32bit windows - with thunking or without thunking.
So you have to call that int13 in a 16bit dll. That will work. But it doesn't solve all problems, because now is the question: How can you call the 16bit dll from your 32bit application. "LoadLibrary" and that stuff won't work.
And this is exactly the point, where you need thunking. With thunking you can't call int13. But with thunking you can call a 16bit dll. And this 16bit dll can call int13.
Everything unclear now?   :-)
0
 
LVL 1

Author Comment

by:jellison
ID: 1343595
Very unclear!  I understand what you are saying but..  I refer you to the Win32 Help file (not sure which version but I'm pretty sure it's OSR2). There is a page headed "Using VWIN32 to Carry Out MS-DOS Functions" which explains about using Vwin32.vxd. That documents a control code value "VWIN32_DIOC_DOS_INT13 (4)      Performs Interrupt 13h commands.". Now I can call Int13 using this mechanism and read a floppy disk - so presumably it does what it says?  Nowhere in the pages regarding Vwin32 does it say anything about thunking?  It does talk about needing to lock devices but it's not very clear. That's why I'm not sure about thunking.
Now, there are a number of virus progs out there which run under W95 and check the Master Boot Record which (as I understand it) is outside the normal logical partitions and therefore needs direct access to the disk. So how do they do it?
Regards,
JohnE
0
 
LVL 20

Expert Comment

by:Madshi
ID: 1343596
Ooops. I looked in my win32 help file. I know, some time ago there were these infos. But now I've Delphi 4 and I don't find "Using VWin32".
I trusted in Igor. He said you need thunking for int13. Perhaps he is wrong. What I wanted to say in my last comment is that you don't need thunking for calling interrupts, but for calling a 16 bit dll.
Ok, I've copied some sources from our sources at work. Psst. Please don't tell my boss about this...
With these functions you can test if the given drive has a partition table. Hope, this helps. We don't use int13 at all. Don't know if we just don't need it, or if it doesn't work. But - if it stands in your win32 help file - it should really work - and without thunking.

function DosInt25(var reg : TReg; txt : string) : boolean;
const VWIN32_DIOC_DOS_INT25 = 2;
var s1 : string;
    cb : DWORD;
    hq : THandle;
    b  : boolean;
begin
  result:=false;
  hq:=CreateFile('\\.\vwin32', 0, 0, nil, 0, 0, 0);
  if hq=INVALID_HANDLE_VALUE then
    begin AlertError('Öffnen Treiber',LastErrStr); exit; end;
  try
    s1:='';
    b:=DeviceIoControl(hq, VWIN32_DIOC_DOS_INT25,
                      @reg, sizeof(reg), @reg, sizeof(reg), cb, nil);
    if (not b) or odd(reg.reg_Flags) then begin
      if reg.reg_EAX<>$8002 then AlertError(txt,'AX:'+IntToHex(reg.reg_EAX,4))
      else                       AlertError(txt,'Es ist keine Diskette eingelegt.');
      exit;
    end;
  finally CloseHandle(hq) end;
  result:=true;
end;

function TestPartTable(drive: char) : boolean;
var bu    : TFATBootSec;
    para  : packed record
             esec   : cardinal;
             anzsec : word;
             buf    : DWORD;
           end;
    reg   : TReg;
    hq    : THandle;
    anz,e : cardinal;
begin
  result:=true; exit;
  result:=false;
  AddExcStack([unitName,'TestPartTable']);
  try try
    drive:=Upcase(drive); if (drive<'A') or (drive>'Z') then exit;
    zeroMemory(@bu,sizeof(bu)); bu.hidd:=1;
    if GetOperatingSystem=osWinNT4 then begin
      hq:=CreateFile(PChar('\\.\'+drive+':'),GENERIC_READ or GENERIC_WRITE,
                               FILE_SHARE_WRITE or FILE_SHARE_READ,NIL,
                               OPEN_EXISTING,0,0);
      try
        if hq=INVALID_HANDLE_VALUE then
          begin AlertError('Öffnen '+Drive,LastErrStr); exit; end;
        (*AlertInfo('Size bu:'+IntToStr(sizeof(bu)));*)
        if not ReadFile(hq,bu,sizeof(bu),anz,nil) then begin
          e:=GetLastError;
          (*AlertError('ReadErr '+Drive,WinErrStr(e)+' '+IntToStr(e));*)
          if e<>87 then begin
            AlertError('Read '+Drive,WinErrStr(e)); exit;
          end;
        end;
      finally
        CloseHandle(hq);
      end;
    end else begin
      hq:=CreateFile('\\.\vwin32', 0, 0, nil, 0, 0, 0);
      if hq=INVALID_HANDLE_VALUE then
         begin AlertError('Öffnen '+Drive,LastErrStr); exit; end;
      try
        with para do begin
          esec:=0; anzsec:=1;
          buf :=DWORD(@bu);
        end;
        with reg do begin
          reg_ECX:=$FFFF;
          reg_EAX:=ord(drive)-ord('A');     // zero-based drive ID
          reg_EDX:=DWORD(@para);
          reg_EBX:=DWORD(@para);
        end;
        if not DosInt25(reg,'Lese Bootsektor (Laufwerk '+drive+':).') then exit;
      finally
        CloseHandle(hq);
      end;
    end;
    (*AlertInfo('hidd:'+IntToStr(bu.hidd)+', booter:'+IntToStr(bu.booter[0]));*)
    result:=(bu.hidd=32) or ((bu.hidd=0) and (bu.booter[0]=0));
    if not result then
      AlertInfo('Die MO-Diskette im Laufwerk '+drive+': hat noch keine|'+
                'Partition-Table!||'+
                'Bitte zuerst mit dem NT-Festplatten-Manager auf dieser|'+
                'MO-Diskette eine "Partition" "erstellen"!');
  except ExceptionProc end finally DelExcStack end;
end;

Regards, Madshi.

P.S: Remove the lines where the compiler stops...
0
 
LVL 1

Author Comment

by:jellison
ID: 1343597
Thanks guys. I appreciate the last message but again it uses int25 which relies on there being a FAT partition of some kind.

I have posted messages all over the place with no success. I have to come to the conclusion that either MS are lying (surely not :-)) or vwin32 is buggy and because it's such an unusual thing to want to do, no-one has noticed or cares?

I really do appreciate your time on this and the acception mark acknowledges that - even if I have to admit defeat.

Regards,
JohnE
0
 
LVL 5

Expert Comment

by:inter
ID: 1343598
Lets take it easy friend. One day there will be no need to cheat in every occasion on WEIRD operating systems. Some team will surely give us fully documented OS we all hope...
igor
0

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Objective: - This article will help user in how to convert their numeric value become words. How to use 1. You can copy this code in your Unit as function 2. than you can perform your function by type this code The Code   (CODE) The Im…
Hello everybody This Article will show you how to validate number with TEdit control, What's the TEdit control? TEdit is a standard Windows edit control on a form, it allows to user to write, read and copy/paste single line of text. Usua…
This demo shows you how to set up the containerized NetScaler CPX with NetScaler Management and Analytics System in a non-routable Mesos/Marathon environment for use with Micro-Services applications.
When you create an app prototype with Adobe XD, you can insert system screens -- sharing or Control Center, for example -- with just a few clicks. This video shows you how. You can take the full course on Experts Exchange at http://bit.ly/XDcourse.

707 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now