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
31 #define WIN32_NO_STATUS
32 #include "wine/debug.h"
33 #include "wine/unicode.h"
36 #include "ntdll_misc.h"
37 #include "wine/server.h"
39 WINE_DEFAULT_DEBUG_CHANNEL(ntdll);
45 /******************************************************************************
46 * NtDuplicateToken [NTDLL.@]
47 * ZwDuplicateToken [NTDLL.@]
49 NTSTATUS WINAPI NtDuplicateToken(
50 IN HANDLE ExistingToken,
51 IN ACCESS_MASK DesiredAccess,
52 IN POBJECT_ATTRIBUTES ObjectAttributes,
53 IN SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
54 IN TOKEN_TYPE TokenType,
59 TRACE("(%p,0x%08x,%p,0x%08x,0x%08x,%p)\n",
60 ExistingToken, DesiredAccess, ObjectAttributes,
61 ImpersonationLevel, TokenType, NewToken);
62 dump_ObjectAttributes(ObjectAttributes);
64 if (ObjectAttributes && ObjectAttributes->SecurityQualityOfService)
66 SECURITY_QUALITY_OF_SERVICE *SecurityQOS = ObjectAttributes->SecurityQualityOfService;
67 TRACE("ObjectAttributes->SecurityQualityOfService = {%d, %d, %d, %s}\n",
68 SecurityQOS->Length, SecurityQOS->ImpersonationLevel,
69 SecurityQOS->ContextTrackingMode,
70 SecurityQOS->EffectiveOnly ? "TRUE" : "FALSE");
71 ImpersonationLevel = SecurityQOS->ImpersonationLevel;
74 SERVER_START_REQ( duplicate_token )
76 req->handle = ExistingToken;
77 req->access = DesiredAccess;
78 req->attributes = ObjectAttributes ? ObjectAttributes->Attributes : 0;
79 req->primary = (TokenType == TokenPrimary);
80 req->impersonation_level = ImpersonationLevel;
81 status = wine_server_call( req );
82 if (!status) *NewToken = reply->new_handle;
89 /******************************************************************************
90 * NtOpenProcessToken [NTDLL.@]
91 * ZwOpenProcessToken [NTDLL.@]
93 NTSTATUS WINAPI NtOpenProcessToken(
100 TRACE("(%p,0x%08x,%p)\n", ProcessHandle,DesiredAccess, TokenHandle);
102 SERVER_START_REQ( open_token )
104 req->handle = ProcessHandle;
105 req->access = DesiredAccess;
108 ret = wine_server_call( req );
109 if (!ret) *TokenHandle = reply->token;
116 /******************************************************************************
117 * NtOpenThreadToken [NTDLL.@]
118 * ZwOpenThreadToken [NTDLL.@]
120 NTSTATUS WINAPI NtOpenThreadToken(
128 TRACE("(%p,0x%08x,0x%08x,%p)\n",
129 ThreadHandle,DesiredAccess, OpenAsSelf, TokenHandle);
131 SERVER_START_REQ( open_token )
133 req->handle = ThreadHandle;
134 req->access = DesiredAccess;
136 req->flags = OPEN_TOKEN_THREAD;
137 if (OpenAsSelf) req->flags |= OPEN_TOKEN_AS_SELF;
138 ret = wine_server_call( req );
139 if (!ret) *TokenHandle = reply->token;
146 /******************************************************************************
147 * NtAdjustPrivilegesToken [NTDLL.@]
148 * ZwAdjustPrivilegesToken [NTDLL.@]
150 * FIXME: parameters unsafe
152 NTSTATUS WINAPI NtAdjustPrivilegesToken(
153 IN HANDLE TokenHandle,
154 IN BOOLEAN DisableAllPrivileges,
155 IN PTOKEN_PRIVILEGES NewState,
156 IN DWORD BufferLength,
157 OUT PTOKEN_PRIVILEGES PreviousState,
158 OUT PDWORD ReturnLength)
162 TRACE("(%p,0x%08x,%p,0x%08x,%p,%p)\n",
163 TokenHandle, DisableAllPrivileges, NewState, BufferLength, PreviousState, ReturnLength);
165 SERVER_START_REQ( adjust_token_privileges )
167 req->handle = TokenHandle;
168 req->disable_all = DisableAllPrivileges;
169 req->get_modified_state = (PreviousState != NULL);
170 if (!DisableAllPrivileges)
172 wine_server_add_data( req, &NewState->Privileges,
173 NewState->PrivilegeCount * sizeof(NewState->Privileges[0]) );
175 if (PreviousState && BufferLength >= FIELD_OFFSET( TOKEN_PRIVILEGES, Privileges ))
176 wine_server_set_reply( req, &PreviousState->Privileges,
177 BufferLength - FIELD_OFFSET( TOKEN_PRIVILEGES, Privileges ) );
178 ret = wine_server_call( req );
181 *ReturnLength = reply->len + FIELD_OFFSET( TOKEN_PRIVILEGES, Privileges );
182 PreviousState->PrivilegeCount = reply->len / sizeof(LUID_AND_ATTRIBUTES);
190 /******************************************************************************
191 * NtQueryInformationToken [NTDLL.@]
192 * ZwQueryInformationToken [NTDLL.@]
195 * Buffer for TokenUser:
196 * 0x00 TOKEN_USER the PSID field points to the SID
200 NTSTATUS WINAPI NtQueryInformationToken(
202 TOKEN_INFORMATION_CLASS tokeninfoclass,
204 ULONG tokeninfolength,
208 NTSTATUS status = STATUS_SUCCESS;
210 TRACE("(%p,%d,%p,%d,%p)\n",
211 token,tokeninfoclass,tokeninfo,tokeninfolength,retlen);
213 switch (tokeninfoclass)
216 len = sizeof(TOKEN_OWNER) + sizeof(SID);
218 case TokenPrimaryGroup:
219 len = sizeof(TOKEN_PRIMARY_GROUP);
221 case TokenDefaultDacl:
222 len = sizeof(TOKEN_DEFAULT_DACL);
225 len = sizeof(TOKEN_SOURCE);
228 len = sizeof (TOKEN_TYPE);
230 case TokenImpersonationLevel:
231 len = sizeof(SECURITY_IMPERSONATION_LEVEL);
233 case TokenStatistics:
234 len = sizeof(TOKEN_STATISTICS);
240 if (retlen) *retlen = len;
242 if (tokeninfolength < len)
243 return STATUS_BUFFER_TOO_SMALL;
245 switch (tokeninfoclass)
248 SERVER_START_REQ( get_token_user )
250 TOKEN_USER * tuser = tokeninfo;
251 PSID sid = (PSID) (tuser + 1);
252 DWORD sid_len = tokeninfolength < sizeof(TOKEN_USER) ? 0 : tokeninfolength - sizeof(TOKEN_USER);
255 wine_server_set_reply( req, sid, sid_len );
256 status = wine_server_call( req );
257 if (retlen) *retlen = reply->user_len + sizeof(TOKEN_USER);
258 if (status == STATUS_SUCCESS)
260 tuser->User.Sid = sid;
261 tuser->User.Attributes = 0;
268 char stack_buffer[256];
269 unsigned int server_buf_len = sizeof(stack_buffer);
270 void *buffer = stack_buffer;
271 BOOLEAN need_more_memory = FALSE;
273 /* we cannot work out the size of the server buffer required for the
274 * input size, since there are two factors affecting how much can be
275 * stored in the buffer - number of groups and lengths of sids */
278 SERVER_START_REQ( get_token_groups )
280 TOKEN_GROUPS *groups = tokeninfo;
283 wine_server_set_reply( req, buffer, server_buf_len );
284 status = wine_server_call( req );
285 if (status == STATUS_BUFFER_TOO_SMALL)
287 if (buffer == stack_buffer)
288 buffer = RtlAllocateHeap(GetProcessHeap(), 0, reply->user_len);
290 buffer = RtlReAllocateHeap(GetProcessHeap(), 0, buffer, reply->user_len);
291 if (!buffer) return STATUS_NO_MEMORY;
293 server_buf_len = reply->user_len;
294 need_more_memory = TRUE;
296 else if (status == STATUS_SUCCESS)
298 struct token_groups *tg = buffer;
299 unsigned int *attr = (unsigned int *)(tg + 1);
301 const int non_sid_portion = (sizeof(struct token_groups) + tg->count * sizeof(unsigned long));
302 SID *sids = (SID *)((char *)tokeninfo + FIELD_OFFSET( TOKEN_GROUPS, Groups[tg->count] ));
303 ULONG needed_bytes = FIELD_OFFSET( TOKEN_GROUPS, Groups[tg->count] ) +
304 reply->user_len - non_sid_portion;
306 if (retlen) *retlen = needed_bytes;
308 if (needed_bytes <= tokeninfolength)
310 groups->GroupCount = tg->count;
311 memcpy( sids, (char *)buffer + non_sid_portion,
312 reply->user_len - non_sid_portion );
314 for (i = 0; i < tg->count; i++)
316 groups->Groups[i].Attributes = attr[i];
317 groups->Groups[i].Sid = sids;
318 sids = (SID *)((char *)sids + RtlLengthSid(sids));
321 else status = STATUS_BUFFER_TOO_SMALL;
323 else if (retlen) *retlen = 0;
326 } while (need_more_memory);
327 if (buffer != stack_buffer) RtlFreeHeap(GetProcessHeap(), 0, buffer);
330 case TokenPrimaryGroup:
333 TOKEN_PRIMARY_GROUP *tgroup = tokeninfo;
334 SID_IDENTIFIER_AUTHORITY sid = {SECURITY_NT_AUTHORITY};
335 RtlAllocateAndInitializeSid( &sid,
337 SECURITY_BUILTIN_DOMAIN_RID,
338 DOMAIN_ALIAS_RID_ADMINS,
340 &(tgroup->PrimaryGroup));
343 case TokenPrivileges:
344 SERVER_START_REQ( get_token_privileges )
346 TOKEN_PRIVILEGES *tpriv = tokeninfo;
348 if (tpriv && tokeninfolength > FIELD_OFFSET( TOKEN_PRIVILEGES, Privileges ))
349 wine_server_set_reply( req, &tpriv->Privileges, tokeninfolength - FIELD_OFFSET( TOKEN_PRIVILEGES, Privileges ) );
350 status = wine_server_call( req );
351 if (retlen) *retlen = FIELD_OFFSET( TOKEN_PRIVILEGES, Privileges ) + reply->len;
352 if (tpriv) tpriv->PrivilegeCount = reply->len / sizeof(LUID_AND_ATTRIBUTES);
359 TOKEN_OWNER *owner = tokeninfo;
360 PSID sid = (PSID) (owner + 1);
361 SID_IDENTIFIER_AUTHORITY localSidAuthority = {SECURITY_NT_AUTHORITY};
362 RtlInitializeSid(sid, &localSidAuthority, 1);
363 *(RtlSubAuthoritySid(sid, 0)) = SECURITY_INTERACTIVE_RID;
367 case TokenImpersonationLevel:
368 SERVER_START_REQ( get_token_impersonation_level )
370 SECURITY_IMPERSONATION_LEVEL *impersonation_level = tokeninfo;
372 status = wine_server_call( req );
373 if (status == STATUS_SUCCESS)
374 *impersonation_level = reply->impersonation_level;
378 case TokenStatistics:
379 SERVER_START_REQ( get_token_statistics )
381 TOKEN_STATISTICS *statistics = tokeninfo;
383 status = wine_server_call( req );
384 if (status == STATUS_SUCCESS)
386 statistics->TokenId.LowPart = reply->token_id.low_part;
387 statistics->TokenId.HighPart = reply->token_id.high_part;
388 statistics->AuthenticationId.LowPart = 0; /* FIXME */
389 statistics->AuthenticationId.HighPart = 0; /* FIXME */
390 statistics->ExpirationTime.HighPart = 0x7fffffff;
391 statistics->ExpirationTime.LowPart = 0xffffffff;
392 statistics->TokenType = reply->primary ? TokenPrimary : TokenImpersonation;
393 statistics->ImpersonationLevel = reply->impersonation_level;
395 /* kernel information not relevant to us */
396 statistics->DynamicCharged = 0;
397 statistics->DynamicAvailable = 0;
399 statistics->GroupCount = reply->group_count;
400 statistics->PrivilegeCount = reply->privilege_count;
401 statistics->ModifiedId.LowPart = reply->modified_id.low_part;
402 statistics->ModifiedId.HighPart = reply->modified_id.high_part;
408 SERVER_START_REQ( get_token_statistics )
410 TOKEN_TYPE *token_type = tokeninfo;
412 status = wine_server_call( req );
413 if (status == STATUS_SUCCESS)
414 *token_type = reply->primary ? TokenPrimary : TokenImpersonation;
420 ERR("Unhandled Token Information class %d!\n", tokeninfoclass);
421 return STATUS_NOT_IMPLEMENTED;
427 /******************************************************************************
428 * NtSetInformationToken [NTDLL.@]
429 * ZwSetInformationToken [NTDLL.@]
431 NTSTATUS WINAPI NtSetInformationToken(
433 TOKEN_INFORMATION_CLASS TokenInformationClass,
434 PVOID TokenInformation,
435 ULONG TokenInformationLength)
437 FIXME("%p %d %p %u\n", TokenHandle, TokenInformationClass,
438 TokenInformation, TokenInformationLength);
439 return STATUS_NOT_IMPLEMENTED;
442 /******************************************************************************
443 * NtAdjustGroupsToken [NTDLL.@]
444 * ZwAdjustGroupsToken [NTDLL.@]
446 NTSTATUS WINAPI NtAdjustGroupsToken(
448 BOOLEAN ResetToDefault,
449 PTOKEN_GROUPS NewState,
451 PTOKEN_GROUPS PreviousState,
454 FIXME("%p %d %p %u %p %p\n", TokenHandle, ResetToDefault,
455 NewState, BufferLength, PreviousState, ReturnLength);
456 return STATUS_NOT_IMPLEMENTED;
459 /******************************************************************************
460 * NtPrivilegeCheck [NTDLL.@]
461 * ZwPrivilegeCheck [NTDLL.@]
463 NTSTATUS WINAPI NtPrivilegeCheck(
465 PPRIVILEGE_SET RequiredPrivileges,
469 SERVER_START_REQ( check_token_privileges )
471 req->handle = ClientToken;
472 req->all_required = ((RequiredPrivileges->Control & PRIVILEGE_SET_ALL_NECESSARY) ? TRUE : FALSE);
473 wine_server_add_data( req, &RequiredPrivileges->Privilege,
474 RequiredPrivileges->PrivilegeCount * sizeof(RequiredPrivileges->Privilege[0]) );
475 wine_server_set_reply( req, &RequiredPrivileges->Privilege,
476 RequiredPrivileges->PrivilegeCount * sizeof(RequiredPrivileges->Privilege[0]) );
478 status = wine_server_call( req );
480 if (status == STATUS_SUCCESS)
481 *Result = (reply->has_privileges ? TRUE : FALSE);
491 /******************************************************************************
492 * NtQuerySection [NTDLL.@]
494 NTSTATUS WINAPI NtQuerySection(
495 IN HANDLE SectionHandle,
496 IN SECTION_INFORMATION_CLASS SectionInformationClass,
497 OUT PVOID SectionInformation,
499 OUT PULONG ResultLength)
501 FIXME("(%p,%d,%p,0x%08x,%p) stub!\n",
502 SectionHandle,SectionInformationClass,SectionInformation,Length,ResultLength);
510 /******************************************************************************
511 * NtCreatePort [NTDLL.@]
512 * ZwCreatePort [NTDLL.@]
514 NTSTATUS WINAPI NtCreatePort(PHANDLE PortHandle,POBJECT_ATTRIBUTES ObjectAttributes,
515 ULONG MaxConnectInfoLength,ULONG MaxDataLength,PULONG reserved)
517 FIXME("(%p,%p,%u,%u,%p),stub!\n",PortHandle,ObjectAttributes,
518 MaxConnectInfoLength,MaxDataLength,reserved);
519 return STATUS_NOT_IMPLEMENTED;
522 /******************************************************************************
523 * NtConnectPort [NTDLL.@]
524 * ZwConnectPort [NTDLL.@]
526 NTSTATUS WINAPI NtConnectPort(
528 PUNICODE_STRING PortName,
529 PSECURITY_QUALITY_OF_SERVICE SecurityQos,
530 PLPC_SECTION_WRITE WriteSection,
531 PLPC_SECTION_READ ReadSection,
532 PULONG MaximumMessageLength,
534 PULONG pConnectInfoLength)
536 FIXME("(%p,%s,%p,%p,%p,%p,%p,%p),stub!\n",
537 PortHandle,debugstr_w(PortName->Buffer),SecurityQos,
538 WriteSection,ReadSection,MaximumMessageLength,ConnectInfo,
540 if (ConnectInfo && pConnectInfoLength)
541 TRACE("\tMessage = %s\n",debugstr_an(ConnectInfo,*pConnectInfoLength));
542 return STATUS_NOT_IMPLEMENTED;
545 /******************************************************************************
546 * NtListenPort [NTDLL.@]
547 * ZwListenPort [NTDLL.@]
549 NTSTATUS WINAPI NtListenPort(HANDLE PortHandle,PLPC_MESSAGE pLpcMessage)
551 FIXME("(%p,%p),stub!\n",PortHandle,pLpcMessage);
552 return STATUS_NOT_IMPLEMENTED;
555 /******************************************************************************
556 * NtAcceptConnectPort [NTDLL.@]
557 * ZwAcceptConnectPort [NTDLL.@]
559 NTSTATUS WINAPI NtAcceptConnectPort(
561 ULONG PortIdentifier,
562 PLPC_MESSAGE pLpcMessage,
564 PLPC_SECTION_WRITE WriteSection,
565 PLPC_SECTION_READ ReadSection)
567 FIXME("(%p,%u,%p,%d,%p,%p),stub!\n",
568 PortHandle,PortIdentifier,pLpcMessage,Accept,WriteSection,ReadSection);
569 return STATUS_NOT_IMPLEMENTED;
572 /******************************************************************************
573 * NtCompleteConnectPort [NTDLL.@]
574 * ZwCompleteConnectPort [NTDLL.@]
576 NTSTATUS WINAPI NtCompleteConnectPort(HANDLE PortHandle)
578 FIXME("(%p),stub!\n",PortHandle);
579 return STATUS_NOT_IMPLEMENTED;
582 /******************************************************************************
583 * NtRegisterThreadTerminatePort [NTDLL.@]
584 * ZwRegisterThreadTerminatePort [NTDLL.@]
586 NTSTATUS WINAPI NtRegisterThreadTerminatePort(HANDLE PortHandle)
588 FIXME("(%p),stub!\n",PortHandle);
589 return STATUS_NOT_IMPLEMENTED;
592 /******************************************************************************
593 * NtRequestWaitReplyPort [NTDLL.@]
594 * ZwRequestWaitReplyPort [NTDLL.@]
596 NTSTATUS WINAPI NtRequestWaitReplyPort(
598 PLPC_MESSAGE pLpcMessageIn,
599 PLPC_MESSAGE pLpcMessageOut)
601 FIXME("(%p,%p,%p),stub!\n",PortHandle,pLpcMessageIn,pLpcMessageOut);
604 TRACE("Message to send:\n");
605 TRACE("\tDataSize = %u\n",pLpcMessageIn->DataSize);
606 TRACE("\tMessageSize = %u\n",pLpcMessageIn->MessageSize);
607 TRACE("\tMessageType = %u\n",pLpcMessageIn->MessageType);
608 TRACE("\tVirtualRangesOffset = %u\n",pLpcMessageIn->VirtualRangesOffset);
609 TRACE("\tClientId.UniqueProcess = %p\n",pLpcMessageIn->ClientId.UniqueProcess);
610 TRACE("\tClientId.UniqueThread = %p\n",pLpcMessageIn->ClientId.UniqueThread);
611 TRACE("\tMessageId = %u\n",pLpcMessageIn->MessageId);
612 TRACE("\tSectionSize = %u\n",pLpcMessageIn->SectionSize);
613 TRACE("\tData = %s\n",
614 debugstr_an((const char*)pLpcMessageIn->Data,pLpcMessageIn->DataSize));
616 return STATUS_NOT_IMPLEMENTED;
619 /******************************************************************************
620 * NtReplyWaitReceivePort [NTDLL.@]
621 * ZwReplyWaitReceivePort [NTDLL.@]
623 NTSTATUS WINAPI NtReplyWaitReceivePort(
625 PULONG PortIdentifier,
626 PLPC_MESSAGE ReplyMessage,
627 PLPC_MESSAGE Message)
629 FIXME("(%p,%p,%p,%p),stub!\n",PortHandle,PortIdentifier,ReplyMessage,Message);
630 return STATUS_NOT_IMPLEMENTED;
637 /******************************************************************************
638 * NtSetIntervalProfile [NTDLL.@]
639 * ZwSetIntervalProfile [NTDLL.@]
641 NTSTATUS WINAPI NtSetIntervalProfile(
643 KPROFILE_SOURCE Source)
645 FIXME("%u,%d\n", Interval, Source);
646 return STATUS_SUCCESS;
649 /******************************************************************************
650 * NtQuerySystemInformation [NTDLL.@]
651 * ZwQuerySystemInformation [NTDLL.@]
654 * SystemInformationClass Index to a certain information structure
655 * SystemTimeAdjustmentInformation SYSTEM_TIME_ADJUSTMENT
656 * SystemCacheInformation SYSTEM_CACHE_INFORMATION
657 * SystemConfigurationInformation CONFIGURATION_INFORMATION
658 * observed (class/len):
664 * SystemInformation caller supplies storage for the information structure
665 * Length size of the structure
666 * ResultLength Data written
668 NTSTATUS WINAPI NtQuerySystemInformation(
669 IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
670 OUT PVOID SystemInformation,
672 OUT PULONG ResultLength)
674 NTSTATUS ret = STATUS_SUCCESS;
677 TRACE("(0x%08x,%p,0x%08x,%p)\n",
678 SystemInformationClass,SystemInformation,Length,ResultLength);
680 switch (SystemInformationClass)
682 case SystemBasicInformation:
684 SYSTEM_BASIC_INFORMATION sbi;
687 sbi.uKeMaximumIncrement = 0;
688 sbi.uPageSize = 1024; /* FIXME */
689 sbi.uMmNumberOfPhysicalPages = 12345; /* FIXME */
690 sbi.uMmLowestPhysicalPage = 0; /* FIXME */
691 sbi.uMmHighestPhysicalPage = 12345; /* FIXME */
692 sbi.uAllocationGranularity = 65536; /* FIXME */
693 sbi.pLowestUserAddress = 0; /* FIXME */
694 sbi.pMmHighestUserAddress = (void*)~0; /* FIXME */
695 sbi.uKeActiveProcessors = 1; /* FIXME */
696 sbi.bKeNumberProcessors = 1; /* FIXME */
701 if (!SystemInformation) ret = STATUS_ACCESS_VIOLATION;
702 else memcpy( SystemInformation, &sbi, len);
704 else ret = STATUS_INFO_LENGTH_MISMATCH;
707 case SystemCpuInformation:
709 SYSTEM_CPU_INFORMATION sci;
711 /* FIXME: move some code from kernel/cpu.c to process this */
712 sci.Architecture = PROCESSOR_ARCHITECTURE_INTEL;
713 sci.Level = 6; /* 686, aka Pentium II+ */
716 sci.FeatureSet = 0x1fff;
721 if (!SystemInformation) ret = STATUS_ACCESS_VIOLATION;
722 else memcpy( SystemInformation, &sci, len);
724 else ret = STATUS_INFO_LENGTH_MISMATCH;
727 case SystemPerformanceInformation:
729 SYSTEM_PERFORMANCE_INFORMATION spi;
731 memset(&spi, 0 , sizeof(spi));
736 if (!SystemInformation) ret = STATUS_ACCESS_VIOLATION;
737 else memcpy( SystemInformation, &spi, len);
739 else ret = STATUS_INFO_LENGTH_MISMATCH;
742 case SystemTimeOfDayInformation:
744 SYSTEM_TIMEOFDAY_INFORMATION sti;
746 memset(&sti, 0 , sizeof(sti));
748 /* liKeSystemTime, liExpTimeZoneBias, uCurrentTimeZoneId */
749 sti.liKeBootTime.QuadPart = server_start_time;
751 if (Length <= sizeof(sti))
754 if (!SystemInformation) ret = STATUS_ACCESS_VIOLATION;
755 else memcpy( SystemInformation, &sti, Length);
757 else ret = STATUS_INFO_LENGTH_MISMATCH;
760 case SystemProcessInformation:
762 SYSTEM_PROCESS_INFORMATION* spi = (SYSTEM_PROCESS_INFORMATION*)SystemInformation;
763 SYSTEM_PROCESS_INFORMATION* last = NULL;
765 WCHAR procname[1024];
768 DWORD procstructlen = 0;
770 SERVER_START_REQ( create_snapshot )
772 req->flags = SNAP_PROCESS | SNAP_THREAD;
775 if (!(ret = wine_server_call( req ))) hSnap = reply->handle;
779 while (ret == STATUS_SUCCESS)
781 SERVER_START_REQ( next_process )
784 req->reset = (len == 0);
785 wine_server_set_reply( req, procname, sizeof(procname)-sizeof(WCHAR) );
786 if (!(ret = wine_server_call( req )))
788 /* Make sure procname is 0 terminated */
789 procname[wine_server_reply_size(reply) / sizeof(WCHAR)] = 0;
791 /* Get only the executable name, not the path */
792 if ((exename = strrchrW(procname, '\\')) != NULL) exename++;
793 else exename = procname;
795 wlen = (strlenW(exename) + 1) * sizeof(WCHAR);
797 procstructlen = sizeof(*spi) + wlen + ((reply->threads - 1) * sizeof(SYSTEM_THREAD_INFORMATION));
799 if (Length >= len + procstructlen)
801 /* ftCreationTime, ftUserTime, ftKernelTime;
802 * vmCounters, ioCounters
805 memset(spi, 0, sizeof(*spi));
807 spi->dwOffset = procstructlen - wlen;
808 spi->dwThreadCount = reply->threads;
810 /* spi->pszProcessName will be set later on */
812 spi->dwBasePriority = reply->priority;
813 spi->dwProcessID = (DWORD)reply->pid;
814 spi->dwParentProcessID = (DWORD)reply->ppid;
815 spi->dwHandleCount = reply->handles;
817 /* spi->ti will be set later on */
819 len += procstructlen;
821 else ret = STATUS_INFO_LENGTH_MISMATCH;
826 if (ret != STATUS_SUCCESS)
828 if (ret == STATUS_NO_MORE_FILES) ret = STATUS_SUCCESS;
831 else /* Length is already checked for */
835 /* set thread info */
837 while (ret == STATUS_SUCCESS)
839 SERVER_START_REQ( next_thread )
842 req->reset = (j == 0);
843 if (!(ret = wine_server_call( req )))
846 if (reply->pid == spi->dwProcessID)
848 /* ftKernelTime, ftUserTime, ftCreateTime;
849 * dwTickCount, dwStartAddress
852 memset(&spi->ti[i], 0, sizeof(spi->ti));
854 spi->ti[i].dwOwningPID = reply->pid;
855 spi->ti[i].dwThreadID = reply->tid;
856 spi->ti[i].dwCurrentPriority = reply->base_pri + reply->delta_pri;
857 spi->ti[i].dwBasePriority = reply->base_pri;
864 if (ret == STATUS_NO_MORE_FILES) ret = STATUS_SUCCESS;
866 /* now append process name */
867 spi->ProcessName.Buffer = (WCHAR*)((char*)spi + spi->dwOffset);
868 spi->ProcessName.Length = wlen - sizeof(WCHAR);
869 spi->ProcessName.MaximumLength = wlen;
870 memcpy( spi->ProcessName.Buffer, exename, wlen );
871 spi->dwOffset += wlen;
874 spi = (SYSTEM_PROCESS_INFORMATION*)((char*)spi + spi->dwOffset);
877 if (ret == STATUS_SUCCESS && last) last->dwOffset = 0;
878 if (hSnap) NtClose(hSnap);
881 case SystemProcessorPerformanceInformation:
883 SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION sppi;
885 memset(&sppi, 0 , sizeof(sppi)); /* FIXME */
890 if (!SystemInformation) ret = STATUS_ACCESS_VIOLATION;
891 else memcpy( SystemInformation, &sppi, len);
893 else ret = STATUS_INFO_LENGTH_MISMATCH;
896 case SystemModuleInformation:
897 /* FIXME: should be system-wide */
898 if (!SystemInformation) ret = STATUS_ACCESS_VIOLATION;
899 else ret = LdrQueryProcessModuleInformation( SystemInformation, Length, &len );
901 case SystemHandleInformation:
903 SYSTEM_HANDLE_INFORMATION shi;
905 memset(&shi, 0, sizeof(shi));
910 if (!SystemInformation) ret = STATUS_ACCESS_VIOLATION;
911 else memcpy( SystemInformation, &shi, len);
913 else ret = STATUS_INFO_LENGTH_MISMATCH;
916 case SystemCacheInformation:
918 SYSTEM_CACHE_INFORMATION sci;
920 memset(&sci, 0, sizeof(sci)); /* FIXME */
925 if (!SystemInformation) ret = STATUS_ACCESS_VIOLATION;
926 else memcpy( SystemInformation, &sci, len);
928 else ret = STATUS_INFO_LENGTH_MISMATCH;
931 case SystemInterruptInformation:
933 SYSTEM_INTERRUPT_INFORMATION sii;
935 memset(&sii, 0, sizeof(sii));
940 if (!SystemInformation) ret = STATUS_ACCESS_VIOLATION;
941 else memcpy( SystemInformation, &sii, len);
943 else ret = STATUS_INFO_LENGTH_MISMATCH;
946 case SystemKernelDebuggerInformation:
948 SYSTEM_KERNEL_DEBUGGER_INFORMATION skdi;
950 skdi.DebuggerEnabled = FALSE;
951 skdi.DebuggerNotPresent = TRUE;
956 if (!SystemInformation) ret = STATUS_ACCESS_VIOLATION;
957 else memcpy( SystemInformation, &skdi, len);
959 else ret = STATUS_INFO_LENGTH_MISMATCH;
962 case SystemRegistryQuotaInformation:
964 /* Something to do with the size of the registry *
965 * Since we don't have a size limitation, fake it *
966 * This is almost certainly wrong. *
967 * This sets each of the three words in the struct to 32 MB, *
968 * which is enough to make the IE 5 installer happy. */
969 SYSTEM_REGISTRY_QUOTA_INFORMATION srqi;
971 srqi.RegistryQuotaAllowed = 0x2000000;
972 srqi.RegistryQuotaUsed = 0x200000;
973 srqi.Reserved1 = (void*)0x200000;
978 if (!SystemInformation) ret = STATUS_ACCESS_VIOLATION;
981 FIXME("SystemRegistryQuotaInformation: faking max registry size of 32 MB\n");
982 memcpy( SystemInformation, &srqi, len);
985 else ret = STATUS_INFO_LENGTH_MISMATCH;
989 FIXME("(0x%08x,%p,0x%08x,%p) stub\n",
990 SystemInformationClass,SystemInformation,Length,ResultLength);
992 /* Several Information Classes are not implemented on Windows and return 2 different values
993 * STATUS_NOT_IMPLEMENTED or STATUS_INVALID_INFO_CLASS
994 * in 95% of the cases it's STATUS_INVALID_INFO_CLASS, so use this as the default
996 ret = STATUS_INVALID_INFO_CLASS;
999 if (ResultLength) *ResultLength = len;
1004 /******************************************************************************
1005 * NtSetSystemInformation [NTDLL.@]
1006 * ZwSetSystemInformation [NTDLL.@]
1008 NTSTATUS WINAPI NtSetSystemInformation(SYSTEM_INFORMATION_CLASS SystemInformationClass, PVOID SystemInformation, ULONG Length)
1010 FIXME("(0x%08x,%p,0x%08x) stub\n",SystemInformationClass,SystemInformation,Length);
1011 return STATUS_SUCCESS;
1014 /******************************************************************************
1015 * NtCreatePagingFile [NTDLL.@]
1016 * ZwCreatePagingFile [NTDLL.@]
1018 NTSTATUS WINAPI NtCreatePagingFile(
1019 PUNICODE_STRING PageFileName,
1020 PLARGE_INTEGER MinimumSize,
1021 PLARGE_INTEGER MaximumSize,
1022 PLARGE_INTEGER ActualSize)
1024 FIXME("(%p %p %p %p) stub\n", PageFileName, MinimumSize, MaximumSize, ActualSize);
1025 return STATUS_SUCCESS;
1028 /******************************************************************************
1029 * NtDisplayString [NTDLL.@]
1031 * writes a string to the nt-textmode screen eg. during startup
1033 NTSTATUS WINAPI NtDisplayString ( PUNICODE_STRING string )
1038 if (!(ret = RtlUnicodeStringToAnsiString( &stringA, string, TRUE )))
1040 MESSAGE( "%.*s", stringA.Length, stringA.Buffer );
1041 RtlFreeAnsiString( &stringA );
1046 /******************************************************************************
1047 * NtInitiatePowerAction [NTDLL.@]
1050 NTSTATUS WINAPI NtInitiatePowerAction(
1051 IN POWER_ACTION SystemAction,
1052 IN SYSTEM_POWER_STATE MinSystemState,
1054 IN BOOLEAN Asynchronous)
1056 FIXME("(%d,%d,0x%08x,%d),stub\n",
1057 SystemAction,MinSystemState,Flags,Asynchronous);
1058 return STATUS_NOT_IMPLEMENTED;
1062 /******************************************************************************
1063 * NtPowerInformation [NTDLL.@]
1066 NTSTATUS WINAPI NtPowerInformation(
1067 IN POWER_INFORMATION_LEVEL InformationLevel,
1068 IN PVOID lpInputBuffer,
1069 IN ULONG nInputBufferSize,
1070 IN PVOID lpOutputBuffer,
1071 IN ULONG nOutputBufferSize)
1073 TRACE("(%d,%p,%d,%p,%d)\n",
1074 InformationLevel,lpInputBuffer,nInputBufferSize,lpOutputBuffer,nOutputBufferSize);
1075 switch(InformationLevel) {
1076 case SystemPowerCapabilities: {
1077 PSYSTEM_POWER_CAPABILITIES PowerCaps = (PSYSTEM_POWER_CAPABILITIES)lpOutputBuffer;
1078 FIXME("semi-stub: SystemPowerCapabilities\n");
1079 if (nOutputBufferSize < sizeof(SYSTEM_POWER_CAPABILITIES))
1080 return STATUS_BUFFER_TOO_SMALL;
1081 /* FIXME: These values are based off a native XP desktop, should probably use APM/ACPI to get the 'real' values */
1082 PowerCaps->PowerButtonPresent = TRUE;
1083 PowerCaps->SleepButtonPresent = FALSE;
1084 PowerCaps->LidPresent = FALSE;
1085 PowerCaps->SystemS1 = TRUE;
1086 PowerCaps->SystemS2 = FALSE;
1087 PowerCaps->SystemS3 = FALSE;
1088 PowerCaps->SystemS4 = TRUE;
1089 PowerCaps->SystemS5 = TRUE;
1090 PowerCaps->HiberFilePresent = TRUE;
1091 PowerCaps->FullWake = TRUE;
1092 PowerCaps->VideoDimPresent = FALSE;
1093 PowerCaps->ApmPresent = FALSE;
1094 PowerCaps->UpsPresent = FALSE;
1095 PowerCaps->ThermalControl = FALSE;
1096 PowerCaps->ProcessorThrottle = FALSE;
1097 PowerCaps->ProcessorMinThrottle = 100;
1098 PowerCaps->ProcessorMaxThrottle = 100;
1099 PowerCaps->DiskSpinDown = TRUE;
1100 PowerCaps->SystemBatteriesPresent = FALSE;
1101 PowerCaps->BatteriesAreShortTerm = FALSE;
1102 PowerCaps->BatteryScale[0].Granularity = 0;
1103 PowerCaps->BatteryScale[0].Capacity = 0;
1104 PowerCaps->BatteryScale[1].Granularity = 0;
1105 PowerCaps->BatteryScale[1].Capacity = 0;
1106 PowerCaps->BatteryScale[2].Granularity = 0;
1107 PowerCaps->BatteryScale[2].Capacity = 0;
1108 PowerCaps->AcOnLineWake = PowerSystemUnspecified;
1109 PowerCaps->SoftLidWake = PowerSystemUnspecified;
1110 PowerCaps->RtcWake = PowerSystemSleeping1;
1111 PowerCaps->MinDeviceWakeState = PowerSystemUnspecified;
1112 PowerCaps->DefaultLowLatencyWake = PowerSystemUnspecified;
1113 return STATUS_SUCCESS;
1116 FIXME("Unimplemented NtPowerInformation action: %d\n", InformationLevel);
1117 return STATUS_NOT_IMPLEMENTED;
1121 /******************************************************************************
1122 * NtShutdownSystem [NTDLL.@]
1125 NTSTATUS WINAPI NtShutdownSystem(SHUTDOWN_ACTION Action)
1127 FIXME("%d\n",Action);
1128 return STATUS_SUCCESS;
1131 /******************************************************************************
1132 * NtAllocateLocallyUniqueId (NTDLL.@)
1134 NTSTATUS WINAPI NtAllocateLocallyUniqueId(PLUID Luid)
1138 TRACE("%p\n", Luid);
1141 return STATUS_ACCESS_VIOLATION;
1143 SERVER_START_REQ( allocate_locally_unique_id )
1145 status = wine_server_call( req );
1148 Luid->LowPart = reply->luid.low_part;
1149 Luid->HighPart = reply->luid.high_part;
1157 /******************************************************************************
1158 * VerSetConditionMask (NTDLL.@)
1160 ULONGLONG WINAPI VerSetConditionMask( ULONGLONG dwlConditionMask, DWORD dwTypeBitMask,
1161 BYTE dwConditionMask)
1163 if(dwTypeBitMask == 0)
1164 return dwlConditionMask;
1165 dwConditionMask &= 0x07;
1166 if(dwConditionMask == 0)
1167 return dwlConditionMask;
1169 if(dwTypeBitMask & VER_PRODUCT_TYPE)
1170 dwlConditionMask |= dwConditionMask << 7*3;
1171 else if (dwTypeBitMask & VER_SUITENAME)
1172 dwlConditionMask |= dwConditionMask << 6*3;
1173 else if (dwTypeBitMask & VER_SERVICEPACKMAJOR)
1174 dwlConditionMask |= dwConditionMask << 5*3;
1175 else if (dwTypeBitMask & VER_SERVICEPACKMINOR)
1176 dwlConditionMask |= dwConditionMask << 4*3;
1177 else if (dwTypeBitMask & VER_PLATFORMID)
1178 dwlConditionMask |= dwConditionMask << 3*3;
1179 else if (dwTypeBitMask & VER_BUILDNUMBER)
1180 dwlConditionMask |= dwConditionMask << 2*3;
1181 else if (dwTypeBitMask & VER_MAJORVERSION)
1182 dwlConditionMask |= dwConditionMask << 1*3;
1183 else if (dwTypeBitMask & VER_MINORVERSION)
1184 dwlConditionMask |= dwConditionMask << 0*3;
1185 return dwlConditionMask;
1188 /******************************************************************************
1189 * NtAccessCheckAndAuditAlarm (NTDLL.@)
1190 * ZwAccessCheckAndAuditAlarm (NTDLL.@)
1192 NTSTATUS WINAPI NtAccessCheckAndAuditAlarm(PUNICODE_STRING SubsystemName, HANDLE HandleId, PUNICODE_STRING ObjectTypeName,
1193 PUNICODE_STRING ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor,
1194 ACCESS_MASK DesiredAccess, PGENERIC_MAPPING GenericMapping, BOOLEAN ObjectCreation,
1195 PACCESS_MASK GrantedAccess, PBOOLEAN AccessStatus, PBOOLEAN GenerateOnClose)
1197 FIXME("(%s, %p, %s, %p, 0x%08x, %p, %d, %p, %p, %p), stub\n", debugstr_us(SubsystemName), HandleId,
1198 debugstr_us(ObjectTypeName), SecurityDescriptor, DesiredAccess, GenericMapping, ObjectCreation,
1199 GrantedAccess, AccessStatus, GenerateOnClose);
1201 return STATUS_NOT_IMPLEMENTED;