leveldb-1.22_windows_paths.patch 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. diff --git a/util/env_windows.cc b/util/env_windows.cc
  2. index 09e3df6..5d9b2f2 100644
  3. --- a/util/env_windows.cc
  4. +++ b/util/env_windows.cc
  5. @@ -362,9 +362,11 @@ class WindowsEnv : public Env {
  6. *result = nullptr;
  7. DWORD desired_access = GENERIC_READ;
  8. DWORD share_mode = FILE_SHARE_READ;
  9. - ScopedHandle handle =
  10. - ::CreateFileA(fname.c_str(), desired_access, share_mode, nullptr,
  11. - OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
  12. + auto wFilename = toUtf16(fname);
  13. + ScopedHandle handle = ::CreateFileW(
  14. + wFilename.c_str(), desired_access, share_mode,
  15. + /*lpSecurityAttributes=*/nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
  16. + /*hTemplateFile=*/nullptr);
  17. if (!handle.is_valid()) {
  18. return WindowsError(fname, ::GetLastError());
  19. }
  20. @@ -378,10 +380,12 @@ class WindowsEnv : public Env {
  21. DWORD desired_access = GENERIC_READ;
  22. DWORD share_mode = FILE_SHARE_READ;
  23. DWORD file_flags = FILE_ATTRIBUTE_READONLY;
  24. -
  25. + auto wFilename = toUtf16(fname);
  26. ScopedHandle handle =
  27. - ::CreateFileA(fname.c_str(), desired_access, share_mode, nullptr,
  28. - OPEN_EXISTING, file_flags, nullptr);
  29. + ::CreateFileW(wFilename.c_str(), desired_access, share_mode,
  30. + /*lpSecurityAttributes=*/nullptr, OPEN_EXISTING,
  31. + FILE_ATTRIBUTE_READONLY,
  32. + /*hTemplateFile=*/nullptr);
  33. if (!handle.is_valid()) {
  34. return WindowsError(fname, ::GetLastError());
  35. }
  36. @@ -396,10 +400,12 @@ class WindowsEnv : public Env {
  37. }
  38. ScopedHandle mapping =
  39. - ::CreateFileMappingA(handle.get(),
  40. - /*security attributes=*/nullptr, PAGE_READONLY,
  41. - /*dwMaximumSizeHigh=*/0,
  42. - /*dwMaximumSizeLow=*/0, nullptr);
  43. + ::CreateFileMappingW(handle.get(),
  44. + /*security attributes=*/nullptr,
  45. + PAGE_READONLY,
  46. + /*dwMaximumSizeHigh=*/0,
  47. + /*dwMaximumSizeLow=*/0,
  48. + /*lpName=*/nullptr);
  49. if (mapping.is_valid()) {
  50. void* base = MapViewOfFile(mapping.get(), FILE_MAP_READ, 0, 0, 0);
  51. if (base) {
  52. @@ -421,10 +427,11 @@ class WindowsEnv : public Env {
  53. WritableFile** result) override {
  54. DWORD desired_access = GENERIC_WRITE;
  55. DWORD share_mode = 0;
  56. -
  57. - ScopedHandle handle =
  58. - ::CreateFileA(fname.c_str(), desired_access, share_mode, nullptr,
  59. - CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);
  60. + auto wFilename = toUtf16(fname);
  61. + ScopedHandle handle = ::CreateFileW(
  62. + wFilename.c_str(), desired_access, share_mode,
  63. + /*lpSecurityAttributes=*/nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL,
  64. + /*hTemplateFile=*/nullptr);
  65. if (!handle.is_valid()) {
  66. *result = nullptr;
  67. return WindowsError(fname, ::GetLastError());
  68. @@ -436,9 +443,13 @@ class WindowsEnv : public Env {
  69. Status NewAppendableFile(const std::string& fname,
  70. WritableFile** result) override {
  71. - ScopedHandle handle =
  72. - ::CreateFileA(fname.c_str(), FILE_APPEND_DATA, 0, nullptr, OPEN_ALWAYS,
  73. - FILE_ATTRIBUTE_NORMAL, nullptr);
  74. + DWORD desired_access = FILE_APPEND_DATA;
  75. + DWORD share_mode = 0; // Exclusive access.
  76. + auto wFilename = toUtf16(fname);
  77. + ScopedHandle handle = ::CreateFileW(
  78. + wFilename.c_str(), desired_access, share_mode,
  79. + /*lpSecurityAttributes=*/nullptr, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL,
  80. + /*hTemplateFile=*/nullptr);
  81. if (!handle.is_valid()) {
  82. *result = nullptr;
  83. return WindowsError(fname, ::GetLastError());
  84. @@ -449,14 +460,16 @@ class WindowsEnv : public Env {
  85. }
  86. bool FileExists(const std::string& fname) override {
  87. - return GetFileAttributesA(fname.c_str()) != INVALID_FILE_ATTRIBUTES;
  88. + auto wFilename = toUtf16(fname);
  89. + return GetFileAttributesW(wFilename.c_str()) != INVALID_FILE_ATTRIBUTES;
  90. }
  91. Status GetChildren(const std::string& dir,
  92. std::vector<std::string>* result) override {
  93. const std::string find_pattern = dir + "\\*";
  94. - WIN32_FIND_DATAA find_data;
  95. - HANDLE dir_handle = ::FindFirstFileA(find_pattern.c_str(), &find_data);
  96. + WIN32_FIND_DATAW find_data;
  97. + auto wFind_pattern = toUtf16(find_pattern);
  98. + HANDLE dir_handle = ::FindFirstFileW(wFind_pattern.c_str(), &find_data);
  99. if (dir_handle == INVALID_HANDLE_VALUE) {
  100. DWORD last_error = ::GetLastError();
  101. if (last_error == ERROR_FILE_NOT_FOUND) {
  102. @@ -468,11 +481,12 @@ class WindowsEnv : public Env {
  103. char base_name[_MAX_FNAME];
  104. char ext[_MAX_EXT];
  105. - if (!_splitpath_s(find_data.cFileName, nullptr, 0, nullptr, 0, base_name,
  106. + auto find_data_filename = toUtf8(find_data.cFileName);
  107. + if (!_splitpath_s(find_data_filename.c_str(), nullptr, 0, nullptr, 0, base_name,
  108. ARRAYSIZE(base_name), ext, ARRAYSIZE(ext))) {
  109. result->emplace_back(std::string(base_name) + ext);
  110. }
  111. - } while (::FindNextFileA(dir_handle, &find_data));
  112. + } while (::FindNextFileW(dir_handle, &find_data));
  113. DWORD last_error = ::GetLastError();
  114. ::FindClose(dir_handle);
  115. if (last_error != ERROR_NO_MORE_FILES) {
  116. @@ -482,21 +496,24 @@ class WindowsEnv : public Env {
  117. }
  118. Status DeleteFile(const std::string& fname) override {
  119. - if (!::DeleteFileA(fname.c_str())) {
  120. + auto wFilename = toUtf16(fname);
  121. + if (!::DeleteFileW(wFilename.c_str())) {
  122. return WindowsError(fname, ::GetLastError());
  123. }
  124. return Status::OK();
  125. }
  126. Status CreateDir(const std::string& name) override {
  127. - if (!::CreateDirectoryA(name.c_str(), nullptr)) {
  128. + auto wDirname = toUtf16(name);
  129. + if (!::CreateDirectoryW(wDirname.c_str(), nullptr)) {
  130. return WindowsError(name, ::GetLastError());
  131. }
  132. return Status::OK();
  133. }
  134. Status DeleteDir(const std::string& name) override {
  135. - if (!::RemoveDirectoryA(name.c_str())) {
  136. + auto wDirname = toUtf16(name);
  137. + if (!::RemoveDirectoryW(wDirname.c_str())) {
  138. return WindowsError(name, ::GetLastError());
  139. }
  140. return Status::OK();
  141. @@ -504,7 +521,9 @@ class WindowsEnv : public Env {
  142. Status GetFileSize(const std::string& fname, uint64_t* size) override {
  143. WIN32_FILE_ATTRIBUTE_DATA attrs;
  144. - if (!::GetFileAttributesExA(fname.c_str(), GetFileExInfoStandard, &attrs)) {
  145. + auto wFilename = toUtf16(filename);
  146. + if (!::GetFileAttributesExW(wFilename.c_str(), GetFileExInfoStandard,
  147. + &attrs)) {
  148. return WindowsError(fname, ::GetLastError());
  149. }
  150. ULARGE_INTEGER file_size;
  151. @@ -518,7 +537,9 @@ class WindowsEnv : public Env {
  152. const std::string& target) override {
  153. // Try a simple move first. It will only succeed when |to_path| doesn't
  154. // already exist.
  155. - if (::MoveFileA(src.c_str(), target.c_str())) {
  156. + auto wFrom = toUtf16(src);
  157. + auto wTo = toUtf16(target);
  158. + if (::MoveFileW(wFrom.c_str(), wTo.c_str())) {
  159. return Status::OK();
  160. }
  161. DWORD move_error = ::GetLastError();
  162. @@ -527,7 +548,7 @@ class WindowsEnv : public Env {
  163. // succeed when |to_path| does exist. When writing to a network share, we
  164. // may not be able to change the ACLs. Ignore ACL errors then
  165. // (REPLACEFILE_IGNORE_MERGE_ERRORS).
  166. - if (::ReplaceFileA(target.c_str(), src.c_str(), nullptr,
  167. + if (::ReplaceFileW(wTo.c_str(), wFrom.c_str(), /*lpBackupFileName=*/nullptr,
  168. REPLACEFILE_IGNORE_MERGE_ERRORS, nullptr, nullptr)) {
  169. return Status::OK();
  170. }
  171. @@ -546,8 +567,9 @@ class WindowsEnv : public Env {
  172. Status LockFile(const std::string& fname, FileLock** lock) override {
  173. *lock = nullptr;
  174. Status result;
  175. - ScopedHandle handle = ::CreateFileA(
  176. - fname.c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ,
  177. + auto wFilename = toUtf16(fname);
  178. + ScopedHandle handle = ::CreateFileW(
  179. + wFilename.c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ,
  180. /*lpSecurityAttributes=*/nullptr, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL,
  181. nullptr);
  182. if (!handle.is_valid()) {
  183. @@ -584,10 +606,11 @@ class WindowsEnv : public Env {
  184. return Status::OK();
  185. }
  186. - char tmp_path[MAX_PATH];
  187. - if (!GetTempPathA(ARRAYSIZE(tmp_path), tmp_path)) {
  188. + wchar_t wtmp_path[MAX_PATH];
  189. + if (!GetTempPathW(ARRAYSIZE(wtmp_path), wtmp_path)) {
  190. return WindowsError("GetTempPath", ::GetLastError());
  191. }
  192. + std::string tmp_path = toUtf8(std::wstring(wtmp_path));
  193. std::stringstream ss;
  194. ss << tmp_path << "leveldbtest-" << std::this_thread::get_id();
  195. *result = ss.str();
  196. @@ -598,7 +621,8 @@ class WindowsEnv : public Env {
  197. }
  198. Status NewLogger(const std::string& filename, Logger** result) override {
  199. - std::FILE* fp = std::fopen(filename.c_str(), "w");
  200. + auto wFilename = toUtf16(filename);
  201. + std::FILE* fp = _wfopen(wFilename.c_str(), L"w");
  202. if (fp == nullptr) {
  203. *result = nullptr;
  204. return WindowsError("NewLogger", ::GetLastError());
  205. @@ -640,6 +664,31 @@ class WindowsEnv : public Env {
  206. bool started_bgthread_;
  207. std::deque<BGItem> queue_;
  208. Limiter mmap_limiter_;
  209. +
  210. + // Converts a Windows wide multi-byte UTF-16 string to a UTF-8 string.
  211. + // See http://utf8everywhere.org/#windows
  212. + std::string toUtf8(const std::wstring& wstr) {
  213. + if (wstr.empty()) return std::string();
  214. + int size_needed = WideCharToMultiByte(
  215. + CP_UTF8, 0, &wstr[0], (int)wstr.size(), NULL, 0, NULL, NULL);
  216. + std::string strTo(size_needed, 0);
  217. + WideCharToMultiByte(CP_UTF8, 0, &wstr[0], (int)wstr.size(), &strTo[0],
  218. + size_needed, NULL, NULL);
  219. + return strTo;
  220. + }
  221. +
  222. + // Converts a UTF-8 string to a Windows UTF-16 multi-byte wide character
  223. + // string.
  224. + // See http://utf8everywhere.org/#windows
  225. + std::wstring toUtf16(const std::string& str) {
  226. + if (str.empty()) return std::wstring();
  227. + int size_needed = MultiByteToWideChar(
  228. + CP_UTF8, 0, &str[0], (int)str.size(), NULL, 0);
  229. + std::wstring strTo(size_needed, 0);
  230. + MultiByteToWideChar(CP_UTF8, 0, &str[0], (int)str.size(), &strTo[0],
  231. + size_needed);
  232. + return strTo;
  233. + }
  234. };
  235. // Return the maximum number of concurrent mmaps.