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