Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Reading floppy disks at the track/sector level

324 views
Skip to first unread message

Frank LaRosa

unread,
May 31, 2000, 3:00:00 AM5/31/00
to
Hello,

I have some floppy disks that I would like to access and read sector for
sector, rather than through the file system. Is this possible in Win32
without writing a driver? The last time I did anything like this was in the
good old days of MS-DOS and INT 21. Now I'm using NT 4.

In case you're wondering, no, I'm not trying to concoct some retro-80's copy
protection scheme, I'm just trying to read some disks from my venerable
TRS-80 Model 3. It uses the same type of drive as old PCs so I'm sure the
drive can read the disk, but I know Windows won't make anything of the file
system. Thanks for any help you can provide.

Frank

Slava M. Usov

unread,
Jun 1, 2000, 3:00:00 AM6/1/00
to
Frank LaRosa <fr...@franklarosa.com> wrote in message
news:OFivwV2y$GA.197@cppssbbsa05...

The following program will read the whole floppy and write its contents to a
file. Run from the command line:

flop \\.\A: c:\floppy.image

The standard NT floppy driver does expect the floppy to be low level
formatted in a standard way, anything exotic, and it will reject it.

#include <iostream>
#include <windows.h>
#include <winioctl.h> // for IO control codes & structures
using namespace std;

// only works for small disks,
// will produce bogus results for
// modern hard drives
inline DWORD GetDiskSize(HANDLE h)
{
DWORD bytes;
DISK_GEOMETRY geo;
BOOL status = DeviceIoControl(
h,
IOCTL_DISK_GET_DRIVE_GEOMETRY,
0, 0, // no input buffer
&geo, sizeof(geo),
&bytes,
0
);
if( status )
{
return geo.BytesPerSector
* geo.SectorsPerTrack
* geo.TracksPerCylinder
* geo.Cylinders.QuadPart;
}

return 0;
}

int main(int argc, char **argv)
{
if( argc != 3 )
{
cout << "usage: <device name> <file name>" << endl;
return __LINE__;
}

// prevent "drive not ready", etc
// messages from system
// we want just error codes
SetErrorMode(SEM_FAILCRITICALERRORS);

// open device "\\.\A:", this is how one
// specifies first floppy under NT
HANDLE h = CreateFile(
argv[1],
GENERIC_READ,
FILE_SHARE_READ,
0,
OPEN_EXISTING,
FILE_FLAG_NO_BUFFERING,
0
);
if( h == INVALID_HANDLE_VALUE )
{
DWORD err = GetLastError();
cout << "Can't open floppy. " << err << endl;
return __LINE__;
}

DWORD size = GetDiskSize(h);
if( !size )
{
DWORD err = GetLastError();
cout << "Can't get disk size. " << err << endl;
return __LINE__;
}

// allocate page-aligned buffer
LPBYTE buf = (LPBYTE)VirtualAlloc(0, size, MEM_COMMIT, PAGE_READWRITE);
if( buf == 0 )
{
DWORD err = GetLastError();
cout << "Can't allocate buffer. " << err << endl;
return __LINE__;
}

// read entire disk
// if only particular sectors are needed,
// use SetFilePointer() to skip
DWORD bytes;
if( !ReadFile(h, buf, size, &bytes, 0) )
{
DWORD err = GetLastError();
cout << "Can't read disk. " << err << endl;
return __LINE__;
}

if( bytes != size ) // shouldn't happen
{
cout << "Couldn't read all data." << endl;
return __LINE__;
}

CloseHandle(h);

h = CreateFile(
argv[2],
GENERIC_WRITE,
0, // no sharing
0,
CREATE_ALWAYS,
FILE_FLAG_NO_BUFFERING,
0
);
if( h == INVALID_HANDLE_VALUE )
{
DWORD err = GetLastError();
cout << "Can't open " << argv[2] << ". " << err << endl;
return __LINE__;
}

// get image size rounded to page boundary
MEMORY_BASIC_INFORMATION mbi;
if( !VirtualQuery(buf, &mbi, sizeof(mbi)) )
{
DWORD err = GetLastError();
cout << "Can't get buffer info. " << err << endl;
return __LINE__;
}

if( SetFilePointer(h, mbi.RegionSize, 0, FILE_BEGIN) != mbi.RegionSize )
{
DWORD err = GetLastError();
cout << "Can't extend file. " << err << endl;
return __LINE__;
}

if( !SetEndOfFile(h) )
{
DWORD err = GetLastError();
cout << "Can't set end of file. " << err << endl;
return __LINE__;
}

if( SetFilePointer(h, 0, 0, FILE_BEGIN) )
{
DWORD err = GetLastError();
cout << "Can't set file pointer. " << err << endl;
return __LINE__;
}

if( !WriteFile(h, buf, mbi.RegionSize, &bytes, 0) )
{
DWORD err = GetLastError();
cout << "Can't write file. " << err << endl;
return __LINE__;
}

if( mbi.RegionSize != bytes ) // shouldn't happen
{
cout << "Couldn't write all data. " << endl;
return __LINE__;
}

CloseHandle(h);

if( mbi.RegionSize == size ) return 0;

// now reopen the file and set its size to the exact image size
h = CreateFile(
argv[2],
GENERIC_WRITE,
0, // no sharing
0,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
0
);
if( h == INVALID_HANDLE_VALUE )
{
DWORD err = GetLastError();
cout << "Can't reopen " << argv[2] << ". " << err << endl;
return __LINE__;
}

if( SetFilePointer(h, size, 0, FILE_BEGIN) != size )
{
DWORD err = GetLastError();
cout << "Can't reduce file. " << err << endl;
return __LINE__;
}

if( !SetEndOfFile(h) )
{
DWORD err = GetLastError();
cout << "Can't set end of file. " << err << endl;
return __LINE__;
}

return 0;
}


--

Slava

Please send any replies to this newsgroup.
microsoft.public.win32.programmer.kernel


Frank LaRosa

unread,
Jun 1, 2000, 3:00:00 AM6/1/00
to
Thanks....

I tried most of last night using a file handle obtained by \\.\A: and all I
could come up with was error 27, "sector not found".

On further examination, I realized that my floppy disks are not formatted
the same was as regular windows disks. The disk I have has 256-byte sectors,
whereas the standard windows disk has 512-byte sectors.

So it looks like I need some way to either inform the existing driver to
read the disk differently or else a way to get at the hardware of the drive
controller itself, assuming it's even capable of reading this format.

Harder than I thought!

Frank

Slava M. Usov

unread,
Jun 1, 2000, 3:00:00 AM6/1/00
to
Frank LaRosa <fr...@franklarosa.com> wrote in message
news:uuZ2MW9y$GA.276@cppssbbsa05...

It is. You can:

1. Write a driver that will read such non-standard sectors and replace the
standard NT driver. If you have the NT DDK, and know *in details* the format
of your old floppies, it may even be trivial, to modify the source of the
standard driver and rebuild it.
2. Write a driver that will talk to the controller hardware and respond to
interrupts as directed by your application, and write an application that
will drive this driver :-)
3. Make sure you have the SeTcbPrivilege, unload the floppy driver, and
write an application that will talk to the hardware directly. You won't be
able to handle interrupts and DMA, though, and I have long forgotten if you
can read floppies without that.

I think the standard hardware is able to cope with such formatting, as I
still remember the proliferation of copy-protection schemes relying on that.

Frank LaRosa

unread,
Jun 1, 2000, 3:00:00 AM6/1/00
to
Thanks again for your help. I'd like to take a crack at modifying the
existing driver, sounds easier than writing my own. Is the source for that
part of the DDK? Is it C or assembler?

Any books you can recommend for a beginning driver programmer?


0 new messages