[bug] Windows-to-Linux remote mount ignores CREATE_NEW #44
This commit is contained in:
		| @@ -10,6 +10,7 @@ | |||||||
| * ~~\#33 Complete initial v2.0 documentation~~ | * ~~\#33 Complete initial v2.0 documentation~~ | ||||||
| * \#42 [bug] Remote mount directory listing on Windows connected to Linux is failing | * \#42 [bug] Remote mount directory listing on Windows connected to Linux is failing | ||||||
| * \#43 [bug] Directories are not importing properly for Sia | * \#43 [bug] Directories are not importing properly for Sia | ||||||
|  | * \#44 [bug] Windows-to-Linux remote mount ignores `CREATE_NEW` | ||||||
|  |  | ||||||
| ### Changes from v2.0.5-rc | ### Changes from v2.0.5-rc | ||||||
|  |  | ||||||
|   | |||||||
| @@ -222,7 +222,6 @@ using WCHAR = wchar_t; | |||||||
|  |  | ||||||
| #define MAX_PATH 260 | #define MAX_PATH 260 | ||||||
|  |  | ||||||
| #define STATUS_SUCCESS std::uint32_t{0U} |  | ||||||
| #define STATUS_ACCESS_DENIED std::uint32_t{0xC0000022L} | #define STATUS_ACCESS_DENIED std::uint32_t{0xC0000022L} | ||||||
| #define STATUS_DEVICE_BUSY std::uint32_t{0x80000011L} | #define STATUS_DEVICE_BUSY std::uint32_t{0x80000011L} | ||||||
| #define STATUS_DEVICE_INSUFFICIENT_RESOURCES std::uint32_t{0xC0000468L} | #define STATUS_DEVICE_INSUFFICIENT_RESOURCES std::uint32_t{0xC0000468L} | ||||||
| @@ -235,11 +234,13 @@ using WCHAR = wchar_t; | |||||||
| #define STATUS_INVALID_HANDLE std::uint32_t{0xC0000006L} | #define STATUS_INVALID_HANDLE std::uint32_t{0xC0000006L} | ||||||
| #define STATUS_INVALID_IMAGE_FORMAT std::uint32_t{0xC000007BL} | #define STATUS_INVALID_IMAGE_FORMAT std::uint32_t{0xC000007BL} | ||||||
| #define STATUS_INVALID_PARAMETER std::uint32_t{0xC000000DL} | #define STATUS_INVALID_PARAMETER std::uint32_t{0xC000000DL} | ||||||
| #define STATUS_NO_MEMORY std::uint32_t{0xC0000017L} |  | ||||||
| #define STATUS_NOT_IMPLEMENTED std::uint32_t{0xC0000002L} | #define STATUS_NOT_IMPLEMENTED std::uint32_t{0xC0000002L} | ||||||
|  | #define STATUS_NO_MEMORY std::uint32_t{0xC0000017L} | ||||||
|  | #define STATUS_OBJECT_NAME_COLLISION std::uint32_t{0xC0000035L} | ||||||
| #define STATUS_OBJECT_NAME_EXISTS std::uint32_t{0x40000000L} | #define STATUS_OBJECT_NAME_EXISTS std::uint32_t{0x40000000L} | ||||||
| #define STATUS_OBJECT_NAME_NOT_FOUND std::uint32_t{0xC0000034L} | #define STATUS_OBJECT_NAME_NOT_FOUND std::uint32_t{0xC0000034L} | ||||||
| #define STATUS_OBJECT_PATH_INVALID std::uint32_t{0xC0000039L} | #define STATUS_OBJECT_PATH_INVALID std::uint32_t{0xC0000039L} | ||||||
|  | #define STATUS_SUCCESS std::uint32_t{0U} | ||||||
| #define STATUS_UNEXPECTED_IO_ERROR std::uint32_t{0xC00000E9L} | #define STATUS_UNEXPECTED_IO_ERROR std::uint32_t{0xC00000E9L} | ||||||
|  |  | ||||||
| #define CONVERT_STATUS_NOT_IMPLEMENTED(e)                                      \ | #define CONVERT_STATUS_NOT_IMPLEMENTED(e)                                      \ | ||||||
|   | |||||||
| @@ -1120,49 +1120,56 @@ auto remote_server::winfsp_create(PWSTR file_name, UINT32 create_options, | |||||||
|     -> packet::error_type { |     -> packet::error_type { | ||||||
|   REPERTORY_USES_FUNCTION_NAME(); |   REPERTORY_USES_FUNCTION_NAME(); | ||||||
|  |  | ||||||
|   const auto relative_path = utils::string::to_utf8(file_name); |   auto relative_path = utils::string::to_utf8(file_name); | ||||||
|   const auto file_path = construct_path(relative_path); |   auto file_path = construct_path(relative_path); | ||||||
|   exists = utils::file::file(file_path).exists(); |   exists = utils::file::file{file_path}.exists() || | ||||||
|  |            utils::file::directory{file_path}.exists(); | ||||||
|  |  | ||||||
|   if ((create_options & FILE_DIRECTORY_FILE) != 0U) { |   auto ret{static_cast<packet::error_type>(STATUS_SUCCESS)}; | ||||||
|     attributes |= FILE_ATTRIBUTE_DIRECTORY; |   if (exists) { | ||||||
|  |     ret = static_cast<packet::error_type>(STATUS_OBJECT_NAME_COLLISION); | ||||||
|   } else { |   } else { | ||||||
|     attributes &= static_cast<UINT32>(~FILE_ATTRIBUTE_DIRECTORY); |     if ((create_options & FILE_DIRECTORY_FILE) != 0U) { | ||||||
|     attributes |= FILE_ATTRIBUTE_ARCHIVE; |       attributes |= FILE_ATTRIBUTE_DIRECTORY; | ||||||
|   } |     } else { | ||||||
|  |       attributes &= static_cast<UINT32>(~FILE_ATTRIBUTE_DIRECTORY); | ||||||
|   remote::file_mode mode{0U}; |       attributes |= FILE_ATTRIBUTE_ARCHIVE; | ||||||
|   std::uint32_t flags{0U}; |  | ||||||
|   utils::windows_create_to_unix(create_options, granted_access, flags, mode); |  | ||||||
|  |  | ||||||
|   int res = 0; |  | ||||||
|   if ((create_options & FILE_DIRECTORY_FILE) != 0U) { |  | ||||||
|     res = mkdir(file_path.c_str(), mode); |  | ||||||
|     if (res >= 0) { |  | ||||||
|       res = open(file_path.c_str(), static_cast<int>(flags)); |  | ||||||
|     } |     } | ||||||
|   } else { |  | ||||||
|     res = open(file_path.c_str(), static_cast<int>(flags), mode); |     remote::file_mode mode{0U}; | ||||||
|  |     std::uint32_t flags{0U}; | ||||||
|  |     utils::windows_create_to_unix(create_options, granted_access, flags, mode); | ||||||
|  |  | ||||||
|  |     int res = 0; | ||||||
|  |     if ((create_options & FILE_DIRECTORY_FILE) != 0U) { | ||||||
|  |       res = mkdir(file_path.c_str(), mode); | ||||||
|  |       if (res >= 0) { | ||||||
|  |         res = open(file_path.c_str(), static_cast<int>(flags)); | ||||||
|  |       } | ||||||
|  |     } else { | ||||||
|  |       res = open(file_path.c_str(), static_cast<int>(flags), mode); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     if (res >= 0) { | ||||||
|  |       *file_desc = reinterpret_cast<PVOID>(res); | ||||||
|  |       drive_.set_item_meta(construct_api_path(file_path), META_ATTRIBUTES, | ||||||
|  |                            std::to_string(attributes)); | ||||||
|  |       set_open_info(res, open_info{ | ||||||
|  |                              "", | ||||||
|  |                              nullptr, | ||||||
|  |                              {}, | ||||||
|  |                              file_path, | ||||||
|  |                          }); | ||||||
|  |  | ||||||
|  |       const auto api_path = utils::path::create_api_path(relative_path); | ||||||
|  |       normalized_name = utils::string::replace_copy(api_path, '/', '\\'); | ||||||
|  |       populate_file_info(api_path, 0, attributes, *file_info); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     ret = static_cast<packet::error_type>( | ||||||
|  |         utils::unix_error_to_windows((res < 0) ? errno : 0)); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   if (res >= 0) { |  | ||||||
|     *file_desc = reinterpret_cast<PVOID>(res); |  | ||||||
|     drive_.set_item_meta(construct_api_path(file_path), META_ATTRIBUTES, |  | ||||||
|                          std::to_string(attributes)); |  | ||||||
|     set_open_info(res, open_info{ |  | ||||||
|                            "", |  | ||||||
|                            nullptr, |  | ||||||
|                            {}, |  | ||||||
|                            file_path, |  | ||||||
|                        }); |  | ||||||
|  |  | ||||||
|     const auto api_path = utils::path::create_api_path(relative_path); |  | ||||||
|     normalized_name = utils::string::replace_copy(api_path, '/', '\\'); |  | ||||||
|     populate_file_info(api_path, 0, attributes, *file_info); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   auto ret = static_cast<packet::error_type>( |  | ||||||
|       utils::unix_error_to_windows((res < 0) ? errno : 0)); |  | ||||||
|   RAISE_REMOTE_FUSE_SERVER_EVENT(function_name, file_path, ret); |   RAISE_REMOTE_FUSE_SERVER_EVENT(function_name, file_path, ret); | ||||||
|   return ret; |   return ret; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -188,23 +188,21 @@ auto remote_client::winfsp_create(PWSTR file_name, UINT32 create_options, | |||||||
|     DECODE_OR_IGNORE(&response, normalized_name); |     DECODE_OR_IGNORE(&response, normalized_name); | ||||||
|     DECODE_OR_IGNORE(&response, exists); |     DECODE_OR_IGNORE(&response, exists); | ||||||
|  |  | ||||||
|     if (ret == STATUS_SUCCESS) { |     *file_desc = reinterpret_cast<PVOID>(handle); | ||||||
|       *file_desc = reinterpret_cast<PVOID>(handle); |     set_open_info(to_handle(*file_desc), open_info{ | ||||||
|       set_open_info(to_handle(*file_desc), |                                              "", | ||||||
|                     open_info{ |                                              nullptr, | ||||||
|                         "", |                                              {}, | ||||||
|                         nullptr, |                                              utils::string::to_utf8(file_name), | ||||||
|                         {}, |                                          }); | ||||||
|                         utils::string::to_utf8(file_name), |  | ||||||
|                     }); |  | ||||||
| #if defined(_WIN32) |  | ||||||
|       if (exists) { |  | ||||||
|         ::SetLastError(ERROR_ALREADY_EXISTS); |  | ||||||
|       } |  | ||||||
| #endif |  | ||||||
|     } |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  | #if defined(_WIN32) | ||||||
|  |   if (ret == STATUS_OBJECT_NAME_COLLISION && exists != 0U) { | ||||||
|  |     ::SetLastError(ERROR_ALREADY_EXISTS); | ||||||
|  |   } | ||||||
|  | #endif // defined(_WIN32) | ||||||
|  |  | ||||||
|   return ret; |   return ret; | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user