mirror of
https://github.com/cmclark00/retro-imager.git
synced 2025-05-18 16:05:21 +01:00
Qt/QML edition
This commit is contained in:
commit
d7b361ba44
2168 changed files with 721948 additions and 0 deletions
193
windows/winfile.cpp
Normal file
193
windows/winfile.cpp
Normal file
|
@ -0,0 +1,193 @@
|
|||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Copyright (C) 2020 Raspberry Pi (Trading) Limited
|
||||
*/
|
||||
|
||||
#include "winfile.h"
|
||||
#include <QDebug>
|
||||
#include <QThread>
|
||||
|
||||
WinFile::WinFile(QObject *parent)
|
||||
: QObject(parent), _locked(false), _h(INVALID_HANDLE_VALUE)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
WinFile::~WinFile()
|
||||
{
|
||||
if (isOpen())
|
||||
close();
|
||||
}
|
||||
|
||||
void WinFile::setFileName(const QString &name)
|
||||
{
|
||||
_name = name;
|
||||
}
|
||||
|
||||
bool WinFile::open(QIODevice::OpenMode)
|
||||
{
|
||||
QByteArray n = _name.toLatin1();
|
||||
|
||||
for (int attempt = 0; attempt < 20; attempt++)
|
||||
{
|
||||
_h = CreateFileA(n.data(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if (_h != INVALID_HANDLE_VALUE)
|
||||
break;
|
||||
|
||||
qDebug() << "Error opening device. Retrying...";
|
||||
QThread::msleep(100);
|
||||
}
|
||||
|
||||
// Try with FILE_SHARE_WRITE
|
||||
if (_h == INVALID_HANDLE_VALUE)
|
||||
_h = CreateFileA(n.data(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);;
|
||||
|
||||
if (_h == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
_lasterror = qt_error_string();
|
||||
qDebug() << "Error opening:" << _lasterror;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void WinFile::close()
|
||||
{
|
||||
if (!isOpen())
|
||||
return;
|
||||
|
||||
if (_locked)
|
||||
{
|
||||
unlockVolume();
|
||||
}
|
||||
|
||||
CloseHandle(_h);
|
||||
_h = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
bool WinFile::isOpen()
|
||||
{
|
||||
return _h != INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
qint64 WinFile::write(const char *data, qint64 maxSize)
|
||||
{
|
||||
DWORD bytesWritten;
|
||||
|
||||
if (maxSize % 512)
|
||||
qDebug() << "write: NOT SECTOR ALIGNED";
|
||||
|
||||
if (!WriteFile(_h, data, maxSize, &bytesWritten, NULL))
|
||||
{
|
||||
_lasterror = qt_error_string();
|
||||
return -1;
|
||||
}
|
||||
|
||||
return bytesWritten;
|
||||
}
|
||||
|
||||
qint64 WinFile::read(char *data, qint64 maxSize)
|
||||
{
|
||||
DWORD bytesRead;
|
||||
|
||||
if (!ReadFile(_h, data, maxSize, &bytesRead, NULL))
|
||||
{
|
||||
_lasterror = qt_error_string();
|
||||
return -1;
|
||||
}
|
||||
|
||||
return bytesRead;
|
||||
}
|
||||
|
||||
bool WinFile::seek(qint64 pos)
|
||||
{
|
||||
LARGE_INTEGER current;
|
||||
LARGE_INTEGER offset;
|
||||
offset.QuadPart = pos;
|
||||
if (!SetFilePointerEx(_h, offset, ¤t, FILE_BEGIN))
|
||||
{
|
||||
_lasterror = qt_error_string();
|
||||
qDebug() << "Error seeking:" << _lasterror;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
qint64 WinFile::pos()
|
||||
{
|
||||
LARGE_INTEGER current;
|
||||
LARGE_INTEGER offset;
|
||||
offset.QuadPart = 0;
|
||||
if (!SetFilePointerEx(_h, offset, ¤t, FILE_CURRENT))
|
||||
{
|
||||
_lasterror = qt_error_string();
|
||||
return 0;
|
||||
}
|
||||
|
||||
return qint64(current.QuadPart);
|
||||
}
|
||||
|
||||
HANDLE WinFile::handle()
|
||||
{
|
||||
return _h;
|
||||
}
|
||||
|
||||
QString WinFile::errorString() const
|
||||
{
|
||||
return _lasterror;
|
||||
}
|
||||
|
||||
bool WinFile::flush()
|
||||
{
|
||||
if (!FlushFileBuffers(_h))
|
||||
{
|
||||
_lasterror = qt_error_string();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WinFile::lockVolume()
|
||||
{
|
||||
DWORD bytesRet;
|
||||
DeviceIoControl(_h, FSCTL_ALLOW_EXTENDED_DASD_IO, NULL, 0, NULL, 0, &bytesRet, NULL);
|
||||
for (int attempt = 0; attempt < 20; attempt++)
|
||||
{
|
||||
qDebug() << "Locking volume" << _name;
|
||||
|
||||
if (DeviceIoControl(_h, FSCTL_LOCK_VOLUME, NULL, 0, NULL, 0, &bytesRet, NULL))
|
||||
{
|
||||
_locked = true;
|
||||
qDebug() << "Locked volume";
|
||||
return true;
|
||||
}
|
||||
|
||||
qDebug() << "FSCTL_LOCK_VOLUME failed. Retrying in 0.1 sec";
|
||||
QThread::msleep(100);
|
||||
}
|
||||
|
||||
qDebug() << "Giving up locking volume";
|
||||
return false;
|
||||
}
|
||||
|
||||
bool WinFile::unlockVolume()
|
||||
{
|
||||
if (!_locked)
|
||||
return true;
|
||||
|
||||
DWORD bytesRet;
|
||||
if (DeviceIoControl(_h, FSCTL_UNLOCK_VOLUME, NULL, 0, NULL, 0, &bytesRet, NULL))
|
||||
{
|
||||
_locked = false;
|
||||
qDebug() << "Unlocked volume";
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
qDebug() << "FSCTL_UNLOCK_VOLUME failed";
|
||||
return false;
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue