Fix SetDataFormat and implement GetDeviceInfo for mouse device.
[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(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                 req->fd     = -1;
75                 status = wine_server_call( req );
76                 if (status == STATUS_SUCCESS)
77                 {
78                     p->InheritHandle = (reply->old_flags & HANDLE_FLAG_INHERIT) ? TRUE : FALSE;
79                     p->ProtectFromClose = (reply->old_flags & HANDLE_FLAG_PROTECT_FROM_CLOSE) ? TRUE : FALSE;
80                     if (used_len) *used_len = sizeof(*p);
81                 }
82             }
83             SERVER_END_REQ;
84         }
85         break;
86     default:
87         FIXME("Unsupported information class %u\n", info_class);
88         status = STATUS_NOT_IMPLEMENTED;
89         break;
90     }
91     return status;
92 }
93
94 /******************************************************************
95  *              NtSetInformationObject [NTDLL.@]
96  *              ZwSetInformationObject [NTDLL.@]
97  *
98  */
99 NTSTATUS WINAPI NtSetInformationObject(IN HANDLE handle,
100                                        IN OBJECT_INFORMATION_CLASS info_class,
101                                        IN PVOID ptr, IN ULONG len)
102 {
103     NTSTATUS status;
104
105     TRACE("(%p,0x%08x,%p,0x%08lx): stub\n",
106           handle, info_class, ptr, len);
107
108     switch (info_class)
109     {
110     case ObjectDataInformation:
111         {
112             OBJECT_DATA_INFORMATION* p = (OBJECT_DATA_INFORMATION*)ptr;
113
114             if (len < sizeof(*p)) return STATUS_INVALID_BUFFER_SIZE;
115
116             SERVER_START_REQ( set_handle_info )
117             {
118                 req->handle = handle;
119                 req->flags  = 0;
120                 req->mask   = HANDLE_FLAG_INHERIT | HANDLE_FLAG_PROTECT_FROM_CLOSE;
121                 req->fd     = -1;
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 );
125             }
126             SERVER_END_REQ;
127         }
128         break;
129     default:
130         FIXME("Unsupported information class %u\n", info_class);
131         status = STATUS_NOT_IMPLEMENTED;
132         break;
133     }
134     return status;
135 }
136
137 /******************************************************************************
138  *  NtQuerySecurityObject       [NTDLL.@]
139  *
140  * An ntdll analogue to GetKernelObjectSecurity().
141  *
142  * NOTES
143  *  only the lowest 4 bit of SecurityObjectInformationClass are used
144  *  0x7-0xf returns STATUS_ACCESS_DENIED (even running with system privileges)
145  *
146  * FIXME
147  *  We are constructing a fake sid (Administrators:Full, System:Full, Everyone:Read)
148  */
149 NTSTATUS WINAPI
150 NtQuerySecurityObject(
151         IN HANDLE Object,
152         IN SECURITY_INFORMATION RequestedInformation,
153         OUT PSECURITY_DESCRIPTOR pSecurityDesriptor,
154         IN ULONG Length,
155         OUT PULONG ResultLength)
156 {
157         static SID_IDENTIFIER_AUTHORITY localSidAuthority = {SECURITY_NT_AUTHORITY};
158         static SID_IDENTIFIER_AUTHORITY worldSidAuthority = {SECURITY_WORLD_SID_AUTHORITY};
159         BYTE Buffer[256];
160         PISECURITY_DESCRIPTOR_RELATIVE psd = (PISECURITY_DESCRIPTOR_RELATIVE)Buffer;
161         UINT BufferIndex = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
162
163         FIXME("(%p,0x%08lx,%p,0x%08lx,%p) stub!\n",
164         Object, RequestedInformation, pSecurityDesriptor, Length, ResultLength);
165
166         RequestedInformation &= 0x0000000f;
167
168         if (RequestedInformation & SACL_SECURITY_INFORMATION) return STATUS_ACCESS_DENIED;
169
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);
174
175         /* owner: administrator S-1-5-20-220*/
176         if (OWNER_SECURITY_INFORMATION & RequestedInformation)
177         {
178           PSID psid = (PSID)&(Buffer[BufferIndex]);
179
180           psd->Owner = BufferIndex;
181           BufferIndex += RtlLengthRequiredSid(2);
182
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;
188         }
189
190         /* group: built in domain S-1-5-12 */
191         if (GROUP_SECURITY_INFORMATION & RequestedInformation)
192         {
193           PSID psid = (PSID) &(Buffer[BufferIndex]);
194
195           psd->Group = BufferIndex;
196           BufferIndex += RtlLengthRequiredSid(1);
197
198           psid->Revision = SID_REVISION;
199           psid->SubAuthorityCount = 1;
200           psid->IdentifierAuthority = localSidAuthority;
201           psid->SubAuthority[0] = SECURITY_LOCAL_SYSTEM_RID;
202         }
203
204         /* discretionary ACL */
205         if (DACL_SECURITY_INFORMATION & RequestedInformation)
206         {
207           /* acl header */
208           PACL pacl = (PACL)&(Buffer[BufferIndex]);
209           PACCESS_ALLOWED_ACE pace;
210           PSID psid;
211
212           psd->Dacl = BufferIndex;
213
214           pacl->AclRevision = MIN_ACL_REVISION;
215           pacl->AceCount = 3;
216           pacl->AclSize = BufferIndex; /* storing the start index temporary */
217
218           BufferIndex += sizeof(ACL);
219
220           /* ACE System - full access */
221           pace = (PACCESS_ALLOWED_ACE)&(Buffer[BufferIndex]);
222           BufferIndex += sizeof(ACCESS_ALLOWED_ACE)-sizeof(DWORD);
223
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;
229
230           /* SID S-1-5-12 (System) */
231           psid = (PSID)&(Buffer[BufferIndex]);
232
233           BufferIndex += RtlLengthRequiredSid(1);
234
235           psid->Revision = SID_REVISION;
236           psid->SubAuthorityCount = 1;
237           psid->IdentifierAuthority = localSidAuthority;
238           psid->SubAuthority[0] = SECURITY_LOCAL_SYSTEM_RID;
239
240           /* ACE Administrators - full access*/
241           pace = (PACCESS_ALLOWED_ACE) &(Buffer[BufferIndex]);
242           BufferIndex += sizeof(ACCESS_ALLOWED_ACE)-sizeof(DWORD);
243
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;
249
250           /* S-1-5-12 (Administrators) */
251           psid = (PSID)&(Buffer[BufferIndex]);
252
253           BufferIndex += RtlLengthRequiredSid(2);
254
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;
260
261           /* ACE Everyone - read access */
262           pace = (PACCESS_ALLOWED_ACE)&(Buffer[BufferIndex]);
263           BufferIndex += sizeof(ACCESS_ALLOWED_ACE)-sizeof(DWORD);
264
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;
270
271           /* SID S-1-1-0 (Everyone) */
272           psid = (PSID)&(Buffer[BufferIndex]);
273
274           BufferIndex += RtlLengthRequiredSid(1);
275
276           psid->Revision = SID_REVISION;
277           psid->SubAuthorityCount = 1;
278           psid->IdentifierAuthority = worldSidAuthority;
279           psid->SubAuthority[0] = 0;
280
281           /* calculate used bytes */
282           pacl->AclSize = BufferIndex - pacl->AclSize;
283         }
284         *ResultLength = BufferIndex;
285         TRACE("len=%lu\n", *ResultLength);
286         if (Length < *ResultLength) return STATUS_BUFFER_TOO_SMALL;
287         memcpy(pSecurityDesriptor, Buffer, *ResultLength);
288
289         return STATUS_SUCCESS;
290 }
291
292
293 /******************************************************************************
294  *  NtDuplicateObject           [NTDLL.@]
295  *  ZwDuplicateObject           [NTDLL.@]
296  */
297 NTSTATUS WINAPI NtDuplicateObject( HANDLE source_process, HANDLE source,
298                                    HANDLE dest_process, PHANDLE dest,
299                                    ACCESS_MASK access, ULONG attributes, ULONG options )
300 {
301     NTSTATUS ret;
302     SERVER_START_REQ( dup_handle )
303     {
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;
310
311         if (!(ret = wine_server_call( req )))
312         {
313             if (dest) *dest = reply->handle;
314             if (reply->fd != -1) close( reply->fd );
315         }
316     }
317     SERVER_END_REQ;
318     return ret;
319 }
320
321 /**************************************************************************
322  *                 NtClose                              [NTDLL.@]
323  *
324  * Close a handle reference to an object.
325  * 
326  * PARAMS
327  *  Handle [I] handle to close
328  *
329  * RETURNS
330  *  Success: ERROR_SUCCESS.
331  *  Failure: An NTSTATUS error code.
332  */
333 NTSTATUS WINAPI NtClose( HANDLE Handle )
334 {
335     NTSTATUS ret;
336     SERVER_START_REQ( close_handle )
337     {
338         req->handle = Handle;
339         ret = wine_server_call( req );
340         if (!ret && reply->fd != -1) close( reply->fd );
341     }
342     SERVER_END_REQ;
343     return ret;
344 }
345
346 /*
347  *      Directory functions
348  */
349
350 /**************************************************************************
351  * NtOpenDirectoryObject [NTDLL.@]
352  * ZwOpenDirectoryObject [NTDLL.@]
353  *
354  * Open a namespace directory object.
355  * 
356  * PARAMS
357  *  DirectoryHandle  [O] Destination for the new directory handle
358  *  DesiredAccess    [I] Desired access to the directory
359  *  ObjectAttributes [I] Structure describing the directory
360  *
361  * RETURNS
362  *  Success: ERROR_SUCCESS.
363  *  Failure: An NTSTATUS error code.
364  */
365 NTSTATUS WINAPI NtOpenDirectoryObject(
366         PHANDLE DirectoryHandle,
367         ACCESS_MASK DesiredAccess,
368         POBJECT_ATTRIBUTES ObjectAttributes)
369 {
370         FIXME("(%p,0x%08lx,%p): stub\n",
371         DirectoryHandle, DesiredAccess, ObjectAttributes);
372         dump_ObjectAttributes(ObjectAttributes);
373         return 0;
374 }
375
376 /******************************************************************************
377  *  NtCreateDirectoryObject     [NTDLL.@]
378  *  ZwCreateDirectoryObject     [NTDLL.@]
379  */
380 NTSTATUS WINAPI NtCreateDirectoryObject(
381         PHANDLE DirectoryHandle,
382         ACCESS_MASK DesiredAccess,
383         POBJECT_ATTRIBUTES ObjectAttributes)
384 {
385         FIXME("(%p,0x%08lx,%p),stub!\n",
386         DirectoryHandle,DesiredAccess,ObjectAttributes);
387         dump_ObjectAttributes(ObjectAttributes);
388         return 0;
389 }
390
391 /******************************************************************************
392  * NtQueryDirectoryObject [NTDLL.@]
393  * ZwQueryDirectoryObject [NTDLL.@]
394  *
395  * Read information from a namespace directory.
396  * 
397  * PARAMS
398  *  DirObjHandle      [I]   Object handle
399  *  DirObjInformation [O]   Buffer to hold the data read
400  *  BufferLength      [I]   Size of the buffer in bytes
401  *  GetNextIndex      [I]   Set ObjectIndex to TRUE=next object, FALSE=last object
402  *  IgnoreInputIndex  [I]   Start reading at index TRUE=0, FALSE=ObjectIndex
403  *  ObjectIndex       [I/O] 0 based index into the directory, see IgnoreInputIndex and GetNextIndex
404  *  DataWritten       [O]   Caller supplied storage for the number of bytes written (or NULL)
405  *
406  * RETURNS
407  *  Success: ERROR_SUCCESS.
408  *  Failure: An NTSTATUS error code.
409  */
410 NTSTATUS WINAPI NtQueryDirectoryObject(
411         IN HANDLE DirObjHandle,
412         OUT POBJDIR_INFORMATION DirObjInformation,
413         IN ULONG BufferLength,
414         IN BOOLEAN GetNextIndex,
415         IN BOOLEAN IgnoreInputIndex,
416         IN OUT PULONG ObjectIndex,
417         OUT PULONG DataWritten OPTIONAL)
418 {
419         FIXME("(%p,%p,0x%08lx,0x%08x,0x%08x,%p,%p) stub\n",
420                 DirObjHandle, DirObjInformation, BufferLength, GetNextIndex,
421                 IgnoreInputIndex, ObjectIndex, DataWritten);
422     return 0xc0000000; /* We don't have any. Whatever. (Yet.) */
423 }
424
425 /*
426  *      Link objects
427  */
428
429 /******************************************************************************
430  *  NtOpenSymbolicLinkObject    [NTDLL.@]
431  */
432 NTSTATUS WINAPI NtOpenSymbolicLinkObject(
433         OUT PHANDLE LinkHandle,
434         IN ACCESS_MASK DesiredAccess,
435         IN POBJECT_ATTRIBUTES ObjectAttributes)
436 {
437         FIXME("(%p,0x%08lx,%p) stub\n",
438         LinkHandle, DesiredAccess, ObjectAttributes);
439         dump_ObjectAttributes(ObjectAttributes);
440         return 0;
441 }
442
443 /******************************************************************************
444  *  NtCreateSymbolicLinkObject  [NTDLL.@]
445  */
446 NTSTATUS WINAPI NtCreateSymbolicLinkObject(
447         OUT PHANDLE SymbolicLinkHandle,
448         IN ACCESS_MASK DesiredAccess,
449         IN POBJECT_ATTRIBUTES ObjectAttributes,
450         IN PUNICODE_STRING Name)
451 {
452         FIXME("(%p,0x%08lx,%p, %p) stub\n",
453         SymbolicLinkHandle, DesiredAccess, ObjectAttributes, debugstr_us(Name));
454         dump_ObjectAttributes(ObjectAttributes);
455         return 0;
456 }
457
458 /******************************************************************************
459  *  NtQuerySymbolicLinkObject   [NTDLL.@]
460  */
461 NTSTATUS WINAPI NtQuerySymbolicLinkObject(
462         IN HANDLE LinkHandle,
463         IN OUT PUNICODE_STRING LinkTarget,
464         OUT PULONG ReturnedLength OPTIONAL)
465 {
466         FIXME("(%p,%p,%p) stub\n",
467         LinkHandle, debugstr_us(LinkTarget), ReturnedLength);
468
469         return 0;
470 }
471
472 /******************************************************************************
473  *  NtAllocateUuids   [NTDLL.@]
474  *
475  * NOTES
476  *  I have seen lpdwCount pointing to a pointer once...
477  */
478 NTSTATUS WINAPI NtAllocateUuids(LPDWORD lpdwCount, LPDWORD *p2, LPDWORD *p3)
479 {
480         FIXME("(%p[%ld],%p,%p), stub.\n", lpdwCount,
481                                          lpdwCount ? *lpdwCount : 0,
482                                          p2, p3);
483         return 0;
484 }