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
32 #include "wine/debug.h"
38 #include "ntdll_misc.h"
39 #include "wine/server.h"
41 WINE_DEFAULT_DEBUG_CHANNEL(ntdll
);
43 /* move to somewhere */
44 typedef void * POBJDIR_INFORMATION
;
47 * Generic object functions
50 /******************************************************************************
51 * NtQueryObject [NTDLL.@]
52 * ZwQueryObject [NTDLL.@]
54 NTSTATUS WINAPI
NtQueryObject(IN HANDLE handle
,
55 IN OBJECT_INFORMATION_CLASS info_class
,
56 OUT PVOID ptr
, IN ULONG len
, OUT PULONG used_len
)
60 TRACE("(%p,0x%08x,%p,0x%08lx,%p): stub\n",
61 handle
, info_class
, ptr
, len
, used_len
);
63 if (used_len
) *used_len
= 0;
67 case ObjectDataInformation
:
69 OBJECT_DATA_INFORMATION
* p
= (OBJECT_DATA_INFORMATION
*)ptr
;
71 if (len
< sizeof(*p
)) return STATUS_INVALID_BUFFER_SIZE
;
73 SERVER_START_REQ( set_handle_info
)
79 status
= wine_server_call( req
);
80 if (status
== STATUS_SUCCESS
)
82 p
->InheritHandle
= (reply
->old_flags
& HANDLE_FLAG_INHERIT
) ? TRUE
: FALSE
;
83 p
->ProtectFromClose
= (reply
->old_flags
& HANDLE_FLAG_PROTECT_FROM_CLOSE
) ? TRUE
: FALSE
;
84 if (used_len
) *used_len
= sizeof(*p
);
91 FIXME("Unsupported information class %u\n", info_class
);
92 status
= STATUS_NOT_IMPLEMENTED
;
98 /******************************************************************
99 * NtSetInformationObject [NTDLL.@]
100 * ZwSetInformationObject [NTDLL.@]
103 NTSTATUS WINAPI
NtSetInformationObject(IN HANDLE handle
,
104 IN OBJECT_INFORMATION_CLASS info_class
,
105 IN PVOID ptr
, IN ULONG len
)
109 TRACE("(%p,0x%08x,%p,0x%08lx): stub\n",
110 handle
, info_class
, ptr
, len
);
114 case ObjectDataInformation
:
116 OBJECT_DATA_INFORMATION
* p
= (OBJECT_DATA_INFORMATION
*)ptr
;
118 if (len
< sizeof(*p
)) return STATUS_INVALID_BUFFER_SIZE
;
120 SERVER_START_REQ( set_handle_info
)
122 req
->handle
= handle
;
124 req
->mask
= HANDLE_FLAG_INHERIT
| HANDLE_FLAG_PROTECT_FROM_CLOSE
;
126 if (p
->InheritHandle
) req
->flags
|= HANDLE_FLAG_INHERIT
;
127 if (p
->ProtectFromClose
) req
->flags
|= HANDLE_FLAG_PROTECT_FROM_CLOSE
;
128 status
= wine_server_call( req
);
134 FIXME("Unsupported information class %u\n", info_class
);
135 status
= STATUS_NOT_IMPLEMENTED
;
141 /******************************************************************************
142 * NtQuerySecurityObject [NTDLL.@]
144 * An ntdll analogue to GetKernelObjectSecurity().
147 * only the lowest 4 bit of SecurityObjectInformationClass are used
148 * 0x7-0xf returns STATUS_ACCESS_DENIED (even running with system privileges)
151 * We are constructing a fake sid (Administrators:Full, System:Full, Everyone:Read)
154 NtQuerySecurityObject(
156 IN SECURITY_INFORMATION RequestedInformation
,
157 OUT PSECURITY_DESCRIPTOR pSecurityDesriptor
,
159 OUT PULONG ResultLength
)
161 static SID_IDENTIFIER_AUTHORITY localSidAuthority
= {SECURITY_NT_AUTHORITY
};
162 static SID_IDENTIFIER_AUTHORITY worldSidAuthority
= {SECURITY_WORLD_SID_AUTHORITY
};
164 PISECURITY_DESCRIPTOR_RELATIVE psd
= (PISECURITY_DESCRIPTOR_RELATIVE
)Buffer
;
165 UINT BufferIndex
= sizeof(SECURITY_DESCRIPTOR_RELATIVE
);
167 FIXME("(%p,0x%08lx,%p,0x%08lx,%p) stub!\n",
168 Object
, RequestedInformation
, pSecurityDesriptor
, Length
, ResultLength
);
170 RequestedInformation
&= 0x0000000f;
172 if (RequestedInformation
& SACL_SECURITY_INFORMATION
) return STATUS_ACCESS_DENIED
;
174 ZeroMemory(Buffer
, 256);
175 RtlCreateSecurityDescriptor((PSECURITY_DESCRIPTOR
)psd
, SECURITY_DESCRIPTOR_REVISION
);
176 psd
->Control
= SE_SELF_RELATIVE
|
177 ((RequestedInformation
& DACL_SECURITY_INFORMATION
) ? SE_DACL_PRESENT
:0);
179 /* owner: administrator S-1-5-20-220*/
180 if (OWNER_SECURITY_INFORMATION
& RequestedInformation
)
182 PSID psid
= (PSID
)&(Buffer
[BufferIndex
]);
184 psd
->Owner
= BufferIndex
;
185 BufferIndex
+= RtlLengthRequiredSid(2);
187 psid
->Revision
= SID_REVISION
;
188 psid
->SubAuthorityCount
= 2;
189 psid
->IdentifierAuthority
= localSidAuthority
;
190 psid
->SubAuthority
[0] = SECURITY_BUILTIN_DOMAIN_RID
;
191 psid
->SubAuthority
[1] = DOMAIN_ALIAS_RID_ADMINS
;
194 /* group: built in domain S-1-5-12 */
195 if (GROUP_SECURITY_INFORMATION
& RequestedInformation
)
197 PSID psid
= (PSID
) &(Buffer
[BufferIndex
]);
199 psd
->Group
= BufferIndex
;
200 BufferIndex
+= RtlLengthRequiredSid(1);
202 psid
->Revision
= SID_REVISION
;
203 psid
->SubAuthorityCount
= 1;
204 psid
->IdentifierAuthority
= localSidAuthority
;
205 psid
->SubAuthority
[0] = SECURITY_LOCAL_SYSTEM_RID
;
208 /* discretionary ACL */
209 if (DACL_SECURITY_INFORMATION
& RequestedInformation
)
212 PACL pacl
= (PACL
)&(Buffer
[BufferIndex
]);
213 PACCESS_ALLOWED_ACE pace
;
216 psd
->Dacl
= BufferIndex
;
218 pacl
->AclRevision
= MIN_ACL_REVISION
;
220 pacl
->AclSize
= BufferIndex
; /* storing the start index temporary */
222 BufferIndex
+= sizeof(ACL
);
224 /* ACE System - full access */
225 pace
= (PACCESS_ALLOWED_ACE
)&(Buffer
[BufferIndex
]);
226 BufferIndex
+= sizeof(ACCESS_ALLOWED_ACE
)-sizeof(DWORD
);
228 pace
->Header
.AceType
= ACCESS_ALLOWED_ACE_TYPE
;
229 pace
->Header
.AceFlags
= CONTAINER_INHERIT_ACE
;
230 pace
->Header
.AceSize
= sizeof(ACCESS_ALLOWED_ACE
)-sizeof(DWORD
) + RtlLengthRequiredSid(1);
231 pace
->Mask
= DELETE
| READ_CONTROL
| WRITE_DAC
| WRITE_OWNER
| 0x3f;
232 pace
->SidStart
= BufferIndex
;
234 /* SID S-1-5-12 (System) */
235 psid
= (PSID
)&(Buffer
[BufferIndex
]);
237 BufferIndex
+= RtlLengthRequiredSid(1);
239 psid
->Revision
= SID_REVISION
;
240 psid
->SubAuthorityCount
= 1;
241 psid
->IdentifierAuthority
= localSidAuthority
;
242 psid
->SubAuthority
[0] = SECURITY_LOCAL_SYSTEM_RID
;
244 /* ACE Administrators - full access*/
245 pace
= (PACCESS_ALLOWED_ACE
) &(Buffer
[BufferIndex
]);
246 BufferIndex
+= sizeof(ACCESS_ALLOWED_ACE
)-sizeof(DWORD
);
248 pace
->Header
.AceType
= ACCESS_ALLOWED_ACE_TYPE
;
249 pace
->Header
.AceFlags
= CONTAINER_INHERIT_ACE
;
250 pace
->Header
.AceSize
= sizeof(ACCESS_ALLOWED_ACE
)-sizeof(DWORD
) + RtlLengthRequiredSid(2);
251 pace
->Mask
= DELETE
| READ_CONTROL
| WRITE_DAC
| WRITE_OWNER
| 0x3f;
252 pace
->SidStart
= BufferIndex
;
254 /* S-1-5-12 (Administrators) */
255 psid
= (PSID
)&(Buffer
[BufferIndex
]);
257 BufferIndex
+= RtlLengthRequiredSid(2);
259 psid
->Revision
= SID_REVISION
;
260 psid
->SubAuthorityCount
= 2;
261 psid
->IdentifierAuthority
= localSidAuthority
;
262 psid
->SubAuthority
[0] = SECURITY_BUILTIN_DOMAIN_RID
;
263 psid
->SubAuthority
[1] = DOMAIN_ALIAS_RID_ADMINS
;
265 /* ACE Everyone - read access */
266 pace
= (PACCESS_ALLOWED_ACE
)&(Buffer
[BufferIndex
]);
267 BufferIndex
+= sizeof(ACCESS_ALLOWED_ACE
)-sizeof(DWORD
);
269 pace
->Header
.AceType
= ACCESS_ALLOWED_ACE_TYPE
;
270 pace
->Header
.AceFlags
= CONTAINER_INHERIT_ACE
;
271 pace
->Header
.AceSize
= sizeof(ACCESS_ALLOWED_ACE
)-sizeof(DWORD
) + RtlLengthRequiredSid(1);
272 pace
->Mask
= READ_CONTROL
| 0x19;
273 pace
->SidStart
= BufferIndex
;
275 /* SID S-1-1-0 (Everyone) */
276 psid
= (PSID
)&(Buffer
[BufferIndex
]);
278 BufferIndex
+= RtlLengthRequiredSid(1);
280 psid
->Revision
= SID_REVISION
;
281 psid
->SubAuthorityCount
= 1;
282 psid
->IdentifierAuthority
= worldSidAuthority
;
283 psid
->SubAuthority
[0] = 0;
285 /* calculate used bytes */
286 pacl
->AclSize
= BufferIndex
- pacl
->AclSize
;
288 *ResultLength
= BufferIndex
;
289 TRACE("len=%lu\n", *ResultLength
);
290 if (Length
< *ResultLength
) return STATUS_BUFFER_TOO_SMALL
;
291 memcpy(pSecurityDesriptor
, Buffer
, *ResultLength
);
293 return STATUS_SUCCESS
;
297 /******************************************************************************
298 * NtDuplicateObject [NTDLL.@]
299 * ZwDuplicateObject [NTDLL.@]
301 NTSTATUS WINAPI
NtDuplicateObject( HANDLE source_process
, HANDLE source
,
302 HANDLE dest_process
, PHANDLE dest
,
303 ACCESS_MASK access
, ULONG attributes
, ULONG options
)
306 SERVER_START_REQ( dup_handle
)
308 req
->src_process
= source_process
;
309 req
->src_handle
= source
;
310 req
->dst_process
= dest_process
;
311 req
->access
= access
;
312 req
->inherit
= (attributes
& OBJ_INHERIT
) != 0;
313 req
->options
= options
;
315 if (!(ret
= wine_server_call( req
)))
317 if (dest
) *dest
= reply
->handle
;
318 if (reply
->fd
!= -1) close( reply
->fd
);
325 /**************************************************************************
328 * Close a handle reference to an object.
331 * Handle [I] handle to close
334 * Success: ERROR_SUCCESS.
335 * Failure: An NTSTATUS error code.
337 NTSTATUS WINAPI
NtClose( HANDLE Handle
)
340 SERVER_START_REQ( close_handle
)
342 req
->handle
= Handle
;
343 ret
= wine_server_call( req
);
344 if (!ret
&& reply
->fd
!= -1) close( reply
->fd
);
351 * Directory functions
354 /**************************************************************************
355 * NtOpenDirectoryObject [NTDLL.@]
356 * ZwOpenDirectoryObject [NTDLL.@]
358 * Open a namespace directory object.
361 * DirectoryHandle [O] Destination for the new directory handle
362 * DesiredAccess [I] Desired access to the directory
363 * ObjectAttributes [I] Structure describing the directory
366 * Success: ERROR_SUCCESS.
367 * Failure: An NTSTATUS error code.
369 NTSTATUS WINAPI
NtOpenDirectoryObject(
370 PHANDLE DirectoryHandle
,
371 ACCESS_MASK DesiredAccess
,
372 POBJECT_ATTRIBUTES ObjectAttributes
)
374 FIXME("(%p,0x%08lx,%p): stub\n",
375 DirectoryHandle
, DesiredAccess
, ObjectAttributes
);
376 dump_ObjectAttributes(ObjectAttributes
);
380 /******************************************************************************
381 * NtCreateDirectoryObject [NTDLL.@]
382 * ZwCreateDirectoryObject [NTDLL.@]
384 NTSTATUS WINAPI
NtCreateDirectoryObject(
385 PHANDLE DirectoryHandle
,
386 ACCESS_MASK DesiredAccess
,
387 POBJECT_ATTRIBUTES ObjectAttributes
)
389 FIXME("(%p,0x%08lx,%p),stub!\n",
390 DirectoryHandle
,DesiredAccess
,ObjectAttributes
);
391 dump_ObjectAttributes(ObjectAttributes
);
395 /******************************************************************************
396 * NtQueryDirectoryObject [NTDLL.@]
397 * ZwQueryDirectoryObject [NTDLL.@]
399 * Read information from a namespace directory.
402 * DirObjHandle [I] Object handle
403 * DirObjInformation [O] Buffer to hold the data read
404 * BufferLength [I] Size of the buffer in bytes
405 * GetNextIndex [I] Set ObjectIndex to TRUE=next object, FALSE=last object
406 * IgnoreInputIndex [I] Start reading at index TRUE=0, FALSE=ObjectIndex
407 * ObjectIndex [I/O] 0 based index into the directory, see IgnoreInputIndex and GetNextIndex
408 * DataWritten [O] Caller supplied storage for the number of bytes written (or NULL)
411 * Success: ERROR_SUCCESS.
412 * Failure: An NTSTATUS error code.
414 NTSTATUS WINAPI
NtQueryDirectoryObject(
415 IN HANDLE DirObjHandle
,
416 OUT POBJDIR_INFORMATION DirObjInformation
,
417 IN ULONG BufferLength
,
418 IN BOOLEAN GetNextIndex
,
419 IN BOOLEAN IgnoreInputIndex
,
420 IN OUT PULONG ObjectIndex
,
421 OUT PULONG DataWritten OPTIONAL
)
423 FIXME("(%p,%p,0x%08lx,0x%08x,0x%08x,%p,%p) stub\n",
424 DirObjHandle
, DirObjInformation
, BufferLength
, GetNextIndex
,
425 IgnoreInputIndex
, ObjectIndex
, DataWritten
);
426 return 0xc0000000; /* We don't have any. Whatever. (Yet.) */
433 /******************************************************************************
434 * NtOpenSymbolicLinkObject [NTDLL.@]
436 NTSTATUS WINAPI
NtOpenSymbolicLinkObject(
437 OUT PHANDLE LinkHandle
,
438 IN ACCESS_MASK DesiredAccess
,
439 IN POBJECT_ATTRIBUTES ObjectAttributes
)
441 FIXME("(%p,0x%08lx,%p) stub\n",
442 LinkHandle
, DesiredAccess
, ObjectAttributes
);
443 dump_ObjectAttributes(ObjectAttributes
);
447 /******************************************************************************
448 * NtCreateSymbolicLinkObject [NTDLL.@]
450 NTSTATUS WINAPI
NtCreateSymbolicLinkObject(
451 OUT PHANDLE SymbolicLinkHandle
,
452 IN ACCESS_MASK DesiredAccess
,
453 IN POBJECT_ATTRIBUTES ObjectAttributes
,
454 IN PUNICODE_STRING Name
)
456 FIXME("(%p,0x%08lx,%p, %p) stub\n",
457 SymbolicLinkHandle
, DesiredAccess
, ObjectAttributes
, debugstr_us(Name
));
458 dump_ObjectAttributes(ObjectAttributes
);
462 /******************************************************************************
463 * NtQuerySymbolicLinkObject [NTDLL.@]
465 NTSTATUS WINAPI
NtQuerySymbolicLinkObject(
466 IN HANDLE LinkHandle
,
467 IN OUT PUNICODE_STRING LinkTarget
,
468 OUT PULONG ReturnedLength OPTIONAL
)
470 FIXME("(%p,%p,%p) stub\n",
471 LinkHandle
, debugstr_us(LinkTarget
), ReturnedLength
);
476 /******************************************************************************
477 * NtAllocateUuids [NTDLL.@]
480 * I have seen lpdwCount pointing to a pointer once...
482 NTSTATUS WINAPI
NtAllocateUuids(LPDWORD lpdwCount
, LPDWORD
*p2
, LPDWORD
*p3
)
484 FIXME("(%p[%ld],%p,%p), stub.\n", lpdwCount
,
485 lpdwCount
? *lpdwCount
: 0,