Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

490 lines
15 KiB

#include "precomp.h"
#pragma hdrstop
/////////////////////////////////////////////////////////////////////////////
// //
// dmfimage.c Program for retrieving entire contents of a floppy disk //
// into an image file, or writing such an image file to //
// a floppy disk. //
// //
// Code is targeted as Win32 console application. //
// //
// Author: Tom McGuire (tommcg) //
// //
// Original version written May, 1994. //
// //
// (C) Copyright 1994-1996, Microsoft Corporation //
// //
/////////////////////////////////////////////////////////////////////////////
#define DEVICE_TO_FILE 0
#define FILE_TO_DEVICE 1
#define FILE_NO_SHARING 0
#define GETLASTERROR 0xFFFFFFFF
#define IMAGE_SIZE_DMF 1720320 // 80x2x21x512 (DMF 1.7MB)
#define IMAGE_SIZE_144 1474560 // 80x2x18x512 (standard 1.44MB)
#define IMAGE_SIZE_12 1228800 // 80x2x15x512 (standard 1.2MB)
void FormatDmf( HANDLE hDevice );
void FormatHD( HANDLE hDevice, MEDIA_TYPE eMediaType );
void ErrorExit( DWORD dwGLE, const char *szFormat, ... );
void Copyright( void );
void __cdecl main( int argc, char *argv[] ) {
CHAR chDeviceName[ MAX_PATH ] = "\\\\.\\";
CHAR chFileName[ MAX_PATH ];
DWORD dwFileSize = 0;
DWORD dwMediaSize, dwActual, dwGLE;
HANDLE hFile, hDevice, hMap;
PVOID pMappedView;
DISK_GEOMETRY dg;
DISK_GEOMETRY dgArray[ 20 ];
INT fDirection = 0;
BOOL bFormatTarget = FALSE;
BOOL b288 = FALSE;
UINT n, nElements;
Copyright();
//
// Check usage.
//
if ( argc < 3 ) {
ErrorExit( 0, "\n"
"Usage: DMFIMAGE source target [-f]\n"
"\n"
" Either source or target must be a floppy drive.\n"
" -f indicates format target media before writing.\n"
"\n"
"Examples: DMFIMAGE a: myfile.img\n"
" DMFIMAGE myfile.img b: -f\n"
"\n" );
}
SetErrorMode( SEM_FAILCRITICALERRORS ); // no drive-not-ready popups
SetFileApisToOEM();
//
// Determine source and target.
//
if (( argv[ 1 ][ 1 ] == ':' ) && ( argv[ 1 ][ 2 ] == '\0' )) {
strcat( chDeviceName, argv[ 1 ] );
strcpy( chFileName, argv[ 2 ] );
fDirection = DEVICE_TO_FILE;
if ( ( argv[ 2 ][ 1 ] == ':' ) && ( argv[ 2 ][ 2 ] == '\0' )) {
ErrorExit( 0, "Either source or destination must be a file\n" );
}
}
else if ( ( argv[ 2 ][ 1 ] == ':' ) && ( argv[ 2 ][ 2 ] == '\0' )) {
strcat( chDeviceName, argv[ 2 ] );
strcpy( chFileName, argv[ 1 ] );
fDirection = FILE_TO_DEVICE;
}
else {
ErrorExit( 0, "Either source or destination must be floppy drive "
"(like A:)\n" );
}
if (( argc > 3 ) &&
(( argv[ 3 ][ 0 ] == '/' ) || ( argv[ 3 ][ 0 ] == '-' )) &&
(( argv[ 3 ][ 1 ] == 'f' ) || ( argv[ 3 ][ 1 ] == 'F' ))) {
bFormatTarget = TRUE;
}
//
// Open device and determine size.
//
hDevice = CreateFile( chDeviceName,
( fDirection == FILE_TO_DEVICE ) ? GENERIC_READ | GENERIC_WRITE : GENERIC_READ,
( fDirection == FILE_TO_DEVICE ) ? FILE_NO_SHARING : FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_FLAG_NO_BUFFERING,
NULL );
if ( hDevice == INVALID_HANDLE_VALUE ) {
ErrorExit( GETLASTERROR, "Could not open device %s\n",
chDeviceName );
}
if ( ! DeviceIoControl( hDevice,
IOCTL_DISK_GET_DRIVE_GEOMETRY,
NULL,
0,
&dg,
sizeof( dg ),
&dwActual,
NULL )) {
ErrorExit( GETLASTERROR, "Unable to query disk information on %s\n",
chDeviceName );
}
if ( dg.MediaType == Unknown ) {
dwMediaSize = 0;
bFormatTarget = TRUE;
}
else {
dwMediaSize = dg.Cylinders.LowPart
* dg.TracksPerCylinder
* dg.SectorsPerTrack
* dg.BytesPerSector;
}
if ( ! DeviceIoControl( hDevice,
IOCTL_DISK_GET_MEDIA_TYPES,
NULL,
0,
&dgArray,
sizeof( dgArray ),
&dwActual,
NULL )) {
ErrorExit( GETLASTERROR, "Unable to query disk information on %s\n",
chDeviceName );
}
nElements = dwActual / sizeof( dgArray[ 0 ] );
for ( n = 0; n < nElements; n++ ) {
switch ( dgArray[ n ].MediaType ) {
case F5_1Pt2_512:
if ( dwMediaSize == 0 )
dwMediaSize = IMAGE_SIZE_12;
break;
case F3_1Pt44_512:
if ( dwMediaSize == 0 )
dwMediaSize = IMAGE_SIZE_144;
break;
case F3_2Pt88_512:
b288 = TRUE;
break;
}
}
//
// Open file
//
hFile = CreateFile( chFileName,
( fDirection == FILE_TO_DEVICE ) ? GENERIC_READ : GENERIC_READ | GENERIC_WRITE,
( fDirection == FILE_TO_DEVICE ) ? FILE_SHARE_READ : FILE_NO_SHARING,
NULL,
( fDirection == FILE_TO_DEVICE ) ? OPEN_EXISTING : CREATE_ALWAYS,
( fDirection == FILE_TO_DEVICE ) ? FILE_FLAG_SEQUENTIAL_SCAN : FILE_ATTRIBUTE_NORMAL |
FILE_FLAG_NO_BUFFERING,
NULL );
if ( hFile == INVALID_HANDLE_VALUE ) {
ErrorExit( GETLASTERROR, "Could not open file %s\n",
chFileName );
}
//
// If reading from file, make sure file is correct size for media
//
if ( fDirection == FILE_TO_DEVICE ) {
dwFileSize = GetFileSize( hFile, NULL );
if (( dwFileSize == IMAGE_SIZE_DMF ) &&
(( dwMediaSize == IMAGE_SIZE_DMF ) ||
( dwMediaSize == IMAGE_SIZE_144 ))) {
if ( b288 ) {
ErrorExit( 0, "Cannot create DMF diskette in 2.88MB drive\n" );
}
//
// DMF targets always get formatted
//
bFormatTarget = TRUE;
dwMediaSize = IMAGE_SIZE_DMF;
}
else if (( dwFileSize == IMAGE_SIZE_144 ) &&
( dwMediaSize == IMAGE_SIZE_DMF )) {
bFormatTarget = TRUE;
dwMediaSize = IMAGE_SIZE_144;
}
if ( bFormatTarget ) {
if (( dwMediaSize != IMAGE_SIZE_DMF ) &&
( dwMediaSize != IMAGE_SIZE_144 ) &&
( dwMediaSize != IMAGE_SIZE_12 )) {
ErrorExit( 0, "Only 1.2MB, 1.44MB, and DMF formatting is supported\n" );
}
}
if ( dwFileSize != dwMediaSize ) {
ErrorExit( 0, "Source image is not compatible with target media\n"
"(source size is %d bytes but target media is %d)\n",
dwFileSize,
dwMediaSize );
}
if ( bFormatTarget ) {
printf( "Formatting..." );
switch ( dwMediaSize ) {
case IMAGE_SIZE_DMF:
FormatDmf( hDevice );
break;
case IMAGE_SIZE_144:
FormatHD( hDevice, F3_1Pt44_512 );
break;
case IMAGE_SIZE_12:
FormatHD( hDevice, F5_1Pt2_512 );
}
printf( "done\n" );
}
}
//
// Map file for transfer
//
hMap = CreateFileMapping( hFile,
NULL,
( fDirection == FILE_TO_DEVICE ) ? PAGE_READONLY : PAGE_READWRITE,
0,
( fDirection == FILE_TO_DEVICE ) ? dwFileSize : dwMediaSize,
NULL );
if ( hMap == NULL ) {
dwGLE = GetLastError();
if ( fDirection == DEVICE_TO_FILE ) {
CloseHandle( hFile );
DeleteFile( chFileName );
}
ErrorExit( dwGLE, "Unable to map file %s\n", chFileName );
}
pMappedView = MapViewOfFile( hMap,
( fDirection == FILE_TO_DEVICE ) ? FILE_MAP_READ : FILE_MAP_WRITE,
0,
0,
0 );
if ( pMappedView == NULL ) {
dwGLE = GetLastError();
if ( fDirection == DEVICE_TO_FILE ) {
CloseHandle( hMap );
CloseHandle( hFile );
DeleteFile( chFileName );
}
ErrorExit( dwGLE, "Unable to map file %s\n", chFileName );
}
//
// Now we're ready to transfer.
//
printf( "Copying..." );
try { // might take in-page exception from mapped view error
if ( fDirection == FILE_TO_DEVICE ) {
if ( ! WriteFile( hDevice,
pMappedView,
dwFileSize,
&dwActual,
NULL )) {
ErrorExit( GETLASTERROR, "error while copying\n" );
}
}
else { // ( fDirection == DEVICE_TO_FILE )
if ( ! ReadFile( hDevice,
pMappedView,
dwMediaSize,
&dwActual,
NULL )) {
ErrorExit( GETLASTERROR, "error while copying\n" );
}
}
}
except( EXCEPTION_EXECUTE_HANDLER ) {
ErrorExit( 0, "exception %08X while copying\n", GetExceptionCode() );
}
printf( "done\n" );
//
// cleanup is free
//
exit( 0 );
}
void FormatDmf( HANDLE hDevice ) {
#define FORMAT_PARAMETERS_SIZE ( sizeof( FORMAT_EX_PARAMETERS ) \
+ sizeof( USHORT ) * 20 )
CHAR formatParametersBuffer[FORMAT_PARAMETERS_SIZE];
PFORMAT_EX_PARAMETERS formatParameters;
ULONG i, next;
BOOL b;
DWORD bytesWritten;
USHORT swapBuffer[3];
// Prepare the format parameters.
formatParameters = (PFORMAT_EX_PARAMETERS) formatParametersBuffer;
formatParameters->MediaType = F3_1Pt44_512;
formatParameters->FormatGapLength = 8;
formatParameters->SectorsPerTrack = 21;
next = 0;
for (i = 0; i < formatParameters->SectorsPerTrack; i += 2) {
formatParameters->SectorNumber[i] = (USHORT) (i/2 + 1);
next++;
}
for (i = 1; i < formatParameters->SectorsPerTrack; i += 2) {
formatParameters->SectorNumber[i] = (USHORT) (i/2 + next + 1);
}
// Start off by putting the boot sector as the last sector of
// the first track.
MoveMemory(&formatParameters->SectorNumber[0],
&formatParameters->SectorNumber[1],
20*sizeof(USHORT));
formatParameters->SectorNumber[20] = 1;
// Format each track on the floppy.
for (i = 0; i < 80; i++) {
formatParameters->StartCylinderNumber =
formatParameters->EndCylinderNumber = i;
formatParameters->StartHeadNumber = 0;
formatParameters->EndHeadNumber = 1;
b = DeviceIoControl(hDevice, IOCTL_DISK_FORMAT_TRACKS_EX,
formatParameters, FORMAT_PARAMETERS_SIZE,
NULL, 0, &bytesWritten, NULL);
if ( ! b ) {
ErrorExit( GETLASTERROR, "DMF format failed\n" );
}
// Skew the next cylinder by 3 sectors from this one.
MoveMemory(swapBuffer,
&formatParameters->SectorNumber[18],
3*sizeof(USHORT));
MoveMemory(&formatParameters->SectorNumber[3],
&formatParameters->SectorNumber[0],
18*sizeof(USHORT));
MoveMemory(&formatParameters->SectorNumber[0],
swapBuffer,
3*sizeof(USHORT));
}
}
void FormatHD( HANDLE hDevice, MEDIA_TYPE eMediaType ) {
FORMAT_PARAMETERS fp;
DWORD dwActual;
BOOL bSuccess;
if (( eMediaType != F5_1Pt2_512 ) &&
( eMediaType != F3_1Pt44_512 )) {
ErrorExit( 0, "Invalid media type for format request\n" );
}
fp.MediaType = eMediaType;
fp.StartCylinderNumber = 0;
fp.EndCylinderNumber = 79;
fp.StartHeadNumber = 0;
fp.EndHeadNumber = 1;
bSuccess = DeviceIoControl( hDevice,
IOCTL_DISK_FORMAT_TRACKS,
&fp,
sizeof( fp ),
NULL,
0,
&dwActual,
NULL );
if ( ! bSuccess ) {
ErrorExit( GETLASTERROR, "format failed\n" );
}
}
void ErrorExit( DWORD dwGLE, const char *szFormat, ... ) {
CHAR chBuffer[ 256 ];
va_list vaArgs;
if ( dwGLE == GETLASTERROR )
dwGLE = GetLastError();
va_start( vaArgs, szFormat );
vfprintf( stdout, szFormat, vaArgs );
va_end( vaArgs );
if ( dwGLE ) {
if ( FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
dwGLE,
0x409,
chBuffer,
sizeof( chBuffer ),
NULL )) {
printf( "(%d) %s\n", dwGLE, chBuffer );
}
else {
printf( "Error code %d\n", dwGLE );
}
}
exit( 1 );
}
void Copyright( void ) {
printf( "\n"
"DMFIMAGE Diskette Image Utility Version 1.05\n"
"Copyright (C) Microsoft, 1994-1996. All rights reserved.\n"
"For Microsoft internal use only.\n"
"\n" );
}