• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
BlockingWrite(const PlatformHandle & handle,const void * buffer,size_t bytes_to_write,size_t * bytes_written)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 
BlockingRead(const PlatformHandle & handle,void * buffer,size_t buffer_size,size_t * bytes_read)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 
NonBlockingRead(const PlatformHandle & handle,void * buffer,size_t buffer_size,size_t * bytes_read)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 
PlatformHandleFromFILE(base::ScopedFILE fp)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 
FILEFromPlatformHandle(ScopedPlatformHandle h,const char * mode)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