bool FileSystem::uncheckedRenameReplace(const QString& originFileName, const QString& destinationFileName, QString* errorString) { #ifndef Q_OS_WIN bool success; QFile orig(originFileName); #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) success = orig.fileEngine()->rename(destinationFileName); // qDebug() << "Renaming " << tmpFile.fileName() << " to " << fn; #else // We want a rename that also overwites. QFile::rename does not overwite. // Qt 5.1 has QSaveFile::renameOverwrite we could use. // ### FIXME success = true; bool destExists = fileExists(destinationFileName); if( destExists && !QFile::remove(destinationFileName) ) { *errorString = orig.errorString(); qDebug() << Q_FUNC_INFO << "Target file could not be removed."; success = false; } if( success ) { success = orig.rename(destinationFileName); } #endif if (!success) { *errorString = orig.errorString(); qDebug() << "FAIL: renaming temp file to final failed: " << *errorString ; return false; } #else //Q_OS_WIN BOOL ok; QString orig = longWinPath(originFileName); QString dest = longWinPath(destinationFileName); ok = MoveFileEx((wchar_t*)orig.utf16(), (wchar_t*)dest.utf16(), MOVEFILE_REPLACE_EXISTING+MOVEFILE_COPY_ALLOWED+MOVEFILE_WRITE_THROUGH); if (!ok) { wchar_t *string = 0; FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM, NULL, ::GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPWSTR)&string, 0, NULL); *errorString = QString::fromWCharArray(string); qDebug() << "FAIL: renaming temp file to final failed: " << *errorString; LocalFree((HLOCAL)string); return false; } #endif return true; }
bool FileSystem::uncheckedRenameReplace(const QString &originFileName, const QString &destinationFileName, QString *errorString) { #ifndef Q_OS_WIN bool success; QFile orig(originFileName); // We want a rename that also overwites. QFile::rename does not overwite. // Qt 5.1 has QSaveFile::renameOverwrite we could use. // ### FIXME success = true; bool destExists = fileExists(destinationFileName); if (destExists && !QFile::remove(destinationFileName)) { *errorString = orig.errorString(); qCWarning(lcFileSystem) << "Target file could not be removed."; success = false; } if (success) { success = orig.rename(destinationFileName); } if (!success) { *errorString = orig.errorString(); qCWarning(lcFileSystem) << "Renaming temp file to final failed: " << *errorString; return false; } #else //Q_OS_WIN // You can not overwrite a read-only file on windows. if (!QFileInfo(destinationFileName).isWritable()) { setFileReadOnly(destinationFileName, false); } BOOL ok; QString orig = longWinPath(originFileName); QString dest = longWinPath(destinationFileName); ok = MoveFileEx((wchar_t *)orig.utf16(), (wchar_t *)dest.utf16(), MOVEFILE_REPLACE_EXISTING + MOVEFILE_COPY_ALLOWED + MOVEFILE_WRITE_THROUGH); if (!ok) { wchar_t *string = 0; FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, ::GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPWSTR)&string, 0, NULL); *errorString = QString::fromWCharArray(string); qCWarning(lcFileSystem) << "Renaming temp file to final failed: " << *errorString; LocalFree((HLOCAL)string); return false; } #endif return true; }
bool FileSystem::rename(const QString &originFileName, const QString &destinationFileName, QString *errorString) { bool success = false; QString error; #ifdef Q_OS_WIN QString orig = longWinPath(originFileName); QString dest = longWinPath(destinationFileName); if (isLnkFile(originFileName) || isLnkFile(destinationFileName)) { success = MoveFileEx((wchar_t*)orig.utf16(), (wchar_t*)dest.utf16(), MOVEFILE_COPY_ALLOWED | MOVEFILE_WRITE_THROUGH); if (!success) { wchar_t *string = 0; FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, ::GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPWSTR)&string, 0, NULL); error = QString::fromWCharArray(string); LocalFree((HLOCAL)string); } } else #endif { QFile orig(originFileName); success = orig.rename(destinationFileName); if (!success) { error = orig.errorString(); } } if (!success) { qDebug() << "FAIL: renaming file" << originFileName << "to" << destinationFileName << "failed: " << error; if (errorString) { *errorString = error; } } return success; }
void FileSystem::setFileHidden(const QString& filename, bool hidden) { #ifdef _WIN32 QString fName = longWinPath(filename); DWORD dwAttrs; dwAttrs = GetFileAttributesW( (wchar_t*)fName.utf16() ); if (dwAttrs != INVALID_FILE_ATTRIBUTES) { if (hidden && !(dwAttrs & FILE_ATTRIBUTE_HIDDEN)) { SetFileAttributesW((wchar_t*)fName.utf16(), dwAttrs | FILE_ATTRIBUTE_HIDDEN ); } else if (!hidden && (dwAttrs & FILE_ATTRIBUTE_HIDDEN)) { SetFileAttributesW((wchar_t*)fName.utf16(), dwAttrs & ~FILE_ATTRIBUTE_HIDDEN ); } } #endif }
bool FileSystem::openAndSeekFileSharedRead(QFile* file, QString* errorOrNull, qint64 seek) { QString errorDummy; // avoid many if (errorOrNull) later. QString& error = errorOrNull ? *errorOrNull : errorDummy; error.clear(); #ifdef Q_OS_WIN // // The following code is adapted from Qt's QFSFileEnginePrivate::nativeOpen() // by including the FILE_SHARE_DELETE share mode. // // Enable full sharing. DWORD shareMode = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE; int accessRights = GENERIC_READ; DWORD creationDisp = OPEN_EXISTING; // Create the file handle. SECURITY_ATTRIBUTES securityAtts = { sizeof(SECURITY_ATTRIBUTES), NULL, FALSE }; QString fName = longWinPath(file->fileName()); HANDLE fileHandle = CreateFileW( (const wchar_t*)fName.utf16(), accessRights, shareMode, &securityAtts, creationDisp, FILE_ATTRIBUTE_NORMAL, NULL); // Bail out on error. if (fileHandle == INVALID_HANDLE_VALUE) { error = qt_error_string(); return false; } // Convert the HANDLE to an fd and pass it to QFile's foreign-open // function. The fd owns the handle, so when QFile later closes // the fd the handle will be closed too. int fd = _open_osfhandle((intptr_t)fileHandle, _O_RDONLY); if (fd == -1) { error = "could not make fd from handle"; return false; } if (!file->open(fd, QIODevice::ReadOnly, QFile::AutoCloseHandle)) { error = file->errorString(); return false; } // Seek to the right spot LARGE_INTEGER *li = reinterpret_cast<LARGE_INTEGER*>(&seek); DWORD newFilePointer = SetFilePointer(fileHandle, li->LowPart, &li->HighPart, FILE_BEGIN); if (newFilePointer == 0xFFFFFFFF && GetLastError() != NO_ERROR) { error = qt_error_string(); return false; } return true; #else if (!file->open(QFile::ReadOnly)) { error = file->errorString(); return false; } if (!file->seek(seek)) { error = file->errorString(); return false; } return true; #endif }