FreeRDP
Loading...
Searching...
No Matches
libwinpr/handle/handle.h
1
20#ifndef WINPR_HANDLE_PRIVATE_H
21#define WINPR_HANDLE_PRIVATE_H
22
23#include <stdlib.h>
24
25#include <winpr/handle.h>
26#include <winpr/file.h>
27#include <winpr/interlocked.h>
28#include <winpr/synch.h>
29#include <winpr/winsock.h>
30
31#define HANDLE_TYPE_NONE 0
32#define HANDLE_TYPE_PROCESS 1
33#define HANDLE_TYPE_THREAD 2
34#define HANDLE_TYPE_EVENT 3
35#define HANDLE_TYPE_MUTEX 4
36#define HANDLE_TYPE_SEMAPHORE 5
37#define HANDLE_TYPE_TIMER 6
38#define HANDLE_TYPE_NAMED_PIPE 7
39#define HANDLE_TYPE_ANONYMOUS_PIPE 8
40#define HANDLE_TYPE_ACCESS_TOKEN 9
41#define HANDLE_TYPE_FILE 10
42#define HANDLE_TYPE_TIMER_QUEUE 11
43#define HANDLE_TYPE_TIMER_QUEUE_TIMER 12
44#define HANDLE_TYPE_COMM 13
45
46typedef BOOL (*pcIsHandled)(HANDLE handle);
47typedef BOOL (*pcCloseHandle)(HANDLE handle);
48typedef int (*pcGetFd)(HANDLE handle);
49typedef DWORD (*pcCleanupHandle)(HANDLE handle);
50typedef BOOL (*pcReadFile)(PVOID Object, LPVOID lpBuffer, DWORD nNumberOfBytesToRead,
51 LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped);
52typedef BOOL (*pcReadFileEx)(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead,
53 LPOVERLAPPED lpOverlapped,
54 LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine);
55typedef BOOL (*pcReadFileScatter)(HANDLE hFile, FILE_SEGMENT_ELEMENT aSegmentArray[],
56 DWORD nNumberOfBytesToRead, LPDWORD lpReserved,
57 LPOVERLAPPED lpOverlapped);
58typedef BOOL (*pcWriteFile)(PVOID Object, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite,
59 LPDWORD lpNumberOfBytesWritten, LPOVERLAPPED lpOverlapped);
60typedef BOOL (*pcWriteFileEx)(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite,
61 LPOVERLAPPED lpOverlapped,
62 LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine);
63typedef BOOL (*pcWriteFileGather)(HANDLE hFile, FILE_SEGMENT_ELEMENT aSegmentArray[],
64 DWORD nNumberOfBytesToWrite, LPDWORD lpReserved,
65 LPOVERLAPPED lpOverlapped);
66typedef DWORD (*pcGetFileSize)(HANDLE handle, LPDWORD lpFileSizeHigh);
67typedef BOOL (*pcGetFileInformationByHandle)(HANDLE handle,
68 LPBY_HANDLE_FILE_INFORMATION lpFileInformation);
69typedef BOOL (*pcFlushFileBuffers)(HANDLE hFile);
70typedef BOOL (*pcSetEndOfFile)(HANDLE handle);
71typedef DWORD (*pcSetFilePointer)(HANDLE handle, LONG lDistanceToMove, PLONG lpDistanceToMoveHigh,
72 DWORD dwMoveMethod);
73typedef BOOL (*pcSetFilePointerEx)(HANDLE hFile, LARGE_INTEGER liDistanceToMove,
74 PLARGE_INTEGER lpNewFilePointer, DWORD dwMoveMethod);
75typedef BOOL (*pcLockFile)(HANDLE hFile, DWORD dwFileOffsetLow, DWORD dwFileOffsetHigh,
76 DWORD nNumberOfBytesToLockLow, DWORD nNumberOfBytesToLockHigh);
77typedef BOOL (*pcLockFileEx)(HANDLE hFile, DWORD dwFlags, DWORD dwReserved,
78 DWORD nNumberOfBytesToLockLow, DWORD nNumberOfBytesToLockHigh,
79 LPOVERLAPPED lpOverlapped);
80typedef BOOL (*pcUnlockFile)(HANDLE hFile, DWORD dwFileOffsetLow, DWORD dwFileOffsetHigh,
81 DWORD nNumberOfBytesToUnlockLow, DWORD nNumberOfBytesToUnlockHigh);
82typedef BOOL (*pcUnlockFileEx)(HANDLE hFile, DWORD dwReserved, DWORD nNumberOfBytesToUnlockLow,
83 DWORD nNumberOfBytesToUnlockHigh, LPOVERLAPPED lpOverlapped);
84typedef BOOL (*pcSetFileTime)(HANDLE hFile, const FILETIME* lpCreationTime,
85 const FILETIME* lpLastAccessTime, const FILETIME* lpLastWriteTime);
86
87typedef struct
88{
89 pcIsHandled IsHandled;
90 pcCloseHandle CloseHandle;
91 pcGetFd GetFd;
92 pcCleanupHandle CleanupHandle;
93 pcReadFile ReadFile;
94 pcReadFileEx ReadFileEx;
95 pcReadFileScatter ReadFileScatter;
96 pcWriteFile WriteFile;
97 pcWriteFileEx WriteFileEx;
98 pcWriteFileGather WriteFileGather;
99 pcGetFileSize GetFileSize;
100 pcFlushFileBuffers FlushFileBuffers;
101 pcSetEndOfFile SetEndOfFile;
102 pcSetFilePointer SetFilePointer;
103 pcSetFilePointerEx SetFilePointerEx;
104 pcLockFile LockFile;
105 pcLockFileEx LockFileEx;
106 pcUnlockFile UnlockFile;
107 pcUnlockFileEx UnlockFileEx;
108 pcSetFileTime SetFileTime;
109 pcGetFileInformationByHandle GetFileInformationByHandle;
110} HANDLE_OPS;
111
112typedef struct
113{
114 ULONG Type;
115 ULONG Mode;
116 HANDLE_OPS* ops;
117 volatile LONG refCount;
119
120WINPR_ATTR_NODISCARD
121static inline BOOL WINPR_HANDLE_IS_HANDLED(HANDLE handle, ULONG type, BOOL invalidValue)
122{
123 WINPR_HANDLE* pWinprHandle = (WINPR_HANDLE*)handle;
124 BOOL invalid = !pWinprHandle;
125
126 if (invalidValue)
127 {
128 if (INVALID_HANDLE_VALUE == pWinprHandle)
129 invalid = TRUE;
130 }
131
132 if (invalid || (pWinprHandle->Type != type))
133 {
134 SetLastError(ERROR_INVALID_HANDLE);
135 return FALSE;
136 }
137
138 return TRUE;
139}
140
141static inline void WINPR_HANDLE_SET_TYPE_AND_MODE(void* _handle, ULONG _type, ULONG _mode)
142{
143 WINPR_HANDLE* hdl = (WINPR_HANDLE*)_handle;
144
145 hdl->Type = _type;
146 hdl->Mode = _mode;
147 hdl->refCount = 1;
148}
149
150WINPR_ATTR_NODISCARD
151static inline BOOL winpr_Handle_GetInfo(HANDLE handle, ULONG* pType, WINPR_HANDLE** pObject)
152{
153 WINPR_HANDLE* wHandle = nullptr;
154
155 if (handle == nullptr)
156 return FALSE;
157
158 /* INVALID_HANDLE_VALUE is an invalid value for every handle, but it
159 * confuses the clang scanbuild analyzer. */
160#ifndef __clang_analyzer__
161 if (handle == INVALID_HANDLE_VALUE)
162 return FALSE;
163#endif
164
165 wHandle = (WINPR_HANDLE*)handle;
166
167 *pType = wHandle->Type;
168 *pObject = wHandle;
169
170 return TRUE;
171}
172
173static inline void winpr_Handle_AddRef(HANDLE handle)
174{
175 ULONG type = 0;
176 WINPR_HANDLE* hdl = nullptr;
177
178 if (!winpr_Handle_GetInfo(handle, &type, &hdl) || !hdl)
179 return;
180
181 InterlockedIncrement(&hdl->refCount);
182}
183
184/* implemented in nonehandle.c: turns an already-released handle (see CloseHandle() in handle.c)
185 * into a harmless placeholder, for as long as other references to the same struct remain. */
186void winpr_Handle_ConvertToNone(HANDLE handle);
187
188/* decrements refCount and frees the struct once it reaches zero - does not touch the underlying
189 * OS resource, that's the type's real CloseHandle op's job (see CloseHandle() in handle.c).
190 * Returns TRUE if this was the last reference (the handle has been freed). */
191static inline BOOL winpr_Handle_Release(HANDLE handle)
192{
193 ULONG type = 0;
194 WINPR_HANDLE* hdl = nullptr;
195
196 if (!winpr_Handle_GetInfo(handle, &type, &hdl) || !hdl)
197 return FALSE;
198
199 if (InterlockedDecrement(&hdl->refCount) > 0)
200 return FALSE;
201
202 free(hdl);
203 return TRUE;
204}
205
206WINPR_ATTR_NODISCARD
207static inline int winpr_Handle_getFd(HANDLE handle)
208{
209 WINPR_HANDLE* hdl = nullptr;
210 ULONG type = 0;
211
212 if (!winpr_Handle_GetInfo(handle, &type, &hdl))
213 return -1;
214
215 if (!hdl || !hdl->ops || !hdl->ops->GetFd)
216 return -1;
217
218 return hdl->ops->GetFd(handle);
219}
220
221WINPR_ATTR_NODISCARD
222static inline DWORD winpr_Handle_cleanup(HANDLE handle)
223{
224 WINPR_HANDLE* hdl = nullptr;
225 ULONG type = 0;
226
227 if (!winpr_Handle_GetInfo(handle, &type, &hdl))
228 return WAIT_FAILED;
229
230 if (!hdl || !hdl->ops)
231 return WAIT_FAILED;
232
233 /* If there is no cleanup function, assume all ok. */
234 if (!hdl->ops->CleanupHandle)
235 return WAIT_OBJECT_0;
236
237 return hdl->ops->CleanupHandle(handle);
238}
239
240WINPR_ATTR_NODISCARD
241BOOL winpr_set_cloexec(int fd, BOOL cloexec);
242
243#endif /* WINPR_HANDLE_PRIVATE_H */