xref: /reactos/dll/win32/kernel32/client/handle.c (revision a2f7de7e)
1 /*
2  * PROJECT:         ReactOS Win32 Base API
3  * LICENSE:         See COPYING in the top level directory
4  * FILE:            dll/win32/kernel32/client/handle.c
5  * PURPOSE:         Object Handle Functions
6  * PROGRAMMERS:     Ariadne ( ariadne@xs4all.nl)
7  */
8 
9 /* INCLUDES *******************************************************************/
10 
11 #include <k32.h>
12 
13 #define NDEBUG
14 #include <debug.h>
15 
16 /* PRIVATE FUNCTIONS **********************************************************/
17 
18 HANDLE
TranslateStdHandle(IN HANDLE hHandle)19 TranslateStdHandle(IN HANDLE hHandle)
20 {
21     PRTL_USER_PROCESS_PARAMETERS Ppb = NtCurrentPeb()->ProcessParameters;
22 
23     switch ((ULONG_PTR)hHandle)
24     {
25         case STD_INPUT_HANDLE:  return Ppb->StandardInput;
26         case STD_OUTPUT_HANDLE: return Ppb->StandardOutput;
27         case STD_ERROR_HANDLE:  return Ppb->StandardError;
28     }
29 
30     return hHandle;
31 }
32 
33 /* PUBLIC FUNCTIONS ***********************************************************/
34 
35 /*
36  * @implemented
37  */
38 BOOL
39 WINAPI
GetHandleInformation(IN HANDLE hObject,OUT LPDWORD lpdwFlags)40 GetHandleInformation(IN HANDLE hObject,
41                      OUT LPDWORD lpdwFlags)
42 {
43     OBJECT_HANDLE_ATTRIBUTE_INFORMATION HandleInfo;
44     ULONG BytesWritten;
45     NTSTATUS Status;
46     DWORD Flags;
47 
48     hObject = TranslateStdHandle(hObject);
49 
50     if (IsConsoleHandle(hObject))
51     {
52         return GetConsoleHandleInformation(hObject, lpdwFlags);
53     }
54 
55     Status = NtQueryObject(hObject,
56                            ObjectHandleFlagInformation,
57                            &HandleInfo,
58                            sizeof(OBJECT_HANDLE_ATTRIBUTE_INFORMATION),
59                            &BytesWritten);
60     if (!NT_SUCCESS(Status))
61     {
62         BaseSetLastNTError(Status);
63         return FALSE;
64     }
65 
66     Flags = 0;
67     if (HandleInfo.Inherit) Flags |= HANDLE_FLAG_INHERIT;
68     if (HandleInfo.ProtectFromClose) Flags |= HANDLE_FLAG_PROTECT_FROM_CLOSE;
69     *lpdwFlags = Flags;
70     return TRUE;
71 }
72 
73 /*
74  * @implemented
75  */
76 BOOL
77 WINAPI
SetHandleInformation(IN HANDLE hObject,IN DWORD dwMask,IN DWORD dwFlags)78 SetHandleInformation(IN HANDLE hObject,
79                      IN DWORD dwMask,
80                      IN DWORD dwFlags)
81 {
82     OBJECT_HANDLE_ATTRIBUTE_INFORMATION HandleInfo;
83     ULONG BytesWritten;
84     NTSTATUS Status;
85 
86     hObject = TranslateStdHandle(hObject);
87 
88     if (IsConsoleHandle(hObject))
89     {
90         return SetConsoleHandleInformation(hObject, dwMask, dwFlags);
91     }
92 
93     Status = NtQueryObject(hObject,
94                            ObjectHandleFlagInformation,
95                            &HandleInfo,
96                            sizeof(OBJECT_HANDLE_ATTRIBUTE_INFORMATION),
97                            &BytesWritten);
98     if (!NT_SUCCESS(Status))
99     {
100         BaseSetLastNTError(Status);
101         return FALSE;
102     }
103 
104     if (dwMask & HANDLE_FLAG_INHERIT)
105     {
106         HandleInfo.Inherit = (dwFlags & HANDLE_FLAG_INHERIT) != 0;
107     }
108 
109     if (dwMask & HANDLE_FLAG_PROTECT_FROM_CLOSE)
110     {
111         HandleInfo.ProtectFromClose = (dwFlags & HANDLE_FLAG_PROTECT_FROM_CLOSE) != 0;
112     }
113 
114     Status = NtSetInformationObject(hObject,
115                                     ObjectHandleFlagInformation,
116                                     &HandleInfo,
117                                     sizeof(HandleInfo));
118     if (NT_SUCCESS(Status)) return TRUE;
119 
120     BaseSetLastNTError(Status);
121     return FALSE;
122 }
123 
124 /*
125  * @implemented
126  */
127 BOOL
128 WINAPI
CloseHandle(IN HANDLE hObject)129 CloseHandle(IN HANDLE hObject)
130 {
131     NTSTATUS Status;
132 
133     hObject = TranslateStdHandle(hObject);
134 
135     if (IsConsoleHandle(hObject)) return CloseConsoleHandle(hObject);
136 
137     Status = NtClose(hObject);
138     if (NT_SUCCESS(Status)) return TRUE;
139 
140     BaseSetLastNTError(Status);
141     return FALSE;
142 }
143 
144 /*
145  * @implemented
146  */
147 BOOL
148 WINAPI
DuplicateHandle(IN HANDLE hSourceProcessHandle,IN HANDLE hSourceHandle,IN HANDLE hTargetProcessHandle,OUT LPHANDLE lpTargetHandle,IN DWORD dwDesiredAccess,IN BOOL bInheritHandle,IN DWORD dwOptions)149 DuplicateHandle(IN HANDLE hSourceProcessHandle,
150                 IN HANDLE hSourceHandle,
151                 IN HANDLE hTargetProcessHandle,
152                 OUT LPHANDLE lpTargetHandle,
153                 IN DWORD dwDesiredAccess,
154                 IN BOOL bInheritHandle,
155                 IN DWORD dwOptions)
156 {
157     NTSTATUS Status;
158     HANDLE hTargetHandle;
159 
160     hSourceHandle = TranslateStdHandle(hSourceHandle);
161 
162     if ((IsConsoleHandle(hSourceHandle)) &&
163         ((hSourceHandle != NtCurrentProcess()) &&
164          (hSourceHandle != NtCurrentThread())))
165     {
166         /*
167          * We can duplicate console handles only if both the source
168          * and the target processes are in fact the current process.
169          */
170         if ((hSourceProcessHandle != NtCurrentProcess()) ||
171             (hTargetProcessHandle != NtCurrentProcess()))
172         {
173             BaseSetLastNTError(STATUS_INVALID_PARAMETER);
174             return FALSE;
175         }
176 
177         hTargetHandle = DuplicateConsoleHandle(hSourceHandle,
178                                                dwDesiredAccess,
179                                                bInheritHandle,
180                                                dwOptions);
181         if (hTargetHandle != INVALID_HANDLE_VALUE)
182         {
183             if (lpTargetHandle) *lpTargetHandle = hTargetHandle;
184             return TRUE;
185         }
186 
187         return FALSE;
188     }
189 
190     Status = NtDuplicateObject(hSourceProcessHandle,
191                                hSourceHandle,
192                                hTargetProcessHandle,
193                                lpTargetHandle,
194                                dwDesiredAccess,
195                                bInheritHandle ? OBJ_INHERIT : 0,
196                                dwOptions);
197     if (NT_SUCCESS(Status)) return TRUE;
198 
199     BaseSetLastNTError(Status);
200     return FALSE;
201 }
202 
203 /*
204  * @implemented
205  */
206 UINT
207 WINAPI
SetHandleCount(IN UINT nCount)208 SetHandleCount(IN UINT nCount)
209 {
210     return nCount;
211 }
212 
213 /*
214  * @implemented
215  */
216 DWORD
217 WINAPI
GetHandleContext(IN HANDLE Handle)218 GetHandleContext(IN HANDLE Handle)
219 {
220     /* This is Windows behavior, not a ReactOS Stub */
221     DbgPrintEx(0, 0, "Unsupported API - kernel32!GetHandleContext() called\n");
222     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
223     return FALSE;
224 }
225 
226 /*
227  * @implemented
228  */
229 HANDLE
230 WINAPI
CreateSocketHandle(VOID)231 CreateSocketHandle(VOID)
232 {
233     /* This is Windows behavior, not a ReactOS Stub */
234     DbgPrintEx(0, 0, "Unsupported API - kernel32!CreateSocketHandle() called\n");
235     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
236     return FALSE;
237 }
238 
239 /*
240  * @implemented
241  */
242 BOOL
243 WINAPI
SetHandleContext(IN HANDLE Handle,IN DWORD Context)244 SetHandleContext(IN HANDLE Handle,
245                  IN DWORD Context)
246 {
247     /* This is Windows behavior, not a ReactOS Stub */
248     DbgPrintEx(0, 0, "Unsupported API - kernel32!SetHandleContext() called\n");
249     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
250     return FALSE;
251 }
252 
253 /* EOF */
254