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