1 // Copyright 2014 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "mojo/edk/test/test_utils.h" 6 7 #include <windows.h> 8 #include <fcntl.h> 9 #include <io.h> 10 #include <stddef.h> 11 #include <string.h> 12 13 namespace mojo { 14 namespace edk { 15 namespace test { 16 17 bool BlockingWrite(const PlatformHandle& handle, 18 const void* buffer, 19 size_t bytes_to_write, 20 size_t* bytes_written) { 21 OVERLAPPED overlapped = {0}; 22 DWORD bytes_written_dword = 0; 23 24 if (!WriteFile(handle.handle, buffer, static_cast<DWORD>(bytes_to_write), 25 &bytes_written_dword, &overlapped)) { 26 if (GetLastError() != ERROR_IO_PENDING || 27 !GetOverlappedResult(handle.handle, &overlapped, &bytes_written_dword, 28 TRUE)) { 29 return false; 30 } 31 } 32 33 *bytes_written = bytes_written_dword; 34 return true; 35 } 36 37 bool BlockingRead(const PlatformHandle& handle, 38 void* buffer, 39 size_t buffer_size, 40 size_t* bytes_read) { 41 OVERLAPPED overlapped = {0}; 42 DWORD bytes_read_dword = 0; 43 44 if (!ReadFile(handle.handle, buffer, static_cast<DWORD>(buffer_size), 45 &bytes_read_dword, &overlapped)) { 46 if (GetLastError() != ERROR_IO_PENDING || 47 !GetOverlappedResult(handle.handle, &overlapped, &bytes_read_dword, 48 TRUE)) { 49 return false; 50 } 51 } 52 53 *bytes_read = bytes_read_dword; 54 return true; 55 } 56 57 bool NonBlockingRead(const PlatformHandle& handle, 58 void* buffer, 59 size_t buffer_size, 60 size_t* bytes_read) { 61 OVERLAPPED overlapped = {0}; 62 DWORD bytes_read_dword = 0; 63 64 if (!ReadFile(handle.handle, buffer, static_cast<DWORD>(buffer_size), 65 &bytes_read_dword, &overlapped)) { 66 if (GetLastError() != ERROR_IO_PENDING) 67 return false; 68 69 CancelIo(handle.handle); 70 71 if (!GetOverlappedResult(handle.handle, &overlapped, &bytes_read_dword, 72 TRUE)) { 73 *bytes_read = 0; 74 return true; 75 } 76 } 77 78 *bytes_read = bytes_read_dword; 79 return true; 80 } 81 82 ScopedPlatformHandle PlatformHandleFromFILE(base::ScopedFILE fp) { 83 CHECK(fp); 84 85 HANDLE rv = INVALID_HANDLE_VALUE; 86 PCHECK(DuplicateHandle( 87 GetCurrentProcess(), 88 reinterpret_cast<HANDLE>(_get_osfhandle(_fileno(fp.get()))), 89 GetCurrentProcess(), &rv, 0, TRUE, DUPLICATE_SAME_ACCESS)) 90 << "DuplicateHandle"; 91 return ScopedPlatformHandle(PlatformHandle(rv)); 92 } 93 94 base::ScopedFILE FILEFromPlatformHandle(ScopedPlatformHandle h, 95 const char* mode) { 96 CHECK(h.is_valid()); 97 // Microsoft's documentation for |_open_osfhandle()| only discusses these 98 // flags (and |_O_WTEXT|). Hmmm. 99 int flags = 0; 100 if (strchr(mode, 'a')) 101 flags |= _O_APPEND; 102 if (strchr(mode, 'r')) 103 flags |= _O_RDONLY; 104 if (strchr(mode, 't')) 105 flags |= _O_TEXT; 106 base::ScopedFILE rv(_fdopen( 107 _open_osfhandle(reinterpret_cast<intptr_t>(h.release().handle), flags), 108 mode)); 109 PCHECK(rv) << "_fdopen"; 110 return rv; 111 } 112 113 } // namespace test 114 } // namespace edk 115 } // namespace mojo 116