summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--dive.h1
-rw-r--r--qthelper.cpp7
-rw-r--r--windows.c44
3 files changed, 51 insertions, 1 deletions
diff --git a/dive.h b/dive.h
index 3bcc7b0e2..71a9ab8f2 100644
--- a/dive.h
+++ b/dive.h
@@ -682,6 +682,7 @@ struct user_info {
extern void subsurface_user_info(struct user_info *);
extern int subsurface_rename(const char *path, const char *newpath);
+extern int subsurface_dir_rename(const char *path, const char *newpath);
extern int subsurface_open(const char *path, int oflags, mode_t mode);
extern FILE *subsurface_fopen(const char *path, const char *mode);
extern void *subsurface_opendir(const char *path);
diff --git a/qthelper.cpp b/qthelper.cpp
index c316481f2..31ec43df7 100644
--- a/qthelper.cpp
+++ b/qthelper.cpp
@@ -644,7 +644,12 @@ extern "C" char *move_away(const char *old_path)
if (!oldDir.rename(old_path, newPath)) {
if (verbose)
qDebug() << "rename of" << old_path << "to" << newPath << "failed";
- return strdup("");
+ // this next one we only try on Windows... if we are on a different platform
+ // we simply give up and return an empty string
+#ifdef WIN32
+ if (subsurface_dir_rename(old_path, qPrintable(newPath)) == 0)
+#endif
+ return strdup("");
}
return strdup(qPrintable(newPath));
}
diff --git a/windows.c b/windows.c
index 7d1f1e8af..652a95a26 100644
--- a/windows.c
+++ b/windows.c
@@ -188,6 +188,50 @@ int subsurface_rename(const char *path, const char *newpath)
return ret;
}
+// if the QDir based rename fails, we try this one
+int subsurface_dir_rename(const char *path, const char *newpath)
+{
+ // check if the folder exists
+ BOOL exists = FALSE;
+ DWORD attrib = GetFileAttributes(path);
+ if (attrib != INVALID_FILE_ATTRIBUTES && attrib & FILE_ATTRIBUTE_DIRECTORY)
+ exists = TRUE;
+ if (!exists && verbose) {
+ fprintf(stderr, "folder not found or path is not a folder: %s\n", path);
+ return EXIT_FAILURE;
+ }
+
+ // list of error codes:
+ // https://msdn.microsoft.com/en-us/library/windows/desktop/ms681381(v=vs.85).aspx
+ DWORD errorCode;
+
+ // if this fails something has already obatained (more) exclusive access to the folder
+ HANDLE h = CreateFile(path, GENERIC_WRITE, FILE_SHARE_WRITE |
+ FILE_SHARE_DELETE, 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
+ if (h == INVALID_HANDLE_VALUE) {
+ errorCode = GetLastError();
+ if (verbose)
+ fprintf(stderr, "cannot obtain exclusive write access for folder: %u\n", (unsigned int)errorCode );
+ return EXIT_FAILURE;
+ } else {
+ if (verbose)
+ fprintf(stderr, "exclusive write access obtained...closing handle!");
+ CloseHandle(h);
+
+ // attempt to rename
+ BOOL result = MoveFile(path, newpath);
+ if (!result) {
+ errorCode = GetLastError();
+ if (verbose)
+ fprintf(stderr, "rename failed: %u\n", (unsigned int)errorCode);
+ return EXIT_FAILURE;
+ }
+ if (verbose > 1)
+ fprintf(stderr, "folder rename success: %s ---> %s\n", path, newpath);
+ }
+ return EXIT_SUCCESS;
+}
+
int subsurface_open(const char *path, int oflags, mode_t mode)
{
int ret = -1;