bool DiskWriter_windows::open(const QString &device) { hVolume = getHandleOnVolume(device, GENERIC_WRITE); if (hVolume == INVALID_HANDLE_VALUE) { return false; } if (!getLockOnVolume(hVolume)) { close(); return false; } if (isVolumeMounted(hVolume) && !unmountVolume(hVolume)) { close(); return false; } hRawDisk = getHandleOnDevice(device, GENERIC_WRITE); if (hRawDisk == INVALID_HANDLE_VALUE) { close(); return false; } return true; }
bool CDiskWriter::WriteImageToDisk(const std::wstring sFilename, int iDeviceID, int iVolumeID) { if (!this->FileExists(sFilename)) { status = STATUS_IDLE; CUIHelper::critical(L"File doesn't exist"); return false; } status = STATUS_WRITING; hVolume = getHandleOnVolume(iVolumeID, GENERIC_WRITE); if (hVolume == INVALID_HANDLE_VALUE) { status = STATUS_IDLE; return false; } if (!getLockOnVolume(hVolume)) { CloseHandle(hVolume); status = STATUS_IDLE; hVolume = INVALID_HANDLE_VALUE; return false; } if (!unmountVolume(hVolume)) { removeLockOnVolume(hVolume); CloseHandle(hVolume); status = STATUS_IDLE; hVolume = INVALID_HANDLE_VALUE; return false; } hFile = getHandleOnFile(sFilename.c_str(), GENERIC_READ); if (hFile == INVALID_HANDLE_VALUE) { removeLockOnVolume(hVolume); CloseHandle(hVolume); status = STATUS_IDLE; hVolume = INVALID_HANDLE_VALUE; return false; } hRawDisk = getHandleOnDevice(iDeviceID, GENERIC_WRITE); if (hRawDisk == INVALID_HANDLE_VALUE) { removeLockOnVolume(hVolume); CloseHandle(hFile); CloseHandle(hVolume); status = STATUS_IDLE; hVolume = INVALID_HANDLE_VALUE; hFile = INVALID_HANDLE_VALUE; return false; } unsigned long long i, availablesectors, numsectors; availablesectors = getNumberOfSectors(hRawDisk, §orsize); numsectors = getFileSizeInSectors(hFile, sectorsize); if (numsectors > availablesectors) { CUIHelper::critical(L"Not enough available space!"); return false; } ProgressBar.setRange(0, (numsectors == 0ul) ? 100 : (int)numsectors); for (i = 0ul; i < numsectors && status == STATUS_WRITING; i += 1024ul) { sectorData = readSectorDataFromHandle(hFile, i, (numsectors - i >= 1024ul) ? 1024ul : (numsectors - i), sectorsize); if (sectorData == NULL) { removeLockOnVolume(hVolume); CloseHandle(hRawDisk); CloseHandle(hFile); CloseHandle(hVolume); status = STATUS_IDLE; hRawDisk = INVALID_HANDLE_VALUE; hFile = INVALID_HANDLE_VALUE; hVolume = INVALID_HANDLE_VALUE; return false; } if (!writeSectorDataToHandle(hRawDisk, sectorData, i, (numsectors - i >= 1024ul) ? 1024ul : (numsectors - i), sectorsize)) { delete[] sectorData; removeLockOnVolume(hVolume); CloseHandle(hRawDisk); CloseHandle(hFile); CloseHandle(hVolume); status = STATUS_IDLE; sectorData = NULL; hRawDisk = INVALID_HANDLE_VALUE; hFile = INVALID_HANDLE_VALUE; hVolume = INVALID_HANDLE_VALUE; return false; } delete[] sectorData; sectorData = NULL; ProgressBar.setValue(i); ::Sleep(1); } removeLockOnVolume(hVolume); CloseHandle(hRawDisk); CloseHandle(hFile); CloseHandle(hVolume); hRawDisk = INVALID_HANDLE_VALUE; hFile = INVALID_HANDLE_VALUE; hVolume = INVALID_HANDLE_VALUE; return true; }
int main(int argc, char *argv[]) { if ( argc != 3 ) { return 1; //not enough arguments } const char ltr = argv[2][0]; const char *imagefile = argv[1]; status = STATUS_IDLE; hVolume = INVALID_HANDLE_VALUE; hFile = INVALID_HANDLE_VALUE; hRawDisk = INVALID_HANDLE_VALUE; sectorData = NULL; sectorsize = 0ul; if (strcmp( imagefile, "") != 0) { if(INVALID_FILE_ATTRIBUTES == GetFileAttributes(imagefile) && GetLastError()==ERROR_FILE_NOT_FOUND) { return 2; // .img not found } else { status = STATUS_WRITING; unsigned long long i, availablesectors, numsectors; int volumeID = ltr - 'A'; int deviceID = getDriveNumberFromLetter(ltr); if( deviceID == -1 ) { return 3; // device not found } hVolume = getHandleOnVolume(volumeID, GENERIC_WRITE); if (hVolume == INVALID_HANDLE_VALUE) { status = STATUS_IDLE; return 4; // invalid handle value for volume } if (!getLockOnVolume(hVolume)) { CloseHandle(hVolume); status = STATUS_IDLE; hVolume = INVALID_HANDLE_VALUE; return 5; // can't get lock on volume } if (!unmountVolume(hVolume)) { removeLockOnVolume(hVolume); CloseHandle(hVolume); status = STATUS_IDLE; hVolume = INVALID_HANDLE_VALUE; return 6; // can't unmount volume } hFile = getHandleOnFile(imagefile, GENERIC_READ); if (hFile == INVALID_HANDLE_VALUE) { removeLockOnVolume(hVolume); CloseHandle(hVolume); status = STATUS_IDLE; hVolume = INVALID_HANDLE_VALUE; return 7; // invalid handle value for file } hRawDisk = getHandleOnDevice(deviceID, GENERIC_WRITE); if (hRawDisk == INVALID_HANDLE_VALUE) { removeLockOnVolume(hVolume); CloseHandle(hFile); CloseHandle(hVolume); status = STATUS_IDLE; hVolume = INVALID_HANDLE_VALUE; hFile = INVALID_HANDLE_VALUE; return 8; // invalid handle value for disk } availablesectors = getNumberOfSectors(hRawDisk, §orsize); numsectors = getFileSizeInSectors(hFile, sectorsize); if (numsectors > availablesectors) { return 9; // not enough space on volume } char total_string[32]; sprintf(total_string, "%d", numsectors); for (i = 0ul; i < numsectors && status == STATUS_WRITING; i += 1024ul) { if( i % 100 == 0 ) { char i_string[32]; sprintf(i_string, "%d", i); printf(i_string); printf("/"); printf(total_string); setbuf(stdout, NULL); } sectorData = readSectorDataFromHandle(hFile, i, (numsectors - i >= 1024ul) ? 1024ul:(numsectors - i), sectorsize); if (sectorData == NULL) { removeLockOnVolume(hVolume); CloseHandle(hRawDisk); CloseHandle(hFile); CloseHandle(hVolume); status = STATUS_IDLE; hRawDisk = INVALID_HANDLE_VALUE; hFile = INVALID_HANDLE_VALUE; hVolume = INVALID_HANDLE_VALUE; return 10; // sector data is null } if (!writeSectorDataToHandle(hRawDisk, sectorData, i, (numsectors - i >= 1024ul) ? 1024ul:(numsectors - i), sectorsize)) { delete[] sectorData; removeLockOnVolume(hVolume); CloseHandle(hRawDisk); CloseHandle(hFile); CloseHandle(hVolume); status = STATUS_IDLE; sectorData = NULL; hRawDisk = INVALID_HANDLE_VALUE; hFile = INVALID_HANDLE_VALUE; hVolume = INVALID_HANDLE_VALUE; return 11; // error whilst writing } delete[] sectorData; sectorData = NULL; } removeLockOnVolume(hVolume); CloseHandle(hRawDisk); CloseHandle(hFile); CloseHandle(hVolume); hRawDisk = INVALID_HANDLE_VALUE; hFile = INVALID_HANDLE_VALUE; hVolume = INVALID_HANDLE_VALUE; } return 0; // success } else { return 1; // not enough arguments } status = STATUS_IDLE; return 11; // error whilst writing }