/* * WinSOS NT utility for writing image files to floppy. * * Toomas Kiisk , 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 #include #include #include #include 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 ); }