From 3d3b154b12ec958ee12473f6334a7567cf1a5e5e Mon Sep 17 00:00:00 2001 From: Guy Harris Date: Sat, 26 May 2012 00:44:49 +0000 Subject: [PATCH] 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 --- file.c | 31 ++++++++++++++++++++++++++----- 1 file 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. */