Link to home
Start Free TrialLog in
Avatar of Gwena
Gwena

asked on

Has anyone here ever used these components???

I have been trying to find a freeware component or some source code to let me read/write to disk sectors under NT
...so far no luck at all :(   But I found 2 shareware components at http://hey.to/ants  that look like they might work...   they are TFloppyFormat  and TDirectDisk   they cost 25$ each....I was wondering if anyone has used them..and if so..did they perform with NT?  I don't have access to a computer running NT so I can't tell if the downloaded demo works or not :(  and I can't email a test program to a friend with NT because the demo only works if Delphi is running :'(

I sure wish I could find some freeware code...or better yet I wish I could write it myself :)
Avatar of viktornet
viktornet
Flag of United States of America image

hmm.... why don' you try DeviceIoControl().. that might help you do low level stuff....
Avatar of rwilson032697
rwilson032697

DeviceIoControl is fine if you want to format etc a device, but I don't think its up to directly accessing disk sectors. This is a BIG no no in NT - I suspect nothing short of a device driver is going to do this for you.

Cheers,

Raymond.

som etime ago i received help from madshi re: reading/writing sectors from floppy. i've tuned it up a little bit and came out w/ a floppy imager.
it runs on nt. it uses deviceiocontrol. & it worx, ray.

u can post ur email-address, gwena - i'll send the code over 2 ya. u can have a look at it & decide if it's useful.

regards,

BlackDeath.
gwena: i have source code for directly writing to floppy disk under nt. it is from a tool that i wrote to produce image files of my boot floppies. here it goes:

>>>>>> 

unit DiskImage;

interface

uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;

type
  TDiskGeometry = record
    Cylinders: DWORD;
    CylindersHi: DWORD;
    MediaType: DWORD;
    TracksPerCylinder: DWORD;
    SectorsPerTrack: DWORD;
    BytesPerSector: DWORD;
  end;

  TOnProgressEvent = procedure(percent: integer) of object;
   
  TDiskImage = class(TObject)
    private
      FOnProgress: TOnProgressEvent;
      procedure DoShowProgress( percent: integer );
    public
      function ReadImage( lw, fname: string ): Integer;
      function WriteImage( lw, fname: string ): Integer;
      property OnProgress: TOnProgressEvent read FOnProgress write FOnProgress;
  end;

const VWIN32_DIOC_DOS_INT25 = 2;
      VWIN32_DIOC_DOS_INT26 = 3;
      IOCTL_DISK_GET_DRIVE_GEOMETRY = 7 shl 16;

      DISKIMAGE_SUCCESS = 0;
      DISKIMAGE_ILLEGAL_DRIVE = 1;
      DISKIMAGE_ILLEGAL_FILENAME = 2;
      DISKIMAGE_DRIVE_ACCESS_ERROR = 3;
      DISKIMAGE_ILLEGAL_IMAGE = 4;

implementation

procedure TDiskImage.DoShowProgress(percent: integer);
begin
  if Assigned(FOnProgress) then
    FOnProgress(percent);
end;

{
Create Image
}
function TDiskImage.ReadImage( lw, fname: string ): Integer;
  var hDrive, hImage: THandle;
      fResult: Boolean;
      cyl, dwSize, DriveSize, dwRead: DWORD;
      dgDrive: TDiskGeometry;
      buf: array[ 0..65535 ] of char;
  begin
    if NOT ( UpperCase( lw )[ 1 ] in [ 'A', 'B' ] ) then begin
      result := DISKIMAGE_ILLEGAL_DRIVE;
      exit;
    end;
    if lw[ length( lw ) ] <> ':' then lw := lw + ':';
    hDrive := CreateFile( PChar( '\\.\' + lw ), GENERIC_READ, FILE_SHARE_READ, nil,
               OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL + FILE_FLAG_SEQUENTIAL_SCAN, 0 );
    if hDrive = INVALID_HANDLE_VALUE then begin
      result := DISKIMAGE_ILLEGAL_DRIVE;
      exit;
    end;
    hImage := CreateFile( PChar( fname ), GENERIC_WRITE, FILE_SHARE_WRITE, nil,
              CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL + FILE_FLAG_SEQUENTIAL_SCAN, 0 );
    if hImage = INVALID_HANDLE_VALUE then begin
      result := DISKIMAGE_ILLEGAL_FILENAME;
      exit;
    end;
    fresult := DeviceIoControl( hDrive, IOCTL_DISK_GET_DRIVE_GEOMETRY,
      nil, 0, @dgDrive, sizeof( dgDrive ), dwRead, nil );
    if fresult then begin
      if dgDrive.mediaType > 11 then begin
        result := DISKIMAGE_ILLEGAL_DRIVE; // not a Floppy
        exit;
      end;
      dwSize := dgDrive.BytesPerSector * dgDrive.SectorsPerTrack *  dgDrive.TracksPerCylinder;
      //DriveSize := dgDrive.Cylinders * dwSize;
      cyl := 0;
      while ( cyl < dgDrive.Cylinders ) and fresult = true do begin
        fresult := ReadFile( hDrive, buf, dwSize, dwRead, nil );
        if fresult then fresult := WriteFile( hImage, buf, dwRead, dwRead, nil );
        inc( cyl );
        DoShowProgress( cyl * 100 div dgDrive.Cylinders );
      end;
      if cyl = dgDrive.Cylinders then result := DISKIMAGE_SUCCESS
        else result := DISKIMAGE_DRIVE_ACCESS_ERROR;
    end else result := DISKIMAGE_DRIVE_ACCESS_ERROR;
    CloseHandle( hImage );
    CloseHandle( hDrive );
  end;

{
Write Image to FDD
}
function TDiskImage.WriteImage( lw, fname: string ): Integer;
  var hDrive, hImage: THandle;
      fResult: Boolean;
      cyl, dwSize, DriveSize, dwRead: DWORD;
      dgDrive: TDiskGeometry;
      buf: array[ 0..65535 ] of char;
  begin
    if NOT ( UpperCase( lw )[ 1 ] in [ 'A', 'B' ] ) then begin
      result := DISKIMAGE_ILLEGAL_DRIVE;
      exit;
    end;
    if lw[ length( lw ) ] <> ':' then lw := lw + ':';
    hDrive := CreateFile( PChar( '\\.\' + lw ), GENERIC_WRITE, FILE_SHARE_WRITE, nil,
               OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL + FILE_FLAG_SEQUENTIAL_SCAN, 0 );
    if hDrive = INVALID_HANDLE_VALUE then begin
      result := DISKIMAGE_ILLEGAL_DRIVE;
      exit;
    end;
    hImage := CreateFile( PChar( fname ), GENERIC_READ, FILE_SHARE_READ, nil,
              OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL + FILE_FLAG_SEQUENTIAL_SCAN, 0 );
    if hImage = INVALID_HANDLE_VALUE then begin
      result := DISKIMAGE_ILLEGAL_FILENAME;
      exit;
    end;
    fresult := DeviceIoControl( hDrive, IOCTL_DISK_GET_DRIVE_GEOMETRY,
      nil, 0, @dgDrive, sizeof( dgDrive ), dwRead, nil );
    if fresult then begin
      if dgDrive.mediaType > 11 then begin
        result := DISKIMAGE_ILLEGAL_DRIVE; // not a Floppy
        exit;
      end;
      dwSize := dgDrive.BytesPerSector * dgDrive.SectorsPerTrack *  dgDrive.TracksPerCylinder;
      DriveSize := dgDrive.Cylinders * dwSize;
      dwRead := GetFileSize( hImage, @cyl );
      if DriveSize <> dwRead then begin
        result := DISKIMAGE_ILLEGAL_IMAGE; // wrong size of image
        exit;
      end;
      cyl := 0;
      while ( cyl < dgDrive.Cylinders ) and fresult = true do begin
        fresult := ReadFile( hImage, buf, dwSize, dwRead, nil );
        if fresult then fresult := WriteFile( hDrive, buf, dwRead, dwRead, nil );
        inc( cyl );
        DoShowProgress( cyl * 100 div dgDrive.Cylinders );
      end;
      if cyl = dgDrive.Cylinders then result := DISKIMAGE_SUCCESS
        else result := DISKIMAGE_DRIVE_ACCESS_ERROR;
    end else result := DISKIMAGE_DRIVE_ACCESS_ERROR;
    CloseHandle( hImage );
    CloseHandle( hDrive );
  end;

end.

<<<<<<<<<<<<<<<<<<<<<

HTH,
freter
AAAAAGH! - FRETE! - SORRY!!!

in my f***in muddy brain i remembered madshi, but it's been U!
pleeze accept my apology 4 mixin u up...

btw: the imager runs perfectly well.
still problems on 9x...

anyway
h.a.n.d!

BlackDeath.

Avatar of Gwena

ASKER

Hi Blackdeath :-)

  Gosh..it sounds like you wrote a program a lot like the one I'm struggling to write..
I'm attempting to create a program that makes  stand-alone .exe files that contain within them the image of an entire 1.44 floppy... and when run can reproduce this onto a blank floppy....PLEASE! please send me your code so I can learn from it!
this is my first big project and I'm really sweating over it....I'm going to release it as freeware (if I can finish it ;-) I have managed to figure out how to read/write all the sectors under W9x  but not NT :(  I have figured out how to write a new small exe file that can write the sectors from compressed data that is packed inside it. my email is  gwena@gurlmail.com  I will be waiting eagerly to see your source code :)
and if you want to see what my program is going to look like you can download a small exe file that will give you an idea.... I'm brand new to delphi and programming so don't laugh too hard at how my program looks ;-) I kinda got carried away with
the graphics!  My cousin loves the way it looks (she's 4)  check it out... it's a real
hoot!  here is the link to it ..its 118k

http://www.gurlpages.com/computer/gwena/images/a2exe14.exe

Also...many thanks to freter for posting the source code above !  I will see if I can get it figured out.... you must be pretty good at delphi if you have figured out a way to write to floppy sectors in NT!  I have been asking everyone how to do this and you are the first who seems to have a handle on it......


p.s.
 
Avatar of Gwena

ASKER

Hmmm my ps was deleted from the above comment..

I was gonna ask if I can have the source for the complete program
that uses the unit source listed above.. the application you use to
make the images..I'm a newbie and I need to see exactly how things
are handled..... pretty please :-)

I am using delphi 2 but I have a copy of delphi 3standard a guy gave me as a
hand-me-down and I could load that up too....

...Gwen
no prob, gwena - i'll send it over 2morrow (it's resting @home ... ;-))

but - as i stated above - in the times i wrote that thing i was only able 2 do so, because frete gave me appropriate hints.

so - if u'r gonna accept that project i'm gonna send ya as an answer, we will have 2 let frete have his share, ok?

2morrow then, so far-

BlackDeath.
Avatar of Gwena

ASKER

Ok BlackDeath :)

I'm grateful for your help.. I'll be waiting for the code you used to call the routines in that unit......... I have been playing with that 25$ component that can write sectors
on the floppy in NT... it is way easy to use...BUT.. for some reason it works VERY
slowly :(  I'm certain it's me.. and not the component... I must be missing a piece of the puzzle somewhere... if I fill a 512 byte array and simply write that to each sector 0 through 2879 it take 34 minutes!  eeeeeek!  I am wondering if it takes a special formula to get maximum speed writing sectors... maybe  1 2 3 4 5....
is not the right pattern...maybe the disk has moved past the beginning of the next sector before you can write it and has to spin around to come to the next one..hmmm... maybe I will try 1 3 5 7 9 11 13 15 17  and then 2 4 6 8 10 12 14 16 18... maybe it could then catch the sector beyond  the next sector.. without having to spin around....   man-o-man this project is getting VERY complicated ;-) maybe I can find some info on the web about floppies...

....Gwen
uh-oh. gwena. it's monday already & i've not been @home this weekend. the prob is, i've got a flat in the city & a house w/ my girlfriend some 15 kilometers in the country. there i'm the whole weekend & most of the week. but 2day, i promise!, i'm drivin 2 my flat & get the source 4 fdd imager.
i'm very sorry. i hope u don't suffer from this delay 2 much ...

til 2 morrow,

BlackDeath.
gwena, here is some code that shows how to use the component i listed above:
>>>>>>>>>>>>>>>>>>>>>
program DiskImageTest;

uses SysUtils,
     DiskImage in 'DiskImage.pas';

var DI: TDiskImage;
    res: integer;

begin
  if ( paramstr(1) = '/?' ) or ( paramcount < 3 ) then begin
    writeln('diskgen v1.0 (c) 1999 freter ');
    writeln('-------------------------------------');
    writeln('usage:');
    writeln('diskgen /read d: imgname');
    writeln('diskgen /write d: imgname');
    writeln('where d: is the fdd you want to image');
    writeln('and imgname is the nameof the imagefile.');
    writeln('/read creates the image, whereas');
    writeln('/write will write it back to disk');
    halt(0);
  end
  else if ( uppercase(paramstr(1)) = '/WRITE' ) then begin
    DI := TDiskImage.Create;
    res := DI.WriteImage( paramstr(2), paramstr(3) );
    DI.Free;
  end
  else  if ( uppercase(paramstr(1)) = '/READ' ) then begin
    DI := TDiskImage.Create;
    res := DI.ReadImage( paramstr(2), paramstr(3) );
    DI.Free;
  end;

end.
<<<<<<<<<<<<<<<<<<<<<<<<<

HTH,

<freter>
BD: no sweat, it's an honour to be mixed up with madshi :-)
<freter>
Avatar of Gwena

ASKER

Hi BlackDeath :)

" w/ my girlfriend some 15 kilometers in the country. there i'm the whole
      weekend & most of the week. "

Sounds like you have your priorities set just as they should be :) It is MUCH more important to be w your gf than to send out a bit of source code!  Keep up the good work ;-)

..Gwen..

p.s It's not a huge rush for this code...I'm still working on other parts of this project.... Struggling to figure out how to open files and place them into ram instead of making temporary copies on disk .... filestream and mem stream sort of thingies :)  very tough stuff for a newbie to sort out....
Avatar of Gwena

ASKER

Hi Freter :)

Thanx for the additional info!

If I can get this code of yours to work in my project I will give you credit for the
disk sector reading code .... I will mention you in the about box :)  You should
re-work this into a component and put it up at Torry's and Superpage!  A free
component that can read sectors from the floppy.. under 9x and NT would be
very hot....
It could have properties like these...

DriveName: char;                            A or B
StartSector: Integer;                        0 to 2879
Sectors: Integer;                              1 to 2880
Retries: Byte;                                 maybe 1 to 10
LockDrive: Boolean                        

I have looked at the code I have to read sectors under 9x   I can't figure out
why it only works under 9x and why yours handles NT ????? what is the
difference???

What I'm trying to do is this... Read in all the sectors into memory... compress them using a freeware compression component I found... then adding this compressed data to a new exe file...for a stand alone program that can re-create the original disk... So far all I can do is read the sectors in and store them to a temporary file on disk...then compress this data..and add it to the new exe file...
but only under 9x :(   oh well.... This is my first attempt at a real project with delphi...... I'll be lucky if I can get it to work right even under 9x only..... :)

..Gwen..  



Avatar of Gwena

ASKER

"BD: no sweat, it's an honour to be mixed up with madshi :-)
      <freter>"

Yuppers!... that Madshi is extremely clever!  ... Wonder what he does for a living??
madshi still is student of (something technical), AFAIK.

BTW: thanks for mentioning in the about-box. how about sending me a copy of your app? sounds as if you were a sysadm... that's the kind of people who need such programs the most :-)

<freter>
Avatar of Gwena

ASKER

Hi freter :)

.. Nope,  not a sysadm... I'm just a newbie trying to learn Delphi and assembly language....I started out trying to learn ms C++ 4.0 :( it was AWFUL... luckily
someone took pity on me and gave me some handme down Borland stuff...old
copies of Pascal and Delphi :)   the Pascal box had TASM 2.0 in it so I'm learning
that too....it's funny but I find the assembly easier than the Delphi.... there are
only a few instructions...and the documentation is complete and I can follow it
easier than the Delphi books....each instruction does just an itty-bitty-bit.. so it's
simple to follow...and it's FAST! ... I am amazed at how many things it can do
in just a split second....... I'm still trying to get your disk read/write code to run..
I'm sure it's me and nothing wrong with the code... I tried to install it as a component but D2 and D3 choked on it... I seem to have all sorts of probs installing components :(    anyways..I have my code running with a disk routine a guy sent me from the swag files..it works but not under NT :(  there is a shareware component I have running also..it is really easy to use but I'd need to send the guy 25$ for the priviledge...I guess he's earned it tho cause I bugged him a few x via email ;-)


The reason I decided on a disk imager is I was using a program called WinImage to create stand alone exe files that I could send my cousin so she could see what my latest asm code could do...well it expired and when I discovered they wanted 60$ for the ver that makes exe's I decided this would be a good project..
..... I will let you know where I upload my app once it's done (if it ever is)


Gwena, I've been learning ASM too, so if you need some help with it I'll help you :) Also, I don't know at what level you're so if you;re better than me you could either help me or we could work together on it :o)

..-=ViKtOr=-..
Avatar of Gwena

ASKER

Hi Viktor :)

   I'm no WhizKid yet at asm...but I can do ez things like load/save sectors from the floppy ... all in asm... and I can write a small program that controls the printer
ports and make led's blink....(how incredibly geeky I'm getting ;-)  I can alter the clock from 18.2 to 10,000 and do hi-res timing (how useless is this ;-) and I have written an interupt service routine (that does nothing but print my name to the screen) and placed it's address into the interupt table.....I write com files and use
the freebie dos from caldera to run them from a floppy.... i test my asm stuff only on an old junkie computer... i'm scared they might blow up my real computer :) I use tasm  but someone told me the other day that ms was giving away masm....
I'd love to find out where to get a copy.....I think asm is MUCH easier to play with than Delphi.... it's rules are so simple and precise... I am constantly confused about what is going on in Delphi :(  If I ever manage to really understand delphi I'm going to write a help file for the clueless :)  There needs to be a good FAQ that has demos of how to do geeky things like read/write sectors, get data from a file into memory and USE it, how to easily attach another exe to your exe and modify it and save it to disk (so you can create stand-alone exe's) , control the ports, get data from a file on the internet easily, read memory locations... gee this is hard in Delphi and SO easy in asm, format a diskette. and lots more things......

I'm sure your WAY ahead of me in asm... and I'd love to get some help  :)

..Gwen..  
gwena: the source i posted here is NOT a component! thus, you simply cannot install it to the component palette :-) rather, it is a simple object and must be created by writing something like DI := TDiskImage.Create;

HTH,
<freter>
   
Avatar of Gwena

ASKER

Hi Freter  :)

Oh... I was confused by what you said earlier..
"gwena, here is some code that shows how to use the component i listed above:"
......................So I thought maybe it was a component :)

You guys have been so helpful here trying to get this to soak into my newbie brain...I'm gonna have to give you both (Freter, BlackDeath) 10 points....
(sorry it's so miserly...I used 300 points on a big question to Madshi and I have a LOT more q's I need to ask ;-)
hi, gwena.

finally i've managed 2 send the sources over 2 ya.
tell me if it worx all rite.

bye,
BlackDeath.
Avatar of Gwena

ASKER

Hi BlackDeath :)

  I can't seem to get into my email account.. or access my web page :(
grrrrrrrr it serves me right for putting my email and web page on a server
that is so cutesie that it bills itself as 'just for gurls' I should have known better :(
Hopefully they will solve their probs and I can retrieve my mail and stuff...then
I'm moving it all to better quarters at yahoo or somesuch.... I wrote a little program
that checks your IP and put the link up at NONAGS freeware site pointing to the file on my website..... now that link is broken too :'(   what a !@#$ pain.....

..Gwen..
Avatar of Gwena

ASKER

Ok BD :)
I finally got my email and the files you sent came thru fine :)
I am chekin em out... thanx for sending the exe as well!
Maybe looking at the source for a working exe will help me
get things straight in my mind :)

...Gwen...
Avatar of Gwena

ASKER

BD.. I guess I better close this thread...it's getting to be as long as
War and Peace :)  why don't you send an answer and I will give you
a well deserved A and my 10 stingy points ;-)

..Gwen..

Somehow I need to send freter 10 points as well...hmmm.. how 2 doo?

gwena: for splitting points, the experts are used to the following procedure:
1) open a second question, titled "Points for <name of expert>, Q<reference number of original question>, put in some text for explanation (for the ones reading this question when it is in the PAQ list) and ssign the desired amount of points to it.
2) let one expert answer the original question
3) the second expert answers the additional "dummy" question.
4) now you have to rate both of the answers.
Hint: experts are especially fond of "A rates" :-) and do strongly disklike C or D rates. So, before rating worse than B, better think about not rating a question at all :-)

<freter>

PS: I really would appreciate receiving a copy of your app (when you have finished). You can put it in my box at freter@gmx.net.
'ere u r.
h.a.n.d.
;-)
BlackDeath.
ASKER CERTIFIED SOLUTION
Avatar of BlackDeath
BlackDeath

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Gwena

ASKER

Thanx again BD :)
I'll let u know when (if) I finish this app :)