comctl32: We can now store binary files in the repository.
[wine] / dlls / ntdll / nt.c
1 /*
2  * NT basis DLL
3  *
4  * This file contains the Nt* API functions of NTDLL.DLL.
5  * In the original ntdll.dll they all seem to just call int 0x2e (down to the NTOSKRNL)
6  *
7  * Copyright 1996-1998 Marcus Meissner
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22  */
23
24 #include <stdarg.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <time.h>
29
30 #include "ntstatus.h"
31 #define WIN32_NO_STATUS
32 #include "wine/debug.h"
33 #include "wine/unicode.h"
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  *      Token
43  */
44
45 /******************************************************************************
46  *  NtDuplicateToken            [NTDLL.@]
47  *  ZwDuplicateToken            [NTDLL.@]
48  */
49 NTSTATUS WINAPI NtDuplicateToken(
50         IN HANDLE ExistingToken,
51         IN ACCESS_MASK DesiredAccess,
52         IN POBJECT_ATTRIBUTES ObjectAttributes,
53         IN SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
54         IN TOKEN_TYPE TokenType,
55         OUT PHANDLE NewToken)
56 {
57     NTSTATUS status;
58
59     TRACE("(%p,0x%08x,%p,0x%08x,0x%08x,%p)\n",
60         ExistingToken, DesiredAccess, ObjectAttributes,
61         ImpersonationLevel, TokenType, NewToken);
62         dump_ObjectAttributes(ObjectAttributes);
63
64     if (ObjectAttributes && ObjectAttributes->SecurityQualityOfService)
65     {
66         SECURITY_QUALITY_OF_SERVICE *SecurityQOS = ObjectAttributes->SecurityQualityOfService;
67         TRACE("ObjectAttributes->SecurityQualityOfService = {%d, %d, %d, %s}\n",
68             SecurityQOS->Length, SecurityQOS->ImpersonationLevel,
69             SecurityQOS->ContextTrackingMode,
70             SecurityQOS->EffectiveOnly ? "TRUE" : "FALSE");
71         ImpersonationLevel = SecurityQOS->ImpersonationLevel;
72     }
73
74     SERVER_START_REQ( duplicate_token )
75     {
76         req->handle              = ExistingToken;
77         req->access              = DesiredAccess;
78         req->attributes          = ObjectAttributes ? ObjectAttributes->Attributes : 0;
79         req->primary             = (TokenType == TokenPrimary);
80         req->impersonation_level = ImpersonationLevel;
81         status = wine_server_call( req );
82         if (!status) *NewToken = reply->new_handle;
83     }
84     SERVER_END_REQ;
85
86     return status;
87 }
88
89 /******************************************************************************
90  *  NtOpenProcessToken          [NTDLL.@]
91  *  ZwOpenProcessToken          [NTDLL.@]
92  */
93 NTSTATUS WINAPI NtOpenProcessToken(
94         HANDLE ProcessHandle,
95         DWORD DesiredAccess,
96         HANDLE *TokenHandle)
97 {
98     NTSTATUS ret;
99
100     TRACE("(%p,0x%08x,%p)\n", ProcessHandle,DesiredAccess, TokenHandle);
101
102     SERVER_START_REQ( open_token )
103     {
104         req->handle     = ProcessHandle;
105         req->access     = DesiredAccess;
106         req->attributes = 0;
107         req->flags      = 0;
108         ret = wine_server_call( req );
109         if (!ret) *TokenHandle = reply->token;
110     }
111     SERVER_END_REQ;
112
113     return ret;
114 }
115
116 /******************************************************************************
117  *  NtOpenThreadToken           [NTDLL.@]
118  *  ZwOpenThreadToken           [NTDLL.@]
119  */
120 NTSTATUS WINAPI NtOpenThreadToken(
121         HANDLE ThreadHandle,
122         DWORD DesiredAccess,
123         BOOLEAN OpenAsSelf,
124         HANDLE *TokenHandle)
125 {
126     NTSTATUS ret;
127
128     TRACE("(%p,0x%08x,0x%08x,%p)\n",
129           ThreadHandle,DesiredAccess, OpenAsSelf, TokenHandle);
130
131     SERVER_START_REQ( open_token )
132     {
133         req->handle     = ThreadHandle;
134         req->access     = DesiredAccess;
135         req->attributes = 0;
136         req->flags      = OPEN_TOKEN_THREAD;
137         if (OpenAsSelf) req->flags |= OPEN_TOKEN_AS_SELF;
138         ret = wine_server_call( req );
139         if (!ret) *TokenHandle = reply->token;
140     }
141     SERVER_END_REQ;
142
143     return ret;
144 }
145
146 /******************************************************************************
147  *  NtAdjustPrivilegesToken             [NTDLL.@]
148  *  ZwAdjustPrivilegesToken             [NTDLL.@]
149  *
150  * FIXME: parameters unsafe
151  */
152 NTSTATUS WINAPI NtAdjustPrivilegesToken(
153         IN HANDLE TokenHandle,
154         IN BOOLEAN DisableAllPrivileges,
155         IN PTOKEN_PRIVILEGES NewState,
156         IN DWORD BufferLength,
157         OUT PTOKEN_PRIVILEGES PreviousState,
158         OUT PDWORD ReturnLength)
159 {
160     NTSTATUS ret;
161
162     TRACE("(%p,0x%08x,%p,0x%08x,%p,%p)\n",
163         TokenHandle, DisableAllPrivileges, NewState, BufferLength, PreviousState, ReturnLength);
164
165     SERVER_START_REQ( adjust_token_privileges )
166     {
167         req->handle = TokenHandle;
168         req->disable_all = DisableAllPrivileges;
169         req->get_modified_state = (PreviousState != NULL);
170         if (!DisableAllPrivileges)
171         {
172             wine_server_add_data( req, &NewState->Privileges,
173                                   NewState->PrivilegeCount * sizeof(NewState->Privileges[0]) );
174         }
175         if (PreviousState && BufferLength >= FIELD_OFFSET( TOKEN_PRIVILEGES, Privileges ))
176             wine_server_set_reply( req, &PreviousState->Privileges,
177                                    BufferLength - FIELD_OFFSET( TOKEN_PRIVILEGES, Privileges ) );
178         ret = wine_server_call( req );
179         if (PreviousState)
180         {
181             *ReturnLength = reply->len + FIELD_OFFSET( TOKEN_PRIVILEGES, Privileges );
182             PreviousState->PrivilegeCount = reply->len / sizeof(LUID_AND_ATTRIBUTES);
183         }
184     }
185     SERVER_END_REQ;
186
187     return ret;
188 }
189
190 /******************************************************************************
191 *  NtQueryInformationToken              [NTDLL.@]
192 *  ZwQueryInformationToken              [NTDLL.@]
193 *
194 * NOTES
195 *  Buffer for TokenUser:
196 *   0x00 TOKEN_USER the PSID field points to the SID
197 *   0x08 SID
198 *
199 */
200 NTSTATUS WINAPI NtQueryInformationToken(
201         HANDLE token,
202         TOKEN_INFORMATION_CLASS tokeninfoclass,
203         PVOID tokeninfo,
204         ULONG tokeninfolength,
205         PULONG retlen )
206 {
207     ULONG len;
208     NTSTATUS status = STATUS_SUCCESS;
209
210     TRACE("(%p,%d,%p,%d,%p)\n",
211           token,tokeninfoclass,tokeninfo,tokeninfolength,retlen);
212
213     switch (tokeninfoclass)
214     {
215     case TokenOwner:
216         len = sizeof(TOKEN_OWNER) + sizeof(SID);
217         break;
218     case TokenPrimaryGroup:
219         len = sizeof(TOKEN_PRIMARY_GROUP);
220         break;
221     case TokenDefaultDacl:
222         len = sizeof(TOKEN_DEFAULT_DACL);
223         break;
224     case TokenSource:
225         len = sizeof(TOKEN_SOURCE);
226         break;
227     case TokenType:
228         len = sizeof (TOKEN_TYPE);
229         break;
230     case TokenImpersonationLevel:
231         len = sizeof(SECURITY_IMPERSONATION_LEVEL);
232         break;
233     case TokenStatistics:
234         len = sizeof(TOKEN_STATISTICS);
235         break;
236     default:
237         len = 0;
238     }
239
240     if (retlen) *retlen = len;
241
242     if (tokeninfolength < len)
243         return STATUS_BUFFER_TOO_SMALL;
244
245     switch (tokeninfoclass)
246     {
247     case TokenUser:
248         SERVER_START_REQ( get_token_user )
249         {
250             TOKEN_USER * tuser = tokeninfo;
251             PSID sid = (PSID) (tuser + 1);
252             DWORD sid_len = tokeninfolength < sizeof(TOKEN_USER) ? 0 : tokeninfolength - sizeof(TOKEN_USER);
253
254             req->handle = token;
255             wine_server_set_reply( req, sid, sid_len );
256             status = wine_server_call( req );
257             if (retlen) *retlen = reply->user_len + sizeof(TOKEN_USER);
258             if (status == STATUS_SUCCESS)
259             {
260                 tuser->User.Sid = sid;
261                 tuser->User.Attributes = 0;
262             }
263         }
264         SERVER_END_REQ;
265         break;
266     case TokenGroups:
267     {
268         char stack_buffer[256];
269         unsigned int server_buf_len = sizeof(stack_buffer);
270         void *buffer = stack_buffer;
271         BOOLEAN need_more_memory = FALSE;
272
273         /* we cannot work out the size of the server buffer required for the
274          * input size, since there are two factors affecting how much can be
275          * stored in the buffer - number of groups and lengths of sids */
276         do
277         {
278             SERVER_START_REQ( get_token_groups )
279             {
280                 TOKEN_GROUPS *groups = tokeninfo;
281
282                 req->handle = token;
283                 wine_server_set_reply( req, buffer, server_buf_len );
284                 status = wine_server_call( req );
285                 if (status == STATUS_BUFFER_TOO_SMALL)
286                 {
287                     if (buffer == stack_buffer)
288                         buffer = RtlAllocateHeap(GetProcessHeap(), 0, reply->user_len);
289                     else
290                         buffer = RtlReAllocateHeap(GetProcessHeap(), 0, buffer, reply->user_len);
291                     if (!buffer) return STATUS_NO_MEMORY;
292
293                     server_buf_len = reply->user_len;
294                     need_more_memory = TRUE;
295                 }
296                 else if (status == STATUS_SUCCESS)
297                 {
298                     struct token_groups *tg = buffer;
299                     unsigned int *attr = (unsigned int *)(tg + 1);
300                     ULONG i;
301                     const int non_sid_portion = (sizeof(struct token_groups) + tg->count * sizeof(unsigned long));
302                     SID *sids = (SID *)((char *)tokeninfo + FIELD_OFFSET( TOKEN_GROUPS, Groups[tg->count] ));
303                     ULONG needed_bytes = FIELD_OFFSET( TOKEN_GROUPS, Groups[tg->count] ) +
304                         reply->user_len - non_sid_portion;
305
306                     if (retlen) *retlen = needed_bytes;
307
308                     if (needed_bytes <= tokeninfolength)
309                     {
310                         groups->GroupCount = tg->count;
311                         memcpy( sids, (char *)buffer + non_sid_portion,
312                                 reply->user_len - non_sid_portion );
313
314                         for (i = 0; i < tg->count; i++)
315                         {
316                             groups->Groups[i].Attributes = attr[i];
317                             groups->Groups[i].Sid = sids;
318                             sids = (SID *)((char *)sids + RtlLengthSid(sids));
319                         }
320                     }
321                     else status = STATUS_BUFFER_TOO_SMALL;
322                 }
323                 else if (retlen) *retlen = 0;
324             }
325             SERVER_END_REQ;
326         } while (need_more_memory);
327         if (buffer != stack_buffer) RtlFreeHeap(GetProcessHeap(), 0, buffer);
328         break;
329     }
330     case TokenPrimaryGroup:
331         if (tokeninfo)
332         {
333             TOKEN_PRIMARY_GROUP *tgroup = tokeninfo;
334             SID_IDENTIFIER_AUTHORITY sid = {SECURITY_NT_AUTHORITY};
335             RtlAllocateAndInitializeSid( &sid,
336                                          2,
337                                          SECURITY_BUILTIN_DOMAIN_RID,
338                                          DOMAIN_ALIAS_RID_ADMINS,
339                                          0, 0, 0, 0, 0, 0,
340                                          &(tgroup->PrimaryGroup));
341         }
342         break;
343     case TokenPrivileges:
344         SERVER_START_REQ( get_token_privileges )
345         {
346             TOKEN_PRIVILEGES *tpriv = tokeninfo;
347             req->handle = token;
348             if (tpriv && tokeninfolength > FIELD_OFFSET( TOKEN_PRIVILEGES, Privileges ))
349                 wine_server_set_reply( req, &tpriv->Privileges, tokeninfolength - FIELD_OFFSET( TOKEN_PRIVILEGES, Privileges ) );
350             status = wine_server_call( req );
351             if (retlen) *retlen = FIELD_OFFSET( TOKEN_PRIVILEGES, Privileges ) + reply->len;
352             if (tpriv) tpriv->PrivilegeCount = reply->len / sizeof(LUID_AND_ATTRIBUTES);
353         }
354         SERVER_END_REQ;
355         break;
356     case TokenOwner:
357         if (tokeninfo)
358         {
359             TOKEN_OWNER *owner = tokeninfo;
360             PSID sid = (PSID) (owner + 1);
361             SID_IDENTIFIER_AUTHORITY localSidAuthority = {SECURITY_NT_AUTHORITY};
362             RtlInitializeSid(sid, &localSidAuthority, 1);
363             *(RtlSubAuthoritySid(sid, 0)) = SECURITY_INTERACTIVE_RID;
364             owner->Owner = sid;
365         }
366         break;
367     case TokenImpersonationLevel:
368         SERVER_START_REQ( get_token_impersonation_level )
369         {
370             SECURITY_IMPERSONATION_LEVEL *impersonation_level = tokeninfo;
371             req->handle = token;
372             status = wine_server_call( req );
373             if (status == STATUS_SUCCESS)
374                 *impersonation_level = reply->impersonation_level;
375         }
376         SERVER_END_REQ;
377         break;
378     case TokenStatistics:
379         SERVER_START_REQ( get_token_statistics )
380         {
381             TOKEN_STATISTICS *statistics = tokeninfo;
382             req->handle = token;
383             status = wine_server_call( req );
384             if (status == STATUS_SUCCESS)
385             {
386                 statistics->TokenId.LowPart  = reply->token_id.low_part;
387                 statistics->TokenId.HighPart = reply->token_id.high_part;
388                 statistics->AuthenticationId.LowPart  = 0; /* FIXME */
389                 statistics->AuthenticationId.HighPart = 0; /* FIXME */
390                 statistics->ExpirationTime.HighPart = 0x7fffffff;
391                 statistics->ExpirationTime.LowPart  = 0xffffffff;
392                 statistics->TokenType = reply->primary ? TokenPrimary : TokenImpersonation;
393                 statistics->ImpersonationLevel = reply->impersonation_level;
394
395                 /* kernel information not relevant to us */
396                 statistics->DynamicCharged = 0;
397                 statistics->DynamicAvailable = 0;
398
399                 statistics->GroupCount = reply->group_count;
400                 statistics->PrivilegeCount = reply->privilege_count;
401                 statistics->ModifiedId.LowPart  = reply->modified_id.low_part;
402                 statistics->ModifiedId.HighPart = reply->modified_id.high_part;
403             }
404         }
405         SERVER_END_REQ;
406         break;
407     case TokenType:
408         SERVER_START_REQ( get_token_statistics )
409         {
410             TOKEN_TYPE *token_type = tokeninfo;
411             req->handle = token;
412             status = wine_server_call( req );
413             if (status == STATUS_SUCCESS)
414                 *token_type = reply->primary ? TokenPrimary : TokenImpersonation;
415         }
416         SERVER_END_REQ;
417         break;
418     default:
419         {
420             ERR("Unhandled Token Information class %d!\n", tokeninfoclass);
421             return STATUS_NOT_IMPLEMENTED;
422         }
423     }
424     return status;
425 }
426
427 /******************************************************************************
428 *  NtSetInformationToken                [NTDLL.@]
429 *  ZwSetInformationToken                [NTDLL.@]
430 */
431 NTSTATUS WINAPI NtSetInformationToken(
432         HANDLE TokenHandle,
433         TOKEN_INFORMATION_CLASS TokenInformationClass,
434         PVOID TokenInformation,
435         ULONG TokenInformationLength)
436 {
437     FIXME("%p %d %p %u\n", TokenHandle, TokenInformationClass,
438           TokenInformation, TokenInformationLength);
439     return STATUS_NOT_IMPLEMENTED;
440 }
441
442 /******************************************************************************
443 *  NtAdjustGroupsToken          [NTDLL.@]
444 *  ZwAdjustGroupsToken          [NTDLL.@]
445 */
446 NTSTATUS WINAPI NtAdjustGroupsToken(
447         HANDLE TokenHandle,
448         BOOLEAN ResetToDefault,
449         PTOKEN_GROUPS NewState,
450         ULONG BufferLength,
451         PTOKEN_GROUPS PreviousState,
452         PULONG ReturnLength)
453 {
454     FIXME("%p %d %p %u %p %p\n", TokenHandle, ResetToDefault,
455           NewState, BufferLength, PreviousState, ReturnLength);
456     return STATUS_NOT_IMPLEMENTED;
457 }
458
459 /******************************************************************************
460 *  NtPrivilegeCheck             [NTDLL.@]
461 *  ZwPrivilegeCheck             [NTDLL.@]
462 */
463 NTSTATUS WINAPI NtPrivilegeCheck(
464     HANDLE ClientToken,
465     PPRIVILEGE_SET RequiredPrivileges,
466     PBOOLEAN Result)
467 {
468     NTSTATUS status;
469     SERVER_START_REQ( check_token_privileges )
470     {
471         req->handle = ClientToken;
472         req->all_required = ((RequiredPrivileges->Control & PRIVILEGE_SET_ALL_NECESSARY) ? TRUE : FALSE);
473         wine_server_add_data( req, &RequiredPrivileges->Privilege,
474             RequiredPrivileges->PrivilegeCount * sizeof(RequiredPrivileges->Privilege[0]) );
475         wine_server_set_reply( req, &RequiredPrivileges->Privilege,
476             RequiredPrivileges->PrivilegeCount * sizeof(RequiredPrivileges->Privilege[0]) );
477
478         status = wine_server_call( req );
479
480         if (status == STATUS_SUCCESS)
481             *Result = (reply->has_privileges ? TRUE : FALSE);
482     }
483     SERVER_END_REQ;
484     return status;
485 }
486
487 /*
488  *      Section
489  */
490
491 /******************************************************************************
492  *  NtQuerySection      [NTDLL.@]
493  */
494 NTSTATUS WINAPI NtQuerySection(
495         IN HANDLE SectionHandle,
496         IN SECTION_INFORMATION_CLASS SectionInformationClass,
497         OUT PVOID SectionInformation,
498         IN ULONG Length,
499         OUT PULONG ResultLength)
500 {
501         FIXME("(%p,%d,%p,0x%08x,%p) stub!\n",
502         SectionHandle,SectionInformationClass,SectionInformation,Length,ResultLength);
503         return 0;
504 }
505
506 /*
507  *      ports
508  */
509
510 /******************************************************************************
511  *  NtCreatePort                [NTDLL.@]
512  *  ZwCreatePort                [NTDLL.@]
513  */
514 NTSTATUS WINAPI NtCreatePort(PHANDLE PortHandle,POBJECT_ATTRIBUTES ObjectAttributes,
515                              ULONG MaxConnectInfoLength,ULONG MaxDataLength,PULONG reserved)
516 {
517   FIXME("(%p,%p,%u,%u,%p),stub!\n",PortHandle,ObjectAttributes,
518         MaxConnectInfoLength,MaxDataLength,reserved);
519   return STATUS_NOT_IMPLEMENTED;
520 }
521
522 /******************************************************************************
523  *  NtConnectPort               [NTDLL.@]
524  *  ZwConnectPort               [NTDLL.@]
525  */
526 NTSTATUS WINAPI NtConnectPort(
527         PHANDLE PortHandle,
528         PUNICODE_STRING PortName,
529         PSECURITY_QUALITY_OF_SERVICE SecurityQos,
530         PLPC_SECTION_WRITE WriteSection,
531         PLPC_SECTION_READ ReadSection,
532         PULONG MaximumMessageLength,
533         PVOID ConnectInfo,
534         PULONG pConnectInfoLength)
535 {
536     FIXME("(%p,%s,%p,%p,%p,%p,%p,%p),stub!\n",
537           PortHandle,debugstr_w(PortName->Buffer),SecurityQos,
538           WriteSection,ReadSection,MaximumMessageLength,ConnectInfo,
539           pConnectInfoLength);
540     if (ConnectInfo && pConnectInfoLength)
541         TRACE("\tMessage = %s\n",debugstr_an(ConnectInfo,*pConnectInfoLength));
542     return STATUS_NOT_IMPLEMENTED;
543 }
544
545 /******************************************************************************
546  *  NtListenPort                [NTDLL.@]
547  *  ZwListenPort                [NTDLL.@]
548  */
549 NTSTATUS WINAPI NtListenPort(HANDLE PortHandle,PLPC_MESSAGE pLpcMessage)
550 {
551   FIXME("(%p,%p),stub!\n",PortHandle,pLpcMessage);
552   return STATUS_NOT_IMPLEMENTED;
553 }
554
555 /******************************************************************************
556  *  NtAcceptConnectPort [NTDLL.@]
557  *  ZwAcceptConnectPort [NTDLL.@]
558  */
559 NTSTATUS WINAPI NtAcceptConnectPort(
560         PHANDLE PortHandle,
561         ULONG PortIdentifier,
562         PLPC_MESSAGE pLpcMessage,
563         BOOLEAN Accept,
564         PLPC_SECTION_WRITE WriteSection,
565         PLPC_SECTION_READ ReadSection)
566 {
567   FIXME("(%p,%u,%p,%d,%p,%p),stub!\n",
568         PortHandle,PortIdentifier,pLpcMessage,Accept,WriteSection,ReadSection);
569   return STATUS_NOT_IMPLEMENTED;
570 }
571
572 /******************************************************************************
573  *  NtCompleteConnectPort       [NTDLL.@]
574  *  ZwCompleteConnectPort       [NTDLL.@]
575  */
576 NTSTATUS WINAPI NtCompleteConnectPort(HANDLE PortHandle)
577 {
578   FIXME("(%p),stub!\n",PortHandle);
579   return STATUS_NOT_IMPLEMENTED;
580 }
581
582 /******************************************************************************
583  *  NtRegisterThreadTerminatePort       [NTDLL.@]
584  *  ZwRegisterThreadTerminatePort       [NTDLL.@]
585  */
586 NTSTATUS WINAPI NtRegisterThreadTerminatePort(HANDLE PortHandle)
587 {
588   FIXME("(%p),stub!\n",PortHandle);
589   return STATUS_NOT_IMPLEMENTED;
590 }
591
592 /******************************************************************************
593  *  NtRequestWaitReplyPort              [NTDLL.@]
594  *  ZwRequestWaitReplyPort              [NTDLL.@]
595  */
596 NTSTATUS WINAPI NtRequestWaitReplyPort(
597         HANDLE PortHandle,
598         PLPC_MESSAGE pLpcMessageIn,
599         PLPC_MESSAGE pLpcMessageOut)
600 {
601   FIXME("(%p,%p,%p),stub!\n",PortHandle,pLpcMessageIn,pLpcMessageOut);
602   if(pLpcMessageIn)
603   {
604     TRACE("Message to send:\n");
605     TRACE("\tDataSize            = %u\n",pLpcMessageIn->DataSize);
606     TRACE("\tMessageSize         = %u\n",pLpcMessageIn->MessageSize);
607     TRACE("\tMessageType         = %u\n",pLpcMessageIn->MessageType);
608     TRACE("\tVirtualRangesOffset = %u\n",pLpcMessageIn->VirtualRangesOffset);
609     TRACE("\tClientId.UniqueProcess = %p\n",pLpcMessageIn->ClientId.UniqueProcess);
610     TRACE("\tClientId.UniqueThread  = %p\n",pLpcMessageIn->ClientId.UniqueThread);
611     TRACE("\tMessageId           = %u\n",pLpcMessageIn->MessageId);
612     TRACE("\tSectionSize         = %u\n",pLpcMessageIn->SectionSize);
613     TRACE("\tData                = %s\n",
614       debugstr_an((const char*)pLpcMessageIn->Data,pLpcMessageIn->DataSize));
615   }
616   return STATUS_NOT_IMPLEMENTED;
617 }
618
619 /******************************************************************************
620  *  NtReplyWaitReceivePort      [NTDLL.@]
621  *  ZwReplyWaitReceivePort      [NTDLL.@]
622  */
623 NTSTATUS WINAPI NtReplyWaitReceivePort(
624         HANDLE PortHandle,
625         PULONG PortIdentifier,
626         PLPC_MESSAGE ReplyMessage,
627         PLPC_MESSAGE Message)
628 {
629   FIXME("(%p,%p,%p,%p),stub!\n",PortHandle,PortIdentifier,ReplyMessage,Message);
630   return STATUS_NOT_IMPLEMENTED;
631 }
632
633 /*
634  *      Misc
635  */
636
637  /******************************************************************************
638  *  NtSetIntervalProfile        [NTDLL.@]
639  *  ZwSetIntervalProfile        [NTDLL.@]
640  */
641 NTSTATUS WINAPI NtSetIntervalProfile(
642         ULONG Interval,
643         KPROFILE_SOURCE Source)
644 {
645     FIXME("%u,%d\n", Interval, Source);
646     return STATUS_SUCCESS;
647 }
648
649 /******************************************************************************
650  * NtQuerySystemInformation [NTDLL.@]
651  * ZwQuerySystemInformation [NTDLL.@]
652  *
653  * ARGUMENTS:
654  *  SystemInformationClass      Index to a certain information structure
655  *      SystemTimeAdjustmentInformation SYSTEM_TIME_ADJUSTMENT
656  *      SystemCacheInformation          SYSTEM_CACHE_INFORMATION
657  *      SystemConfigurationInformation  CONFIGURATION_INFORMATION
658  *      observed (class/len):
659  *              0x0/0x2c
660  *              0x12/0x18
661  *              0x2/0x138
662  *              0x8/0x600
663  *              0x25/0xc
664  *  SystemInformation   caller supplies storage for the information structure
665  *  Length              size of the structure
666  *  ResultLength        Data written
667  */
668 NTSTATUS WINAPI NtQuerySystemInformation(
669         IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
670         OUT PVOID SystemInformation,
671         IN ULONG Length,
672         OUT PULONG ResultLength)
673 {
674     NTSTATUS    ret = STATUS_SUCCESS;
675     ULONG       len = 0;
676
677     TRACE("(0x%08x,%p,0x%08x,%p)\n",
678           SystemInformationClass,SystemInformation,Length,ResultLength);
679
680     switch (SystemInformationClass)
681     {
682     case SystemBasicInformation:
683         {
684             SYSTEM_BASIC_INFORMATION sbi;
685
686             sbi.dwUnknown1 = 0;
687             sbi.uKeMaximumIncrement = 0;
688             sbi.uPageSize = 1024; /* FIXME */
689             sbi.uMmNumberOfPhysicalPages = 12345; /* FIXME */
690             sbi.uMmLowestPhysicalPage = 0; /* FIXME */
691             sbi.uMmHighestPhysicalPage = 12345; /* FIXME */
692             sbi.uAllocationGranularity = 65536; /* FIXME */
693             sbi.pLowestUserAddress = 0; /* FIXME */
694             sbi.pMmHighestUserAddress = (void*)~0; /* FIXME */
695             sbi.uKeActiveProcessors = 1; /* FIXME */
696             sbi.bKeNumberProcessors = 1; /* FIXME */
697             len = sizeof(sbi);
698
699             if ( Length == len)
700             {
701                 if (!SystemInformation) ret = STATUS_ACCESS_VIOLATION;
702                 else memcpy( SystemInformation, &sbi, len);
703             }
704             else ret = STATUS_INFO_LENGTH_MISMATCH;
705         }
706         break;
707     case SystemCpuInformation:
708         {
709             SYSTEM_CPU_INFORMATION sci;
710
711             /* FIXME: move some code from kernel/cpu.c to process this */
712             sci.Architecture = PROCESSOR_ARCHITECTURE_INTEL;
713             sci.Level = 6; /* 686, aka Pentium II+ */
714             sci.Revision = 0;
715             sci.Reserved = 0;
716             sci.FeatureSet = 0x1fff;
717             len = sizeof(sci);
718
719             if ( Length >= len)
720             {
721                 if (!SystemInformation) ret = STATUS_ACCESS_VIOLATION;
722                 else memcpy( SystemInformation, &sci, len);
723             }
724             else ret = STATUS_INFO_LENGTH_MISMATCH;
725         }
726         break;
727     case SystemPerformanceInformation:
728         {
729             SYSTEM_PERFORMANCE_INFORMATION spi;
730
731             memset(&spi, 0 , sizeof(spi));
732             len = sizeof(spi);
733
734             if (Length >= len)
735             {
736                 if (!SystemInformation) ret = STATUS_ACCESS_VIOLATION;
737                 else memcpy( SystemInformation, &spi, len);
738             }
739             else ret = STATUS_INFO_LENGTH_MISMATCH;
740         }
741         break;
742     case SystemTimeOfDayInformation:
743         {
744             SYSTEM_TIMEOFDAY_INFORMATION sti;
745
746             memset(&sti, 0 , sizeof(sti));
747
748             /* liKeSystemTime, liExpTimeZoneBias, uCurrentTimeZoneId */
749             sti.liKeBootTime.QuadPart = server_start_time;
750
751             if (Length <= sizeof(sti))
752             {
753                 len = Length;
754                 if (!SystemInformation) ret = STATUS_ACCESS_VIOLATION;
755                 else memcpy( SystemInformation, &sti, Length);
756             }
757             else ret = STATUS_INFO_LENGTH_MISMATCH;
758         }
759         break;
760     case SystemProcessInformation:
761         {
762             SYSTEM_PROCESS_INFORMATION* spi = (SYSTEM_PROCESS_INFORMATION*)SystemInformation;
763             SYSTEM_PROCESS_INFORMATION* last = NULL;
764             HANDLE hSnap = 0;
765             WCHAR procname[1024];
766             WCHAR* exename;
767             DWORD wlen = 0;
768             DWORD procstructlen = 0;
769
770             SERVER_START_REQ( create_snapshot )
771             {
772                 req->flags      = SNAP_PROCESS | SNAP_THREAD;
773                 req->attributes = 0;
774                 req->pid        = 0;
775                 if (!(ret = wine_server_call( req ))) hSnap = reply->handle;
776             }
777             SERVER_END_REQ;
778             len = 0;
779             while (ret == STATUS_SUCCESS)
780             {
781                 SERVER_START_REQ( next_process )
782                 {
783                     req->handle = hSnap;
784                     req->reset = (len == 0);
785                     wine_server_set_reply( req, procname, sizeof(procname)-sizeof(WCHAR) );
786                     if (!(ret = wine_server_call( req )))
787                     {
788                         /* Make sure procname is 0 terminated */
789                         procname[wine_server_reply_size(reply) / sizeof(WCHAR)] = 0;
790
791                         /* Get only the executable name, not the path */
792                         if ((exename = strrchrW(procname, '\\')) != NULL) exename++;
793                         else exename = procname;
794
795                         wlen = (strlenW(exename) + 1) * sizeof(WCHAR);
796
797                         procstructlen = sizeof(*spi) + wlen + ((reply->threads - 1) * sizeof(SYSTEM_THREAD_INFORMATION));
798
799                         if (Length >= len + procstructlen)
800                         {
801                             /* ftCreationTime, ftUserTime, ftKernelTime;
802                              * vmCounters, ioCounters
803                              */
804  
805                             memset(spi, 0, sizeof(*spi));
806
807                             spi->dwOffset = procstructlen - wlen;
808                             spi->dwThreadCount = reply->threads;
809
810                             /* spi->pszProcessName will be set later on */
811
812                             spi->dwBasePriority = reply->priority;
813                             spi->dwProcessID = (DWORD)reply->pid;
814                             spi->dwParentProcessID = (DWORD)reply->ppid;
815                             spi->dwHandleCount = reply->handles;
816
817                             /* spi->ti will be set later on */
818
819                             len += procstructlen;
820                         }
821                         else ret = STATUS_INFO_LENGTH_MISMATCH;
822                     }
823                 }
824                 SERVER_END_REQ;
825  
826                 if (ret != STATUS_SUCCESS)
827                 {
828                     if (ret == STATUS_NO_MORE_FILES) ret = STATUS_SUCCESS;
829                     break;
830                 }
831                 else /* Length is already checked for */
832                 {
833                     int     i, j;
834
835                     /* set thread info */
836                     i = j = 0;
837                     while (ret == STATUS_SUCCESS)
838                     {
839                         SERVER_START_REQ( next_thread )
840                         {
841                             req->handle = hSnap;
842                             req->reset = (j == 0);
843                             if (!(ret = wine_server_call( req )))
844                             {
845                                 j++;
846                                 if (reply->pid == spi->dwProcessID)
847                                 {
848                                     /* ftKernelTime, ftUserTime, ftCreateTime;
849                                      * dwTickCount, dwStartAddress
850                                      */
851
852                                     memset(&spi->ti[i], 0, sizeof(spi->ti));
853
854                                     spi->ti[i].dwOwningPID = reply->pid;
855                                     spi->ti[i].dwThreadID  = reply->tid;
856                                     spi->ti[i].dwCurrentPriority = reply->base_pri + reply->delta_pri;
857                                     spi->ti[i].dwBasePriority = reply->base_pri;
858                                     i++;
859                                 }
860                             }
861                         }
862                         SERVER_END_REQ;
863                     }
864                     if (ret == STATUS_NO_MORE_FILES) ret = STATUS_SUCCESS;
865
866                     /* now append process name */
867                     spi->ProcessName.Buffer = (WCHAR*)((char*)spi + spi->dwOffset);
868                     spi->ProcessName.Length = wlen - sizeof(WCHAR);
869                     spi->ProcessName.MaximumLength = wlen;
870                     memcpy( spi->ProcessName.Buffer, exename, wlen );
871                     spi->dwOffset += wlen;
872
873                     last = spi;
874                     spi = (SYSTEM_PROCESS_INFORMATION*)((char*)spi + spi->dwOffset);
875                 }
876             }
877             if (ret == STATUS_SUCCESS && last) last->dwOffset = 0;
878             if (hSnap) NtClose(hSnap);
879         }
880         break;
881     case SystemProcessorPerformanceInformation:
882         {
883             SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION sppi;
884
885             memset(&sppi, 0 , sizeof(sppi)); /* FIXME */
886             len = sizeof(sppi);
887
888             if (Length >= len)
889             {
890                 if (!SystemInformation) ret = STATUS_ACCESS_VIOLATION;
891                 else memcpy( SystemInformation, &sppi, len);
892             }
893             else ret = STATUS_INFO_LENGTH_MISMATCH;
894         }
895         break;
896     case SystemModuleInformation:
897         /* FIXME: should be system-wide */
898         if (!SystemInformation) ret = STATUS_ACCESS_VIOLATION;
899         else ret = LdrQueryProcessModuleInformation( SystemInformation, Length, &len );
900         break;
901     case SystemHandleInformation:
902         {
903             SYSTEM_HANDLE_INFORMATION shi;
904
905             memset(&shi, 0, sizeof(shi));
906             len = sizeof(shi);
907
908             if ( Length >= len)
909             {
910                 if (!SystemInformation) ret = STATUS_ACCESS_VIOLATION;
911                 else memcpy( SystemInformation, &shi, len);
912             }
913             else ret = STATUS_INFO_LENGTH_MISMATCH;
914         }
915         break;
916     case SystemCacheInformation:
917         {
918             SYSTEM_CACHE_INFORMATION sci;
919
920             memset(&sci, 0, sizeof(sci)); /* FIXME */
921             len = sizeof(sci);
922
923             if ( Length >= len)
924             {
925                 if (!SystemInformation) ret = STATUS_ACCESS_VIOLATION;
926                 else memcpy( SystemInformation, &sci, len);
927             }
928             else ret = STATUS_INFO_LENGTH_MISMATCH;
929         }
930         break;
931     case SystemInterruptInformation:
932         {
933             SYSTEM_INTERRUPT_INFORMATION sii;
934
935             memset(&sii, 0, sizeof(sii));
936             len = sizeof(sii);
937
938             if ( Length >= len)
939             {
940                 if (!SystemInformation) ret = STATUS_ACCESS_VIOLATION;
941                 else memcpy( SystemInformation, &sii, len);
942             }
943             else ret = STATUS_INFO_LENGTH_MISMATCH;
944         }
945         break;
946     case SystemKernelDebuggerInformation:
947         {
948             SYSTEM_KERNEL_DEBUGGER_INFORMATION skdi;
949
950             skdi.DebuggerEnabled = FALSE;
951             skdi.DebuggerNotPresent = TRUE;
952             len = sizeof(skdi);
953
954             if ( Length >= len)
955             {
956                 if (!SystemInformation) ret = STATUS_ACCESS_VIOLATION;
957                 else memcpy( SystemInformation, &skdi, len);
958             }
959             else ret = STATUS_INFO_LENGTH_MISMATCH;
960         }
961         break;
962     case SystemRegistryQuotaInformation:
963         {
964             /* Something to do with the size of the registry             *
965              * Since we don't have a size limitation, fake it            *
966              * This is almost certainly wrong.                           *
967              * This sets each of the three words in the struct to 32 MB, *
968              * which is enough to make the IE 5 installer happy.         */
969             SYSTEM_REGISTRY_QUOTA_INFORMATION srqi;
970
971             srqi.RegistryQuotaAllowed = 0x2000000;
972             srqi.RegistryQuotaUsed = 0x200000;
973             srqi.Reserved1 = (void*)0x200000;
974             len = sizeof(srqi);
975
976             if ( Length >= len)
977             {
978                 if (!SystemInformation) ret = STATUS_ACCESS_VIOLATION;
979                 else
980                 {
981                     FIXME("SystemRegistryQuotaInformation: faking max registry size of 32 MB\n");
982                     memcpy( SystemInformation, &srqi, len);
983                 }
984             }
985             else ret = STATUS_INFO_LENGTH_MISMATCH;
986         }
987         break;
988     default:
989         FIXME("(0x%08x,%p,0x%08x,%p) stub\n",
990               SystemInformationClass,SystemInformation,Length,ResultLength);
991
992         /* Several Information Classes are not implemented on Windows and return 2 different values 
993          * STATUS_NOT_IMPLEMENTED or STATUS_INVALID_INFO_CLASS
994          * in 95% of the cases it's STATUS_INVALID_INFO_CLASS, so use this as the default
995         */
996         ret = STATUS_INVALID_INFO_CLASS;
997     }
998
999     if (ResultLength) *ResultLength = len;
1000
1001     return ret;
1002 }
1003
1004 /******************************************************************************
1005  * NtSetSystemInformation [NTDLL.@]
1006  * ZwSetSystemInformation [NTDLL.@]
1007  */
1008 NTSTATUS WINAPI NtSetSystemInformation(SYSTEM_INFORMATION_CLASS SystemInformationClass, PVOID SystemInformation, ULONG Length)
1009 {
1010     FIXME("(0x%08x,%p,0x%08x) stub\n",SystemInformationClass,SystemInformation,Length);
1011     return STATUS_SUCCESS;
1012 }
1013
1014 /******************************************************************************
1015  *  NtCreatePagingFile          [NTDLL.@]
1016  *  ZwCreatePagingFile          [NTDLL.@]
1017  */
1018 NTSTATUS WINAPI NtCreatePagingFile(
1019         PUNICODE_STRING PageFileName,
1020         PLARGE_INTEGER MinimumSize,
1021         PLARGE_INTEGER MaximumSize,
1022         PLARGE_INTEGER ActualSize)
1023 {
1024     FIXME("(%p %p %p %p) stub\n", PageFileName, MinimumSize, MaximumSize, ActualSize);
1025     return STATUS_SUCCESS;
1026 }
1027
1028 /******************************************************************************
1029  *  NtDisplayString                             [NTDLL.@]
1030  *
1031  * writes a string to the nt-textmode screen eg. during startup
1032  */
1033 NTSTATUS WINAPI NtDisplayString ( PUNICODE_STRING string )
1034 {
1035     STRING stringA;
1036     NTSTATUS ret;
1037
1038     if (!(ret = RtlUnicodeStringToAnsiString( &stringA, string, TRUE )))
1039     {
1040         MESSAGE( "%.*s", stringA.Length, stringA.Buffer );
1041         RtlFreeAnsiString( &stringA );
1042     }
1043     return ret;
1044 }
1045
1046 /******************************************************************************
1047  *  NtInitiatePowerAction                       [NTDLL.@]
1048  *
1049  */
1050 NTSTATUS WINAPI NtInitiatePowerAction(
1051         IN POWER_ACTION SystemAction,
1052         IN SYSTEM_POWER_STATE MinSystemState,
1053         IN ULONG Flags,
1054         IN BOOLEAN Asynchronous)
1055 {
1056         FIXME("(%d,%d,0x%08x,%d),stub\n",
1057                 SystemAction,MinSystemState,Flags,Asynchronous);
1058         return STATUS_NOT_IMPLEMENTED;
1059 }
1060         
1061
1062 /******************************************************************************
1063  *  NtPowerInformation                          [NTDLL.@]
1064  *
1065  */
1066 NTSTATUS WINAPI NtPowerInformation(
1067         IN POWER_INFORMATION_LEVEL InformationLevel,
1068         IN PVOID lpInputBuffer,
1069         IN ULONG nInputBufferSize,
1070         IN PVOID lpOutputBuffer,
1071         IN ULONG nOutputBufferSize)
1072 {
1073         TRACE("(%d,%p,%d,%p,%d)\n",
1074                 InformationLevel,lpInputBuffer,nInputBufferSize,lpOutputBuffer,nOutputBufferSize);
1075         switch(InformationLevel) {
1076                 case SystemPowerCapabilities: {
1077                         PSYSTEM_POWER_CAPABILITIES PowerCaps = (PSYSTEM_POWER_CAPABILITIES)lpOutputBuffer;
1078                         FIXME("semi-stub: SystemPowerCapabilities\n");
1079                         if (nOutputBufferSize < sizeof(SYSTEM_POWER_CAPABILITIES))
1080                                 return STATUS_BUFFER_TOO_SMALL;
1081                         /* FIXME: These values are based off a native XP desktop, should probably use APM/ACPI to get the 'real' values */
1082                         PowerCaps->PowerButtonPresent = TRUE;
1083                         PowerCaps->SleepButtonPresent = FALSE;
1084                         PowerCaps->LidPresent = FALSE;
1085                         PowerCaps->SystemS1 = TRUE;
1086                         PowerCaps->SystemS2 = FALSE;
1087                         PowerCaps->SystemS3 = FALSE;
1088                         PowerCaps->SystemS4 = TRUE;
1089                         PowerCaps->SystemS5 = TRUE;
1090                         PowerCaps->HiberFilePresent = TRUE;
1091                         PowerCaps->FullWake = TRUE;
1092                         PowerCaps->VideoDimPresent = FALSE;
1093                         PowerCaps->ApmPresent = FALSE;
1094                         PowerCaps->UpsPresent = FALSE;
1095                         PowerCaps->ThermalControl = FALSE;
1096                         PowerCaps->ProcessorThrottle = FALSE;
1097                         PowerCaps->ProcessorMinThrottle = 100;
1098                         PowerCaps->ProcessorMaxThrottle = 100;
1099                         PowerCaps->DiskSpinDown = TRUE;
1100                         PowerCaps->SystemBatteriesPresent = FALSE;
1101                         PowerCaps->BatteriesAreShortTerm = FALSE;
1102                         PowerCaps->BatteryScale[0].Granularity = 0;
1103                         PowerCaps->BatteryScale[0].Capacity = 0;
1104                         PowerCaps->BatteryScale[1].Granularity = 0;
1105                         PowerCaps->BatteryScale[1].Capacity = 0;
1106                         PowerCaps->BatteryScale[2].Granularity = 0;
1107                         PowerCaps->BatteryScale[2].Capacity = 0;
1108                         PowerCaps->AcOnLineWake = PowerSystemUnspecified;
1109                         PowerCaps->SoftLidWake = PowerSystemUnspecified;
1110                         PowerCaps->RtcWake = PowerSystemSleeping1;
1111                         PowerCaps->MinDeviceWakeState = PowerSystemUnspecified;
1112                         PowerCaps->DefaultLowLatencyWake = PowerSystemUnspecified;
1113                         return STATUS_SUCCESS;
1114                 }
1115                 default:
1116                         FIXME("Unimplemented NtPowerInformation action: %d\n", InformationLevel);
1117                         return STATUS_NOT_IMPLEMENTED;
1118         }
1119 }
1120
1121 /******************************************************************************
1122  *  NtShutdownSystem                            [NTDLL.@]
1123  *
1124  */
1125 NTSTATUS WINAPI NtShutdownSystem(SHUTDOWN_ACTION Action)
1126 {
1127     FIXME("%d\n",Action);
1128     return STATUS_SUCCESS;
1129 }
1130
1131 /******************************************************************************
1132  *  NtAllocateLocallyUniqueId (NTDLL.@)
1133  */
1134 NTSTATUS WINAPI NtAllocateLocallyUniqueId(PLUID Luid)
1135 {
1136     NTSTATUS status;
1137
1138     TRACE("%p\n", Luid);
1139
1140     if (!Luid)
1141         return STATUS_ACCESS_VIOLATION;
1142
1143     SERVER_START_REQ( allocate_locally_unique_id )
1144     {
1145         status = wine_server_call( req );
1146         if (!status)
1147         {
1148             Luid->LowPart = reply->luid.low_part;
1149             Luid->HighPart = reply->luid.high_part;
1150         }
1151     }
1152     SERVER_END_REQ;
1153
1154     return status;
1155 }
1156
1157 /******************************************************************************
1158  *        VerSetConditionMask   (NTDLL.@)
1159  */
1160 ULONGLONG WINAPI VerSetConditionMask( ULONGLONG dwlConditionMask, DWORD dwTypeBitMask,
1161                                       BYTE dwConditionMask)
1162 {
1163     if(dwTypeBitMask == 0)
1164         return dwlConditionMask;
1165     dwConditionMask &= 0x07;
1166     if(dwConditionMask == 0)
1167         return dwlConditionMask;
1168
1169     if(dwTypeBitMask & VER_PRODUCT_TYPE)
1170         dwlConditionMask |= dwConditionMask << 7*3;
1171     else if (dwTypeBitMask & VER_SUITENAME)
1172         dwlConditionMask |= dwConditionMask << 6*3;
1173     else if (dwTypeBitMask & VER_SERVICEPACKMAJOR)
1174         dwlConditionMask |= dwConditionMask << 5*3;
1175     else if (dwTypeBitMask & VER_SERVICEPACKMINOR)
1176         dwlConditionMask |= dwConditionMask << 4*3;
1177     else if (dwTypeBitMask & VER_PLATFORMID)
1178         dwlConditionMask |= dwConditionMask << 3*3;
1179     else if (dwTypeBitMask & VER_BUILDNUMBER)
1180         dwlConditionMask |= dwConditionMask << 2*3;
1181     else if (dwTypeBitMask & VER_MAJORVERSION)
1182         dwlConditionMask |= dwConditionMask << 1*3;
1183     else if (dwTypeBitMask & VER_MINORVERSION)
1184         dwlConditionMask |= dwConditionMask << 0*3;
1185     return dwlConditionMask;
1186 }
1187
1188 /******************************************************************************
1189  *  NtAccessCheckAndAuditAlarm   (NTDLL.@)
1190  *  ZwAccessCheckAndAuditAlarm   (NTDLL.@)
1191  */
1192 NTSTATUS WINAPI NtAccessCheckAndAuditAlarm(PUNICODE_STRING SubsystemName, HANDLE HandleId, PUNICODE_STRING ObjectTypeName,
1193                                            PUNICODE_STRING ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor,
1194                                            ACCESS_MASK DesiredAccess, PGENERIC_MAPPING GenericMapping, BOOLEAN ObjectCreation,
1195                                            PACCESS_MASK GrantedAccess, PBOOLEAN AccessStatus, PBOOLEAN GenerateOnClose)
1196 {
1197     FIXME("(%s, %p, %s, %p, 0x%08x, %p, %d, %p, %p, %p), stub\n", debugstr_us(SubsystemName), HandleId,
1198           debugstr_us(ObjectTypeName), SecurityDescriptor, DesiredAccess, GenericMapping, ObjectCreation,
1199           GrantedAccess, AccessStatus, GenerateOnClose);
1200
1201     return STATUS_NOT_IMPLEMENTED;
1202 }