@@ -671,32 +671,70 @@ bool FileSystem::moveToTrash(const QString &fileName, QString *errorString)
671671 return true ;
672672}
673673
674- bool FileSystem::isFileLocked (const QString &fileName)
674+ namespace {
675+
676+ /* *
677+ * This function creates a file handle with the desired LockMode
678+ */
679+ #if defined Q_OS_WIN
680+ Utility::Handle lockFile (const QString &fileName, FileSystem::LockMode mode)
675681{
676- #ifdef Q_OS_WIN
682+ const QString fName = FileSystem::longWinPath (fileName);
683+ int shareMode = 0 ;
684+ int accessMode = GENERIC_READ | GENERIC_WRITE;
685+ switch (mode) {
686+ case FileSystem::LockMode::Exclusive:
687+ shareMode = 0 ;
688+ break ;
689+ case FileSystem::LockMode::Shared:
690+ shareMode = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
691+ break ;
692+ case FileSystem::LockMode::SharedRead:
693+ shareMode = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
694+ accessMode = GENERIC_READ;
695+ break ;
696+ }
677697 // Check if file exists
678- const QString fName = longWinPath (fileName);
679698 DWORD attr = GetFileAttributesW (reinterpret_cast <const wchar_t *>(fName .utf16 ()));
680699 if (attr != INVALID_FILE_ATTRIBUTES) {
681700 // Try to open the file with as much access as possible..
682- HANDLE win_h = CreateFileW (
683- reinterpret_cast <const wchar_t *>(fName .utf16 ()),
684- GENERIC_READ | GENERIC_WRITE,
685- FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
686- nullptr , OPEN_EXISTING,
687- FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS,
688- nullptr );
689-
690- if (win_h == INVALID_HANDLE_VALUE) {
691- /* could not be opened, so locked? */
692- /* 32 == ERROR_SHARING_VIOLATION */
701+ auto out = Utility::Handle{CreateFileW (reinterpret_cast <const wchar_t *>(fName .utf16 ()), accessMode, shareMode, nullptr , OPEN_EXISTING,
702+ FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS, nullptr )};
703+
704+ if (out) {
705+ LARGE_INTEGER start;
706+ start.QuadPart = 0 ;
707+ LARGE_INTEGER end;
708+ end.QuadPart = -1 ;
709+ if (LockFile (out.handle (), start.LowPart , start.HighPart , end.LowPart , end.HighPart )) {
710+ return out;
711+ } else {
712+ return {};
713+ }
714+ }
715+ return out;
716+ }
717+ return {};
718+ }
719+ #endif
720+
721+ }
722+
723+ bool FileSystem::isFileLocked (const QString &fileName, LockMode mode)
724+ {
725+ #ifdef Q_OS_WIN
726+ const auto handle = lockFile (fileName, mode);
727+ if (!handle) {
728+ const auto error = GetLastError ();
729+ if (error == ERROR_SHARING_VIOLATION || error == ERROR_LOCK_VIOLATION) {
693730 return true ;
694- } else {
695- CloseHandle (win_h );
731+ } else if (error != ERROR_FILE_NOT_FOUND && error != ERROR_PATH_NOT_FOUND) {
732+ qCWarning ( lcFileSystem ()) << Q_FUNC_INFO << Utility::formatWinError (error );
696733 }
697734 }
698735#else
699736 Q_UNUSED (fileName);
737+ Q_UNUSED (mode);
700738#endif
701739 return false ;
702740}
0 commit comments