bool CFileSystemObject::isMovableTo(const CFileSystemObject& dest) const { if (!isValid() || !dest.isValid()) return false; const auto fileSystemId = rootFileSystemId(), otherFileSystemId = dest.rootFileSystemId(); return fileSystemId == otherFileSystemId && fileSystemId != std::numeric_limits<uint64_t>::max() && otherFileSystemId != std::numeric_limits<uint64_t>::max(); }
void PrintLevel(const std::wstring & aParentName, CFileSystemObject & aObject) { std::wstring fullName = aParentName + L'\\' + aObject.getName(); printf("0x%x: %S\n", aObject.getFileAttributes(), fullName.c_str()); for (auto it = aObject.begin(); it != aObject.end(); ++it) { PrintLevel(fullName, *it->second); } return; }
void scanDirectory(const CFileSystemObject& root, const std::function<void(const CFileSystemObject&)>& observer, const std::atomic<bool>& abort) { if (observer) observer(root); if (!root.isDir() || abort) return; const auto list = root.qDir().entryInfoList(QDir::Files | QDir::Dirs | QDir::Hidden | QDir::NoSymLinks | QDir::NoDotAndDotDot | QDir::System); for (const auto& entry : list) { scanDirectory(CFileSystemObject(entry), observer, abort); if (abort) return; } }
inline static qulonglong hash(const CFileSystemObject& object) { const auto properties = object.properties(); const auto hashData = QByteArray::fromRawData((const char*)&properties.hash, sizeof(properties.hash)) + QByteArray::fromRawData((const char*)&properties.modificationDate, sizeof(properties.modificationDate)) + QByteArray::fromRawData((const char*)&properties.type, sizeof(properties.type)); return fasthash64(hashData.constData(), hashData.size(), 0); }
static DWORD _BuildTreeLevel(const HANDLE hDirectory, CFileSystemObject & FSObject) { DWORD ret = ERROR_GEN_FAILURE; ret = FSObject.FindChildren(hDirectory); if (ret == ERROR_SUCCESS) { for (auto it = FSObject.begin(); it != FSObject.end(); ++it) { CFileSystemObject *ch = it->second; ULONG attr = ch->getFileAttributes(); if ((attr & FILE_ATTRIBUTE_REPARSE_POINT) == 0 && (attr & FILE_ATTRIBUTE_DIRECTORY) != 0) { HANDLE hChild = NULL; ret = _OpenDirectoryName(hDirectory, ch->getName(), &hChild); if (ret == ERROR_SUCCESS) { ret = _BuildTreeLevel(hChild, *ch); CloseHandle(hChild); } } // if (ret != ERROR_SUCCESS) // break; } } return ret; }
static DWORD _ScanFileIds(const std::wstring VolumeName, CFileSystemObject & Root) { HANDLE volumeHandle = NULL; unsigned int i = 0; BY_HANDLE_FILE_INFORMATION bhfi; HANDLE fileHandle = INVALID_HANDLE_VALUE; DWORD ret = ERROR_GEN_FAILURE; volumeHandle = CreateFileW(VolumeName.c_str(), FILE_READ_ATTRIBUTES, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); ret = (volumeHandle != INVALID_HANDLE_VALUE) ? ERROR_SUCCESS : GetLastError(); if (ret == ERROR_SUCCESS) { for (i = 0; i < 16 * 1024 * 1024; ++i) { ret = _OpenFileById(volumeHandle, i, &fileHandle); if (ret == ERROR_SUCCESS) { POBJECT_NAME_INFORMATION oni = NULL; ret = (GetFileInformationByHandle(fileHandle, &bhfi)) ? ERROR_SUCCESS : GetLastError(); if (ret == ERROR_SUCCESS) { ret = QueryObjectName(fileHandle, &oni); if (ret == ERROR_SUCCESS) { CFileSystemObject *o = NULL; std::wstring fileName = std::wstring(oni->Name.Buffer, oni->Name.Length / sizeof(WCHAR)).substr(1); size_t pos = fileName.find_first_of(L'\\'); fileName = fileName.substr(pos + 1); pos = fileName.find_first_of(L'\\'); fileName = fileName.substr(pos + 1); o = new CFileSystemObject(L"", bhfi.dwFileAttributes, i); Root.AddObject(fileName, o); HeapFree(GetProcessHeap(), HEAP_ZERO_MEMORY, oni); } } CloseHandle(fileHandle); } } CloseHandle(volumeHandle); } return ret; }
// Returns true if this object is a child of parent, either direct or indirect bool CFileSystemObject::isChildOf(const CFileSystemObject &parent) const { if (!isValid() || !parent.isValid()) return false; if (fullAbsolutePath().startsWith(parent.fullAbsolutePath(), caseSensitiveFilesystem() ? Qt::CaseSensitive : Qt::CaseInsensitive)) return true; if (!isSymLink() && !parent.isSymLink()) return false; const auto resolvedChildLink = isSymLink() ? symLinkTarget() : fullAbsolutePath(); const auto resolvedParentLink = parent.isSymLink() ? parent.symLinkTarget() : parent.fullAbsolutePath(); assert_and_return_r(!resolvedChildLink.isEmpty() && !resolvedParentLink.isEmpty(), false); return resolvedChildLink.startsWith(resolvedParentLink, caseSensitiveFilesystem() ? Qt::CaseSensitive : Qt::CaseInsensitive); }
DISABLE_COMPILER_WARNINGS #include <QDateTime> #include <QInputDialog> #include <QLineEdit> RESTORE_COMPILER_WARNINGS CPromptDialog::CPromptDialog(QWidget *parent, Operation op, HaltReason promptReason, const CFileSystemObject& source, const CFileSystemObject& dest, const QString& message) : QDialog(parent), ui(new Ui::CPromptDialog), _response(urNone) { ui->setupUi(this); connect(ui->btnCancel, &QPushButton::clicked, this, &CPromptDialog::onCancelClicked); connect(ui->btnCancelDeletion, &QPushButton::clicked, this, &CPromptDialog::onCancelClicked); connect(ui->btnDeleteAnyway, &QPushButton::clicked, this, &CPromptDialog::onProceedClicked); connect(ui->btnDeleteAllAnyway, &QPushButton::clicked, this, &CPromptDialog::onProceedAllClicked); connect(ui->btnOverwrite, &QPushButton::clicked, this, &CPromptDialog::onProceedClicked); connect(ui->btnOverwriteAll, &QPushButton::clicked, this, &CPromptDialog::onProceedAllClicked); connect(ui->btnRename, &QPushButton::clicked, this, &CPromptDialog::onRenameClicked); connect(ui->btnSkip, &QPushButton::clicked, this, &CPromptDialog::onSkipClicked); connect(ui->btnSkipAll, &QPushButton::clicked, this, &CPromptDialog::onSkipAllClicked); connect(ui->btnSkipDeletion, &QPushButton::clicked, this, &CPromptDialog::onSkipClicked); connect(ui->btnSkipAllDeletion, &QPushButton::clicked, this, &CPromptDialog::onSkipAllClicked); connect(ui->btnRetry, &QPushButton::clicked, this, &CPromptDialog::onRetryClicked); switch (promptReason) { case hrFileExists: ui->lblQuestion->setText("File or folder already exists."); break; case hrSourceFileIsReadOnly: ui->btnOverwrite->setVisible(false); ui->btnOverwriteAll->setVisible(false); ui->btnRename->setVisible(false); ui->lblQuestion->setText("The source file or folder is read-only."); break; case hrDestFileIsReadOnly: ui->lblQuestion->setText("The destination file or folder is read-only."); break; case hrFailedToMakeItemWritable: ui->lblQuestion->setText("Failed to make the file or folder writable."); ui->btnOverwrite->setVisible(false); ui->btnOverwriteAll->setVisible(false); ui->btnRename->setVisible(false); case hrFileDoesntExit: ui->lblQuestion->setText("The file or folder doesn't exist."); ui->btnOverwrite->setVisible(false); ui->btnOverwriteAll->setVisible(false); ui->btnRename->setVisible(false); ui->btnDeleteAllAnyway->setVisible(false); ui->btnDeleteAnyway->setVisible(false); break; case hrCreatingFolderFailed: ui->lblQuestion->setText(tr("Failed to create the folder\n%1").arg(source.fullAbsolutePath())); ui->btnOverwrite->setVisible(false); ui->btnOverwriteAll->setVisible(false); ui->btnRename->setVisible(false); break; case hrFailedToDelete: ui->btnOverwrite->setVisible(false); ui->btnOverwriteAll->setVisible(false); ui->btnDeleteAnyway->setVisible(false); ui->btnDeleteAllAnyway->setVisible(false); ui->btnRename->setVisible(false); ui->lblQuestion->setText(tr("Failed to delete\n%1").arg(source.fullAbsolutePath())); break; case hrUnknownError: ui->lblQuestion->setText("An unknown error occurred. What do you want to do?"); ui->btnOverwrite->setVisible(false); ui->btnOverwriteAll->setVisible(false); ui->btnRename->setVisible(false); break; default: ui->lblQuestion->setText("An unknown error occurred. What do you want to do?"); break; } if (!message.isEmpty()) ui->lblQuestion->setText(ui->lblQuestion->text() + "\n\n" + message); if (op == operationDelete || promptReason == hrSourceFileIsReadOnly || promptReason == hrFailedToMakeItemWritable) { ui->stackedWidget->setCurrentIndex(1); ui->m_lblItemBeingDeleted->setText(source.fullAbsolutePath()); ui->lblSize->setText(fileSizeToString(source.size())); QDateTime modificationDate; modificationDate.setTime_t((uint)source.properties().modificationDate); modificationDate = modificationDate.toLocalTime(); ui->lblModTime->setText(modificationDate.toString("dd.MM.yyyy hh:mm")); } else { ui->stackedWidget->setCurrentIndex(0); if (source.isValid()) { ui->lblSrcFile->setText(source.fullAbsolutePath()); ui->lblSourceSize->setText(fileSizeToString(source.size())); QDateTime modificationDate; modificationDate.setTime_t((uint)source.properties().modificationDate); modificationDate = modificationDate.toLocalTime(); ui->lblSourceModTime->setText(modificationDate.toString("dd.MM.yyyy hh:mm")); } else WidgetUtils::setLayoutVisible(ui->sourceFileInfo, false); if (dest.isValid()) { ui->lblDstFile->setText(dest.fullAbsolutePath()); ui->lblDestSize->setText(fileSizeToString(dest.size())); QDateTime modificationDate; modificationDate.setTime_t((uint)dest.properties().modificationDate); modificationDate = modificationDate.toLocalTime(); ui->lblDestModTime->setText(modificationDate.toString("dd.MM.yyyy hh:mm")); } else WidgetUtils::setLayoutVisible(ui->destFileInfo, false); } _srcFileName = source.fullName(); }
bool CFileSystemObject::operator==(const CFileSystemObject& other) const { return hash() == other.hash(); }