|
|
/*++
Copyright (c) 2000 Microsoft Corporation
Module Name:
dskimage.cpp
Abstract:
Tool to create images of floppy disks.
NOTE: Currently used by WinPE image creation script for IA64 ISO CD image
Author:
Vijay Jayaseelan (vijayj) 12 March 2001
Revision History:
None. --*/
#include <iostream>
#include <string>
#include <windows.h>
#include "msg.h"
#include <libmsg.h>
//
// Global variables used to get formatted message for this program.
//
HMODULE ThisModule = NULL; WCHAR Message[4096];
//
// Helper dump operators
//
inline std::ostream& operator<<(std::ostream &os, const std::wstring &str) { FILE *OutStream = (&os == &std::cerr) ? stderr : stdout;
fputws(str.c_str(), OutStream); return os; }
inline std::ostream& operator<<(std::ostream &os, PCTSTR str) { return os << std::wstring(str); }
//
// Exceptions
//
struct ProgramException : public std::exception { virtual void Dump(std::ostream &os) = 0; };
//
// Abstracts a Win32 error
//
struct W32Error : public ProgramException { DWORD ErrorCode; W32Error(DWORD ErrCode = GetLastError()) : ErrorCode(ErrCode){} void Dump(std::ostream &os) { WCHAR MsgBuffer[4096];
MsgBuffer[0] = UNICODE_NULL; if (GetFormattedMessage(ThisModule, FALSE, MsgBuffer, sizeof(MsgBuffer)/sizeof(MsgBuffer[0]), ErrorCode)){ std::wstring Msg(MsgBuffer); os << Msg; } else { os << std::hex << ErrorCode; } } };
//
// Invalid arguments
//
struct ProgramUsage : public ProgramException { std::wstring PrgUsage;
ProgramUsage(const std::wstring &Usg) : PrgUsage(Usg) {} const char *what() const throw() { return "Program Usage exception"; }
void Dump(std::ostream &os) { os << PrgUsage << std::endl; } };
//
// Argument cracker
//
struct ProgramArguments { std::wstring DriveLetter; std::wstring ImageName;
ProgramArguments(int Argc, wchar_t *Argv[]) { bool ValidArgs = false; bool ShowUsage = false;
for (ULONG Index = 1; !ShowUsage && (Index < Argc); Index++) { ShowUsage = !_wcsicmp(Argv[Index], TEXT("/?")); } if (!ShowUsage && (Argc > 2)) { DriveLetter = Argv[1]; ImageName = Argv[2];
ValidArgs = ((DriveLetter.length() == 2) && (DriveLetter[1] == TEXT(':'))); }
if (!ValidArgs) { throw new ProgramUsage(GetFormattedMessage( ThisModule, FALSE, Message, sizeof(Message)/sizeof(Message[0]), MSG_PGM_USAGE)); }
DriveLetter = TEXT("\\\\.\\") + DriveLetter; }
friend std::ostream& operator<<(std::ostream &os, const ProgramArguments &Args) { os << GetFormattedMessage( ThisModule, FALSE, Message, sizeof(Message)/sizeof(Message[0]), MSG_DRVLETTER_AND_IMGNAME, Args.DriveLetter, Args.ImageName) << std::endl; return os; } };
//
// Prototypes
//
VOID CreateImage( IN const ProgramArguments &Args ) { DWORD Error = ERROR_SUCCESS;
//
// Open the source file
//
HANDLE SourceHandle = CreateFile(Args.DriveLetter.c_str(), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (SourceHandle == INVALID_HANDLE_VALUE) { throw new W32Error(); }
//
// Open the destination file
//
HANDLE DestHandle = CreateFile(Args.ImageName.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (DestHandle == INVALID_HANDLE_VALUE) { Error = GetLastError();
CloseHandle(SourceHandle); throw new W32Error(Error); }
//
// Read contents of the source and write it to destination
//
LPBYTE lpBuffer = NULL; DWORD BufferSize = 64 * 1024; DWORD BytesRead = 0, BytesWritten = 0; LONGLONG TotalBytesWritten = 0;
lpBuffer = (LPBYTE) HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, BufferSize ); if ( lpBuffer ) { while (ReadFile(SourceHandle, lpBuffer, BufferSize, &BytesRead, NULL) && BytesRead && WriteFile(DestHandle, lpBuffer, BytesRead, &BytesWritten, NULL) && (BytesRead == BytesWritten)) { TotalBytesWritten += BytesWritten; BytesRead = BytesWritten = 0; }
HeapFree( GetProcessHeap(), 0, lpBuffer); }
//
// Cleanup
//
Error = GetLastError(); CloseHandle(SourceHandle); CloseHandle(DestHandle);
//
// Check, if the operation was successful ?
//
if (!TotalBytesWritten || (BytesRead != BytesWritten)) { throw new W32Error(Error); } }
//
// Main entry point
//
INT __cdecl wmain( IN INT Argc, IN WCHAR *Argv[] ) { INT Result = 0; ThisModule = GetModuleHandle(NULL); try { ProgramArguments Args(Argc, Argv);
CreateImage(Args); } catch(W32Error *Error) { if (Error) { Result = (INT)(Error->ErrorCode); Error->Dump(std::cout); delete Error; } } catch(ProgramException *Exp) { if (Exp) { Exp->Dump(std::cout); delete Exp; } } catch(...) { Result = 1; }
return Result; }
|