aboutsummaryrefslogtreecommitdiffstats
path: root/file.c
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2012-05-26 00:44:49 +0000
committerGuy Harris <guy@alum.mit.edu>2012-05-26 00:44:49 +0000
commit3d3b154b12ec958ee12473f6334a7567cf1a5e5e (patch)
tree7699e7e0b44c555875e22e2e4a002fd54d14f3c6 /file.c
parent92f38021bf69cee23a8cf22366bede8d520d11cd (diff)
We can't save a live capture file with a ws_rename() on Windows, as we
have the file open. Go back to doing it with a copy on Windows. Explain what the problem is, and give a way in which we might be able to make it work on Windows (without using any NT native API calls...). svn path=/trunk/; revision=42859
Diffstat (limited to 'file.c')
-rw-r--r--file.c31
1 files changed, 26 insertions, 5 deletions
diff --git a/file.c b/file.c
index 3322f679df..8557314a55 100644
--- a/file.c
+++ b/file.c
@@ -3836,11 +3836,28 @@ cf_save_packets(capture_file *cf, const char *fname, guint save_format,
first, try renaming the capture buffer file to the new name.
This acts as a "safe save", in that, if the file already
exists, the existing file will be removed only if the rename
- succeeds. (This is true even on Windows, as we're using
- ws_rename(), which is #defined to be ws_stdio_rename() on
- Windows, and ws_stdio_rename() uses MoveFileEx() with
- MOVEFILE_REPLACE_EXISTING, so it will remove the target if
- it exists. */
+ succeeds.
+
+ Sadly, on Windows, as we have the current capture file
+ open, even MoveFileEx() with MOVEFILE_REPLACE_EXISTING
+ (to cause the rename to remove an existing target), as
+ done by ws_stdio_rename() (ws_rename() is #defined to
+ be ws_stdio_rename() on Windows) will fail.
+
+ According to the MSDN documentation for CreateFile(), if,
+ when we open a capture file, we were to directly do a CreateFile(),
+ opening with FILE_SHARE_DELETE|FILE_SHARE_READ, and then
+ convert it to a file descriptor with _open_osfhandle(),
+ that would allow the file to be renamed out from under us.
+
+ It would also allow it to be deleted out from under us; according
+ to the MSDN documentation on DeleteFile(), "The DeleteFile function
+ marks a file for deletion on close. Therefore, the file deletion
+ does not occur until the last handle to the file is closed.
+ Subsequent calls to CreateFile to open the file fail with
+ ERROR_ACCESS_DENIED.", so it sounds as if deleting it out from
+ under us would be safe. */
+#ifndef _WIN32
if (ws_rename(cf->filename, fname) == 0) {
/* That succeeded - there's no need to copy the source file. */
do_copy = FALSE;
@@ -3862,6 +3879,10 @@ cf_save_packets(capture_file *cf, const char *fname, guint save_format,
goto fail;
}
}
+#else
+ do_copy = TRUE;
+ from_filename = cf->filename;
+#endif
} else {
/* It's a permanent file, so we should copy it, and not remove the
original. */