Gray C++ Libraries  0.0.2
A set of C++ libraries for MSVC, GNU on Windows, WinCE, Linux
cOSHandle.h
Go to the documentation of this file.
1 //
5 //
6 
7 #ifndef _INC_cOSHandle_H
8 #define _INC_cOSHandle_H
9 #ifndef NO_PRAGMA_ONCE
10 #pragma once
11 #endif
12 
13 #include "HResult.h"
14 #include "cTimeSys.h" // TIMESYSD_t
15 #include "cNonCopyable.h"
16 #include "cUnitTestDecl.h"
17 #include "cDebugAssert.h"
18 
19 namespace Gray
20 {
21 #define HANDLE_NULL NULL
22 
23 #define WINHANDLE_NULL NULL
24 
25 #ifdef __linux__
26  typedef int HANDLE;
27  static const HANDLE INVALID_HANDLE_VALUE = ((HANDLE)-1);
28 
29  typedef void* HMODULE;
30  typedef void* HINSTANCE;
31 #endif
32 
34  {
39  SEEK_Set = 0,
40  SEEK_Cur = 1,
41  SEEK_End = 2,
42  SEEK_MASK = 0x0007,
43  };
44 
45 #if defined(_MFC_VER) && ( _MFC_VER > 0x0600 )
46  typedef LONGLONG STREAM_OFFSET_t;
47  typedef ULONGLONG STREAM_SEEKRET_t;
48  typedef ULONGLONG STREAM_POS_t; // same as FILE_SIZE_t.
49 #define USE_FILE_POS64
50 
51 #else
52  typedef LONG_PTR STREAM_OFFSET_t;
53  typedef LONG_PTR STREAM_SEEKRET_t;
54  typedef ULONG_PTR STREAM_POS_t;
55 
56 #endif // ! _MFC_VER
57 
59  {
66 
67  public:
68  HANDLE m_h;
69 
70  protected:
71  void CloseHandleLast() noexcept
72  {
73  // Assume destruction or my caller will clear m_h
74  if (!isValidHandle())
75  return;
76  CloseHandle(m_h);
77  }
78 
79  public:
80  explicit inline cOSHandle(HANDLE h = INVALID_HANDLE_VALUE) noexcept
81  : m_h(h)
82  {
83  }
84 
85  cOSHandle(const cOSHandle& Handle) noexcept
86  : m_h(Handle.Duplicate())
87  {
88  }
89  cOSHandle& operator=(const cOSHandle& Handle)
90  {
91  if (m_h != Handle.m_h)
92  {
93  AttachHandle(Handle.Duplicate());
94  }
95  return (*this);
96  }
97 
98  inline ~cOSHandle()
99  {
100  CloseHandleLast();
101  }
102 
103  operator HANDLE () const noexcept
104  {
105  return m_h;
106  }
107  HANDLE get_Handle() const noexcept
108  {
109  return m_h;
110  }
111  HANDLE& ref_Handle() noexcept
112  {
113  return m_h;
114  }
115 
116  static bool inline IsValidHandle(HANDLE h) noexcept
117  {
119 #ifdef _WIN32
120  if (h == HANDLE_NULL)
121  return false;
122 #endif
123  return(h != INVALID_HANDLE_VALUE); // -1
124  }
125  bool isValidHandle() const noexcept
126  {
127  return IsValidHandle(m_h);
128  }
129 
130  static inline bool CloseHandle(HANDLE h) noexcept // static
131  {
135 #ifdef _WIN32
136  const BOOL bRet = ::CloseHandle(h); // ignored bool return.
137  return bRet;
138 #elif defined(__linux__)
139  const int iRet = ::close(h);
140  return iRet == 0;
141 #endif
142  }
143  void CloseHandle() noexcept
144  {
145  if (!isValidHandle())
146  return;
147  HANDLE h = m_h;
148  m_h = INVALID_HANDLE_VALUE;
149  CloseHandle(h);
150  }
151 
152 #ifdef __linux__
153  void OpenHandle( const char* pszPath, UINT uFlags, UINT uMode=0)
154  {
158  CloseHandleLast();
159  m_h = ::open(pszPath, uFlags, uMode);
160  }
161 #endif
162 
163  void AttachHandle(HANDLE h) noexcept
164  {
165  if (m_h != h)
166  {
167  CloseHandleLast();
168  m_h = h;
169  }
170  }
171  HANDLE DetachHandle() noexcept
172  {
173  HANDLE h = m_h;
174  m_h = INVALID_HANDLE_VALUE;
175  return h;
176  }
177 
178  HRESULT WriteX(const void* pData, size_t nDataSize) const
179  {
183 
184  if (nDataSize <= 0) // Do nothing.
185  return S_OK;
186 #if defined(_WIN32)
187  DWORD nLengthWritten = 0;
188  const bool bRet = ::WriteFile(m_h, pData, (DWORD)nDataSize, &nLengthWritten, nullptr);
189  if (!bRet)
190 #elif defined(__linux__)
191  int nLengthWritten = ::write(m_h, (const char*)pData, (long)nDataSize);
192  if (nLengthWritten <= 0)
193 #endif
194  {
195  return HResult::GetLastDef(HRESULT_WIN32_C(ERROR_WRITE_FAULT)); // E_HANDLE = file handle m_h is bad.
196  }
197  return (HRESULT) nLengthWritten;
198  }
199 
200  HRESULT ReadX(void* pData, size_t nDataSize) const
201  {
203  if (nDataSize <= 0)
204  return S_OK;
205 #ifdef _WIN32
206  DWORD nLengthRead;
207  const bool bRet = ::ReadFile(m_h, pData, (DWORD)nDataSize, &nLengthRead, nullptr);
208  if (!bRet)
209 #elif defined(__linux__)
210  int nLengthRead = ::read(m_h, pData, (long)nDataSize);
211  if (nLengthRead == 0) // EOF
212  return HRESULT_WIN32_C(ERROR_HANDLE_EOF);
213  if (nLengthRead < 0)
214 #endif
215  {
216  // ERROR_HANDLE_EOF = No more data = EOF.
217  return HResult::GetLastDef(HRESULT_WIN32_C(ERROR_READ_FAULT));
218  }
219  return (HRESULT) nLengthRead;
220  }
221 
222  HRESULT FlushX() const
223  {
225 #ifdef _WIN32
226  if (!::FlushFileBuffers(m_h))
227 #elif defined(__linux__)
228  int iRet = ::fsync(m_h);
229  if (iRet != 0)
230 #endif
231  {
232  return HResult::GetLastDef(HRESULT_WIN32_C(ERROR_WRITE_FAULT));
233  }
234  return S_OK;
235  }
236 
238  {
242 #ifdef _WIN32
243 #ifdef USE_FILE_POS64
244  LARGE_INTEGER NewFilePointer;
245  NewFilePointer.QuadPart = lOffset;
246  const bool bRet = ::SetFilePointerEx(m_h, NewFilePointer, &NewFilePointer, eSeekOrigin);
247  if (!bRet)
248  {
249  return((STREAM_POS_t)-1);
250  }
251  return((STREAM_POS_t)NewFilePointer.QuadPart);
252 #else
253  return ::SetFilePointer(m_h, (LONG)lOffset, nullptr, eSeekOrigin);
254 #endif // USE_FILE_POS64
255 #else
256  return ::lseek(m_h, lOffset, eSeekOrigin);
257 #endif
258  }
259 
260  HRESULT WaitForSingleObject(TIMESYSD_t dwMilliseconds) const;
261 
262 #ifdef __linux__
263  int IOCtl(int nCmd, void* pArgs) const;
264  int IOCtl(int nCmd, int nArgs) const;
265 #endif
266 
267 #if defined(_WIN32) && ! defined(UNDER_CE)
268  DWORD GetInformation() const
269  {
271  ASSERT(isValidHandle());
272  DWORD dwHandleInfo = 0;
273  if (!::GetHandleInformation(m_h, &dwHandleInfo))
274  {
275  return 0;
276  }
277  return dwHandleInfo;
278  }
279  bool SetInformation(DWORD dwMask, DWORD dwFlags) const
280  {
281  ASSERT(isValidHandle());
282  const bool bRet = ::SetHandleInformation(m_h, dwMask, dwFlags);
283  return bRet;
284  }
285 #endif
286 
287 #ifdef _WIN32
288  HANDLE Duplicate(HANDLE hTargetProcess = INVALID_HANDLE_VALUE, DWORD dwDesiredAccess = DUPLICATE_SAME_ACCESS, bool bInheritHandle = false, DWORD dwOptions = DUPLICATE_SAME_ACCESS) const
289  {
292  ASSERT(isValidHandle());
293  HANDLE hNewHandle = INVALID_HANDLE_VALUE;
294  HANDLE hCurrentProcess = ::GetCurrentProcess();
295  if (hTargetProcess == INVALID_HANDLE_VALUE)
296  hTargetProcess = hCurrentProcess;
297  const bool bRet = ::DuplicateHandle(hCurrentProcess, m_h, hTargetProcess,
298  &hNewHandle, dwDesiredAccess, bInheritHandle, dwOptions);
300  return hNewHandle;
301  }
302 #elif defined(__linux__)
303  HANDLE Duplicate() const
304  {
305  // http://linux.about.com/library/cmd/blcmdl2_dup.htm
306  return ::dup(m_h);
307  }
308 #endif
309 
311  };
312 
313 };
314 #endif // _INC_cOSHandle_H
#define GRAYCORE_LINK
Definition: GrayCore.h:47
#define HRESULT_WIN32_C(x)
a constant LSTATUS/error_status_t with no check, unlike HRESULT_FROM_WIN32()
Definition: HResult.h:79
#define UNREFERENCED_PARAMETER(P)
< _WIN32 type thing. get rid of stupid warning.
Definition: SysTypes.h:299
INT32 HRESULT
_WIN32 style error codes. INT32
Definition: SysTypes.h:465
#define ASSERT(exp)
Definition: cDebugAssert.h:87
#define HANDLE_NULL
Invalid OS handle for _WIN32. Not invalid OS handle for linux.
Definition: cOSHandle.h:21
#define UNITTEST_FRIEND(n)
Define this in the class body to be unit tested. Allow the unit test to access private/protected stuf...
Definition: cUnitTestDecl.h:17
static HRESULT GetLastDef(HRESULT hResDef=E_FAIL) noexcept
Definition: HResult.h:242
Definition: cNonCopyable.h:17
Definition: cOSHandle.h:59
HRESULT ReadX(void *pData, size_t nDataSize) const
Definition: cOSHandle.h:200
static bool IsValidHandle(HANDLE h) noexcept
Definition: cOSHandle.h:116
void AttachHandle(HANDLE h) noexcept
Definition: cOSHandle.h:163
cOSHandle & operator=(const cOSHandle &Handle)
Definition: cOSHandle.h:89
STREAM_SEEKRET_t Seek(STREAM_OFFSET_t lOffset, SEEK_ORIGIN_TYPE eSeekOrigin) const
Definition: cOSHandle.h:237
void CloseHandle() noexcept
Definition: cOSHandle.h:143
~cOSHandle()
Definition: cOSHandle.h:98
cOSHandle(const cOSHandle &Handle) noexcept
Definition: cOSHandle.h:85
bool isValidHandle() const noexcept
Definition: cOSHandle.h:125
void CloseHandleLast() noexcept
Definition: cOSHandle.h:71
HRESULT FlushX() const
Definition: cOSHandle.h:222
HANDLE & ref_Handle() noexcept
Definition: cOSHandle.h:111
HRESULT WriteX(const void *pData, size_t nDataSize) const
Definition: cOSHandle.h:178
cOSHandle(HANDLE h=INVALID_HANDLE_VALUE) noexcept
Definition: cOSHandle.h:80
HANDLE get_Handle() const noexcept
Definition: cOSHandle.h:107
static bool CloseHandle(HANDLE h) noexcept
Definition: cOSHandle.h:130
HANDLE m_h
Definition: cOSHandle.h:68
HANDLE DetachHandle() noexcept
Definition: cOSHandle.h:171
< The main namespace for all Core functions.
Definition: GrayCore.cpp:14
LONG_PTR STREAM_OFFSET_t
Might be 64 or 32 bit. TODO SET USE_FILE_POS64.
Definition: cOSHandle.h:52
LONG_PTR STREAM_SEEKRET_t
return from Seek()
Definition: cOSHandle.h:53
INT32 TIMESYSD_t
Time delta. signed milli-Seconds Span. cTimeSys::k_DMAX, cTimeSys::k_INF = MAILSLOT_WAIT_FOREVER.
Definition: cTimeSys.h:28
ULONG_PTR STREAM_POS_t
NOT same as FILE_SIZE_t in 32 bit. Why not ?
Definition: cOSHandle.h:54
SEEK_ORIGIN_TYPE
Definition: cOSHandle.h:34
@ SEEK_End
SEEK_END = FILE_END = STREAM_SEEK_END = 2 = relative to the end of the file.
Definition: cOSHandle.h:41
@ SEEK_Set
SEEK_SET = FILE_BEGIN = STREAM_SEEK_SET = 0 = relative to the start of the file.
Definition: cOSHandle.h:39
@ SEEK_MASK
| _BITMASK(SEEK_Set) allow extra bits above SEEK_ORIGIN_TYPE ?
Definition: cOSHandle.h:42
@ SEEK_Cur
SEEK_CUR = FILE_CURRENT = STREAM_SEEK_CUR = 1 = relative to the current position.
Definition: cOSHandle.h:40