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