Opening a USB flash drive for low level raw write

  • Thread starter Thread starter Matt_FL
  • Start date Start date
M

Matt_FL

Guest
How do I open a USB flash drive for raw writing (and reading) starting at sector 0?

The goal is to replicate USB flash drives. I'm using VDS to get a volume path to the device, then using CreateFile() to open the device. But I think the way I'm opening the drive isn't giving me low enough level access. I've got a binary image of a bootable USB flash drive that I created using "dd" in Linux, and I verified it's a good image by using dd to write it back to other flash drives and then booting from them. However with the code below, if I try to write it to a blank USB flash drive (no partitions at all), it fails with error 87,


ERROR_INVALID_PARAMETER. If I try it again with a USB flash drive that contains a formatted partition, it will write the data, but the result is a disk that cannot be read, so I think it's not starting the write at sector 0.

Is there a way to open the device for binary write starting at sector 0? Here's the code I'm using to open and write to the device:


// Open the device using the volume path obtained with VDS
// Remove trailing slashes or CreateFile will fail
CString *pcsVolumePath = new CString(iStr->data()); /* iStr == volume path, such as "\\?\Volume{141a7400-fc2f-11e5-bf53-005056c00008}\" */
pcsVolumePath->TrimRight(L"?\\");

// Open handle to target device
HANDLE hTarget = CreateFile( pcsVolumePath->GetString(),
GENERIC_WRITE,
0, /* Exclusive access until we close the handle */
NULL /* Default security */,
OPEN_EXISTING, /* Docs say OPEN_EXISTING for devices other than files */
FILE_ATTRIBUTE_NORMAL,
NULL);
if( hTarget == INVALID_HANDLE_VALUE )
{
DWORD createFileError = GetLastError();
wcerr << L"ERROR: Failed to open volume handle for write: " << createFileError << endl;
}


// Open the binary source file
CString csSourceFile = L"C:\\temp\\image.bin";
HANDLE hSource = CreateFile( csSourceFile.GetString(),
GENERIC_READ,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL );
if( hSource == INVALID_HANDLE_VALUE )
{
DWORD openFileError = GetLastError();
wcerr << L"ERROR: Failed to open source file for read: " << openFileError << endl;
}
else
{
// Start reading data and stuffing it into the device
DWORD bytesRead = 0;
DWORD bytesWritten = 0;
unsigned long long uiTotalBytesWritten = 0;
const int iBufSize = 4096 * 4;
char cBuffer[iBufSize] = { 0 };
wcout << L"Beginning write to: " << pcsVolumePath->GetString() << endl;
while( ReadFile( hSource, cBuffer, iBufSize, &bytesRead, NULL) == true && bytesRead > 0)
{
if( WriteFile( hTarget, cBuffer, bytesRead, &bytesWritten, NULL) == false || bytesWritten <= 0 || bytesWritten != bytesRead)
{
if( bytesWritten != bytesRead )
{
wcerr << L"ERROR: Bytes written " << bytesWritten << " != bytesRead " << bytesRead << endl;
}
wcerr << L"ERROR: error writing to destination volume: " << GetLastError() << endl;
break;
} // if()
else
{
uiTotalBytesWritten += bytesWritten;
if( uiTotalBytesWritten % (1024 * 1024 * 10) == 0 ) wcout << L"Bytes written: " << uiTotalBytesWritten << L"\r";
}
} // while()

wcout << L"\nWrite complete, total bytes written: " << uiTotalBytesWritten << endl;






Continue reading...
 
Back
Top