widl: Convert interface lists to standard Wine lists.
[wine/hacks.git] / dlls / ntdll / om.c
blob6057caa01701cf1c42607a8124f7758afb43b8d6
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 ObjectDataInformation:
68 OBJECT_DATA_INFORMATION* p = (OBJECT_DATA_INFORMATION*)ptr;
70 if (len < sizeof(*p)) return STATUS_INVALID_BUFFER_SIZE;
72 SERVER_START_REQ( set_handle_info )
74 req->handle = handle;
75 req->flags = 0;
76 req->mask = 0;
77 status = wine_server_call( req );
78 if (status == STATUS_SUCCESS)
80 p->InheritHandle = (reply->old_flags & HANDLE_FLAG_INHERIT) ? TRUE : FALSE;
81 p->ProtectFromClose = (reply->old_flags & HANDLE_FLAG_PROTECT_FROM_CLOSE) ? TRUE : FALSE;
82 if (used_len) *used_len = sizeof(*p);
85 SERVER_END_REQ;
87 break;
88 default:
89 FIXME("Unsupported information class %u\n", info_class);
90 status = STATUS_NOT_IMPLEMENTED;
91 break;
93 return status;
96 /******************************************************************
97 * NtSetInformationObject [NTDLL.@]
98 * ZwSetInformationObject [NTDLL.@]
101 NTSTATUS WINAPI NtSetInformationObject(IN HANDLE handle,
102 IN OBJECT_INFORMATION_CLASS info_class,
103 IN PVOID ptr, IN ULONG len)
105 NTSTATUS status;
107 TRACE("(%p,0x%08x,%p,0x%08x): stub\n",
108 handle, info_class, ptr, len);
110 switch (info_class)
112 case ObjectDataInformation:
114 OBJECT_DATA_INFORMATION* p = (OBJECT_DATA_INFORMATION*)ptr;
116 if (len < sizeof(*p)) return STATUS_INVALID_BUFFER_SIZE;
118 SERVER_START_REQ( set_handle_info )
120 req->handle = handle;
121 req->flags = 0;
122 req->mask = HANDLE_FLAG_INHERIT | HANDLE_FLAG_PROTECT_FROM_CLOSE;
123 if (p->InheritHandle) req->flags |= HANDLE_FLAG_INHERIT;
124 if (p->ProtectFromClose) req->flags |= HANDLE_FLAG_PROTECT_FROM_CLOSE;
125 status = wine_server_call( req );
127 SERVER_END_REQ;
129 break;
130 default:
131 FIXME("Unsupported information class %u\n", info_class);
132 status = STATUS_NOT_IMPLEMENTED;
133 break;
135 return status;
138 /******************************************************************************
139 * NtQuerySecurityObject [NTDLL.@]
141 * An ntdll analogue to GetKernelObjectSecurity().
143 * NOTES
144 * only the lowest 4 bit of SecurityObjectInformationClass are used
145 * 0x7-0xf returns STATUS_ACCESS_DENIED (even running with system privileges)
147 * FIXME
148 * We are constructing a fake sid (Administrators:Full, System:Full, Everyone:Read)
150 NTSTATUS WINAPI
151 NtQuerySecurityObject(
152 IN HANDLE Object,
153 IN SECURITY_INFORMATION RequestedInformation,
154 OUT PSECURITY_DESCRIPTOR pSecurityDesriptor,
155 IN ULONG Length,
156 OUT PULONG ResultLength)
158 static const SID_IDENTIFIER_AUTHORITY localSidAuthority = {SECURITY_NT_AUTHORITY};
159 static const SID_IDENTIFIER_AUTHORITY worldSidAuthority = {SECURITY_WORLD_SID_AUTHORITY};
160 BYTE Buffer[256];
161 PISECURITY_DESCRIPTOR_RELATIVE psd = (PISECURITY_DESCRIPTOR_RELATIVE)Buffer;
162 UINT BufferIndex = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
164 FIXME("(%p,0x%08x,%p,0x%08x,%p) stub!\n",
165 Object, RequestedInformation, pSecurityDesriptor, Length, ResultLength);
167 RequestedInformation &= 0x0000000f;
169 if (RequestedInformation & SACL_SECURITY_INFORMATION) return STATUS_ACCESS_DENIED;
171 ZeroMemory(Buffer, 256);
172 RtlCreateSecurityDescriptor((PSECURITY_DESCRIPTOR)psd, SECURITY_DESCRIPTOR_REVISION);
173 psd->Control = SE_SELF_RELATIVE |
174 ((RequestedInformation & DACL_SECURITY_INFORMATION) ? SE_DACL_PRESENT:0);
176 /* owner: administrator S-1-5-20-220*/
177 if (OWNER_SECURITY_INFORMATION & RequestedInformation)
179 SID* psid = (SID*)&(Buffer[BufferIndex]);
181 psd->Owner = BufferIndex;
182 BufferIndex += RtlLengthRequiredSid(2);
184 psid->Revision = SID_REVISION;
185 psid->SubAuthorityCount = 2;
186 psid->IdentifierAuthority = localSidAuthority;
187 psid->SubAuthority[0] = SECURITY_BUILTIN_DOMAIN_RID;
188 psid->SubAuthority[1] = DOMAIN_ALIAS_RID_ADMINS;
191 /* group: built in domain S-1-5-12 */
192 if (GROUP_SECURITY_INFORMATION & RequestedInformation)
194 SID* psid = (SID*) &(Buffer[BufferIndex]);
196 psd->Group = BufferIndex;
197 BufferIndex += RtlLengthRequiredSid(1);
199 psid->Revision = SID_REVISION;
200 psid->SubAuthorityCount = 1;
201 psid->IdentifierAuthority = localSidAuthority;
202 psid->SubAuthority[0] = SECURITY_LOCAL_SYSTEM_RID;
205 /* discretionary ACL */
206 if (DACL_SECURITY_INFORMATION & RequestedInformation)
208 /* acl header */
209 PACL pacl = (PACL)&(Buffer[BufferIndex]);
210 PACCESS_ALLOWED_ACE pace;
211 SID* psid;
213 psd->Dacl = BufferIndex;
215 pacl->AclRevision = MIN_ACL_REVISION;
216 pacl->AceCount = 3;
217 pacl->AclSize = BufferIndex; /* storing the start index temporary */
219 BufferIndex += sizeof(ACL);
221 /* ACE System - full access */
222 pace = (PACCESS_ALLOWED_ACE)&(Buffer[BufferIndex]);
223 BufferIndex += sizeof(ACCESS_ALLOWED_ACE)-sizeof(DWORD);
225 pace->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
226 pace->Header.AceFlags = CONTAINER_INHERIT_ACE;
227 pace->Header.AceSize = sizeof(ACCESS_ALLOWED_ACE)-sizeof(DWORD) + RtlLengthRequiredSid(1);
228 pace->Mask = DELETE | READ_CONTROL | WRITE_DAC | WRITE_OWNER | 0x3f;
229 pace->SidStart = BufferIndex;
231 /* SID S-1-5-12 (System) */
232 psid = (SID*)&(Buffer[BufferIndex]);
234 BufferIndex += RtlLengthRequiredSid(1);
236 psid->Revision = SID_REVISION;
237 psid->SubAuthorityCount = 1;
238 psid->IdentifierAuthority = localSidAuthority;
239 psid->SubAuthority[0] = SECURITY_LOCAL_SYSTEM_RID;
241 /* ACE Administrators - full access*/
242 pace = (PACCESS_ALLOWED_ACE) &(Buffer[BufferIndex]);
243 BufferIndex += sizeof(ACCESS_ALLOWED_ACE)-sizeof(DWORD);
245 pace->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
246 pace->Header.AceFlags = CONTAINER_INHERIT_ACE;
247 pace->Header.AceSize = sizeof(ACCESS_ALLOWED_ACE)-sizeof(DWORD) + RtlLengthRequiredSid(2);
248 pace->Mask = DELETE | READ_CONTROL | WRITE_DAC | WRITE_OWNER | 0x3f;
249 pace->SidStart = BufferIndex;
251 /* S-1-5-12 (Administrators) */
252 psid = (SID*)&(Buffer[BufferIndex]);
254 BufferIndex += RtlLengthRequiredSid(2);
256 psid->Revision = SID_REVISION;
257 psid->SubAuthorityCount = 2;
258 psid->IdentifierAuthority = localSidAuthority;
259 psid->SubAuthority[0] = SECURITY_BUILTIN_DOMAIN_RID;
260 psid->SubAuthority[1] = DOMAIN_ALIAS_RID_ADMINS;
262 /* ACE Everyone - read access */
263 pace = (PACCESS_ALLOWED_ACE)&(Buffer[BufferIndex]);
264 BufferIndex += sizeof(ACCESS_ALLOWED_ACE)-sizeof(DWORD);
266 pace->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
267 pace->Header.AceFlags = CONTAINER_INHERIT_ACE;
268 pace->Header.AceSize = sizeof(ACCESS_ALLOWED_ACE)-sizeof(DWORD) + RtlLengthRequiredSid(1);
269 pace->Mask = READ_CONTROL| 0x19;
270 pace->SidStart = BufferIndex;
272 /* SID S-1-1-0 (Everyone) */
273 psid = (SID*)&(Buffer[BufferIndex]);
275 BufferIndex += RtlLengthRequiredSid(1);
277 psid->Revision = SID_REVISION;
278 psid->SubAuthorityCount = 1;
279 psid->IdentifierAuthority = worldSidAuthority;
280 psid->SubAuthority[0] = 0;
282 /* calculate used bytes */
283 pacl->AclSize = BufferIndex - pacl->AclSize;
285 *ResultLength = BufferIndex;
286 TRACE("len=%u\n", *ResultLength);
287 if (Length < *ResultLength) return STATUS_BUFFER_TOO_SMALL;
288 memcpy(pSecurityDesriptor, Buffer, *ResultLength);
290 return STATUS_SUCCESS;
294 /******************************************************************************
295 * NtDuplicateObject [NTDLL.@]
296 * ZwDuplicateObject [NTDLL.@]
298 NTSTATUS WINAPI NtDuplicateObject( HANDLE source_process, HANDLE source,
299 HANDLE dest_process, PHANDLE dest,
300 ACCESS_MASK access, ULONG attributes, ULONG options )
302 NTSTATUS ret;
303 SERVER_START_REQ( dup_handle )
305 req->src_process = source_process;
306 req->src_handle = source;
307 req->dst_process = dest_process;
308 req->access = access;
309 req->attributes = attributes;
310 req->options = options;
312 if (!(ret = wine_server_call( req )))
314 if (dest) *dest = reply->handle;
315 if (reply->closed)
317 if (reply->self)
319 int fd = server_remove_fd_from_cache( source );
320 if (fd != -1) close( fd );
323 else if (options & DUPLICATE_CLOSE_SOURCE)
324 WARN( "failed to close handle %p in process %p\n", source, source_process );
327 SERVER_END_REQ;
328 return ret;
331 /**************************************************************************
332 * NtClose [NTDLL.@]
334 * Close a handle reference to an object.
336 * PARAMS
337 * Handle [I] handle to close
339 * RETURNS
340 * Success: ERROR_SUCCESS.
341 * Failure: An NTSTATUS error code.
343 NTSTATUS WINAPI NtClose( HANDLE Handle )
345 NTSTATUS ret;
346 int fd = server_remove_fd_from_cache( Handle );
348 SERVER_START_REQ( close_handle )
350 req->handle = Handle;
351 ret = wine_server_call( req );
353 SERVER_END_REQ;
354 if (fd != -1) close( fd );
355 return ret;
359 * Directory functions
362 /**************************************************************************
363 * NtOpenDirectoryObject [NTDLL.@]
364 * ZwOpenDirectoryObject [NTDLL.@]
366 * Open a namespace directory object.
368 * PARAMS
369 * DirectoryHandle [O] Destination for the new directory handle
370 * DesiredAccess [I] Desired access to the directory
371 * ObjectAttributes [I] Structure describing the directory
373 * RETURNS
374 * Success: ERROR_SUCCESS.
375 * Failure: An NTSTATUS error code.
377 NTSTATUS WINAPI NtOpenDirectoryObject(PHANDLE DirectoryHandle, ACCESS_MASK DesiredAccess,
378 POBJECT_ATTRIBUTES ObjectAttributes)
380 NTSTATUS ret;
381 TRACE("(%p,0x%08x)\n", DirectoryHandle, DesiredAccess);
382 dump_ObjectAttributes(ObjectAttributes);
384 if (!DirectoryHandle) return STATUS_ACCESS_VIOLATION;
385 if (!ObjectAttributes) return STATUS_INVALID_PARAMETER;
386 /* Have to test it here because server won't know difference between
387 * ObjectName == NULL and ObjectName == "" */
388 if (!ObjectAttributes->ObjectName)
390 if (ObjectAttributes->RootDirectory)
391 return STATUS_OBJECT_NAME_INVALID;
392 else
393 return STATUS_OBJECT_PATH_SYNTAX_BAD;
396 SERVER_START_REQ(open_directory)
398 req->access = DesiredAccess;
399 req->attributes = ObjectAttributes->Attributes;
400 req->rootdir = ObjectAttributes->RootDirectory;
401 if (ObjectAttributes->ObjectName)
402 wine_server_add_data(req, ObjectAttributes->ObjectName->Buffer,
403 ObjectAttributes->ObjectName->Length);
404 ret = wine_server_call( req );
405 *DirectoryHandle = reply->handle;
407 SERVER_END_REQ;
408 return ret;
411 /******************************************************************************
412 * NtCreateDirectoryObject [NTDLL.@]
413 * ZwCreateDirectoryObject [NTDLL.@]
415 * Create a namespace directory object.
417 * PARAMS
418 * DirectoryHandle [O] Destination for the new directory handle
419 * DesiredAccess [I] Desired access to the directory
420 * ObjectAttributes [I] Structure describing the directory
422 * RETURNS
423 * Success: ERROR_SUCCESS.
424 * Failure: An NTSTATUS error code.
426 NTSTATUS WINAPI NtCreateDirectoryObject(PHANDLE DirectoryHandle, ACCESS_MASK DesiredAccess,
427 POBJECT_ATTRIBUTES ObjectAttributes)
429 NTSTATUS ret;
430 TRACE("(%p,0x%08x)\n", DirectoryHandle, DesiredAccess);
431 dump_ObjectAttributes(ObjectAttributes);
433 if (!DirectoryHandle) return STATUS_ACCESS_VIOLATION;
435 SERVER_START_REQ(create_directory)
437 req->access = DesiredAccess;
438 req->attributes = ObjectAttributes ? ObjectAttributes->Attributes : 0;
439 req->rootdir = ObjectAttributes ? ObjectAttributes->RootDirectory : 0;
440 if (ObjectAttributes && ObjectAttributes->ObjectName)
441 wine_server_add_data(req, ObjectAttributes->ObjectName->Buffer,
442 ObjectAttributes->ObjectName->Length);
443 ret = wine_server_call( req );
444 *DirectoryHandle = reply->handle;
446 SERVER_END_REQ;
447 return ret;
450 /******************************************************************************
451 * NtQueryDirectoryObject [NTDLL.@]
452 * ZwQueryDirectoryObject [NTDLL.@]
454 * Read information from a namespace directory.
456 * PARAMS
457 * DirectoryHandle [I] Handle to a directory object
458 * Buffer [O] Buffer to hold the read data
459 * BufferLength [I] Size of the buffer in bytes
460 * ReturnSingleEntry [I] If TRUE, return a single entry, if FALSE, return as many as fit in the buffer
461 * RestartScan [I] If TRUE, start scanning from the start, if FALSE, scan from Context
462 * Context [I/O] Indicates what point of the directory the scan is at
463 * ReturnLength [O] Caller supplied storage for the number of bytes written (or NULL)
465 * RETURNS
466 * Success: ERROR_SUCCESS.
467 * Failure: An NTSTATUS error code.
469 NTSTATUS WINAPI NtQueryDirectoryObject(IN HANDLE DirectoryHandle, OUT PDIRECTORY_BASIC_INFORMATION Buffer,
470 IN ULONG BufferLength, IN BOOLEAN ReturnSingleEntry, IN BOOLEAN RestartScan,
471 IN OUT PULONG Context, OUT PULONG ReturnLength OPTIONAL)
473 FIXME("(%p,%p,0x%08x,0x%08x,0x%08x,%p,%p), stub\n", DirectoryHandle, Buffer, BufferLength, ReturnSingleEntry,
474 RestartScan, Context, ReturnLength);
476 return STATUS_NOT_IMPLEMENTED;
480 * Link objects
483 /******************************************************************************
484 * NtOpenSymbolicLinkObject [NTDLL.@]
485 * ZwOpenSymbolicLinkObject [NTDLL.@]
487 * Open a namespace symbolic link object.
489 * PARAMS
490 * LinkHandle [O] Destination for the new symbolic link handle
491 * DesiredAccess [I] Desired access to the symbolic link
492 * ObjectAttributes [I] Structure describing the symbolic link
494 * RETURNS
495 * Success: ERROR_SUCCESS.
496 * Failure: An NTSTATUS error code.
498 NTSTATUS WINAPI NtOpenSymbolicLinkObject(OUT PHANDLE LinkHandle, IN ACCESS_MASK DesiredAccess,
499 IN POBJECT_ATTRIBUTES ObjectAttributes)
501 NTSTATUS ret;
502 TRACE("(%p,0x%08x,%p)\n",LinkHandle, DesiredAccess, ObjectAttributes);
503 dump_ObjectAttributes(ObjectAttributes);
505 if (!LinkHandle) return STATUS_ACCESS_VIOLATION;
506 if (!ObjectAttributes) return STATUS_INVALID_PARAMETER;
507 /* Have to test it here because server won't know difference between
508 * ObjectName == NULL and ObjectName == "" */
509 if (!ObjectAttributes->ObjectName)
511 if (ObjectAttributes->RootDirectory)
512 return STATUS_OBJECT_NAME_INVALID;
513 else
514 return STATUS_OBJECT_PATH_SYNTAX_BAD;
517 SERVER_START_REQ(open_symlink)
519 req->access = DesiredAccess;
520 req->attributes = ObjectAttributes->Attributes;
521 req->rootdir = ObjectAttributes->RootDirectory;
522 if (ObjectAttributes->ObjectName)
523 wine_server_add_data(req, ObjectAttributes->ObjectName->Buffer,
524 ObjectAttributes->ObjectName->Length);
525 ret = wine_server_call( req );
526 *LinkHandle = reply->handle;
528 SERVER_END_REQ;
529 return ret;
532 /******************************************************************************
533 * NtCreateSymbolicLinkObject [NTDLL.@]
534 * ZwCreateSymbolicLinkObject [NTDLL.@]
536 * Open a namespace symbolic link object.
538 * PARAMS
539 * SymbolicLinkHandle [O] Destination for the new symbolic link handle
540 * DesiredAccess [I] Desired access to the symbolic link
541 * ObjectAttributes [I] Structure describing the symbolic link
542 * TargetName [I] Name of the target symbolic link points to
544 * RETURNS
545 * Success: ERROR_SUCCESS.
546 * Failure: An NTSTATUS error code.
548 NTSTATUS WINAPI NtCreateSymbolicLinkObject(OUT PHANDLE SymbolicLinkHandle,IN ACCESS_MASK DesiredAccess,
549 IN POBJECT_ATTRIBUTES ObjectAttributes,
550 IN PUNICODE_STRING TargetName)
552 NTSTATUS ret;
553 TRACE("(%p,0x%08x,%p, -> %s)\n", SymbolicLinkHandle, DesiredAccess, ObjectAttributes,
554 debugstr_us(TargetName));
555 dump_ObjectAttributes(ObjectAttributes);
557 if (!SymbolicLinkHandle || !TargetName) return STATUS_ACCESS_VIOLATION;
558 if (!TargetName->Buffer) return STATUS_INVALID_PARAMETER;
560 SERVER_START_REQ(create_symlink)
562 req->access = DesiredAccess;
563 req->attributes = ObjectAttributes ? ObjectAttributes->Attributes : 0;
564 req->rootdir = ObjectAttributes ? ObjectAttributes->RootDirectory : 0;
565 if (ObjectAttributes && ObjectAttributes->ObjectName)
567 req->name_len = ObjectAttributes->ObjectName->Length;
568 wine_server_add_data(req, ObjectAttributes->ObjectName->Buffer,
569 ObjectAttributes->ObjectName->Length);
571 else
572 req->name_len = 0;
573 wine_server_add_data(req, TargetName->Buffer, TargetName->Length);
574 ret = wine_server_call( req );
575 *SymbolicLinkHandle = reply->handle;
577 SERVER_END_REQ;
578 return ret;
581 /******************************************************************************
582 * NtQuerySymbolicLinkObject [NTDLL.@]
583 * ZwQuerySymbolicLinkObject [NTDLL.@]
585 * Query a namespace symbolic link object target name.
587 * PARAMS
588 * LinkHandle [I] Handle to a symbolic link object
589 * LinkTarget [O] Destination for the symbolic link target
590 * ReturnedLength [O] Size of returned data
592 * RETURNS
593 * Success: ERROR_SUCCESS.
594 * Failure: An NTSTATUS error code.
596 NTSTATUS WINAPI NtQuerySymbolicLinkObject(IN HANDLE LinkHandle, IN OUT PUNICODE_STRING LinkTarget,
597 OUT PULONG ReturnedLength OPTIONAL)
599 NTSTATUS ret;
600 TRACE("(%p,%p,%p)\n", LinkHandle, LinkTarget, ReturnedLength);
602 if (!LinkTarget) return STATUS_ACCESS_VIOLATION;
604 SERVER_START_REQ(query_symlink)
606 req->handle = LinkHandle;
607 wine_server_set_reply( req, LinkTarget->Buffer, LinkTarget->MaximumLength );
608 if (!(ret = wine_server_call( req )))
610 LinkTarget->Length = wine_server_reply_size(reply);
611 if (ReturnedLength) *ReturnedLength = LinkTarget->Length;
614 SERVER_END_REQ;
615 return ret;
618 /******************************************************************************
619 * NtAllocateUuids [NTDLL.@]
621 NTSTATUS WINAPI NtAllocateUuids(
622 PULARGE_INTEGER Time,
623 PULONG Range,
624 PULONG Sequence)
626 FIXME("(%p,%p,%p), stub.\n", Time, Range, Sequence);
627 return 0;