push 97f44e0adb27fff75ba63d8fb97c65db9edfbe82
[wine/hacks.git] / dlls / ntdll / om.c
blob7cb7f06006a48248851439c524bba9cd17da8122
1 /*
2 * Object management functions
4 * Copyright 1999, 2000 Juergen Schmied
5 * Copyright 2005 Vitaliy Margolen
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #include "config.h"
24 #include <stdarg.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #ifdef HAVE_IO_H
28 # include <io.h>
29 #endif
30 #ifdef HAVE_UNISTD_H
31 # include <unistd.h>
32 #endif
34 #include "ntstatus.h"
35 #define WIN32_NO_STATUS
36 #include "wine/debug.h"
37 #include "windef.h"
38 #include "winternl.h"
39 #include "ntdll_misc.h"
40 #include "wine/server.h"
42 WINE_DEFAULT_DEBUG_CHANNEL(ntdll);
46 * Generic object functions
49 /******************************************************************************
50 * NtQueryObject [NTDLL.@]
51 * ZwQueryObject [NTDLL.@]
53 NTSTATUS WINAPI NtQueryObject(IN HANDLE handle,
54 IN OBJECT_INFORMATION_CLASS info_class,
55 OUT PVOID ptr, IN ULONG len, OUT PULONG used_len)
57 NTSTATUS status;
59 TRACE("(%p,0x%08x,%p,0x%08x,%p): stub\n",
60 handle, info_class, ptr, len, used_len);
62 if (used_len) *used_len = 0;
64 switch (info_class)
66 case ObjectBasicInformation:
68 POBJECT_BASIC_INFORMATION p = (POBJECT_BASIC_INFORMATION)ptr;
70 if (len < sizeof(*p)) return STATUS_INVALID_BUFFER_SIZE;
72 SERVER_START_REQ( get_object_info )
74 req->handle = handle;
75 status = wine_server_call( req );
76 if (status == STATUS_SUCCESS)
78 memset( p, 0, sizeof(*p) );
79 p->GrantedAccess = reply->access;
80 p->PointerCount = reply->ref_count;
81 p->HandleCount = 1; /* at least one */
82 if (used_len) *used_len = sizeof(*p);
85 SERVER_END_REQ;
87 break;
88 case ObjectDataInformation:
90 OBJECT_DATA_INFORMATION* p = (OBJECT_DATA_INFORMATION*)ptr;
92 if (len < sizeof(*p)) return STATUS_INVALID_BUFFER_SIZE;
94 SERVER_START_REQ( set_handle_info )
96 req->handle = handle;
97 req->flags = 0;
98 req->mask = 0;
99 status = wine_server_call( req );
100 if (status == STATUS_SUCCESS)
102 p->InheritHandle = (reply->old_flags & HANDLE_FLAG_INHERIT) ? TRUE : FALSE;
103 p->ProtectFromClose = (reply->old_flags & HANDLE_FLAG_PROTECT_FROM_CLOSE) ? TRUE : FALSE;
104 if (used_len) *used_len = sizeof(*p);
107 SERVER_END_REQ;
109 break;
110 default:
111 FIXME("Unsupported information class %u\n", info_class);
112 status = STATUS_NOT_IMPLEMENTED;
113 break;
115 return status;
118 /******************************************************************
119 * NtSetInformationObject [NTDLL.@]
120 * ZwSetInformationObject [NTDLL.@]
123 NTSTATUS WINAPI NtSetInformationObject(IN HANDLE handle,
124 IN OBJECT_INFORMATION_CLASS info_class,
125 IN PVOID ptr, IN ULONG len)
127 NTSTATUS status;
129 TRACE("(%p,0x%08x,%p,0x%08x): stub\n",
130 handle, info_class, ptr, len);
132 switch (info_class)
134 case ObjectDataInformation:
136 OBJECT_DATA_INFORMATION* p = (OBJECT_DATA_INFORMATION*)ptr;
138 if (len < sizeof(*p)) return STATUS_INVALID_BUFFER_SIZE;
140 SERVER_START_REQ( set_handle_info )
142 req->handle = handle;
143 req->flags = 0;
144 req->mask = HANDLE_FLAG_INHERIT | HANDLE_FLAG_PROTECT_FROM_CLOSE;
145 if (p->InheritHandle) req->flags |= HANDLE_FLAG_INHERIT;
146 if (p->ProtectFromClose) req->flags |= HANDLE_FLAG_PROTECT_FROM_CLOSE;
147 status = wine_server_call( req );
149 SERVER_END_REQ;
151 break;
152 default:
153 FIXME("Unsupported information class %u\n", info_class);
154 status = STATUS_NOT_IMPLEMENTED;
155 break;
157 return status;
160 /******************************************************************************
161 * NtQuerySecurityObject [NTDLL.@]
163 * An ntdll analogue to GetKernelObjectSecurity().
166 NTSTATUS WINAPI
167 NtQuerySecurityObject(
168 IN HANDLE Object,
169 IN SECURITY_INFORMATION RequestedInformation,
170 OUT PSECURITY_DESCRIPTOR pSecurityDescriptor,
171 IN ULONG Length,
172 OUT PULONG ResultLength)
174 PISECURITY_DESCRIPTOR_RELATIVE psd = pSecurityDescriptor;
175 NTSTATUS status;
176 unsigned int buffer_size = 512;
177 BOOLEAN need_more_memory = FALSE;
179 TRACE("(%p,0x%08x,%p,0x%08x,%p)\n",
180 Object, RequestedInformation, pSecurityDescriptor, Length, ResultLength);
184 char *buffer = RtlAllocateHeap(GetProcessHeap(), 0, buffer_size);
185 if (!buffer)
186 return STATUS_NO_MEMORY;
188 SERVER_START_REQ( get_security_object )
190 req->handle = Object;
191 req->security_info = RequestedInformation;
192 wine_server_set_reply( req, buffer, buffer_size );
193 status = wine_server_call( req );
194 if (status == STATUS_SUCCESS)
196 struct security_descriptor *sd = (struct security_descriptor *)buffer;
197 if (reply->sd_len)
199 *ResultLength = sizeof(SECURITY_DESCRIPTOR_RELATIVE) +
200 sd->owner_len + sd->group_len + sd->sacl_len + sd->dacl_len;
201 if (Length >= *ResultLength)
203 psd->Revision = SECURITY_DESCRIPTOR_REVISION;
204 psd->Sbz1 = 0;
205 psd->Control = sd->control | SE_SELF_RELATIVE;
206 psd->Owner = sd->owner_len ? sizeof(SECURITY_DESCRIPTOR_RELATIVE) : 0;
207 psd->Group = sd->group_len ? sizeof(SECURITY_DESCRIPTOR_RELATIVE) + sd->owner_len : 0;
208 psd->Sacl = sd->sacl_len ? sizeof(SECURITY_DESCRIPTOR_RELATIVE) + sd->owner_len + sd->group_len : 0;
209 psd->Dacl = sd->dacl_len ? sizeof(SECURITY_DESCRIPTOR_RELATIVE) + sd->owner_len + sd->group_len + sd->sacl_len : 0;
210 /* owner, group, sacl and dacl are the same type as in the server
211 * and in the same order so we copy the memory in one block */
212 memcpy((char *)pSecurityDescriptor + sizeof(SECURITY_DESCRIPTOR_RELATIVE),
213 buffer + sizeof(struct security_descriptor),
214 sd->owner_len + sd->group_len + sd->sacl_len + sd->dacl_len);
216 else
217 status = STATUS_BUFFER_TOO_SMALL;
219 else
221 *ResultLength = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
222 if (Length >= *ResultLength)
224 memset(psd, 0, sizeof(*psd));
225 psd->Revision = SECURITY_DESCRIPTOR_REVISION;
226 psd->Control = SE_SELF_RELATIVE;
228 else
229 status = STATUS_BUFFER_TOO_SMALL;
232 else if (status == STATUS_BUFFER_TOO_SMALL)
234 buffer_size = reply->sd_len;
235 need_more_memory = TRUE;
238 SERVER_END_REQ;
239 RtlFreeHeap(GetProcessHeap(), 0, buffer);
240 } while (need_more_memory);
242 return status;
246 /******************************************************************************
247 * NtDuplicateObject [NTDLL.@]
248 * ZwDuplicateObject [NTDLL.@]
250 NTSTATUS WINAPI NtDuplicateObject( HANDLE source_process, HANDLE source,
251 HANDLE dest_process, PHANDLE dest,
252 ACCESS_MASK access, ULONG attributes, ULONG options )
254 NTSTATUS ret;
255 SERVER_START_REQ( dup_handle )
257 req->src_process = source_process;
258 req->src_handle = source;
259 req->dst_process = dest_process;
260 req->access = access;
261 req->attributes = attributes;
262 req->options = options;
264 if (!(ret = wine_server_call( req )))
266 if (dest) *dest = reply->handle;
267 if (reply->closed)
269 if (reply->self)
271 int fd = server_remove_fd_from_cache( source );
272 if (fd != -1) close( fd );
275 else if (options & DUPLICATE_CLOSE_SOURCE)
276 WARN( "failed to close handle %p in process %p\n", source, source_process );
279 SERVER_END_REQ;
280 return ret;
283 /**************************************************************************
284 * NtClose [NTDLL.@]
286 * Close a handle reference to an object.
288 * PARAMS
289 * Handle [I] handle to close
291 * RETURNS
292 * Success: ERROR_SUCCESS.
293 * Failure: An NTSTATUS error code.
295 NTSTATUS WINAPI NtClose( HANDLE Handle )
297 NTSTATUS ret;
298 int fd = server_remove_fd_from_cache( Handle );
300 SERVER_START_REQ( close_handle )
302 req->handle = Handle;
303 ret = wine_server_call( req );
305 SERVER_END_REQ;
306 if (fd != -1) close( fd );
307 return ret;
311 * Directory functions
314 /**************************************************************************
315 * NtOpenDirectoryObject [NTDLL.@]
316 * ZwOpenDirectoryObject [NTDLL.@]
318 * Open a namespace directory object.
320 * PARAMS
321 * DirectoryHandle [O] Destination for the new directory handle
322 * DesiredAccess [I] Desired access to the directory
323 * ObjectAttributes [I] Structure describing the directory
325 * RETURNS
326 * Success: ERROR_SUCCESS.
327 * Failure: An NTSTATUS error code.
329 NTSTATUS WINAPI NtOpenDirectoryObject(PHANDLE DirectoryHandle, ACCESS_MASK DesiredAccess,
330 POBJECT_ATTRIBUTES ObjectAttributes)
332 NTSTATUS ret;
333 TRACE("(%p,0x%08x)\n", DirectoryHandle, DesiredAccess);
334 dump_ObjectAttributes(ObjectAttributes);
336 if (!DirectoryHandle) return STATUS_ACCESS_VIOLATION;
337 if (!ObjectAttributes) return STATUS_INVALID_PARAMETER;
338 /* Have to test it here because server won't know difference between
339 * ObjectName == NULL and ObjectName == "" */
340 if (!ObjectAttributes->ObjectName)
342 if (ObjectAttributes->RootDirectory)
343 return STATUS_OBJECT_NAME_INVALID;
344 else
345 return STATUS_OBJECT_PATH_SYNTAX_BAD;
348 SERVER_START_REQ(open_directory)
350 req->access = DesiredAccess;
351 req->attributes = ObjectAttributes->Attributes;
352 req->rootdir = ObjectAttributes->RootDirectory;
353 if (ObjectAttributes->ObjectName)
354 wine_server_add_data(req, ObjectAttributes->ObjectName->Buffer,
355 ObjectAttributes->ObjectName->Length);
356 ret = wine_server_call( req );
357 *DirectoryHandle = reply->handle;
359 SERVER_END_REQ;
360 return ret;
363 /******************************************************************************
364 * NtCreateDirectoryObject [NTDLL.@]
365 * ZwCreateDirectoryObject [NTDLL.@]
367 * Create a namespace directory object.
369 * PARAMS
370 * DirectoryHandle [O] Destination for the new directory handle
371 * DesiredAccess [I] Desired access to the directory
372 * ObjectAttributes [I] Structure describing the directory
374 * RETURNS
375 * Success: ERROR_SUCCESS.
376 * Failure: An NTSTATUS error code.
378 NTSTATUS WINAPI NtCreateDirectoryObject(PHANDLE DirectoryHandle, ACCESS_MASK DesiredAccess,
379 POBJECT_ATTRIBUTES ObjectAttributes)
381 NTSTATUS ret;
382 TRACE("(%p,0x%08x)\n", DirectoryHandle, DesiredAccess);
383 dump_ObjectAttributes(ObjectAttributes);
385 if (!DirectoryHandle) return STATUS_ACCESS_VIOLATION;
387 SERVER_START_REQ(create_directory)
389 req->access = DesiredAccess;
390 req->attributes = ObjectAttributes ? ObjectAttributes->Attributes : 0;
391 req->rootdir = ObjectAttributes ? ObjectAttributes->RootDirectory : 0;
392 if (ObjectAttributes && ObjectAttributes->ObjectName)
393 wine_server_add_data(req, ObjectAttributes->ObjectName->Buffer,
394 ObjectAttributes->ObjectName->Length);
395 ret = wine_server_call( req );
396 *DirectoryHandle = reply->handle;
398 SERVER_END_REQ;
399 return ret;
402 /******************************************************************************
403 * NtQueryDirectoryObject [NTDLL.@]
404 * ZwQueryDirectoryObject [NTDLL.@]
406 * Read information from a namespace directory.
408 * PARAMS
409 * DirectoryHandle [I] Handle to a directory object
410 * Buffer [O] Buffer to hold the read data
411 * BufferLength [I] Size of the buffer in bytes
412 * ReturnSingleEntry [I] If TRUE, return a single entry, if FALSE, return as many as fit in the buffer
413 * RestartScan [I] If TRUE, start scanning from the start, if FALSE, scan from Context
414 * Context [I/O] Indicates what point of the directory the scan is at
415 * ReturnLength [O] Caller supplied storage for the number of bytes written (or NULL)
417 * RETURNS
418 * Success: ERROR_SUCCESS.
419 * Failure: An NTSTATUS error code.
421 NTSTATUS WINAPI NtQueryDirectoryObject(IN HANDLE DirectoryHandle, OUT PDIRECTORY_BASIC_INFORMATION Buffer,
422 IN ULONG BufferLength, IN BOOLEAN ReturnSingleEntry, IN BOOLEAN RestartScan,
423 IN OUT PULONG Context, OUT PULONG ReturnLength OPTIONAL)
425 FIXME("(%p,%p,0x%08x,0x%08x,0x%08x,%p,%p), stub\n", DirectoryHandle, Buffer, BufferLength, ReturnSingleEntry,
426 RestartScan, Context, ReturnLength);
428 return STATUS_NOT_IMPLEMENTED;
432 * Link objects
435 /******************************************************************************
436 * NtOpenSymbolicLinkObject [NTDLL.@]
437 * ZwOpenSymbolicLinkObject [NTDLL.@]
439 * Open a namespace symbolic link object.
441 * PARAMS
442 * LinkHandle [O] Destination for the new symbolic link handle
443 * DesiredAccess [I] Desired access to the symbolic link
444 * ObjectAttributes [I] Structure describing the symbolic link
446 * RETURNS
447 * Success: ERROR_SUCCESS.
448 * Failure: An NTSTATUS error code.
450 NTSTATUS WINAPI NtOpenSymbolicLinkObject(OUT PHANDLE LinkHandle, IN ACCESS_MASK DesiredAccess,
451 IN POBJECT_ATTRIBUTES ObjectAttributes)
453 NTSTATUS ret;
454 TRACE("(%p,0x%08x,%p)\n",LinkHandle, DesiredAccess, ObjectAttributes);
455 dump_ObjectAttributes(ObjectAttributes);
457 if (!LinkHandle) return STATUS_ACCESS_VIOLATION;
458 if (!ObjectAttributes) return STATUS_INVALID_PARAMETER;
459 /* Have to test it here because server won't know difference between
460 * ObjectName == NULL and ObjectName == "" */
461 if (!ObjectAttributes->ObjectName)
463 if (ObjectAttributes->RootDirectory)
464 return STATUS_OBJECT_NAME_INVALID;
465 else
466 return STATUS_OBJECT_PATH_SYNTAX_BAD;
469 SERVER_START_REQ(open_symlink)
471 req->access = DesiredAccess;
472 req->attributes = ObjectAttributes->Attributes;
473 req->rootdir = ObjectAttributes->RootDirectory;
474 if (ObjectAttributes->ObjectName)
475 wine_server_add_data(req, ObjectAttributes->ObjectName->Buffer,
476 ObjectAttributes->ObjectName->Length);
477 ret = wine_server_call( req );
478 *LinkHandle = reply->handle;
480 SERVER_END_REQ;
481 return ret;
484 /******************************************************************************
485 * NtCreateSymbolicLinkObject [NTDLL.@]
486 * ZwCreateSymbolicLinkObject [NTDLL.@]
488 * Open a namespace symbolic link object.
490 * PARAMS
491 * SymbolicLinkHandle [O] Destination for the new symbolic link handle
492 * DesiredAccess [I] Desired access to the symbolic link
493 * ObjectAttributes [I] Structure describing the symbolic link
494 * TargetName [I] Name of the target symbolic link points to
496 * RETURNS
497 * Success: ERROR_SUCCESS.
498 * Failure: An NTSTATUS error code.
500 NTSTATUS WINAPI NtCreateSymbolicLinkObject(OUT PHANDLE SymbolicLinkHandle,IN ACCESS_MASK DesiredAccess,
501 IN POBJECT_ATTRIBUTES ObjectAttributes,
502 IN PUNICODE_STRING TargetName)
504 NTSTATUS ret;
505 TRACE("(%p,0x%08x,%p, -> %s)\n", SymbolicLinkHandle, DesiredAccess, ObjectAttributes,
506 debugstr_us(TargetName));
507 dump_ObjectAttributes(ObjectAttributes);
509 if (!SymbolicLinkHandle || !TargetName) return STATUS_ACCESS_VIOLATION;
510 if (!TargetName->Buffer) return STATUS_INVALID_PARAMETER;
512 SERVER_START_REQ(create_symlink)
514 req->access = DesiredAccess;
515 req->attributes = ObjectAttributes ? ObjectAttributes->Attributes : 0;
516 req->rootdir = ObjectAttributes ? ObjectAttributes->RootDirectory : 0;
517 if (ObjectAttributes && ObjectAttributes->ObjectName)
519 req->name_len = ObjectAttributes->ObjectName->Length;
520 wine_server_add_data(req, ObjectAttributes->ObjectName->Buffer,
521 ObjectAttributes->ObjectName->Length);
523 else
524 req->name_len = 0;
525 wine_server_add_data(req, TargetName->Buffer, TargetName->Length);
526 ret = wine_server_call( req );
527 *SymbolicLinkHandle = reply->handle;
529 SERVER_END_REQ;
530 return ret;
533 /******************************************************************************
534 * NtQuerySymbolicLinkObject [NTDLL.@]
535 * ZwQuerySymbolicLinkObject [NTDLL.@]
537 * Query a namespace symbolic link object target name.
539 * PARAMS
540 * LinkHandle [I] Handle to a symbolic link object
541 * LinkTarget [O] Destination for the symbolic link target
542 * ReturnedLength [O] Size of returned data
544 * RETURNS
545 * Success: ERROR_SUCCESS.
546 * Failure: An NTSTATUS error code.
548 NTSTATUS WINAPI NtQuerySymbolicLinkObject(IN HANDLE LinkHandle, IN OUT PUNICODE_STRING LinkTarget,
549 OUT PULONG ReturnedLength OPTIONAL)
551 NTSTATUS ret;
552 TRACE("(%p,%p,%p)\n", LinkHandle, LinkTarget, ReturnedLength);
554 if (!LinkTarget) return STATUS_ACCESS_VIOLATION;
556 SERVER_START_REQ(query_symlink)
558 req->handle = LinkHandle;
559 wine_server_set_reply( req, LinkTarget->Buffer, LinkTarget->MaximumLength );
560 if (!(ret = wine_server_call( req )))
562 LinkTarget->Length = wine_server_reply_size(reply);
563 if (ReturnedLength) *ReturnedLength = LinkTarget->Length;
566 SERVER_END_REQ;
567 return ret;
570 /******************************************************************************
571 * NtAllocateUuids [NTDLL.@]
573 NTSTATUS WINAPI NtAllocateUuids(
574 PULARGE_INTEGER Time,
575 PULONG Range,
576 PULONG Sequence)
578 FIXME("(%p,%p,%p), stub.\n", Time, Range, Sequence);
579 return 0;