push 98299ad1251baa2727aab065c47e9d935978c732
[wine/hacks.git] / dlls / ntdll / nt.c
blob7d24731c5287f19872679b2e5321f9910e1af513
1 /*
2 * NT basis DLL
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)
7 * Copyright 1996-1998 Marcus Meissner
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.
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.
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
24 #include <stdarg.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <time.h>
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"
40 #ifdef __APPLE__
41 #include <mach/mach_init.h>
42 #include <mach/mach_host.h>
43 #include <mach/vm_map.h>
44 #endif
46 WINE_DEFAULT_DEBUG_CHANNEL(ntdll);
49 * Token
52 /******************************************************************************
53 * NtDuplicateToken [NTDLL.@]
54 * ZwDuplicateToken [NTDLL.@]
56 NTSTATUS WINAPI NtDuplicateToken(
57 IN HANDLE ExistingToken,
58 IN ACCESS_MASK DesiredAccess,
59 IN POBJECT_ATTRIBUTES ObjectAttributes,
60 IN SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
61 IN TOKEN_TYPE TokenType,
62 OUT PHANDLE NewToken)
64 NTSTATUS status;
66 TRACE("(%p,0x%08x,%p,0x%08x,0x%08x,%p)\n",
67 ExistingToken, DesiredAccess, ObjectAttributes,
68 ImpersonationLevel, TokenType, NewToken);
69 dump_ObjectAttributes(ObjectAttributes);
71 if (ObjectAttributes && ObjectAttributes->SecurityQualityOfService)
73 SECURITY_QUALITY_OF_SERVICE *SecurityQOS = ObjectAttributes->SecurityQualityOfService;
74 TRACE("ObjectAttributes->SecurityQualityOfService = {%d, %d, %d, %s}\n",
75 SecurityQOS->Length, SecurityQOS->ImpersonationLevel,
76 SecurityQOS->ContextTrackingMode,
77 SecurityQOS->EffectiveOnly ? "TRUE" : "FALSE");
78 ImpersonationLevel = SecurityQOS->ImpersonationLevel;
81 SERVER_START_REQ( duplicate_token )
83 req->handle = wine_server_obj_handle( ExistingToken );
84 req->access = DesiredAccess;
85 req->attributes = ObjectAttributes ? ObjectAttributes->Attributes : 0;
86 req->primary = (TokenType == TokenPrimary);
87 req->impersonation_level = ImpersonationLevel;
88 status = wine_server_call( req );
89 if (!status) *NewToken = wine_server_ptr_handle( reply->new_handle );
91 SERVER_END_REQ;
93 return status;
96 /******************************************************************************
97 * NtOpenProcessToken [NTDLL.@]
98 * ZwOpenProcessToken [NTDLL.@]
100 NTSTATUS WINAPI NtOpenProcessToken(
101 HANDLE ProcessHandle,
102 DWORD DesiredAccess,
103 HANDLE *TokenHandle)
105 return NtOpenProcessTokenEx( ProcessHandle, DesiredAccess, 0, TokenHandle );
108 /******************************************************************************
109 * NtOpenProcessTokenEx [NTDLL.@]
110 * ZwOpenProcessTokenEx [NTDLL.@]
112 NTSTATUS WINAPI NtOpenProcessTokenEx( HANDLE process, DWORD access, DWORD attributes,
113 HANDLE *handle )
115 NTSTATUS ret;
117 TRACE("(%p,0x%08x,0x%08x,%p)\n", process, access, attributes, handle);
119 SERVER_START_REQ( open_token )
121 req->handle = wine_server_obj_handle( process );
122 req->access = access;
123 req->attributes = attributes;
124 req->flags = 0;
125 ret = wine_server_call( req );
126 if (!ret) *handle = wine_server_ptr_handle( reply->token );
128 SERVER_END_REQ;
129 return ret;
132 /******************************************************************************
133 * NtOpenThreadToken [NTDLL.@]
134 * ZwOpenThreadToken [NTDLL.@]
136 NTSTATUS WINAPI NtOpenThreadToken(
137 HANDLE ThreadHandle,
138 DWORD DesiredAccess,
139 BOOLEAN OpenAsSelf,
140 HANDLE *TokenHandle)
142 return NtOpenThreadTokenEx( ThreadHandle, DesiredAccess, OpenAsSelf, 0, TokenHandle );
145 /******************************************************************************
146 * NtOpenThreadTokenEx [NTDLL.@]
147 * ZwOpenThreadTokenEx [NTDLL.@]
149 NTSTATUS WINAPI NtOpenThreadTokenEx( HANDLE thread, DWORD access, BOOLEAN as_self, DWORD attributes,
150 HANDLE *handle )
152 NTSTATUS ret;
154 TRACE("(%p,0x%08x,%u,0x%08x,%p)\n", thread, access, as_self, attributes, handle );
156 SERVER_START_REQ( open_token )
158 req->handle = wine_server_obj_handle( thread );
159 req->access = access;
160 req->attributes = attributes;
161 req->flags = OPEN_TOKEN_THREAD;
162 if (as_self) req->flags |= OPEN_TOKEN_AS_SELF;
163 ret = wine_server_call( req );
164 if (!ret) *handle = wine_server_ptr_handle( reply->token );
166 SERVER_END_REQ;
168 return ret;
171 /******************************************************************************
172 * NtAdjustPrivilegesToken [NTDLL.@]
173 * ZwAdjustPrivilegesToken [NTDLL.@]
175 * FIXME: parameters unsafe
177 NTSTATUS WINAPI NtAdjustPrivilegesToken(
178 IN HANDLE TokenHandle,
179 IN BOOLEAN DisableAllPrivileges,
180 IN PTOKEN_PRIVILEGES NewState,
181 IN DWORD BufferLength,
182 OUT PTOKEN_PRIVILEGES PreviousState,
183 OUT PDWORD ReturnLength)
185 NTSTATUS ret;
187 TRACE("(%p,0x%08x,%p,0x%08x,%p,%p)\n",
188 TokenHandle, DisableAllPrivileges, NewState, BufferLength, PreviousState, ReturnLength);
190 SERVER_START_REQ( adjust_token_privileges )
192 req->handle = wine_server_obj_handle( TokenHandle );
193 req->disable_all = DisableAllPrivileges;
194 req->get_modified_state = (PreviousState != NULL);
195 if (!DisableAllPrivileges)
197 wine_server_add_data( req, NewState->Privileges,
198 NewState->PrivilegeCount * sizeof(NewState->Privileges[0]) );
200 if (PreviousState && BufferLength >= FIELD_OFFSET( TOKEN_PRIVILEGES, Privileges ))
201 wine_server_set_reply( req, PreviousState->Privileges,
202 BufferLength - FIELD_OFFSET( TOKEN_PRIVILEGES, Privileges ) );
203 ret = wine_server_call( req );
204 if (PreviousState)
206 *ReturnLength = reply->len + FIELD_OFFSET( TOKEN_PRIVILEGES, Privileges );
207 PreviousState->PrivilegeCount = reply->len / sizeof(LUID_AND_ATTRIBUTES);
210 SERVER_END_REQ;
212 return ret;
215 /******************************************************************************
216 * NtQueryInformationToken [NTDLL.@]
217 * ZwQueryInformationToken [NTDLL.@]
219 * NOTES
220 * Buffer for TokenUser:
221 * 0x00 TOKEN_USER the PSID field points to the SID
222 * 0x08 SID
225 NTSTATUS WINAPI NtQueryInformationToken(
226 HANDLE token,
227 TOKEN_INFORMATION_CLASS tokeninfoclass,
228 PVOID tokeninfo,
229 ULONG tokeninfolength,
230 PULONG retlen )
232 ULONG len;
233 NTSTATUS status = STATUS_SUCCESS;
235 TRACE("(%p,%d,%p,%d,%p)\n",
236 token,tokeninfoclass,tokeninfo,tokeninfolength,retlen);
238 switch (tokeninfoclass)
240 case TokenOwner:
241 len = sizeof(TOKEN_OWNER) + sizeof(SID);
242 break;
243 case TokenPrimaryGroup:
244 len = sizeof(TOKEN_PRIMARY_GROUP);
245 break;
246 case TokenDefaultDacl:
247 len = sizeof(TOKEN_DEFAULT_DACL);
248 break;
249 case TokenSource:
250 len = sizeof(TOKEN_SOURCE);
251 break;
252 case TokenType:
253 len = sizeof (TOKEN_TYPE);
254 break;
255 case TokenImpersonationLevel:
256 len = sizeof(SECURITY_IMPERSONATION_LEVEL);
257 break;
258 case TokenStatistics:
259 len = sizeof(TOKEN_STATISTICS);
260 break;
261 default:
262 len = 0;
265 if (retlen) *retlen = len;
267 if (tokeninfolength < len)
268 return STATUS_BUFFER_TOO_SMALL;
270 switch (tokeninfoclass)
272 case TokenUser:
273 SERVER_START_REQ( get_token_user )
275 TOKEN_USER * tuser = tokeninfo;
276 PSID sid = (PSID) (tuser + 1);
277 DWORD sid_len = tokeninfolength < sizeof(TOKEN_USER) ? 0 : tokeninfolength - sizeof(TOKEN_USER);
279 req->handle = wine_server_obj_handle( token );
280 wine_server_set_reply( req, sid, sid_len );
281 status = wine_server_call( req );
282 if (retlen) *retlen = reply->user_len + sizeof(TOKEN_USER);
283 if (status == STATUS_SUCCESS)
285 tuser->User.Sid = sid;
286 tuser->User.Attributes = 0;
289 SERVER_END_REQ;
290 break;
291 case TokenGroups:
293 char stack_buffer[256];
294 unsigned int server_buf_len = sizeof(stack_buffer);
295 void *buffer = stack_buffer;
296 BOOLEAN need_more_memory;
298 /* we cannot work out the size of the server buffer required for the
299 * input size, since there are two factors affecting how much can be
300 * stored in the buffer - number of groups and lengths of sids */
303 need_more_memory = FALSE;
305 SERVER_START_REQ( get_token_groups )
307 TOKEN_GROUPS *groups = tokeninfo;
309 req->handle = wine_server_obj_handle( token );
310 wine_server_set_reply( req, buffer, server_buf_len );
311 status = wine_server_call( req );
312 if (status == STATUS_BUFFER_TOO_SMALL)
314 if (buffer == stack_buffer)
315 buffer = RtlAllocateHeap(GetProcessHeap(), 0, reply->user_len);
316 else
317 buffer = RtlReAllocateHeap(GetProcessHeap(), 0, buffer, reply->user_len);
318 if (!buffer) return STATUS_NO_MEMORY;
320 server_buf_len = reply->user_len;
321 need_more_memory = TRUE;
323 else if (status == STATUS_SUCCESS)
325 struct token_groups *tg = buffer;
326 unsigned int *attr = (unsigned int *)(tg + 1);
327 ULONG i;
328 const int non_sid_portion = (sizeof(struct token_groups) + tg->count * sizeof(unsigned long));
329 SID *sids = (SID *)((char *)tokeninfo + FIELD_OFFSET( TOKEN_GROUPS, Groups[tg->count] ));
330 ULONG needed_bytes = FIELD_OFFSET( TOKEN_GROUPS, Groups[tg->count] ) +
331 reply->user_len - non_sid_portion;
333 if (retlen) *retlen = needed_bytes;
335 if (needed_bytes <= tokeninfolength)
337 groups->GroupCount = tg->count;
338 memcpy( sids, (char *)buffer + non_sid_portion,
339 reply->user_len - non_sid_portion );
341 for (i = 0; i < tg->count; i++)
343 groups->Groups[i].Attributes = attr[i];
344 groups->Groups[i].Sid = sids;
345 sids = (SID *)((char *)sids + RtlLengthSid(sids));
348 else status = STATUS_BUFFER_TOO_SMALL;
350 else if (retlen) *retlen = 0;
352 SERVER_END_REQ;
353 } while (need_more_memory);
354 if (buffer != stack_buffer) RtlFreeHeap(GetProcessHeap(), 0, buffer);
355 break;
357 case TokenPrimaryGroup:
358 if (tokeninfo)
360 TOKEN_PRIMARY_GROUP *tgroup = tokeninfo;
361 SID_IDENTIFIER_AUTHORITY sid = {SECURITY_NT_AUTHORITY};
362 RtlAllocateAndInitializeSid( &sid,
364 SECURITY_BUILTIN_DOMAIN_RID,
365 DOMAIN_ALIAS_RID_ADMINS,
366 0, 0, 0, 0, 0, 0,
367 &(tgroup->PrimaryGroup));
369 break;
370 case TokenPrivileges:
371 SERVER_START_REQ( get_token_privileges )
373 TOKEN_PRIVILEGES *tpriv = tokeninfo;
374 req->handle = wine_server_obj_handle( token );
375 if (tpriv && tokeninfolength > FIELD_OFFSET( TOKEN_PRIVILEGES, Privileges ))
376 wine_server_set_reply( req, tpriv->Privileges, tokeninfolength - FIELD_OFFSET( TOKEN_PRIVILEGES, Privileges ) );
377 status = wine_server_call( req );
378 if (retlen) *retlen = FIELD_OFFSET( TOKEN_PRIVILEGES, Privileges ) + reply->len;
379 if (tpriv) tpriv->PrivilegeCount = reply->len / sizeof(LUID_AND_ATTRIBUTES);
381 SERVER_END_REQ;
382 break;
383 case TokenOwner:
384 if (tokeninfo)
386 TOKEN_OWNER *owner = tokeninfo;
387 PSID sid = (PSID) (owner + 1);
388 SID_IDENTIFIER_AUTHORITY localSidAuthority = {SECURITY_NT_AUTHORITY};
389 RtlInitializeSid(sid, &localSidAuthority, 1);
390 *(RtlSubAuthoritySid(sid, 0)) = SECURITY_INTERACTIVE_RID;
391 owner->Owner = sid;
393 break;
394 case TokenImpersonationLevel:
395 SERVER_START_REQ( get_token_impersonation_level )
397 SECURITY_IMPERSONATION_LEVEL *impersonation_level = tokeninfo;
398 req->handle = wine_server_obj_handle( token );
399 status = wine_server_call( req );
400 if (status == STATUS_SUCCESS)
401 *impersonation_level = reply->impersonation_level;
403 SERVER_END_REQ;
404 break;
405 case TokenStatistics:
406 SERVER_START_REQ( get_token_statistics )
408 TOKEN_STATISTICS *statistics = tokeninfo;
409 req->handle = wine_server_obj_handle( token );
410 status = wine_server_call( req );
411 if (status == STATUS_SUCCESS)
413 statistics->TokenId.LowPart = reply->token_id.low_part;
414 statistics->TokenId.HighPart = reply->token_id.high_part;
415 statistics->AuthenticationId.LowPart = 0; /* FIXME */
416 statistics->AuthenticationId.HighPart = 0; /* FIXME */
417 statistics->ExpirationTime.u.HighPart = 0x7fffffff;
418 statistics->ExpirationTime.u.LowPart = 0xffffffff;
419 statistics->TokenType = reply->primary ? TokenPrimary : TokenImpersonation;
420 statistics->ImpersonationLevel = reply->impersonation_level;
422 /* kernel information not relevant to us */
423 statistics->DynamicCharged = 0;
424 statistics->DynamicAvailable = 0;
426 statistics->GroupCount = reply->group_count;
427 statistics->PrivilegeCount = reply->privilege_count;
428 statistics->ModifiedId.LowPart = reply->modified_id.low_part;
429 statistics->ModifiedId.HighPart = reply->modified_id.high_part;
432 SERVER_END_REQ;
433 break;
434 case TokenType:
435 SERVER_START_REQ( get_token_statistics )
437 TOKEN_TYPE *token_type = tokeninfo;
438 req->handle = wine_server_obj_handle( token );
439 status = wine_server_call( req );
440 if (status == STATUS_SUCCESS)
441 *token_type = reply->primary ? TokenPrimary : TokenImpersonation;
443 SERVER_END_REQ;
444 break;
445 default:
447 ERR("Unhandled Token Information class %d!\n", tokeninfoclass);
448 return STATUS_NOT_IMPLEMENTED;
451 return status;
454 /******************************************************************************
455 * NtSetInformationToken [NTDLL.@]
456 * ZwSetInformationToken [NTDLL.@]
458 NTSTATUS WINAPI NtSetInformationToken(
459 HANDLE TokenHandle,
460 TOKEN_INFORMATION_CLASS TokenInformationClass,
461 PVOID TokenInformation,
462 ULONG TokenInformationLength)
464 FIXME("%p %d %p %u\n", TokenHandle, TokenInformationClass,
465 TokenInformation, TokenInformationLength);
466 return STATUS_NOT_IMPLEMENTED;
469 /******************************************************************************
470 * NtAdjustGroupsToken [NTDLL.@]
471 * ZwAdjustGroupsToken [NTDLL.@]
473 NTSTATUS WINAPI NtAdjustGroupsToken(
474 HANDLE TokenHandle,
475 BOOLEAN ResetToDefault,
476 PTOKEN_GROUPS NewState,
477 ULONG BufferLength,
478 PTOKEN_GROUPS PreviousState,
479 PULONG ReturnLength)
481 FIXME("%p %d %p %u %p %p\n", TokenHandle, ResetToDefault,
482 NewState, BufferLength, PreviousState, ReturnLength);
483 return STATUS_NOT_IMPLEMENTED;
486 /******************************************************************************
487 * NtPrivilegeCheck [NTDLL.@]
488 * ZwPrivilegeCheck [NTDLL.@]
490 NTSTATUS WINAPI NtPrivilegeCheck(
491 HANDLE ClientToken,
492 PPRIVILEGE_SET RequiredPrivileges,
493 PBOOLEAN Result)
495 NTSTATUS status;
496 SERVER_START_REQ( check_token_privileges )
498 req->handle = wine_server_obj_handle( ClientToken );
499 req->all_required = ((RequiredPrivileges->Control & PRIVILEGE_SET_ALL_NECESSARY) ? TRUE : FALSE);
500 wine_server_add_data( req, RequiredPrivileges->Privilege,
501 RequiredPrivileges->PrivilegeCount * sizeof(RequiredPrivileges->Privilege[0]) );
502 wine_server_set_reply( req, RequiredPrivileges->Privilege,
503 RequiredPrivileges->PrivilegeCount * sizeof(RequiredPrivileges->Privilege[0]) );
505 status = wine_server_call( req );
507 if (status == STATUS_SUCCESS)
508 *Result = (reply->has_privileges ? TRUE : FALSE);
510 SERVER_END_REQ;
511 return status;
515 * Section
518 /******************************************************************************
519 * NtQuerySection [NTDLL.@]
521 NTSTATUS WINAPI NtQuerySection(
522 IN HANDLE SectionHandle,
523 IN SECTION_INFORMATION_CLASS SectionInformationClass,
524 OUT PVOID SectionInformation,
525 IN ULONG Length,
526 OUT PULONG ResultLength)
528 FIXME("(%p,%d,%p,0x%08x,%p) stub!\n",
529 SectionHandle,SectionInformationClass,SectionInformation,Length,ResultLength);
530 return 0;
534 * ports
537 /******************************************************************************
538 * NtCreatePort [NTDLL.@]
539 * ZwCreatePort [NTDLL.@]
541 NTSTATUS WINAPI NtCreatePort(PHANDLE PortHandle,POBJECT_ATTRIBUTES ObjectAttributes,
542 ULONG MaxConnectInfoLength,ULONG MaxDataLength,PULONG reserved)
544 FIXME("(%p,%p,%u,%u,%p),stub!\n",PortHandle,ObjectAttributes,
545 MaxConnectInfoLength,MaxDataLength,reserved);
546 return STATUS_NOT_IMPLEMENTED;
549 /******************************************************************************
550 * NtConnectPort [NTDLL.@]
551 * ZwConnectPort [NTDLL.@]
553 NTSTATUS WINAPI NtConnectPort(
554 PHANDLE PortHandle,
555 PUNICODE_STRING PortName,
556 PSECURITY_QUALITY_OF_SERVICE SecurityQos,
557 PLPC_SECTION_WRITE WriteSection,
558 PLPC_SECTION_READ ReadSection,
559 PULONG MaximumMessageLength,
560 PVOID ConnectInfo,
561 PULONG pConnectInfoLength)
563 FIXME("(%p,%s,%p,%p,%p,%p,%p,%p),stub!\n",
564 PortHandle,debugstr_w(PortName->Buffer),SecurityQos,
565 WriteSection,ReadSection,MaximumMessageLength,ConnectInfo,
566 pConnectInfoLength);
567 if (ConnectInfo && pConnectInfoLength)
568 TRACE("\tMessage = %s\n",debugstr_an(ConnectInfo,*pConnectInfoLength));
569 return STATUS_NOT_IMPLEMENTED;
572 /******************************************************************************
573 * NtListenPort [NTDLL.@]
574 * ZwListenPort [NTDLL.@]
576 NTSTATUS WINAPI NtListenPort(HANDLE PortHandle,PLPC_MESSAGE pLpcMessage)
578 FIXME("(%p,%p),stub!\n",PortHandle,pLpcMessage);
579 return STATUS_NOT_IMPLEMENTED;
582 /******************************************************************************
583 * NtAcceptConnectPort [NTDLL.@]
584 * ZwAcceptConnectPort [NTDLL.@]
586 NTSTATUS WINAPI NtAcceptConnectPort(
587 PHANDLE PortHandle,
588 ULONG PortIdentifier,
589 PLPC_MESSAGE pLpcMessage,
590 BOOLEAN Accept,
591 PLPC_SECTION_WRITE WriteSection,
592 PLPC_SECTION_READ ReadSection)
594 FIXME("(%p,%u,%p,%d,%p,%p),stub!\n",
595 PortHandle,PortIdentifier,pLpcMessage,Accept,WriteSection,ReadSection);
596 return STATUS_NOT_IMPLEMENTED;
599 /******************************************************************************
600 * NtCompleteConnectPort [NTDLL.@]
601 * ZwCompleteConnectPort [NTDLL.@]
603 NTSTATUS WINAPI NtCompleteConnectPort(HANDLE PortHandle)
605 FIXME("(%p),stub!\n",PortHandle);
606 return STATUS_NOT_IMPLEMENTED;
609 /******************************************************************************
610 * NtRegisterThreadTerminatePort [NTDLL.@]
611 * ZwRegisterThreadTerminatePort [NTDLL.@]
613 NTSTATUS WINAPI NtRegisterThreadTerminatePort(HANDLE PortHandle)
615 FIXME("(%p),stub!\n",PortHandle);
616 return STATUS_NOT_IMPLEMENTED;
619 /******************************************************************************
620 * NtRequestWaitReplyPort [NTDLL.@]
621 * ZwRequestWaitReplyPort [NTDLL.@]
623 NTSTATUS WINAPI NtRequestWaitReplyPort(
624 HANDLE PortHandle,
625 PLPC_MESSAGE pLpcMessageIn,
626 PLPC_MESSAGE pLpcMessageOut)
628 FIXME("(%p,%p,%p),stub!\n",PortHandle,pLpcMessageIn,pLpcMessageOut);
629 if(pLpcMessageIn)
631 TRACE("Message to send:\n");
632 TRACE("\tDataSize = %u\n",pLpcMessageIn->DataSize);
633 TRACE("\tMessageSize = %u\n",pLpcMessageIn->MessageSize);
634 TRACE("\tMessageType = %u\n",pLpcMessageIn->MessageType);
635 TRACE("\tVirtualRangesOffset = %u\n",pLpcMessageIn->VirtualRangesOffset);
636 TRACE("\tClientId.UniqueProcess = %p\n",pLpcMessageIn->ClientId.UniqueProcess);
637 TRACE("\tClientId.UniqueThread = %p\n",pLpcMessageIn->ClientId.UniqueThread);
638 TRACE("\tMessageId = %u\n",pLpcMessageIn->MessageId);
639 TRACE("\tSectionSize = %u\n",pLpcMessageIn->SectionSize);
640 TRACE("\tData = %s\n",
641 debugstr_an((const char*)pLpcMessageIn->Data,pLpcMessageIn->DataSize));
643 return STATUS_NOT_IMPLEMENTED;
646 /******************************************************************************
647 * NtReplyWaitReceivePort [NTDLL.@]
648 * ZwReplyWaitReceivePort [NTDLL.@]
650 NTSTATUS WINAPI NtReplyWaitReceivePort(
651 HANDLE PortHandle,
652 PULONG PortIdentifier,
653 PLPC_MESSAGE ReplyMessage,
654 PLPC_MESSAGE Message)
656 FIXME("(%p,%p,%p,%p),stub!\n",PortHandle,PortIdentifier,ReplyMessage,Message);
657 return STATUS_NOT_IMPLEMENTED;
661 * Misc
664 /******************************************************************************
665 * NtSetIntervalProfile [NTDLL.@]
666 * ZwSetIntervalProfile [NTDLL.@]
668 NTSTATUS WINAPI NtSetIntervalProfile(
669 ULONG Interval,
670 KPROFILE_SOURCE Source)
672 FIXME("%u,%d\n", Interval, Source);
673 return STATUS_SUCCESS;
676 /******************************************************************************
677 * NtQuerySystemInformation [NTDLL.@]
678 * ZwQuerySystemInformation [NTDLL.@]
680 * ARGUMENTS:
681 * SystemInformationClass Index to a certain information structure
682 * SystemTimeAdjustmentInformation SYSTEM_TIME_ADJUSTMENT
683 * SystemCacheInformation SYSTEM_CACHE_INFORMATION
684 * SystemConfigurationInformation CONFIGURATION_INFORMATION
685 * observed (class/len):
686 * 0x0/0x2c
687 * 0x12/0x18
688 * 0x2/0x138
689 * 0x8/0x600
690 * 0x25/0xc
691 * SystemInformation caller supplies storage for the information structure
692 * Length size of the structure
693 * ResultLength Data written
695 NTSTATUS WINAPI NtQuerySystemInformation(
696 IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
697 OUT PVOID SystemInformation,
698 IN ULONG Length,
699 OUT PULONG ResultLength)
701 NTSTATUS ret = STATUS_SUCCESS;
702 ULONG len = 0;
704 TRACE("(0x%08x,%p,0x%08x,%p)\n",
705 SystemInformationClass,SystemInformation,Length,ResultLength);
707 switch (SystemInformationClass)
709 case SystemBasicInformation:
711 SYSTEM_BASIC_INFORMATION sbi;
713 virtual_get_system_info( &sbi );
714 len = sizeof(sbi);
716 if ( Length == len)
718 if (!SystemInformation) ret = STATUS_ACCESS_VIOLATION;
719 else memcpy( SystemInformation, &sbi, len);
721 else ret = STATUS_INFO_LENGTH_MISMATCH;
723 break;
724 case SystemCpuInformation:
726 SYSTEM_CPU_INFORMATION sci;
728 /* FIXME: move some code from kernel/cpu.c to process this */
729 sci.Architecture = PROCESSOR_ARCHITECTURE_INTEL;
730 sci.Level = 6; /* 686, aka Pentium II+ */
731 sci.Revision = 0;
732 sci.Reserved = 0;
733 sci.FeatureSet = 0x1fff;
734 len = sizeof(sci);
736 if ( Length >= len)
738 if (!SystemInformation) ret = STATUS_ACCESS_VIOLATION;
739 else memcpy( SystemInformation, &sci, len);
741 else ret = STATUS_INFO_LENGTH_MISMATCH;
743 break;
744 case SystemPerformanceInformation:
746 SYSTEM_PERFORMANCE_INFORMATION spi;
747 static BOOL fixme_written = FALSE;
749 memset(&spi, 0 , sizeof(spi));
750 len = sizeof(spi);
752 if (Length >= len)
754 if (!SystemInformation) ret = STATUS_ACCESS_VIOLATION;
755 else memcpy( SystemInformation, &spi, len);
757 else ret = STATUS_INFO_LENGTH_MISMATCH;
758 if(!fixme_written) {
759 FIXME("info_class SYSTEM_PERFORMANCE_INFORMATION\n");
760 fixme_written = TRUE;
763 break;
764 case SystemTimeOfDayInformation:
766 SYSTEM_TIMEOFDAY_INFORMATION sti;
768 memset(&sti, 0 , sizeof(sti));
770 /* liKeSystemTime, liExpTimeZoneBias, uCurrentTimeZoneId */
771 sti.liKeBootTime.QuadPart = server_start_time;
773 if (Length <= sizeof(sti))
775 len = Length;
776 if (!SystemInformation) ret = STATUS_ACCESS_VIOLATION;
777 else memcpy( SystemInformation, &sti, Length);
779 else ret = STATUS_INFO_LENGTH_MISMATCH;
781 break;
782 case SystemProcessInformation:
784 SYSTEM_PROCESS_INFORMATION* spi = (SYSTEM_PROCESS_INFORMATION*)SystemInformation;
785 SYSTEM_PROCESS_INFORMATION* last = NULL;
786 HANDLE hSnap = 0;
787 WCHAR procname[1024];
788 WCHAR* exename;
789 DWORD wlen = 0;
790 DWORD procstructlen = 0;
792 SERVER_START_REQ( create_snapshot )
794 req->flags = SNAP_PROCESS | SNAP_THREAD;
795 req->attributes = 0;
796 if (!(ret = wine_server_call( req )))
797 hSnap = wine_server_ptr_handle( reply->handle );
799 SERVER_END_REQ;
800 len = 0;
801 while (ret == STATUS_SUCCESS)
803 SERVER_START_REQ( next_process )
805 req->handle = wine_server_obj_handle( hSnap );
806 req->reset = (len == 0);
807 wine_server_set_reply( req, procname, sizeof(procname)-sizeof(WCHAR) );
808 if (!(ret = wine_server_call( req )))
810 /* Make sure procname is 0 terminated */
811 procname[wine_server_reply_size(reply) / sizeof(WCHAR)] = 0;
813 /* Get only the executable name, not the path */
814 if ((exename = strrchrW(procname, '\\')) != NULL) exename++;
815 else exename = procname;
817 wlen = (strlenW(exename) + 1) * sizeof(WCHAR);
819 procstructlen = sizeof(*spi) + wlen + ((reply->threads - 1) * sizeof(SYSTEM_THREAD_INFORMATION));
821 if (Length >= len + procstructlen)
823 /* ftCreationTime, ftUserTime, ftKernelTime;
824 * vmCounters, ioCounters
827 memset(spi, 0, sizeof(*spi));
829 spi->NextEntryOffset = procstructlen - wlen;
830 spi->dwThreadCount = reply->threads;
832 /* spi->pszProcessName will be set later on */
834 spi->dwBasePriority = reply->priority;
835 spi->UniqueProcessId = UlongToHandle(reply->pid);
836 spi->ParentProcessId = UlongToHandle(reply->ppid);
837 spi->HandleCount = reply->handles;
839 /* spi->ti will be set later on */
841 len += procstructlen;
843 else ret = STATUS_INFO_LENGTH_MISMATCH;
846 SERVER_END_REQ;
848 if (ret != STATUS_SUCCESS)
850 if (ret == STATUS_NO_MORE_FILES) ret = STATUS_SUCCESS;
851 break;
853 else /* Length is already checked for */
855 int i, j;
857 /* set thread info */
858 i = j = 0;
859 while (ret == STATUS_SUCCESS)
861 SERVER_START_REQ( next_thread )
863 req->handle = wine_server_obj_handle( hSnap );
864 req->reset = (j == 0);
865 if (!(ret = wine_server_call( req )))
867 j++;
868 if (UlongToHandle(reply->pid) == spi->UniqueProcessId)
870 /* ftKernelTime, ftUserTime, ftCreateTime;
871 * dwTickCount, dwStartAddress
874 memset(&spi->ti[i], 0, sizeof(spi->ti));
876 spi->ti[i].CreateTime.QuadPart = 0xdeadbeef;
877 spi->ti[i].ClientId.UniqueProcess = UlongToHandle(reply->pid);
878 spi->ti[i].ClientId.UniqueThread = UlongToHandle(reply->tid);
879 spi->ti[i].dwCurrentPriority = reply->base_pri + reply->delta_pri;
880 spi->ti[i].dwBasePriority = reply->base_pri;
881 i++;
885 SERVER_END_REQ;
887 if (ret == STATUS_NO_MORE_FILES) ret = STATUS_SUCCESS;
889 /* now append process name */
890 spi->ProcessName.Buffer = (WCHAR*)((char*)spi + spi->NextEntryOffset);
891 spi->ProcessName.Length = wlen - sizeof(WCHAR);
892 spi->ProcessName.MaximumLength = wlen;
893 memcpy( spi->ProcessName.Buffer, exename, wlen );
894 spi->NextEntryOffset += wlen;
896 last = spi;
897 spi = (SYSTEM_PROCESS_INFORMATION*)((char*)spi + spi->NextEntryOffset);
900 if (ret == STATUS_SUCCESS && last) last->NextEntryOffset = 0;
901 if (hSnap) NtClose(hSnap);
903 break;
904 case SystemProcessorPerformanceInformation:
906 SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION *sppi = NULL;
907 unsigned int cpus = 0;
908 int out_cpus = Length / sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION);
910 if (out_cpus == 0)
912 len = 0;
913 ret = STATUS_INFO_LENGTH_MISMATCH;
914 break;
916 else
917 #ifdef __APPLE__
919 processor_cpu_load_info_data_t *pinfo;
920 mach_msg_type_number_t info_count;
922 if (host_processor_info (mach_host_self (),
923 PROCESSOR_CPU_LOAD_INFO,
924 &cpus,
925 (processor_info_array_t*)&pinfo,
926 &info_count) == 0)
928 int i;
929 cpus = min(cpus,out_cpus);
930 len = sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION) * cpus;
931 sppi = RtlAllocateHeap(GetProcessHeap(), 0,len);
932 for (i = 0; i < cpus; i++)
934 sppi[i].liIdleTime.QuadPart = pinfo[i].cpu_ticks[CPU_STATE_IDLE];
935 sppi[i].liKernelTime.QuadPart = pinfo[i].cpu_ticks[CPU_STATE_SYSTEM];
936 sppi[i].liUserTime.QuadPart = pinfo[i].cpu_ticks[CPU_STATE_USER];
938 vm_deallocate (mach_task_self (), (vm_address_t) pinfo, info_count * sizeof(natural_t));
941 #else
943 FILE *cpuinfo = fopen("/proc/stat","r");
944 if (cpuinfo)
946 unsigned usr,nice,sys;
947 unsigned long idle;
948 int count;
949 char name[10];
950 char line[255];
952 /* first line is combined usage */
953 if (fgets(line,255,cpuinfo))
954 count = sscanf(line,"%s %u %u %u %lu",name, &usr, &nice,
955 &sys, &idle);
956 else
957 count = 0;
958 /* we set this up in the for older non-smp enabled kernels */
959 if (count == 5 && strcmp(name,"cpu")==0)
961 sppi = RtlAllocateHeap(GetProcessHeap(), 0,
962 sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION));
963 sppi->liIdleTime.QuadPart = idle;
964 sppi->liKernelTime.QuadPart = sys;
965 sppi->liUserTime.QuadPart = usr;
966 cpus = 1;
967 len = sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION);
972 if (fgets(line,255,cpuinfo))
973 count = sscanf(line,"%s %u %u %u %lu",name, &usr,
974 &nice, &sys, &idle);
975 else
976 count = 0;
977 if (count == 5 && strncmp(name,"cpu",3)==0)
979 out_cpus --;
980 if (name[3]=='0') /* first cpu */
982 sppi->liIdleTime.QuadPart = idle;
983 sppi->liKernelTime.QuadPart = sys;
984 sppi->liUserTime.QuadPart = usr;
986 else /* new cpu */
988 len = sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION) * (cpus+1);
989 sppi = RtlReAllocateHeap(GetProcessHeap(), 0, sppi, len);
990 sppi[cpus].liIdleTime.QuadPart = idle;
991 sppi[cpus].liKernelTime.QuadPart = sys;
992 sppi[cpus].liUserTime.QuadPart = usr;
993 cpus++;
996 else
997 break;
998 } while (out_cpus > 0);
999 fclose(cpuinfo);
1002 #endif
1004 if (cpus == 0)
1006 static int i = 1;
1008 sppi = RtlAllocateHeap(GetProcessHeap(),0,sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION));
1010 memset(sppi, 0 , sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION));
1011 FIXME("stub info_class SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION\n");
1013 /* many programs expect these values to change so fake change */
1014 len = sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION);
1015 sppi->liKernelTime.QuadPart = 1 * i;
1016 sppi->liUserTime.QuadPart = 2 * i;
1017 sppi->liIdleTime.QuadPart = 3 * i;
1018 i++;
1021 if (Length >= len)
1023 if (!SystemInformation) ret = STATUS_ACCESS_VIOLATION;
1024 else memcpy( SystemInformation, sppi, len);
1026 else ret = STATUS_INFO_LENGTH_MISMATCH;
1028 RtlFreeHeap(GetProcessHeap(),0,sppi);
1030 break;
1031 case SystemModuleInformation:
1032 /* FIXME: should be system-wide */
1033 if (!SystemInformation) ret = STATUS_ACCESS_VIOLATION;
1034 else ret = LdrQueryProcessModuleInformation( SystemInformation, Length, &len );
1035 break;
1036 case SystemHandleInformation:
1038 SYSTEM_HANDLE_INFORMATION shi;
1040 memset(&shi, 0, sizeof(shi));
1041 len = sizeof(shi);
1043 if ( Length >= len)
1045 if (!SystemInformation) ret = STATUS_ACCESS_VIOLATION;
1046 else memcpy( SystemInformation, &shi, len);
1048 else ret = STATUS_INFO_LENGTH_MISMATCH;
1049 FIXME("info_class SYSTEM_HANDLE_INFORMATION\n");
1051 break;
1052 case SystemCacheInformation:
1054 SYSTEM_CACHE_INFORMATION sci;
1056 memset(&sci, 0, sizeof(sci)); /* FIXME */
1057 len = sizeof(sci);
1059 if ( Length >= len)
1061 if (!SystemInformation) ret = STATUS_ACCESS_VIOLATION;
1062 else memcpy( SystemInformation, &sci, len);
1064 else ret = STATUS_INFO_LENGTH_MISMATCH;
1065 FIXME("info_class SYSTEM_CACHE_INFORMATION\n");
1067 break;
1068 case SystemInterruptInformation:
1070 SYSTEM_INTERRUPT_INFORMATION sii;
1072 memset(&sii, 0, sizeof(sii));
1073 len = sizeof(sii);
1075 if ( Length >= len)
1077 if (!SystemInformation) ret = STATUS_ACCESS_VIOLATION;
1078 else memcpy( SystemInformation, &sii, len);
1080 else ret = STATUS_INFO_LENGTH_MISMATCH;
1081 FIXME("info_class SYSTEM_INTERRUPT_INFORMATION\n");
1083 break;
1084 case SystemKernelDebuggerInformation:
1086 SYSTEM_KERNEL_DEBUGGER_INFORMATION skdi;
1088 skdi.DebuggerEnabled = FALSE;
1089 skdi.DebuggerNotPresent = TRUE;
1090 len = sizeof(skdi);
1092 if ( Length >= len)
1094 if (!SystemInformation) ret = STATUS_ACCESS_VIOLATION;
1095 else memcpy( SystemInformation, &skdi, len);
1097 else ret = STATUS_INFO_LENGTH_MISMATCH;
1099 break;
1100 case SystemRegistryQuotaInformation:
1102 /* Something to do with the size of the registry *
1103 * Since we don't have a size limitation, fake it *
1104 * This is almost certainly wrong. *
1105 * This sets each of the three words in the struct to 32 MB, *
1106 * which is enough to make the IE 5 installer happy. */
1107 SYSTEM_REGISTRY_QUOTA_INFORMATION srqi;
1109 srqi.RegistryQuotaAllowed = 0x2000000;
1110 srqi.RegistryQuotaUsed = 0x200000;
1111 srqi.Reserved1 = (void*)0x200000;
1112 len = sizeof(srqi);
1114 if ( Length >= len)
1116 if (!SystemInformation) ret = STATUS_ACCESS_VIOLATION;
1117 else
1119 FIXME("SystemRegistryQuotaInformation: faking max registry size of 32 MB\n");
1120 memcpy( SystemInformation, &srqi, len);
1123 else ret = STATUS_INFO_LENGTH_MISMATCH;
1125 break;
1126 default:
1127 FIXME("(0x%08x,%p,0x%08x,%p) stub\n",
1128 SystemInformationClass,SystemInformation,Length,ResultLength);
1130 /* Several Information Classes are not implemented on Windows and return 2 different values
1131 * STATUS_NOT_IMPLEMENTED or STATUS_INVALID_INFO_CLASS
1132 * in 95% of the cases it's STATUS_INVALID_INFO_CLASS, so use this as the default
1134 ret = STATUS_INVALID_INFO_CLASS;
1137 if (ResultLength) *ResultLength = len;
1139 return ret;
1142 /******************************************************************************
1143 * NtSetSystemInformation [NTDLL.@]
1144 * ZwSetSystemInformation [NTDLL.@]
1146 NTSTATUS WINAPI NtSetSystemInformation(SYSTEM_INFORMATION_CLASS SystemInformationClass, PVOID SystemInformation, ULONG Length)
1148 FIXME("(0x%08x,%p,0x%08x) stub\n",SystemInformationClass,SystemInformation,Length);
1149 return STATUS_SUCCESS;
1152 /******************************************************************************
1153 * NtCreatePagingFile [NTDLL.@]
1154 * ZwCreatePagingFile [NTDLL.@]
1156 NTSTATUS WINAPI NtCreatePagingFile(
1157 PUNICODE_STRING PageFileName,
1158 PLARGE_INTEGER MinimumSize,
1159 PLARGE_INTEGER MaximumSize,
1160 PLARGE_INTEGER ActualSize)
1162 FIXME("(%p %p %p %p) stub\n", PageFileName, MinimumSize, MaximumSize, ActualSize);
1163 return STATUS_SUCCESS;
1166 /******************************************************************************
1167 * NtDisplayString [NTDLL.@]
1169 * writes a string to the nt-textmode screen eg. during startup
1171 NTSTATUS WINAPI NtDisplayString ( PUNICODE_STRING string )
1173 STRING stringA;
1174 NTSTATUS ret;
1176 if (!(ret = RtlUnicodeStringToAnsiString( &stringA, string, TRUE )))
1178 MESSAGE( "%.*s", stringA.Length, stringA.Buffer );
1179 RtlFreeAnsiString( &stringA );
1181 return ret;
1184 /******************************************************************************
1185 * NtInitiatePowerAction [NTDLL.@]
1188 NTSTATUS WINAPI NtInitiatePowerAction(
1189 IN POWER_ACTION SystemAction,
1190 IN SYSTEM_POWER_STATE MinSystemState,
1191 IN ULONG Flags,
1192 IN BOOLEAN Asynchronous)
1194 FIXME("(%d,%d,0x%08x,%d),stub\n",
1195 SystemAction,MinSystemState,Flags,Asynchronous);
1196 return STATUS_NOT_IMPLEMENTED;
1200 /******************************************************************************
1201 * NtPowerInformation [NTDLL.@]
1204 NTSTATUS WINAPI NtPowerInformation(
1205 IN POWER_INFORMATION_LEVEL InformationLevel,
1206 IN PVOID lpInputBuffer,
1207 IN ULONG nInputBufferSize,
1208 IN PVOID lpOutputBuffer,
1209 IN ULONG nOutputBufferSize)
1211 TRACE("(%d,%p,%d,%p,%d)\n",
1212 InformationLevel,lpInputBuffer,nInputBufferSize,lpOutputBuffer,nOutputBufferSize);
1213 switch(InformationLevel) {
1214 case SystemPowerCapabilities: {
1215 PSYSTEM_POWER_CAPABILITIES PowerCaps = (PSYSTEM_POWER_CAPABILITIES)lpOutputBuffer;
1216 FIXME("semi-stub: SystemPowerCapabilities\n");
1217 if (nOutputBufferSize < sizeof(SYSTEM_POWER_CAPABILITIES))
1218 return STATUS_BUFFER_TOO_SMALL;
1219 /* FIXME: These values are based off a native XP desktop, should probably use APM/ACPI to get the 'real' values */
1220 PowerCaps->PowerButtonPresent = TRUE;
1221 PowerCaps->SleepButtonPresent = FALSE;
1222 PowerCaps->LidPresent = FALSE;
1223 PowerCaps->SystemS1 = TRUE;
1224 PowerCaps->SystemS2 = FALSE;
1225 PowerCaps->SystemS3 = FALSE;
1226 PowerCaps->SystemS4 = TRUE;
1227 PowerCaps->SystemS5 = TRUE;
1228 PowerCaps->HiberFilePresent = TRUE;
1229 PowerCaps->FullWake = TRUE;
1230 PowerCaps->VideoDimPresent = FALSE;
1231 PowerCaps->ApmPresent = FALSE;
1232 PowerCaps->UpsPresent = FALSE;
1233 PowerCaps->ThermalControl = FALSE;
1234 PowerCaps->ProcessorThrottle = FALSE;
1235 PowerCaps->ProcessorMinThrottle = 100;
1236 PowerCaps->ProcessorMaxThrottle = 100;
1237 PowerCaps->DiskSpinDown = TRUE;
1238 PowerCaps->SystemBatteriesPresent = FALSE;
1239 PowerCaps->BatteriesAreShortTerm = FALSE;
1240 PowerCaps->BatteryScale[0].Granularity = 0;
1241 PowerCaps->BatteryScale[0].Capacity = 0;
1242 PowerCaps->BatteryScale[1].Granularity = 0;
1243 PowerCaps->BatteryScale[1].Capacity = 0;
1244 PowerCaps->BatteryScale[2].Granularity = 0;
1245 PowerCaps->BatteryScale[2].Capacity = 0;
1246 PowerCaps->AcOnLineWake = PowerSystemUnspecified;
1247 PowerCaps->SoftLidWake = PowerSystemUnspecified;
1248 PowerCaps->RtcWake = PowerSystemSleeping1;
1249 PowerCaps->MinDeviceWakeState = PowerSystemUnspecified;
1250 PowerCaps->DefaultLowLatencyWake = PowerSystemUnspecified;
1251 return STATUS_SUCCESS;
1253 default:
1254 FIXME("Unimplemented NtPowerInformation action: %d\n", InformationLevel);
1255 return STATUS_NOT_IMPLEMENTED;
1259 /******************************************************************************
1260 * NtShutdownSystem [NTDLL.@]
1263 NTSTATUS WINAPI NtShutdownSystem(SHUTDOWN_ACTION Action)
1265 FIXME("%d\n",Action);
1266 return STATUS_SUCCESS;
1269 /******************************************************************************
1270 * NtAllocateLocallyUniqueId (NTDLL.@)
1272 NTSTATUS WINAPI NtAllocateLocallyUniqueId(PLUID Luid)
1274 NTSTATUS status;
1276 TRACE("%p\n", Luid);
1278 if (!Luid)
1279 return STATUS_ACCESS_VIOLATION;
1281 SERVER_START_REQ( allocate_locally_unique_id )
1283 status = wine_server_call( req );
1284 if (!status)
1286 Luid->LowPart = reply->luid.low_part;
1287 Luid->HighPart = reply->luid.high_part;
1290 SERVER_END_REQ;
1292 return status;
1295 /******************************************************************************
1296 * VerSetConditionMask (NTDLL.@)
1298 ULONGLONG WINAPI VerSetConditionMask( ULONGLONG dwlConditionMask, DWORD dwTypeBitMask,
1299 BYTE dwConditionMask)
1301 if(dwTypeBitMask == 0)
1302 return dwlConditionMask;
1303 dwConditionMask &= 0x07;
1304 if(dwConditionMask == 0)
1305 return dwlConditionMask;
1307 if(dwTypeBitMask & VER_PRODUCT_TYPE)
1308 dwlConditionMask |= dwConditionMask << 7*3;
1309 else if (dwTypeBitMask & VER_SUITENAME)
1310 dwlConditionMask |= dwConditionMask << 6*3;
1311 else if (dwTypeBitMask & VER_SERVICEPACKMAJOR)
1312 dwlConditionMask |= dwConditionMask << 5*3;
1313 else if (dwTypeBitMask & VER_SERVICEPACKMINOR)
1314 dwlConditionMask |= dwConditionMask << 4*3;
1315 else if (dwTypeBitMask & VER_PLATFORMID)
1316 dwlConditionMask |= dwConditionMask << 3*3;
1317 else if (dwTypeBitMask & VER_BUILDNUMBER)
1318 dwlConditionMask |= dwConditionMask << 2*3;
1319 else if (dwTypeBitMask & VER_MAJORVERSION)
1320 dwlConditionMask |= dwConditionMask << 1*3;
1321 else if (dwTypeBitMask & VER_MINORVERSION)
1322 dwlConditionMask |= dwConditionMask << 0*3;
1323 return dwlConditionMask;
1326 /******************************************************************************
1327 * NtAccessCheckAndAuditAlarm (NTDLL.@)
1328 * ZwAccessCheckAndAuditAlarm (NTDLL.@)
1330 NTSTATUS WINAPI NtAccessCheckAndAuditAlarm(PUNICODE_STRING SubsystemName, HANDLE HandleId, PUNICODE_STRING ObjectTypeName,
1331 PUNICODE_STRING ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor,
1332 ACCESS_MASK DesiredAccess, PGENERIC_MAPPING GenericMapping, BOOLEAN ObjectCreation,
1333 PACCESS_MASK GrantedAccess, PBOOLEAN AccessStatus, PBOOLEAN GenerateOnClose)
1335 FIXME("(%s, %p, %s, %p, 0x%08x, %p, %d, %p, %p, %p), stub\n", debugstr_us(SubsystemName), HandleId,
1336 debugstr_us(ObjectTypeName), SecurityDescriptor, DesiredAccess, GenericMapping, ObjectCreation,
1337 GrantedAccess, AccessStatus, GenerateOnClose);
1339 return STATUS_NOT_IMPLEMENTED;