Abort with error if the app uses our api to subclass and then theirs
[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("(0x%08x,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  * 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: we are constructing a fake sid
72  *  (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("(0x%08x,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  * FUNCTION: Closes a handle reference to an object
249  * ARGUMENTS:
250  *      Handle  handle to close
251  */
252 NTSTATUS WINAPI NtClose( HANDLE Handle )
253 {
254     NTSTATUS ret;
255     SERVER_START_REQ( close_handle )
256     {
257         req->handle = Handle;
258         ret = wine_server_call( req );
259         if (!ret && reply->fd != -1) close( reply->fd );
260     }
261     SERVER_END_REQ;
262     return ret;
263 }
264
265 /******************************************************************************
266  *  NtWaitForSingleObject               [NTDLL.@]
267  *  ZwWaitForSingleObject               [NTDLL.@]
268  */
269 NTSTATUS WINAPI NtWaitForSingleObject(
270         IN HANDLE Object,
271         IN BOOLEAN Alertable,
272         IN PLARGE_INTEGER Time)
273 {
274         FIXME("(0x%08x,0x%08x,%p),stub!\n",Object,Alertable,Time);
275         return 0;
276 }
277
278 /*
279  *      Directory functions
280  */
281
282 /**************************************************************************
283  * NtOpenDirectoryObject [NTDLL.@]
284  * ZwOpenDirectoryObject [NTDLL.@]
285  * FUNCTION: Opens a namespace directory object
286  * ARGUMENTS:
287  *  DirectoryHandle     Variable which receives the directory handle
288  *  DesiredAccess       Desired access to the directory
289  *  ObjectAttributes    Structure describing the directory
290  * RETURNS: Status
291  */
292 NTSTATUS WINAPI NtOpenDirectoryObject(
293         PHANDLE DirectoryHandle,
294         ACCESS_MASK DesiredAccess,
295         POBJECT_ATTRIBUTES ObjectAttributes)
296 {
297         FIXME("(%p,0x%08lx,%p): stub\n",
298         DirectoryHandle, DesiredAccess, ObjectAttributes);
299         dump_ObjectAttributes(ObjectAttributes);
300         return 0;
301 }
302
303 /******************************************************************************
304  *  NtCreateDirectoryObject     [NTDLL.@]
305  *  ZwCreateDirectoryObject     [NTDLL.@]
306  */
307 NTSTATUS WINAPI NtCreateDirectoryObject(
308         PHANDLE DirectoryHandle,
309         ACCESS_MASK DesiredAccess,
310         POBJECT_ATTRIBUTES ObjectAttributes)
311 {
312         FIXME("(%p,0x%08lx,%p),stub!\n",
313         DirectoryHandle,DesiredAccess,ObjectAttributes);
314         dump_ObjectAttributes(ObjectAttributes);
315         return 0;
316 }
317
318 /******************************************************************************
319  * NtQueryDirectoryObject [NTDLL.@]
320  * ZwQueryDirectoryObject [NTDLL.@]
321  * FUNCTION: Reads information from a namespace directory
322  * ARGUMENTS:
323  *  DirObjInformation   Buffer to hold the data read
324  *  BufferLength        Size of the buffer in bytes
325  *  GetNextIndex        If TRUE then set ObjectIndex to the index of the next object
326  *                      If FALSE then set ObjectIndex to the number of objects in the directory
327  *  IgnoreInputIndex    If TRUE start reading at index 0
328  *                      If FALSE start reading at the index specified by object index
329  *  ObjectIndex         Zero based index into the directory, interpretation depends on IgnoreInputIndex and GetNextIndex
330  *  DataWritten         Caller supplied storage for the number of bytes written (or NULL)
331  */
332 NTSTATUS WINAPI NtQueryDirectoryObject(
333         IN HANDLE DirObjHandle,
334         OUT POBJDIR_INFORMATION DirObjInformation,
335         IN ULONG BufferLength,
336         IN BOOLEAN GetNextIndex,
337         IN BOOLEAN IgnoreInputIndex,
338         IN OUT PULONG ObjectIndex,
339         OUT PULONG DataWritten OPTIONAL)
340 {
341         FIXME("(0x%08x,%p,0x%08lx,0x%08x,0x%08x,%p,%p) stub\n",
342                 DirObjHandle, DirObjInformation, BufferLength, GetNextIndex,
343                 IgnoreInputIndex, ObjectIndex, DataWritten);
344     return 0xc0000000; /* We don't have any. Whatever. (Yet.) */
345 }
346
347 /*
348  *      Link objects
349  */
350
351 /******************************************************************************
352  *  NtOpenSymbolicLinkObject    [NTDLL.@]
353  */
354 NTSTATUS WINAPI NtOpenSymbolicLinkObject(
355         OUT PHANDLE LinkHandle,
356         IN ACCESS_MASK DesiredAccess,
357         IN POBJECT_ATTRIBUTES ObjectAttributes)
358 {
359         FIXME("(%p,0x%08lx,%p) stub\n",
360         LinkHandle, DesiredAccess, ObjectAttributes);
361         dump_ObjectAttributes(ObjectAttributes);
362         return 0;
363 }
364
365 /******************************************************************************
366  *  NtCreateSymbolicLinkObject  [NTDLL.@]
367  */
368 NTSTATUS WINAPI NtCreateSymbolicLinkObject(
369         OUT PHANDLE SymbolicLinkHandle,
370         IN ACCESS_MASK DesiredAccess,
371         IN POBJECT_ATTRIBUTES ObjectAttributes,
372         IN PUNICODE_STRING Name)
373 {
374         FIXME("(%p,0x%08lx,%p, %p) stub\n",
375         SymbolicLinkHandle, DesiredAccess, ObjectAttributes, debugstr_us(Name));
376         dump_ObjectAttributes(ObjectAttributes);
377         return 0;
378 }
379
380 /******************************************************************************
381  *  NtQuerySymbolicLinkObject   [NTDLL.@]
382  */
383 NTSTATUS WINAPI NtQuerySymbolicLinkObject(
384         IN HANDLE LinkHandle,
385         IN OUT PUNICODE_STRING LinkTarget,
386         OUT PULONG ReturnedLength OPTIONAL)
387 {
388         FIXME("(0x%08x,%p,%p) stub\n",
389         LinkHandle, debugstr_us(LinkTarget), ReturnedLength);
390
391         return 0;
392 }
393
394 /******************************************************************************
395  *  NtAllocateUuids   [NTDLL.@]
396  *
397  * I have seen lpdwCount pointing to a pointer once...
398  */
399 NTSTATUS WINAPI NtAllocateUuids(LPDWORD lpdwCount, LPDWORD *p2, LPDWORD *p3)
400 {
401         FIXME("(%p[%ld],%p,%p), stub.\n", lpdwCount,
402                                          lpdwCount ? *lpdwCount : 0,
403                                          p2, p3);
404         return 0;
405 }