From 60f283cffb85fc6ffe4e8597fbecf9e196943058 Mon Sep 17 00:00:00 2001 From: Zhang Zhaolong Date: Mon, 18 Aug 2014 16:00:34 +0800 Subject: [PATCH] drive: fix contents lost when cut-paste a folder. --- channels/drive/client/drive_file.c | 31 ++++++++++++++++++++++++++++++ channels/drive/client/drive_file.h | 1 + channels/drive/client/drive_main.c | 3 +++ 3 files changed, 35 insertions(+) diff --git a/channels/drive/client/drive_file.c b/channels/drive/client/drive_file.c index d7b3852fc..9e8103b06 100644 --- a/channels/drive/client/drive_file.c +++ b/channels/drive/client/drive_file.c @@ -52,6 +52,11 @@ #include #endif +#ifdef _WIN32 +#pragma comment(lib, "Shlwapi.lib") +#include +#endif + #include "drive_file.h" #ifdef _WIN32 @@ -425,6 +430,29 @@ BOOL drive_file_query_information(DRIVE_FILE* file, UINT32 FsInformationClass, w return TRUE; } +int dir_empty(const char *path) +{ +#ifdef _WIN32 + return PathIsDirectoryEmptyA(path); +#else + struct dirent *dp; + int empty = 1; + + DIR *dir = opendir(path); + if (dir == NULL) //Not a directory or doesn't exist + return 1; + + while ((dp = readdir(dir)) != NULL) { + if (strcmp(dp->d_name, ".") == 0 || strcmp(dp->d_name, "..") == 0) + continue; /* Skip . and .. */ + + empty = 0; + break; + } + closedir(dir); + return empty; +#endif +} BOOL drive_file_set_information(DRIVE_FILE* file, UINT32 FsInformationClass, UINT32 Length, wStream* input) { char* s = NULL; @@ -492,6 +520,9 @@ BOOL drive_file_set_information(DRIVE_FILE* file, UINT32 FsInformationClass, UIN case FileDispositionInformation: /* http://msdn.microsoft.com/en-us/library/cc232098.aspx */ /* http://msdn.microsoft.com/en-us/library/cc241371.aspx */ + if (file->is_dir && !dir_empty(file->fullpath)) + break; + if (Length) Stream_Read_UINT8(input, file->delete_pending); else diff --git a/channels/drive/client/drive_file.h b/channels/drive/client/drive_file.h index 28ac5780a..36b869c72 100644 --- a/channels/drive/client/drive_file.h +++ b/channels/drive/client/drive_file.h @@ -117,6 +117,7 @@ BOOL drive_file_query_information(DRIVE_FILE* file, UINT32 FsInformationClass, w BOOL drive_file_set_information(DRIVE_FILE* file, UINT32 FsInformationClass, UINT32 Length, wStream* input); BOOL drive_file_query_directory(DRIVE_FILE* file, UINT32 FsInformationClass, BYTE InitialQuery, const char* path, wStream* output); +int dir_empty(const char *path); extern UINT sys_code_page; diff --git a/channels/drive/client/drive_main.c b/channels/drive/client/drive_main.c index 0363b6b41..36dd232d4 100644 --- a/channels/drive/client/drive_main.c +++ b/channels/drive/client/drive_main.c @@ -346,6 +346,9 @@ static void drive_process_irp_set_information(DRIVE_DEVICE* drive, IRP* irp) } + if (file->is_dir && !dir_empty(file->fullpath)) + irp->IoStatus = STATUS_DIRECTORY_NOT_EMPTY; + Stream_Write_UINT32(irp->output, Length); irp->Complete(irp);