Fix an error introduced when converting dialog lists to standard
[wine] / dlls / ntdll / om.c
1 /*
2  *      Object management functions
3  *
4  * Copyright 1999, 2000 Juergen Schmied
5  *
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.
10  *
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.
15  *
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
19  */
20
21 #include "config.h"
22
23 #include <stdarg.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #ifdef HAVE_IO_H
27 # include <io.h>
28 #endif
29 #ifdef HAVE_UNISTD_H
30 # include <unistd.h>
31 #endif
32 #include "wine/debug.h"
33
34 #include "windef.h"
35 #include "winternl.h"
36 #include "ntdll_misc.h"
37 #include "wine/server.h"
38
39 WINE_DEFAULT_DEBUG_CHANNEL(ntdll);
40
41
42 /*
43  *      Generic object functions
44  */
45
46 /******************************************************************************
47  * NtQueryObject [NTDLL.@]
48  * ZwQueryObject [NTDLL.@]
49  */
50 NTSTATUS WINAPI NtQueryObject(IN HANDLE handle,
51                               IN OBJECT_INFORMATION_CLASS info_class,
52                               OUT PVOID ptr, IN ULONG len, OUT PULONG used_len)
53 {
54     NTSTATUS status;
55
56     TRACE("(%p,0x%08x,%p,0x%08lx,%p): stub\n",
57           handle, info_class, ptr, len, used_len);
58
59     if (used_len) *used_len = 0;
60
61     switch (info_class)
62     {
63     case ObjectDataInformation:
64         {
65             OBJECT_DATA_INFORMATION* p = (OBJECT_DATA_INFORMATION*)ptr;
66
67             if (len < sizeof(*p)) return STATUS_INVALID_BUFFER_SIZE;
68
69             SERVER_START_REQ( set_handle_info )
70             {
71                 req->handle = handle;
72                 req->flags  = 0;
73                 req->mask   = 0;
74                 status = wine_server_call( req );
75                 if (status == STATUS_SUCCESS)
76                 {
77                     p->InheritHandle = (reply->old_flags & HANDLE_FLAG_INHERIT) ? TRUE : FALSE;
78                     p->ProtectFromClose = (reply->old_flags & HANDLE_FLAG_PROTECT_FROM_CLOSE) ? TRUE : FALSE;
79                     if (used_len) *used_len = sizeof(*p);
80                 }
81             }
82             SERVER_END_REQ;
83         }
84         break;
85     default:
86         FIXME("Unsupported information class %u\n", info_class);
87         status = STATUS_NOT_IMPLEMENTED;
88         break;
89     }
90     return status;
91 }
92
93 /******************************************************************
94  *              NtSetInformationObject [NTDLL.@]
95  *              ZwSetInformationObject [NTDLL.@]
96  *
97  */
98 NTSTATUS WINAPI NtSetInformationObject(IN HANDLE handle,
99                                        IN OBJECT_INFORMATION_CLASS info_class,
100                                        IN PVOID ptr, IN ULONG len)
101 {
102     NTSTATUS status;
103
104     TRACE("(%p,0x%08x,%p,0x%08lx): stub\n",
105           handle, info_class, ptr, len);
106
107     switch (info_class)
108     {
109     case ObjectDataInformation:
110         {
111             OBJECT_DATA_INFORMATION* p = (OBJECT_DATA_INFORMATION*)ptr;
112
113             if (len < sizeof(*p)) return STATUS_INVALID_BUFFER_SIZE;
114
115             SERVER_START_REQ( set_handle_info )
116             {
117                 req->handle = handle;
118                 req->flags  = 0;
119                 req->mask   = HANDLE_FLAG_INHERIT | HANDLE_FLAG_PROTECT_FROM_CLOSE;
120                 if (p->InheritHandle)    req->flags |= HANDLE_FLAG_INHERIT;
121                 if (p->ProtectFromClose) req->flags |= HANDLE_FLAG_PROTECT_FROM_CLOSE;
122                 status = wine_server_call( req );
123             }
124             SERVER_END_REQ;
125         }
126         break;
127     default:
128         FIXME("Unsupported information class %u\n", info_class);
129         status = STATUS_NOT_IMPLEMENTED;
130         break;
131     }
132     return status;
133 }
134
135 /******************************************************************************
136  *  NtQuerySecurityObject       [NTDLL.@]
137  *
138  * An ntdll analogue to GetKernelObjectSecurity().
139  *
140  * NOTES
141  *  only the lowest 4 bit of SecurityObjectInformationClass are used
142  *  0x7-0xf returns STATUS_ACCESS_DENIED (even running with system privileges)
143  *
144  * FIXME
145  *  We are constructing a fake sid (Administrators:Full, System:Full, Everyone:Read)
146  */
147 NTSTATUS WINAPI
148 NtQuerySecurityObject(
149         IN HANDLE Object,
150         IN SECURITY_INFORMATION RequestedInformation,
151         OUT PSECURITY_DESCRIPTOR pSecurityDesriptor,
152         IN ULONG Length,
153         OUT PULONG ResultLength)
154 {
155         static SID_IDENTIFIER_AUTHORITY localSidAuthority = {SECURITY_NT_AUTHORITY};
156         static SID_IDENTIFIER_AUTHORITY worldSidAuthority = {SECURITY_WORLD_SID_AUTHORITY};
157         BYTE Buffer[256];
158         PISECURITY_DESCRIPTOR_RELATIVE psd = (PISECURITY_DESCRIPTOR_RELATIVE)Buffer;
159         UINT BufferIndex = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
160
161         FIXME("(%p,0x%08lx,%p,0x%08lx,%p) stub!\n",
162         Object, RequestedInformation, pSecurityDesriptor, Length, ResultLength);
163
164         RequestedInformation &= 0x0000000f;
165
166         if (RequestedInformation & SACL_SECURITY_INFORMATION) return STATUS_ACCESS_DENIED;
167
168         ZeroMemory(Buffer, 256);
169         RtlCreateSecurityDescriptor((PSECURITY_DESCRIPTOR)psd, SECURITY_DESCRIPTOR_REVISION);
170         psd->Control = SE_SELF_RELATIVE |
171           ((RequestedInformation & DACL_SECURITY_INFORMATION) ? SE_DACL_PRESENT:0);
172
173         /* owner: administrator S-1-5-20-220*/
174         if (OWNER_SECURITY_INFORMATION & RequestedInformation)
175         {
176           SID* psid = (SID*)&(Buffer[BufferIndex]);
177
178           psd->Owner = BufferIndex;
179           BufferIndex += RtlLengthRequiredSid(2);
180
181           psid->Revision = SID_REVISION;
182           psid->SubAuthorityCount = 2;
183           psid->IdentifierAuthority = localSidAuthority;
184           psid->SubAuthority[0] = SECURITY_BUILTIN_DOMAIN_RID;
185           psid->SubAuthority[1] = DOMAIN_ALIAS_RID_ADMINS;
186         }
187
188         /* group: built in domain S-1-5-12 */
189         if (GROUP_SECURITY_INFORMATION & RequestedInformation)
190         {
191           SID* psid = (SID*) &(Buffer[BufferIndex]);
192
193           psd->Group = BufferIndex;
194           BufferIndex += RtlLengthRequiredSid(1);
195
196           psid->Revision = SID_REVISION;
197           psid->SubAuthorityCount = 1;
198           psid->IdentifierAuthority = localSidAuthority;
199           psid->SubAuthority[0] = SECURITY_LOCAL_SYSTEM_RID;
200         }
201
202         /* discretionary ACL */
203         if (DACL_SECURITY_INFORMATION & RequestedInformation)
204         {
205           /* acl header */
206           PACL pacl = (PACL)&(Buffer[BufferIndex]);
207           PACCESS_ALLOWED_ACE pace;
208           SID* psid;
209
210           psd->Dacl = BufferIndex;
211
212           pacl->AclRevision = MIN_ACL_REVISION;
213           pacl->AceCount = 3;
214           pacl->AclSize = BufferIndex; /* storing the start index temporary */
215
216           BufferIndex += sizeof(ACL);
217
218           /* ACE System - full access */
219           pace = (PACCESS_ALLOWED_ACE)&(Buffer[BufferIndex]);
220           BufferIndex += sizeof(ACCESS_ALLOWED_ACE)-sizeof(DWORD);
221
222           pace->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
223           pace->Header.AceFlags = CONTAINER_INHERIT_ACE;
224           pace->Header.AceSize = sizeof(ACCESS_ALLOWED_ACE)-sizeof(DWORD) + RtlLengthRequiredSid(1);
225           pace->Mask = DELETE | READ_CONTROL | WRITE_DAC | WRITE_OWNER  | 0x3f;
226           pace->SidStart = BufferIndex;
227
228           /* SID S-1-5-12 (System) */
229           psid = (SID*)&(Buffer[BufferIndex]);
230
231           BufferIndex += RtlLengthRequiredSid(1);
232
233           psid->Revision = SID_REVISION;
234           psid->SubAuthorityCount = 1;
235           psid->IdentifierAuthority = localSidAuthority;
236           psid->SubAuthority[0] = SECURITY_LOCAL_SYSTEM_RID;
237
238           /* ACE Administrators - full access*/
239           pace = (PACCESS_ALLOWED_ACE) &(Buffer[BufferIndex]);
240           BufferIndex += sizeof(ACCESS_ALLOWED_ACE)-sizeof(DWORD);
241
242           pace->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
243           pace->Header.AceFlags = CONTAINER_INHERIT_ACE;
244           pace->Header.AceSize = sizeof(ACCESS_ALLOWED_ACE)-sizeof(DWORD) + RtlLengthRequiredSid(2);
245           pace->Mask = DELETE | READ_CONTROL | WRITE_DAC | WRITE_OWNER  | 0x3f;
246           pace->SidStart = BufferIndex;
247
248           /* S-1-5-12 (Administrators) */
249           psid = (SID*)&(Buffer[BufferIndex]);
250
251           BufferIndex += RtlLengthRequiredSid(2);
252
253           psid->Revision = SID_REVISION;
254           psid->SubAuthorityCount = 2;
255           psid->IdentifierAuthority = localSidAuthority;
256           psid->SubAuthority[0] = SECURITY_BUILTIN_DOMAIN_RID;
257           psid->SubAuthority[1] = DOMAIN_ALIAS_RID_ADMINS;
258
259           /* ACE Everyone - read access */
260           pace = (PACCESS_ALLOWED_ACE)&(Buffer[BufferIndex]);
261           BufferIndex += sizeof(ACCESS_ALLOWED_ACE)-sizeof(DWORD);
262
263           pace->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
264           pace->Header.AceFlags = CONTAINER_INHERIT_ACE;
265           pace->Header.AceSize = sizeof(ACCESS_ALLOWED_ACE)-sizeof(DWORD) + RtlLengthRequiredSid(1);
266           pace->Mask = READ_CONTROL| 0x19;
267           pace->SidStart = BufferIndex;
268
269           /* SID S-1-1-0 (Everyone) */
270           psid = (SID*)&(Buffer[BufferIndex]);
271
272           BufferIndex += RtlLengthRequiredSid(1);
273
274           psid->Revision = SID_REVISION;
275           psid->SubAuthorityCount = 1;
276           psid->IdentifierAuthority = worldSidAuthority;
277           psid->SubAuthority[0] = 0;
278
279           /* calculate used bytes */
280           pacl->AclSize = BufferIndex - pacl->AclSize;
281         }
282         *ResultLength = BufferIndex;
283         TRACE("len=%lu\n", *ResultLength);
284         if (Length < *ResultLength) return STATUS_BUFFER_TOO_SMALL;
285         memcpy(pSecurityDesriptor, Buffer, *ResultLength);
286
287         return STATUS_SUCCESS;
288 }
289
290
291 /******************************************************************************
292  *  NtDuplicateObject           [NTDLL.@]
293  *  ZwDuplicateObject           [NTDLL.@]
294  */
295 NTSTATUS WINAPI NtDuplicateObject( HANDLE source_process, HANDLE source,
296                                    HANDLE dest_process, PHANDLE dest,
297                                    ACCESS_MASK access, ULONG attributes, ULONG options )
298 {
299     NTSTATUS ret;
300     SERVER_START_REQ( dup_handle )
301     {
302         req->src_process = source_process;
303         req->src_handle  = source;
304         req->dst_process = dest_process;
305         req->access      = access;
306         req->inherit     = (attributes & OBJ_INHERIT) != 0;
307         req->options     = options;
308
309         if (!(ret = wine_server_call( req )))
310         {
311             if (dest) *dest = reply->handle;
312             if (reply->fd != -1) close( reply->fd );
313         }
314     }
315     SERVER_END_REQ;
316     return ret;
317 }
318
319 /**************************************************************************
320  *                 NtClose                              [NTDLL.@]
321  *
322  * Close a handle reference to an object.
323  * 
324  * PARAMS
325  *  Handle [I] handle to close
326  *
327  * RETURNS
328  *  Success: ERROR_SUCCESS.
329  *  Failure: An NTSTATUS error code.
330  */
331 NTSTATUS WINAPI NtClose( HANDLE Handle )
332 {
333     NTSTATUS ret;
334     SERVER_START_REQ( close_handle )
335     {
336         req->handle = Handle;
337         ret = wine_server_call( req );
338         if (!ret && reply->fd != -1) close( reply->fd );
339     }
340     SERVER_END_REQ;
341     return ret;
342 }
343
344 /*
345  *      Directory functions
346  */
347
348 /**************************************************************************
349  * NtOpenDirectoryObject [NTDLL.@]
350  * ZwOpenDirectoryObject [NTDLL.@]
351  *
352  * Open a namespace directory object.
353  * 
354  * PARAMS
355  *  DirectoryHandle  [O] Destination for the new directory handle
356  *  DesiredAccess    [I] Desired access to the directory
357  *  ObjectAttributes [I] Structure describing the directory
358  *
359  * RETURNS
360  *  Success: ERROR_SUCCESS.
361  *  Failure: An NTSTATUS error code.
362  */
363 NTSTATUS WINAPI NtOpenDirectoryObject(
364         PHANDLE DirectoryHandle,
365         ACCESS_MASK DesiredAccess,
366         POBJECT_ATTRIBUTES ObjectAttributes)
367 {
368         FIXME("(%p,0x%08lx,%p): stub\n",
369         DirectoryHandle, DesiredAccess, ObjectAttributes);
370         dump_ObjectAttributes(ObjectAttributes);
371         return 0;
372 }
373
374 /******************************************************************************
375  *  NtCreateDirectoryObject     [NTDLL.@]
376  *  ZwCreateDirectoryObject     [NTDLL.@]
377  */
378 NTSTATUS WINAPI NtCreateDirectoryObject(
379         PHANDLE DirectoryHandle,
380         ACCESS_MASK DesiredAccess,
381         POBJECT_ATTRIBUTES ObjectAttributes)
382 {
383         FIXME("(%p,0x%08lx,%p),stub!\n",
384         DirectoryHandle,DesiredAccess,ObjectAttributes);
385         dump_ObjectAttributes(ObjectAttributes);
386         return 0;
387 }
388
389 /******************************************************************************
390  * NtQueryDirectoryObject [NTDLL.@]
391  * ZwQueryDirectoryObject [NTDLL.@]
392  *
393  * Read information from a namespace directory.
394  * 
395  * PARAMS
396  *  DirObjHandle      [I]   Object handle
397  *  DirObjInformation [O]   Buffer to hold the data read
398  *  BufferLength      [I]   Size of the buffer in bytes
399  *  GetNextIndex      [I]   Set ObjectIndex to TRUE=next object, FALSE=last object
400  *  IgnoreInputIndex  [I]   Start reading at index TRUE=0, FALSE=ObjectIndex
401  *  ObjectIndex       [I/O] 0 based index into the directory, see IgnoreInputIndex and GetNextIndex
402  *  DataWritten       [O]   Caller supplied storage for the number of bytes written (or NULL)
403  *
404  * RETURNS
405  *  Success: ERROR_SUCCESS.
406  *  Failure: An NTSTATUS error code.
407  */
408 NTSTATUS WINAPI NtQueryDirectoryObject(
409         IN HANDLE DirObjHandle,
410         OUT POBJDIR_INFORMATION DirObjInformation,
411         IN ULONG BufferLength,
412         IN BOOLEAN GetNextIndex,
413         IN BOOLEAN IgnoreInputIndex,
414         IN OUT PULONG ObjectIndex,
415         OUT PULONG DataWritten OPTIONAL)
416 {
417         FIXME("(%p,%p,0x%08lx,0x%08x,0x%08x,%p,%p) stub\n",
418                 DirObjHandle, DirObjInformation, BufferLength, GetNextIndex,
419                 IgnoreInputIndex, ObjectIndex, DataWritten);
420     return 0xc0000000; /* We don't have any. Whatever. (Yet.) */
421 }
422
423 /*
424  *      Link objects
425  */
426
427 /******************************************************************************
428  *  NtOpenSymbolicLinkObject    [NTDLL.@]
429  */
430 NTSTATUS WINAPI NtOpenSymbolicLinkObject(
431         OUT PHANDLE LinkHandle,
432         IN ACCESS_MASK DesiredAccess,
433         IN POBJECT_ATTRIBUTES ObjectAttributes)
434 {
435         FIXME("(%p,0x%08lx,%p) stub\n",
436         LinkHandle, DesiredAccess, ObjectAttributes);
437         dump_ObjectAttributes(ObjectAttributes);
438         return STATUS_OBJECT_NAME_NOT_FOUND;
439 }
440
441 /******************************************************************************
442  *  NtCreateSymbolicLinkObject  [NTDLL.@]
443  */
444 NTSTATUS WINAPI NtCreateSymbolicLinkObject(
445         OUT PHANDLE SymbolicLinkHandle,
446         IN ACCESS_MASK DesiredAccess,
447         IN POBJECT_ATTRIBUTES ObjectAttributes,
448         IN PUNICODE_STRING Name)
449 {
450         FIXME("(%p,0x%08lx,%p, %p) stub\n",
451         SymbolicLinkHandle, DesiredAccess, ObjectAttributes, debugstr_us(Name));
452         dump_ObjectAttributes(ObjectAttributes);
453         return 0;
454 }
455
456 /******************************************************************************
457  *  NtQuerySymbolicLinkObject   [NTDLL.@]
458  */
459 NTSTATUS WINAPI NtQuerySymbolicLinkObject(
460         IN HANDLE LinkHandle,
461         IN OUT PUNICODE_STRING LinkTarget,
462         OUT PULONG ReturnedLength OPTIONAL)
463 {
464         FIXME("(%p,%p,%p) stub\n",
465         LinkHandle, debugstr_us(LinkTarget), ReturnedLength);
466
467         return 0;
468 }
469
470 /******************************************************************************
471  *  NtAllocateUuids   [NTDLL.@]
472  */
473 NTSTATUS WINAPI NtAllocateUuids(
474         PULARGE_INTEGER Time,
475         PULONG Range,
476         PULONG Sequence)
477 {
478         FIXME("(%p,%p,%p), stub.\n", Time, Range, Sequence);
479         return 0;
480 }