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, &sectorsize);
	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, &sectorsize);
            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
}