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