1 /**
2  * WinPR: Windows Portable Runtime
3  * Handle Management
4  *
5  * Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *     http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 
20 #ifndef WINPR_HANDLE_PRIVATE_H
21 #define WINPR_HANDLE_PRIVATE_H
22 
23 #include <winpr/handle.h>
24 #include <winpr/file.h>
25 #include <winpr/synch.h>
26 #include <winpr/winsock.h>
27 
28 #define HANDLE_TYPE_NONE 0
29 #define HANDLE_TYPE_PROCESS 1
30 #define HANDLE_TYPE_THREAD 2
31 #define HANDLE_TYPE_EVENT 3
32 #define HANDLE_TYPE_MUTEX 4
33 #define HANDLE_TYPE_SEMAPHORE 5
34 #define HANDLE_TYPE_TIMER 6
35 #define HANDLE_TYPE_NAMED_PIPE 7
36 #define HANDLE_TYPE_ANONYMOUS_PIPE 8
37 #define HANDLE_TYPE_ACCESS_TOKEN 9
38 #define HANDLE_TYPE_FILE 10
39 #define HANDLE_TYPE_TIMER_QUEUE 11
40 #define HANDLE_TYPE_TIMER_QUEUE_TIMER 12
41 #define HANDLE_TYPE_COMM 13
42 
43 #define WINPR_HANDLE_DEF() \
44 	ULONG Type;            \
45 	ULONG Mode;            \
46 	HANDLE_OPS* ops
47 
48 typedef BOOL (*pcIsHandled)(HANDLE handle);
49 typedef BOOL (*pcCloseHandle)(HANDLE handle);
50 typedef int (*pcGetFd)(HANDLE handle);
51 typedef DWORD (*pcCleanupHandle)(HANDLE handle);
52 typedef BOOL (*pcReadFile)(PVOID Object, LPVOID lpBuffer, DWORD nNumberOfBytesToRead,
53                            LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped);
54 typedef BOOL (*pcReadFileEx)(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead,
55                              LPOVERLAPPED lpOverlapped,
56                              LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine);
57 typedef BOOL (*pcReadFileScatter)(HANDLE hFile, FILE_SEGMENT_ELEMENT aSegmentArray[],
58                                   DWORD nNumberOfBytesToRead, LPDWORD lpReserved,
59                                   LPOVERLAPPED lpOverlapped);
60 typedef BOOL (*pcWriteFile)(PVOID Object, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite,
61                             LPDWORD lpNumberOfBytesWritten, LPOVERLAPPED lpOverlapped);
62 typedef BOOL (*pcWriteFileEx)(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite,
63                               LPOVERLAPPED lpOverlapped,
64                               LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine);
65 typedef BOOL (*pcWriteFileGather)(HANDLE hFile, FILE_SEGMENT_ELEMENT aSegmentArray[],
66                                   DWORD nNumberOfBytesToWrite, LPDWORD lpReserved,
67                                   LPOVERLAPPED lpOverlapped);
68 typedef DWORD (*pcGetFileSize)(HANDLE handle, LPDWORD lpFileSizeHigh);
69 typedef BOOL (*pcFlushFileBuffers)(HANDLE hFile);
70 typedef BOOL (*pcSetEndOfFile)(HANDLE handle);
71 typedef DWORD (*pcSetFilePointer)(HANDLE handle, LONG lDistanceToMove, PLONG lpDistanceToMoveHigh,
72                                   DWORD dwMoveMethod);
73 typedef BOOL (*pcSetFilePointerEx)(HANDLE hFile, LARGE_INTEGER liDistanceToMove,
74                                    PLARGE_INTEGER lpNewFilePointer, DWORD dwMoveMethod);
75 typedef BOOL (*pcLockFile)(HANDLE hFile, DWORD dwFileOffsetLow, DWORD dwFileOffsetHigh,
76                            DWORD nNumberOfBytesToLockLow, DWORD nNumberOfBytesToLockHigh);
77 typedef BOOL (*pcLockFileEx)(HANDLE hFile, DWORD dwFlags, DWORD dwReserved,
78                              DWORD nNumberOfBytesToLockLow, DWORD nNumberOfBytesToLockHigh,
79                              LPOVERLAPPED lpOverlapped);
80 typedef BOOL (*pcUnlockFile)(HANDLE hFile, DWORD dwFileOffsetLow, DWORD dwFileOffsetHigh,
81                              DWORD nNumberOfBytesToUnlockLow, DWORD nNumberOfBytesToUnlockHigh);
82 typedef BOOL (*pcUnlockFileEx)(HANDLE hFile, DWORD dwReserved, DWORD nNumberOfBytesToUnlockLow,
83                                DWORD nNumberOfBytesToUnlockHigh, LPOVERLAPPED lpOverlapped);
84 typedef BOOL (*pcSetFileTime)(HANDLE hFile, const FILETIME* lpCreationTime,
85                               const FILETIME* lpLastAccessTime, const FILETIME* lpLastWriteTime);
86 
87 typedef struct _HANDLE_OPS
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 } HANDLE_OPS;
110 
111 struct winpr_handle
112 {
113 	WINPR_HANDLE_DEF();
114 };
115 typedef struct winpr_handle WINPR_HANDLE;
116 
WINPR_HANDLE_SET_TYPE_AND_MODE(void * _handle,ULONG _type,ULONG _mode)117 static INLINE void WINPR_HANDLE_SET_TYPE_AND_MODE(void* _handle, ULONG _type, ULONG _mode)
118 {
119 	WINPR_HANDLE* hdl = (WINPR_HANDLE*)_handle;
120 
121 	hdl->Type = _type;
122 	hdl->Mode = _mode;
123 }
124 
winpr_Handle_GetInfo(HANDLE handle,ULONG * pType,WINPR_HANDLE ** pObject)125 static INLINE BOOL winpr_Handle_GetInfo(HANDLE handle, ULONG* pType, WINPR_HANDLE** pObject)
126 {
127 	WINPR_HANDLE* wHandle;
128 
129 	if (handle == NULL)
130 		return FALSE;
131 
132 		/* INVALID_HANDLE_VALUE is an invalid value for every handle, but it
133 		 * confuses the clang scanbuild analyzer. */
134 #ifndef __clang_analyzer__
135 	if (handle == INVALID_HANDLE_VALUE)
136 		return FALSE;
137 #endif
138 
139 	wHandle = (WINPR_HANDLE*)handle;
140 
141 	*pType = wHandle->Type;
142 	*pObject = handle;
143 
144 	return TRUE;
145 }
146 
winpr_Handle_getFd(HANDLE handle)147 static INLINE int winpr_Handle_getFd(HANDLE handle)
148 {
149 	WINPR_HANDLE* hdl;
150 	ULONG type;
151 
152 	if (!winpr_Handle_GetInfo(handle, &type, &hdl))
153 		return -1;
154 
155 	if (!hdl || !hdl->ops || !hdl->ops->GetFd)
156 		return -1;
157 
158 	return hdl->ops->GetFd(handle);
159 }
160 
winpr_Handle_cleanup(HANDLE handle)161 static INLINE DWORD winpr_Handle_cleanup(HANDLE handle)
162 {
163 	WINPR_HANDLE* hdl;
164 	ULONG type;
165 
166 	if (!winpr_Handle_GetInfo(handle, &type, &hdl))
167 		return WAIT_FAILED;
168 
169 	if (!hdl || !hdl->ops)
170 		return WAIT_FAILED;
171 
172 	/* If there is no cleanup function, assume all ok. */
173 	if (!hdl->ops->CleanupHandle)
174 		return WAIT_OBJECT_0;
175 
176 	return hdl->ops->CleanupHandle(handle);
177 }
178 
179 #endif /* WINPR_HANDLE_PRIVATE_H */
180