| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "mojo/edk/system/raw_channel.h" | 5 #include "mojo/edk/system/raw_channel.h" |
| 6 | 6 |
| 7 #include <windows.h> | 7 #include <windows.h> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/lazy_instance.h" | 10 #include "base/lazy_instance.h" |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 44 DWORD handle_pid; | 44 DWORD handle_pid; |
| 45 HANDLE handle; | 45 HANDLE handle; |
| 46 }; | 46 }; |
| 47 | 47 |
| 48 class VistaOrHigherFunctions { | 48 class VistaOrHigherFunctions { |
| 49 public: | 49 public: |
| 50 VistaOrHigherFunctions() | 50 VistaOrHigherFunctions() |
| 51 : is_vista_or_higher_( | 51 : is_vista_or_higher_( |
| 52 base::win::GetVersion() >= base::win::VERSION_VISTA), | 52 base::win::GetVersion() >= base::win::VERSION_VISTA), |
| 53 set_file_completion_notification_modes_(nullptr), | 53 set_file_completion_notification_modes_(nullptr), |
| 54 cancel_io_ex_(nullptr) { | 54 cancel_io_ex_(nullptr), |
| 55 get_file_information_by_handle_ex_(nullptr) { |
| 55 if (!is_vista_or_higher_) | 56 if (!is_vista_or_higher_) |
| 56 return; | 57 return; |
| 57 | 58 |
| 58 HMODULE module = GetModuleHandleW(L"kernel32.dll"); | 59 HMODULE module = GetModuleHandleW(L"kernel32.dll"); |
| 59 set_file_completion_notification_modes_ = | 60 set_file_completion_notification_modes_ = |
| 60 reinterpret_cast<SetFileCompletionNotificationModesFunc>( | 61 reinterpret_cast<SetFileCompletionNotificationModesFunc>( |
| 61 GetProcAddress(module, "SetFileCompletionNotificationModes")); | 62 GetProcAddress(module, "SetFileCompletionNotificationModes")); |
| 62 DCHECK(set_file_completion_notification_modes_); | 63 DCHECK(set_file_completion_notification_modes_); |
| 63 | 64 |
| 64 cancel_io_ex_ = | 65 cancel_io_ex_ = |
| 65 reinterpret_cast<CancelIoExFunc>(GetProcAddress(module, "CancelIoEx")); | 66 reinterpret_cast<CancelIoExFunc>(GetProcAddress(module, "CancelIoEx")); |
| 66 DCHECK(cancel_io_ex_); | 67 DCHECK(cancel_io_ex_); |
| 68 |
| 69 get_file_information_by_handle_ex_ = |
| 70 reinterpret_cast<GetFileInformationByHandleExFunc>( |
| 71 GetProcAddress(module, "GetFileInformationByHandleEx")); |
| 72 DCHECK(get_file_information_by_handle_ex_); |
| 67 } | 73 } |
| 68 | 74 |
| 69 bool is_vista_or_higher() const { return is_vista_or_higher_; } | 75 bool is_vista_or_higher() const { return is_vista_or_higher_; } |
| 70 | 76 |
| 71 BOOL SetFileCompletionNotificationModes(HANDLE handle, UCHAR flags) { | 77 BOOL SetFileCompletionNotificationModes(HANDLE handle, UCHAR flags) { |
| 72 return set_file_completion_notification_modes_(handle, flags); | 78 return set_file_completion_notification_modes_(handle, flags); |
| 73 } | 79 } |
| 74 | 80 |
| 75 BOOL CancelIoEx(HANDLE handle, LPOVERLAPPED overlapped) { | 81 BOOL CancelIoEx(HANDLE handle, LPOVERLAPPED overlapped) { |
| 76 return cancel_io_ex_(handle, overlapped); | 82 return cancel_io_ex_(handle, overlapped); |
| 77 } | 83 } |
| 78 | 84 |
| 85 BOOL GetFileInformationByHandleEx(HANDLE handle, |
| 86 FILE_INFO_BY_HANDLE_CLASS file_info_class, |
| 87 LPVOID file_info, |
| 88 DWORD buffer_size) { |
| 89 return get_file_information_by_handle_ex_( |
| 90 handle, file_info_class, file_info, buffer_size); |
| 91 } |
| 92 |
| 79 private: | 93 private: |
| 80 using SetFileCompletionNotificationModesFunc = BOOL(WINAPI*)(HANDLE, UCHAR); | 94 using SetFileCompletionNotificationModesFunc = BOOL(WINAPI*)(HANDLE, UCHAR); |
| 81 using CancelIoExFunc = BOOL(WINAPI*)(HANDLE, LPOVERLAPPED); | 95 using CancelIoExFunc = BOOL(WINAPI*)(HANDLE, LPOVERLAPPED); |
| 96 using GetFileInformationByHandleExFunc = BOOL(WINAPI*)( |
| 97 HANDLE, FILE_INFO_BY_HANDLE_CLASS, LPVOID, DWORD); |
| 82 | 98 |
| 83 bool is_vista_or_higher_; | 99 bool is_vista_or_higher_; |
| 84 SetFileCompletionNotificationModesFunc | 100 SetFileCompletionNotificationModesFunc |
| 85 set_file_completion_notification_modes_; | 101 set_file_completion_notification_modes_; |
| 86 CancelIoExFunc cancel_io_ex_; | 102 CancelIoExFunc cancel_io_ex_; |
| 103 GetFileInformationByHandleExFunc get_file_information_by_handle_ex_; |
| 87 }; | 104 }; |
| 88 | 105 |
| 89 base::LazyInstance<VistaOrHigherFunctions> g_vista_or_higher_functions = | 106 base::LazyInstance<VistaOrHigherFunctions> g_vista_or_higher_functions = |
| 90 LAZY_INSTANCE_INITIALIZER; | 107 LAZY_INSTANCE_INITIALIZER; |
| 91 | 108 |
| 92 class RawChannelWin final : public RawChannel { | 109 class RawChannelWin final : public RawChannel { |
| 93 public: | 110 public: |
| 94 RawChannelWin(ScopedPlatformHandle handle) | 111 RawChannelWin(ScopedPlatformHandle handle) |
| 95 : handle_(handle.Pass()), | 112 : handle_(handle.Pass()), |
| 96 io_handler_(nullptr), | 113 io_handler_(nullptr), |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 238 preserved_read_buffer_after_detach_ = read_buffer.Pass(); | 255 preserved_read_buffer_after_detach_ = read_buffer.Pass(); |
| 239 if (pending_write_) | 256 if (pending_write_) |
| 240 preserved_write_buffer_after_detach_ = write_buffer.Pass(); | 257 preserved_write_buffer_after_detach_ = write_buffer.Pass(); |
| 241 | 258 |
| 242 owner_ = nullptr; | 259 owner_ = nullptr; |
| 243 if (ShouldSelfDestruct()) | 260 if (ShouldSelfDestruct()) |
| 244 delete this; | 261 delete this; |
| 245 } | 262 } |
| 246 | 263 |
| 247 ScopedPlatformHandle ReleaseHandle(std::vector<char>* read_buffer) { | 264 ScopedPlatformHandle ReleaseHandle(std::vector<char>* read_buffer) { |
| 248 // TODO(jam): handle XP | 265 if (g_vista_or_higher_functions.Get().is_vista_or_higher()) { |
| 249 CancelIoEx(handle(), NULL); | 266 g_vista_or_higher_functions.Get().CancelIoEx(handle(), nullptr); |
| 267 } else { |
| 268 CHECK(false) << "TODO(jam): handle XP"; |
| 269 } |
| 270 |
| 250 // NOTE: The above call will cancel pending IO calls. | 271 // NOTE: The above call will cancel pending IO calls. |
| 251 size_t read_buffer_byte_size = owner_->read_buffer()->num_valid_bytes(); | 272 size_t read_buffer_byte_size = owner_->read_buffer()->num_valid_bytes(); |
| 252 | 273 |
| 253 if (pending_read_) { | 274 if (pending_read_) { |
| 254 DWORD bytes_read_dword = 0; | 275 DWORD bytes_read_dword = 0; |
| 255 | 276 |
| 256 DWORD old_bytes = read_context_.overlapped.InternalHigh; | 277 DWORD old_bytes = read_context_.overlapped.InternalHigh; |
| 257 | 278 |
| 258 // Since we cancelled pending IO calls above, we need to know if the | 279 // Since we cancelled pending IO calls above, we need to know if the |
| 259 // read did succeed (i.e. it completed and there's a pending task posted | 280 // read did succeed (i.e. it completed and there's a pending task posted |
| (...skipping 581 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 841 } | 862 } |
| 842 | 863 |
| 843 size_t RawChannel::GetSerializedPlatformHandleSize() { | 864 size_t RawChannel::GetSerializedPlatformHandleSize() { |
| 844 return sizeof(SerializedHandle); | 865 return sizeof(SerializedHandle); |
| 845 } | 866 } |
| 846 | 867 |
| 847 bool RawChannel::IsOtherEndOf(RawChannel* other) { | 868 bool RawChannel::IsOtherEndOf(RawChannel* other) { |
| 848 PlatformHandle this_handle = HandleForDebuggingNoLock(); | 869 PlatformHandle this_handle = HandleForDebuggingNoLock(); |
| 849 PlatformHandle other_handle = other->HandleForDebuggingNoLock(); | 870 PlatformHandle other_handle = other->HandleForDebuggingNoLock(); |
| 850 | 871 |
| 851 // TODO: XP: see http://stackoverflow.com/questions/65170/how-to-get-name-asso
ciated-with-open-handle/5286888#5286888 | 872 if (g_vista_or_higher_functions.Get().is_vista_or_higher()) { |
| 852 WCHAR data1[_MAX_PATH + sizeof(FILE_NAME_INFO)]; | 873 WCHAR data1[_MAX_PATH + sizeof(FILE_NAME_INFO)]; |
| 853 WCHAR data2[_MAX_PATH + sizeof(FILE_NAME_INFO)]; | 874 WCHAR data2[_MAX_PATH + sizeof(FILE_NAME_INFO)]; |
| 854 FILE_NAME_INFO* fileinfo1 = reinterpret_cast<FILE_NAME_INFO *>(data1); | 875 FILE_NAME_INFO* fileinfo1 = reinterpret_cast<FILE_NAME_INFO *>(data1); |
| 855 FILE_NAME_INFO* fileinfo2 = reinterpret_cast<FILE_NAME_INFO *>(data2); | 876 FILE_NAME_INFO* fileinfo2 = reinterpret_cast<FILE_NAME_INFO *>(data2); |
| 856 CHECK(GetFileInformationByHandleEx( | 877 CHECK(g_vista_or_higher_functions.Get().GetFileInformationByHandleEx( |
| 857 this_handle.handle, FileNameInfo, fileinfo1, arraysize(data1))); | 878 this_handle.handle, FileNameInfo, fileinfo1, arraysize(data1))); |
| 858 CHECK(GetFileInformationByHandleEx( | 879 CHECK(g_vista_or_higher_functions.Get().GetFileInformationByHandleEx( |
| 859 other_handle.handle, FileNameInfo, fileinfo2, arraysize(data2))); | 880 other_handle.handle, FileNameInfo, fileinfo2, arraysize(data2))); |
| 860 std::wstring filepath1(fileinfo1->FileName, fileinfo1->FileNameLength / 2); | 881 std::wstring filepath1(fileinfo1->FileName, fileinfo1->FileNameLength / 2); |
| 861 std::wstring filepath2(fileinfo2->FileName, fileinfo2->FileNameLength / 2); | 882 std::wstring filepath2(fileinfo2->FileName, fileinfo2->FileNameLength / 2); |
| 862 return filepath1 == filepath2; | 883 return filepath1 == filepath2; |
| 884 } else { |
| 885 // TODO: XP: see http://stackoverflow.com/questions/65170/how-to-get-name-as
sociated-with-open-handle/5286888#5286888 |
| 886 CHECK(false) << "TODO(jam): handle XP"; |
| 887 return false; |
| 888 } |
| 863 } | 889 } |
| 864 | 890 |
| 865 } // namespace edk | 891 } // namespace edk |
| 866 } // namespace mojo | 892 } // namespace mojo |
| OLD | NEW |