/*
* WinSOS NT utility for writing image files to floppy.
*
* Toomas Kiisk <
[email protected]>, Mar 27 1999
*
* This program is provided AS IS, with NO WARRANTY, either
* expressed or implied.
*
* This program or parts of it may be used, reused, abused,
* misused and disused for any purpose that is legal in
* your country. Names of the author and contributors may not
* be used to promote products derived from this software.
* Redistribution is not limited.
*
*
* Last modified Apr 1 1999
* some cleanups, 2 (harmless) bugs fixed and new ones
* introduced, of course :)
*
*
*/
#include <windows.h>
#include <winioctl.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
unsigned long int dummy_variable_for_that_stupid_ioctl_function;
#define dummy dummy_variable_for_that_stupid_ioctl_function
#define LOCK_DRIVE( x ) ( DeviceIoControl( x, FSCTL_LOCK_VOLUME, \
NULL, 0, NULL, 0, &dummy, NULL ) )
#define UNLOCK_DRIVE( x ) ( DeviceIoControl( x, FSCTL_UNLOCK_VOLUME, \
NULL, 0, NULL, 0, &dummy, NULL ) )
#define GET_GEOMETRY( x, y ) ( DeviceIoControl( x, IOCTL_DISK_GET_DRIVE_GEOMETRY, \
NULL, 0, y, sizeof( *y ), &dummy, NULL ) )
HANDLE src = INVALID_HANDLE_VALUE, dst = INVALID_HANDLE_VALUE;
unsigned char *buf = NULL;
unsigned int bufsize;
void die( int r, char *fmt, ... );
void usage_exit( char *arg0 );
int main( int argc, char *argv[] )
{
char dev[7], *fn;
DISK_GEOMETRY g;
OSVERSIONINFO v;
unsigned long br, bw, bwt;
v.dwOSVersionInfoSize = sizeof( OSVERSIONINFO );
if ( ! GetVersionEx( &v ) )
die( 2, "GetVersionEx()" );
if ( v.dwPlatformId != VER_PLATFORM_WIN32_NT )
die( 1, "This program works under Windows NT only\n" );
if ( argc != 3 )
usage_exit( argv[0] );
fn = argv[1];
if ( strlen( argv[2] ) != 2 )
die( 1, "Invalid arg -- %s", argv[ 2 ] );
sprintf( dev, "\\\\.\\%s", argv[2] );
src = CreateFile( fn, GENERIC_READ, FILE_SHARE_READ,
NULL, OPEN_EXISTING, 0, NULL );
if ( src == INVALID_HANDLE_VALUE )
die( 2, "Could not open %s", fn );
dst = CreateFile( dev, GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL );
if ( dst == INVALID_HANDLE_VALUE )
die( 2, "Could not open %s", argv[2] );
if ( ! LOCK_DRIVE( dst ) )
die( 2, "Could not lock %s", argv[2] );
if ( ! GET_GEOMETRY( dst, &g ) )
die( 2, "Could not get disk information for %s", argv[2] );
switch ( g.MediaType ) {
case F5_1Pt2_512:
printf( "5.25\", 1.2MB, 512 bytes/sector\n" );
break;
case F3_1Pt44_512:
printf( "3.5\", 1.44MB, 512 bytes/sector\n" );
break;
case F3_2Pt88_512:
printf( "3.5\", 2.88MB, 512 bytes/sector\n" );
break;
case F3_20Pt8_512:
printf( "3.5\", 20.8MB, 512 bytes/sector\n" );
break;
case F3_720_512:
printf( "3.5\", 720KB, 512 bytes/sector\n" );
break;
case F5_360_512:
printf( "5.25\", 360KB, 512 bytes/sector\n" );
break;
case F5_320_512:
printf( "5.25\", 320KB, 512 bytes/sector\n" );
break;
case F5_320_1024:
printf( "5.25\", 320KB, 1024 bytes/sector\n" );
break;
case F5_180_512:
printf( "5.25\", 180KB, 512 bytes/sector\n" );
break;
case F5_160_512:
printf( "5.25\", 160KB, 512 bytes/sector\n" );
break;
case RemovableMedia:
die( 1, "Unsupported media type\n" );
case FixedMedia:
die( 1, "No suicides today, please!\n" );
default:
die( 1, "Unknown media type\n" );
}
bufsize = g.BytesPerSector * g.SectorsPerTrack;
buf = VirtualAlloc( NULL, bufsize, MEM_COMMIT, PAGE_READWRITE );
if ( buf == NULL )
die( 2, "VirualAlloc(): %d bytes", bufsize );
printf( "bufsize is %d\n", bufsize );
for ( bwt=0 ;ReadFile( src, buf, bufsize, &br, NULL ) && br; bwt += br ) {
if ( ! WriteFile( dst, buf, bufsize, &bw, NULL ) )
die( 2, "WriteFile(): %s", argv[ 2 ] );
}
if ( GetLastError() != ERROR_SUCCESS )
die( 2, "ReadFile(): %s", fn );
printf( "%d bytes written\n", bwt );
die( 0, NULL );
/* NOTREACHED */
return 0;
}
void usage_exit( char *arg0 )
{
char *prog;
prog = (prog = strrchr( arg0, '\\' ))?++prog:arg0;
die( 1, "Usage: %s file drive:\n", prog );
}
void die( int r, char *fmt, ... )
{
char *msg, defmsg[] = "[FormatMessage failed]";
va_list a;
unsigned int err;
err = GetLastError();
if ( r > 1 ) { /* OS error */
if ( ! FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM,
NULL, err,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR)&msg, 0, NULL ) )
msg = defmsg;
} else
msg = NULL;
if ( fmt != NULL ) {
va_start( a, fmt );
vfprintf( stderr, fmt, a );
va_end( a );
}
if ( msg ) {
fprintf( stderr, " -- %s\n", msg );
if ( msg != defmsg )
LocalFree( msg );
}
if ( src != INVALID_HANDLE_VALUE )
CloseHandle( src );
if ( dst != INVALID_HANDLE_VALUE ) {
UNLOCK_DRIVE( dst );
CloseHandle( dst );
}
if ( buf != NULL )
VirtualFree( buf, bufsize, MEM_DECOMMIT );
exit( r );
}