2 * Object management functions
4 * Copyright 1999, 2000 Juergen Schmied
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
34 #define WIN32_NO_STATUS
35 #include "wine/debug.h"
38 #include "ntdll_misc.h"
39 #include "wine/server.h"
41 WINE_DEFAULT_DEBUG_CHANNEL(ntdll);
45 * Generic object functions
48 /******************************************************************************
49 * NtQueryObject [NTDLL.@]
50 * ZwQueryObject [NTDLL.@]
52 NTSTATUS WINAPI NtQueryObject(IN HANDLE handle,
53 IN OBJECT_INFORMATION_CLASS info_class,
54 OUT PVOID ptr, IN ULONG len, OUT PULONG used_len)
58 TRACE("(%p,0x%08x,%p,0x%08lx,%p): stub\n",
59 handle, info_class, ptr, len, used_len);
61 if (used_len) *used_len = 0;
65 case ObjectDataInformation:
67 OBJECT_DATA_INFORMATION* p = (OBJECT_DATA_INFORMATION*)ptr;
69 if (len < sizeof(*p)) return STATUS_INVALID_BUFFER_SIZE;
71 SERVER_START_REQ( set_handle_info )
76 status = wine_server_call( req );
77 if (status == STATUS_SUCCESS)
79 p->InheritHandle = (reply->old_flags & HANDLE_FLAG_INHERIT) ? TRUE : FALSE;
80 p->ProtectFromClose = (reply->old_flags & HANDLE_FLAG_PROTECT_FROM_CLOSE) ? TRUE : FALSE;
81 if (used_len) *used_len = sizeof(*p);
88 FIXME("Unsupported information class %u\n", info_class);
89 status = STATUS_NOT_IMPLEMENTED;
95 /******************************************************************
96 * NtSetInformationObject [NTDLL.@]
97 * ZwSetInformationObject [NTDLL.@]
100 NTSTATUS WINAPI NtSetInformationObject(IN HANDLE handle,
101 IN OBJECT_INFORMATION_CLASS info_class,
102 IN PVOID ptr, IN ULONG len)
106 TRACE("(%p,0x%08x,%p,0x%08lx): stub\n",
107 handle, info_class, ptr, len);
111 case ObjectDataInformation:
113 OBJECT_DATA_INFORMATION* p = (OBJECT_DATA_INFORMATION*)ptr;
115 if (len < sizeof(*p)) return STATUS_INVALID_BUFFER_SIZE;
117 SERVER_START_REQ( set_handle_info )
119 req->handle = handle;
121 req->mask = HANDLE_FLAG_INHERIT | HANDLE_FLAG_PROTECT_FROM_CLOSE;
122 if (p->InheritHandle) req->flags |= HANDLE_FLAG_INHERIT;
123 if (p->ProtectFromClose) req->flags |= HANDLE_FLAG_PROTECT_FROM_CLOSE;
124 status = wine_server_call( req );
130 FIXME("Unsupported information class %u\n", info_class);
131 status = STATUS_NOT_IMPLEMENTED;
137 /******************************************************************************
138 * NtQuerySecurityObject [NTDLL.@]
140 * An ntdll analogue to GetKernelObjectSecurity().
143 * only the lowest 4 bit of SecurityObjectInformationClass are used
144 * 0x7-0xf returns STATUS_ACCESS_DENIED (even running with system privileges)
147 * We are constructing a fake sid (Administrators:Full, System:Full, Everyone:Read)
150 NtQuerySecurityObject(
152 IN SECURITY_INFORMATION RequestedInformation,
153 OUT PSECURITY_DESCRIPTOR pSecurityDesriptor,
155 OUT PULONG ResultLength)
157 static SID_IDENTIFIER_AUTHORITY localSidAuthority = {SECURITY_NT_AUTHORITY};
158 static SID_IDENTIFIER_AUTHORITY worldSidAuthority = {SECURITY_WORLD_SID_AUTHORITY};
160 PISECURITY_DESCRIPTOR_RELATIVE psd = (PISECURITY_DESCRIPTOR_RELATIVE)Buffer;
161 UINT BufferIndex = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
163 FIXME("(%p,0x%08lx,%p,0x%08lx,%p) stub!\n",
164 Object, RequestedInformation, pSecurityDesriptor, Length, ResultLength);
166 RequestedInformation &= 0x0000000f;
168 if (RequestedInformation & SACL_SECURITY_INFORMATION) return STATUS_ACCESS_DENIED;
170 ZeroMemory(Buffer, 256);
171 RtlCreateSecurityDescriptor((PSECURITY_DESCRIPTOR)psd, SECURITY_DESCRIPTOR_REVISION);
172 psd->Control = SE_SELF_RELATIVE |
173 ((RequestedInformation & DACL_SECURITY_INFORMATION) ? SE_DACL_PRESENT:0);
175 /* owner: administrator S-1-5-20-220*/
176 if (OWNER_SECURITY_INFORMATION & RequestedInformation)
178 SID* psid = (SID*)&(Buffer[BufferIndex]);
180 psd->Owner = BufferIndex;
181 BufferIndex += RtlLengthRequiredSid(2);
183 psid->Revision = SID_REVISION;
184 psid->SubAuthorityCount = 2;
185 psid->IdentifierAuthority = localSidAuthority;
186 psid->SubAuthority[0] = SECURITY_BUILTIN_DOMAIN_RID;
187 psid->SubAuthority[1] = DOMAIN_ALIAS_RID_ADMINS;
190 /* group: built in domain S-1-5-12 */
191 if (GROUP_SECURITY_INFORMATION & RequestedInformation)
193 SID* psid = (SID*) &(Buffer[BufferIndex]);
195 psd->Group = BufferIndex;
196 BufferIndex += RtlLengthRequiredSid(1);
198 psid->Revision = SID_REVISION;
199 psid->SubAuthorityCount = 1;
200 psid->IdentifierAuthority = localSidAuthority;
201 psid->SubAuthority[0] = SECURITY_LOCAL_SYSTEM_RID;
204 /* discretionary ACL */
205 if (DACL_SECURITY_INFORMATION & RequestedInformation)
208 PACL pacl = (PACL)&(Buffer[BufferIndex]);
209 PACCESS_ALLOWED_ACE pace;
212 psd->Dacl = BufferIndex;
214 pacl->AclRevision = MIN_ACL_REVISION;
216 pacl->AclSize = BufferIndex; /* storing the start index temporary */
218 BufferIndex += sizeof(ACL);
220 /* ACE System - full access */
221 pace = (PACCESS_ALLOWED_ACE)&(Buffer[BufferIndex]);
222 BufferIndex += sizeof(ACCESS_ALLOWED_ACE)-sizeof(DWORD);
224 pace->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
225 pace->Header.AceFlags = CONTAINER_INHERIT_ACE;
226 pace->Header.AceSize = sizeof(ACCESS_ALLOWED_ACE)-sizeof(DWORD) + RtlLengthRequiredSid(1);
227 pace->Mask = DELETE | READ_CONTROL | WRITE_DAC | WRITE_OWNER | 0x3f;
228 pace->SidStart = BufferIndex;
230 /* SID S-1-5-12 (System) */
231 psid = (SID*)&(Buffer[BufferIndex]);
233 BufferIndex += RtlLengthRequiredSid(1);
235 psid->Revision = SID_REVISION;
236 psid->SubAuthorityCount = 1;
237 psid->IdentifierAuthority = localSidAuthority;
238 psid->SubAuthority[0] = SECURITY_LOCAL_SYSTEM_RID;
240 /* ACE Administrators - full access*/
241 pace = (PACCESS_ALLOWED_ACE) &(Buffer[BufferIndex]);
242 BufferIndex += sizeof(ACCESS_ALLOWED_ACE)-sizeof(DWORD);
244 pace->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
245 pace->Header.AceFlags = CONTAINER_INHERIT_ACE;
246 pace->Header.AceSize = sizeof(ACCESS_ALLOWED_ACE)-sizeof(DWORD) + RtlLengthRequiredSid(2);
247 pace->Mask = DELETE | READ_CONTROL | WRITE_DAC | WRITE_OWNER | 0x3f;
248 pace->SidStart = BufferIndex;
250 /* S-1-5-12 (Administrators) */
251 psid = (SID*)&(Buffer[BufferIndex]);
253 BufferIndex += RtlLengthRequiredSid(2);
255 psid->Revision = SID_REVISION;
256 psid->SubAuthorityCount = 2;
257 psid->IdentifierAuthority = localSidAuthority;
258 psid->SubAuthority[0] = SECURITY_BUILTIN_DOMAIN_RID;
259 psid->SubAuthority[1] = DOMAIN_ALIAS_RID_ADMINS;
261 /* ACE Everyone - read access */
262 pace = (PACCESS_ALLOWED_ACE)&(Buffer[BufferIndex]);
263 BufferIndex += sizeof(ACCESS_ALLOWED_ACE)-sizeof(DWORD);
265 pace->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
266 pace->Header.AceFlags = CONTAINER_INHERIT_ACE;
267 pace->Header.AceSize = sizeof(ACCESS_ALLOWED_ACE)-sizeof(DWORD) + RtlLengthRequiredSid(1);
268 pace->Mask = READ_CONTROL| 0x19;
269 pace->SidStart = BufferIndex;
271 /* SID S-1-1-0 (Everyone) */
272 psid = (SID*)&(Buffer[BufferIndex]);
274 BufferIndex += RtlLengthRequiredSid(1);
276 psid->Revision = SID_REVISION;
277 psid->SubAuthorityCount = 1;
278 psid->IdentifierAuthority = worldSidAuthority;
279 psid->SubAuthority[0] = 0;
281 /* calculate used bytes */
282 pacl->AclSize = BufferIndex - pacl->AclSize;
284 *ResultLength = BufferIndex;
285 TRACE("len=%lu\n", *ResultLength);
286 if (Length < *ResultLength) return STATUS_BUFFER_TOO_SMALL;
287 memcpy(pSecurityDesriptor, Buffer, *ResultLength);
289 return STATUS_SUCCESS;
293 /******************************************************************************
294 * NtDuplicateObject [NTDLL.@]
295 * ZwDuplicateObject [NTDLL.@]
297 NTSTATUS WINAPI NtDuplicateObject( HANDLE source_process, HANDLE source,
298 HANDLE dest_process, PHANDLE dest,
299 ACCESS_MASK access, ULONG attributes, ULONG options )
302 SERVER_START_REQ( dup_handle )
304 req->src_process = source_process;
305 req->src_handle = source;
306 req->dst_process = dest_process;
307 req->access = access;
308 req->inherit = (attributes & OBJ_INHERIT) != 0;
309 req->options = options;
311 if (!(ret = wine_server_call( req )))
313 if (dest) *dest = reply->handle;
314 if (reply->fd != -1) close( reply->fd );
321 /**************************************************************************
324 * Close a handle reference to an object.
327 * Handle [I] handle to close
330 * Success: ERROR_SUCCESS.
331 * Failure: An NTSTATUS error code.
333 NTSTATUS WINAPI NtClose( HANDLE Handle )
336 SERVER_START_REQ( close_handle )
338 req->handle = Handle;
339 ret = wine_server_call( req );
340 if (!ret && reply->fd != -1) close( reply->fd );
347 * Directory functions
350 /**************************************************************************
351 * NtOpenDirectoryObject [NTDLL.@]
352 * ZwOpenDirectoryObject [NTDLL.@]
354 * Open a namespace directory object.
357 * DirectoryHandle [O] Destination for the new directory handle
358 * DesiredAccess [I] Desired access to the directory
359 * ObjectAttributes [I] Structure describing the directory
362 * Success: ERROR_SUCCESS.
363 * Failure: An NTSTATUS error code.
365 NTSTATUS WINAPI NtOpenDirectoryObject(PHANDLE DirectoryHandle, ACCESS_MASK DesiredAccess,
366 POBJECT_ATTRIBUTES ObjectAttributes)
369 TRACE("(%p,0x%08lx)\n", DirectoryHandle, DesiredAccess);
370 dump_ObjectAttributes(ObjectAttributes);
372 if (!DirectoryHandle) return STATUS_ACCESS_VIOLATION;
373 if (!ObjectAttributes) return STATUS_INVALID_PARAMETER;
374 /* Have to test it here because server won't know difference between
375 * ObjectName == NULL and ObjectName == "" */
376 if (!ObjectAttributes->ObjectName)
378 if (ObjectAttributes->RootDirectory)
379 return STATUS_OBJECT_NAME_INVALID;
381 return STATUS_OBJECT_PATH_SYNTAX_BAD;
384 SERVER_START_REQ(open_directory)
386 req->access = DesiredAccess;
387 req->attributes = ObjectAttributes->Attributes;
388 req->rootdir = ObjectAttributes->RootDirectory;
389 if (ObjectAttributes->ObjectName)
390 wine_server_add_data(req, ObjectAttributes->ObjectName->Buffer,
391 ObjectAttributes->ObjectName->Length);
392 ret = wine_server_call( req );
393 *DirectoryHandle = reply->handle;
399 /******************************************************************************
400 * NtCreateDirectoryObject [NTDLL.@]
401 * ZwCreateDirectoryObject [NTDLL.@]
403 * Create a namespace directory object.
406 * DirectoryHandle [O] Destination for the new directory handle
407 * DesiredAccess [I] Desired access to the directory
408 * ObjectAttributes [I] Structure describing the directory
411 * Success: ERROR_SUCCESS.
412 * Failure: An NTSTATUS error code.
414 NTSTATUS WINAPI NtCreateDirectoryObject(PHANDLE DirectoryHandle, ACCESS_MASK DesiredAccess,
415 POBJECT_ATTRIBUTES ObjectAttributes)
418 TRACE("(%p,0x%08lx)\n", DirectoryHandle, DesiredAccess);
419 dump_ObjectAttributes(ObjectAttributes);
421 if (!DirectoryHandle) return STATUS_ACCESS_VIOLATION;
423 SERVER_START_REQ(create_directory)
425 req->access = DesiredAccess;
426 req->attributes = ObjectAttributes ? ObjectAttributes->Attributes : 0;
427 req->rootdir = ObjectAttributes ? ObjectAttributes->RootDirectory : 0;
428 if (ObjectAttributes && ObjectAttributes->ObjectName)
429 wine_server_add_data(req, ObjectAttributes->ObjectName->Buffer,
430 ObjectAttributes->ObjectName->Length);
431 ret = wine_server_call( req );
432 *DirectoryHandle = reply->handle;
438 /******************************************************************************
439 * NtQueryDirectoryObject [NTDLL.@]
440 * ZwQueryDirectoryObject [NTDLL.@]
442 * Read information from a namespace directory.
445 * DirectoryHandle [I] Handle to a directory object
446 * Buffer [O] Buffer to hold the read data
447 * BufferLength [I] Size of the buffer in bytes
448 * ReturnSingleEntry [I] If TRUE, return a single entry, if FALSE, return as many as fit in the buffer
449 * RestartScan [I] If TRUE, start scanning from the start, if FALSE, scan from Context
450 * Context [I/O] Indicates what point of the directory the scan is at
451 * ReturnLength [O] Caller supplied storage for the number of bytes written (or NULL)
454 * Success: ERROR_SUCCESS.
455 * Failure: An NTSTATUS error code.
457 NTSTATUS WINAPI NtQueryDirectoryObject(IN HANDLE DirectoryHandle, OUT PDIRECTORY_BASIC_INFORMATION Buffer,
458 IN ULONG BufferLength, IN BOOLEAN ReturnSingleEntry, IN BOOLEAN RestartScan,
459 IN OUT PULONG Context, OUT PULONG ReturnLength OPTIONAL)
461 FIXME("(%p,%p,0x%08lx,0x%08x,0x%08x,%p,%p), stub\n", DirectoryHandle, Buffer, BufferLength, ReturnSingleEntry,
462 RestartScan, Context, ReturnLength);
464 return STATUS_NOT_IMPLEMENTED;
471 /******************************************************************************
472 * NtOpenSymbolicLinkObject [NTDLL.@]
474 NTSTATUS WINAPI NtOpenSymbolicLinkObject(
475 OUT PHANDLE LinkHandle,
476 IN ACCESS_MASK DesiredAccess,
477 IN POBJECT_ATTRIBUTES ObjectAttributes)
479 FIXME("(%p,0x%08lx,%p) stub\n",
480 LinkHandle, DesiredAccess, ObjectAttributes);
481 dump_ObjectAttributes(ObjectAttributes);
482 return STATUS_OBJECT_NAME_NOT_FOUND;
485 /******************************************************************************
486 * NtCreateSymbolicLinkObject [NTDLL.@]
488 NTSTATUS WINAPI NtCreateSymbolicLinkObject(
489 OUT PHANDLE SymbolicLinkHandle,
490 IN ACCESS_MASK DesiredAccess,
491 IN POBJECT_ATTRIBUTES ObjectAttributes,
492 IN PUNICODE_STRING Name)
494 FIXME("(%p,0x%08lx,%p, %p) stub\n",
495 SymbolicLinkHandle, DesiredAccess, ObjectAttributes, debugstr_us(Name));
496 dump_ObjectAttributes(ObjectAttributes);
500 /******************************************************************************
501 * NtQuerySymbolicLinkObject [NTDLL.@]
503 NTSTATUS WINAPI NtQuerySymbolicLinkObject(
504 IN HANDLE LinkHandle,
505 IN OUT PUNICODE_STRING LinkTarget,
506 OUT PULONG ReturnedLength OPTIONAL)
508 FIXME("(%p,%p,%p) stub\n",
509 LinkHandle, debugstr_us(LinkTarget), ReturnedLength);
514 /******************************************************************************
515 * NtAllocateUuids [NTDLL.@]
517 NTSTATUS WINAPI NtAllocateUuids(
518 PULARGE_INTEGER Time,
522 FIXME("(%p,%p,%p), stub.\n", Time, Range, Sequence);