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 SERVER_START_REQ( duplicate_token )
66 req->handle = ExistingToken;
67 req->access = DesiredAccess;
68 req->attributes = ObjectAttributes ? ObjectAttributes->Attributes : 0;
69 req->primary = (TokenType == TokenPrimary);
70 req->impersonation_level = ImpersonationLevel;
71 status = wine_server_call( req );
72 if (!status) *NewToken = reply->new_handle;
79 /******************************************************************************
80 * NtOpenProcessToken [NTDLL.@]
81 * ZwOpenProcessToken [NTDLL.@]
83 NTSTATUS WINAPI NtOpenProcessToken(
90 TRACE("(%p,0x%08x,%p)\n", ProcessHandle,DesiredAccess, TokenHandle);
92 SERVER_START_REQ( open_token )
94 req->handle = ProcessHandle;
95 req->access = DesiredAccess;
98 ret = wine_server_call( req );
99 if (!ret) *TokenHandle = reply->token;
106 /******************************************************************************
107 * NtOpenThreadToken [NTDLL.@]
108 * ZwOpenThreadToken [NTDLL.@]
110 NTSTATUS WINAPI NtOpenThreadToken(
118 TRACE("(%p,0x%08x,0x%08x,%p)\n",
119 ThreadHandle,DesiredAccess, OpenAsSelf, TokenHandle);
121 SERVER_START_REQ( open_token )
123 req->handle = ThreadHandle;
124 req->access = DesiredAccess;
126 req->flags = OPEN_TOKEN_THREAD;
127 if (OpenAsSelf) req->flags |= OPEN_TOKEN_AS_SELF;
128 ret = wine_server_call( req );
129 if (!ret) *TokenHandle = reply->token;
136 /******************************************************************************
137 * NtAdjustPrivilegesToken [NTDLL.@]
138 * ZwAdjustPrivilegesToken [NTDLL.@]
140 * FIXME: parameters unsafe
142 NTSTATUS WINAPI NtAdjustPrivilegesToken(
143 IN HANDLE TokenHandle,
144 IN BOOLEAN DisableAllPrivileges,
145 IN PTOKEN_PRIVILEGES NewState,
146 IN DWORD BufferLength,
147 OUT PTOKEN_PRIVILEGES PreviousState,
148 OUT PDWORD ReturnLength)
152 TRACE("(%p,0x%08x,%p,0x%08x,%p,%p)\n",
153 TokenHandle, DisableAllPrivileges, NewState, BufferLength, PreviousState, ReturnLength);
155 SERVER_START_REQ( adjust_token_privileges )
157 req->handle = TokenHandle;
158 req->disable_all = DisableAllPrivileges;
159 req->get_modified_state = (PreviousState != NULL);
160 if (!DisableAllPrivileges)
162 wine_server_add_data( req, &NewState->Privileges,
163 NewState->PrivilegeCount * sizeof(NewState->Privileges[0]) );
165 if (PreviousState && BufferLength >= FIELD_OFFSET( TOKEN_PRIVILEGES, Privileges ))
166 wine_server_set_reply( req, &PreviousState->Privileges,
167 BufferLength - FIELD_OFFSET( TOKEN_PRIVILEGES, Privileges ) );
168 ret = wine_server_call( req );
171 *ReturnLength = reply->len + FIELD_OFFSET( TOKEN_PRIVILEGES, Privileges );
172 PreviousState->PrivilegeCount = reply->len / sizeof(LUID_AND_ATTRIBUTES);
180 /******************************************************************************
181 * NtQueryInformationToken [NTDLL.@]
182 * ZwQueryInformationToken [NTDLL.@]
185 * Buffer for TokenUser:
186 * 0x00 TOKEN_USER the PSID field points to the SID
190 NTSTATUS WINAPI NtQueryInformationToken(
192 TOKEN_INFORMATION_CLASS tokeninfoclass,
194 ULONG tokeninfolength,
198 NTSTATUS status = STATUS_SUCCESS;
200 TRACE("(%p,%d,%p,%d,%p)\n",
201 token,tokeninfoclass,tokeninfo,tokeninfolength,retlen);
203 switch (tokeninfoclass)
206 len = sizeof(TOKEN_OWNER) + sizeof(SID);
208 case TokenPrimaryGroup:
209 len = sizeof(TOKEN_PRIMARY_GROUP);
211 case TokenDefaultDacl:
212 len = sizeof(TOKEN_DEFAULT_DACL);
215 len = sizeof(TOKEN_SOURCE);
218 len = sizeof (TOKEN_TYPE);
221 case TokenImpersonationLevel:
222 case TokenStatistics:
228 if (retlen) *retlen = len;
230 if (tokeninfolength < len)
231 return STATUS_BUFFER_TOO_SMALL;
233 switch (tokeninfoclass)
236 SERVER_START_REQ( get_token_user )
238 TOKEN_USER * tuser = tokeninfo;
239 PSID sid = (PSID) (tuser + 1);
240 DWORD sid_len = tokeninfolength < sizeof(TOKEN_USER) ? 0 : tokeninfolength - sizeof(TOKEN_USER);
243 wine_server_set_reply( req, sid, sid_len );
244 status = wine_server_call( req );
245 if (retlen) *retlen = reply->user_len + sizeof(TOKEN_USER);
246 if (status == STATUS_SUCCESS)
248 tuser->User.Sid = sid;
249 tuser->User.Attributes = 0;
256 char stack_buffer[256];
257 unsigned int server_buf_len = sizeof(stack_buffer);
258 void *buffer = stack_buffer;
259 BOOLEAN need_more_memory = FALSE;
261 /* we cannot work out the size of the server buffer required for the
262 * input size, since there are two factors affecting how much can be
263 * stored in the buffer - number of groups and lengths of sids */
266 SERVER_START_REQ( get_token_groups )
268 TOKEN_GROUPS *groups = tokeninfo;
271 wine_server_set_reply( req, buffer, server_buf_len );
272 status = wine_server_call( req );
273 if (status == STATUS_BUFFER_TOO_SMALL)
275 if (buffer == stack_buffer)
276 buffer = RtlAllocateHeap(GetProcessHeap(), 0, reply->user_len);
278 buffer = RtlReAllocateHeap(GetProcessHeap(), 0, buffer, reply->user_len);
279 if (!buffer) return STATUS_NO_MEMORY;
281 server_buf_len = reply->user_len;
282 need_more_memory = TRUE;
284 else if (status == STATUS_SUCCESS)
286 struct token_groups *tg = buffer;
287 unsigned int *attr = (unsigned int *)(tg + 1);
289 const int non_sid_portion = (sizeof(struct token_groups) + tg->count * sizeof(unsigned long));
290 SID *sids = (SID *)((char *)tokeninfo + FIELD_OFFSET( TOKEN_GROUPS, Groups[tg->count] ));
291 ULONG needed_bytes = FIELD_OFFSET( TOKEN_GROUPS, Groups[tg->count] ) +
292 reply->user_len - non_sid_portion;
294 if (retlen) *retlen = needed_bytes;
296 if (needed_bytes <= tokeninfolength)
298 groups->GroupCount = tg->count;
299 memcpy( sids, (char *)buffer + non_sid_portion,
300 reply->user_len - non_sid_portion );
302 for (i = 0; i < tg->count; i++)
304 groups->Groups[i].Attributes = attr[i];
305 groups->Groups[i].Sid = sids;
306 sids = (SID *)((char *)sids + RtlLengthSid(sids));
309 else status = STATUS_BUFFER_TOO_SMALL;
311 else if (retlen) *retlen = 0;
314 } while (need_more_memory);
315 if (buffer != stack_buffer) RtlFreeHeap(GetProcessHeap(), 0, buffer);
318 case TokenPrimaryGroup:
321 TOKEN_PRIMARY_GROUP *tgroup = tokeninfo;
322 SID_IDENTIFIER_AUTHORITY sid = {SECURITY_NT_AUTHORITY};
323 RtlAllocateAndInitializeSid( &sid,
325 SECURITY_BUILTIN_DOMAIN_RID,
326 DOMAIN_ALIAS_RID_ADMINS,
328 &(tgroup->PrimaryGroup));
331 case TokenPrivileges:
332 SERVER_START_REQ( get_token_privileges )
334 TOKEN_PRIVILEGES *tpriv = tokeninfo;
336 if (tpriv && tokeninfolength > FIELD_OFFSET( TOKEN_PRIVILEGES, Privileges ))
337 wine_server_set_reply( req, &tpriv->Privileges, tokeninfolength - FIELD_OFFSET( TOKEN_PRIVILEGES, Privileges ) );
338 status = wine_server_call( req );
339 if (retlen) *retlen = FIELD_OFFSET( TOKEN_PRIVILEGES, Privileges ) + reply->len;
340 if (tpriv) tpriv->PrivilegeCount = reply->len / sizeof(LUID_AND_ATTRIBUTES);
347 TOKEN_OWNER *owner = tokeninfo;
348 PSID sid = (PSID) (owner + 1);
349 SID_IDENTIFIER_AUTHORITY localSidAuthority = {SECURITY_NT_AUTHORITY};
350 RtlInitializeSid(sid, &localSidAuthority, 1);
351 *(RtlSubAuthoritySid(sid, 0)) = SECURITY_INTERACTIVE_RID;
357 ERR("Unhandled Token Information class %d!\n", tokeninfoclass);
358 return STATUS_NOT_IMPLEMENTED;
364 /******************************************************************************
365 * NtSetInformationToken [NTDLL.@]
366 * ZwSetInformationToken [NTDLL.@]
368 NTSTATUS WINAPI NtSetInformationToken(
370 TOKEN_INFORMATION_CLASS TokenInformationClass,
371 PVOID TokenInformation,
372 ULONG TokenInformationLength)
374 FIXME("%p %d %p %u\n", TokenHandle, TokenInformationClass,
375 TokenInformation, TokenInformationLength);
376 return STATUS_NOT_IMPLEMENTED;
379 /******************************************************************************
380 * NtAdjustGroupsToken [NTDLL.@]
381 * ZwAdjustGroupsToken [NTDLL.@]
383 NTSTATUS WINAPI NtAdjustGroupsToken(
385 BOOLEAN ResetToDefault,
386 PTOKEN_GROUPS NewState,
388 PTOKEN_GROUPS PreviousState,
391 FIXME("%p %d %p %u %p %p\n", TokenHandle, ResetToDefault,
392 NewState, BufferLength, PreviousState, ReturnLength);
393 return STATUS_NOT_IMPLEMENTED;
396 /******************************************************************************
397 * NtPrivilegeCheck [NTDLL.@]
398 * ZwPrivilegeCheck [NTDLL.@]
400 NTSTATUS WINAPI NtPrivilegeCheck(
402 PPRIVILEGE_SET RequiredPrivileges,
406 SERVER_START_REQ( check_token_privileges )
408 req->handle = ClientToken;
409 req->all_required = ((RequiredPrivileges->Control & PRIVILEGE_SET_ALL_NECESSARY) ? TRUE : FALSE);
410 wine_server_add_data( req, &RequiredPrivileges->Privilege,
411 RequiredPrivileges->PrivilegeCount * sizeof(RequiredPrivileges->Privilege[0]) );
412 wine_server_set_reply( req, &RequiredPrivileges->Privilege,
413 RequiredPrivileges->PrivilegeCount * sizeof(RequiredPrivileges->Privilege[0]) );
415 status = wine_server_call( req );
417 if (status == STATUS_SUCCESS)
418 *Result = (reply->has_privileges ? TRUE : FALSE);
428 /******************************************************************************
429 * NtQuerySection [NTDLL.@]
431 NTSTATUS WINAPI NtQuerySection(
432 IN HANDLE SectionHandle,
433 IN SECTION_INFORMATION_CLASS SectionInformationClass,
434 OUT PVOID SectionInformation,
436 OUT PULONG ResultLength)
438 FIXME("(%p,%d,%p,0x%08x,%p) stub!\n",
439 SectionHandle,SectionInformationClass,SectionInformation,Length,ResultLength);
447 /******************************************************************************
448 * NtCreatePort [NTDLL.@]
449 * ZwCreatePort [NTDLL.@]
451 NTSTATUS WINAPI NtCreatePort(PHANDLE PortHandle,POBJECT_ATTRIBUTES ObjectAttributes,
452 ULONG MaxConnectInfoLength,ULONG MaxDataLength,PULONG reserved)
454 FIXME("(%p,%p,%u,%u,%p),stub!\n",PortHandle,ObjectAttributes,
455 MaxConnectInfoLength,MaxDataLength,reserved);
456 return STATUS_NOT_IMPLEMENTED;
459 /******************************************************************************
460 * NtConnectPort [NTDLL.@]
461 * ZwConnectPort [NTDLL.@]
463 NTSTATUS WINAPI NtConnectPort(
465 PUNICODE_STRING PortName,
466 PSECURITY_QUALITY_OF_SERVICE SecurityQos,
467 PLPC_SECTION_WRITE WriteSection,
468 PLPC_SECTION_READ ReadSection,
469 PULONG MaximumMessageLength,
471 PULONG pConnectInfoLength)
473 FIXME("(%p,%s,%p,%p,%p,%p,%p,%p),stub!\n",
474 PortHandle,debugstr_w(PortName->Buffer),SecurityQos,
475 WriteSection,ReadSection,MaximumMessageLength,ConnectInfo,
477 if (ConnectInfo && pConnectInfoLength)
478 TRACE("\tMessage = %s\n",debugstr_an(ConnectInfo,*pConnectInfoLength));
479 return STATUS_NOT_IMPLEMENTED;
482 /******************************************************************************
483 * NtListenPort [NTDLL.@]
484 * ZwListenPort [NTDLL.@]
486 NTSTATUS WINAPI NtListenPort(HANDLE PortHandle,PLPC_MESSAGE pLpcMessage)
488 FIXME("(%p,%p),stub!\n",PortHandle,pLpcMessage);
489 return STATUS_NOT_IMPLEMENTED;
492 /******************************************************************************
493 * NtAcceptConnectPort [NTDLL.@]
494 * ZwAcceptConnectPort [NTDLL.@]
496 NTSTATUS WINAPI NtAcceptConnectPort(
498 ULONG PortIdentifier,
499 PLPC_MESSAGE pLpcMessage,
501 PLPC_SECTION_WRITE WriteSection,
502 PLPC_SECTION_READ ReadSection)
504 FIXME("(%p,%u,%p,%d,%p,%p),stub!\n",
505 PortHandle,PortIdentifier,pLpcMessage,Accept,WriteSection,ReadSection);
506 return STATUS_NOT_IMPLEMENTED;
509 /******************************************************************************
510 * NtCompleteConnectPort [NTDLL.@]
511 * ZwCompleteConnectPort [NTDLL.@]
513 NTSTATUS WINAPI NtCompleteConnectPort(HANDLE PortHandle)
515 FIXME("(%p),stub!\n",PortHandle);
516 return STATUS_NOT_IMPLEMENTED;
519 /******************************************************************************
520 * NtRegisterThreadTerminatePort [NTDLL.@]
521 * ZwRegisterThreadTerminatePort [NTDLL.@]
523 NTSTATUS WINAPI NtRegisterThreadTerminatePort(HANDLE PortHandle)
525 FIXME("(%p),stub!\n",PortHandle);
526 return STATUS_NOT_IMPLEMENTED;
529 /******************************************************************************
530 * NtRequestWaitReplyPort [NTDLL.@]
531 * ZwRequestWaitReplyPort [NTDLL.@]
533 NTSTATUS WINAPI NtRequestWaitReplyPort(
535 PLPC_MESSAGE pLpcMessageIn,
536 PLPC_MESSAGE pLpcMessageOut)
538 FIXME("(%p,%p,%p),stub!\n",PortHandle,pLpcMessageIn,pLpcMessageOut);
541 TRACE("Message to send:\n");
542 TRACE("\tDataSize = %u\n",pLpcMessageIn->DataSize);
543 TRACE("\tMessageSize = %u\n",pLpcMessageIn->MessageSize);
544 TRACE("\tMessageType = %u\n",pLpcMessageIn->MessageType);
545 TRACE("\tVirtualRangesOffset = %u\n",pLpcMessageIn->VirtualRangesOffset);
546 TRACE("\tClientId.UniqueProcess = %p\n",pLpcMessageIn->ClientId.UniqueProcess);
547 TRACE("\tClientId.UniqueThread = %p\n",pLpcMessageIn->ClientId.UniqueThread);
548 TRACE("\tMessageId = %u\n",pLpcMessageIn->MessageId);
549 TRACE("\tSectionSize = %u\n",pLpcMessageIn->SectionSize);
550 TRACE("\tData = %s\n",
551 debugstr_an((const char*)pLpcMessageIn->Data,pLpcMessageIn->DataSize));
553 return STATUS_NOT_IMPLEMENTED;
556 /******************************************************************************
557 * NtReplyWaitReceivePort [NTDLL.@]
558 * ZwReplyWaitReceivePort [NTDLL.@]
560 NTSTATUS WINAPI NtReplyWaitReceivePort(
562 PULONG PortIdentifier,
563 PLPC_MESSAGE ReplyMessage,
564 PLPC_MESSAGE Message)
566 FIXME("(%p,%p,%p,%p),stub!\n",PortHandle,PortIdentifier,ReplyMessage,Message);
567 return STATUS_NOT_IMPLEMENTED;
574 /******************************************************************************
575 * NtSetIntervalProfile [NTDLL.@]
576 * ZwSetIntervalProfile [NTDLL.@]
578 NTSTATUS WINAPI NtSetIntervalProfile(
580 KPROFILE_SOURCE Source)
582 FIXME("%u,%d\n", Interval, Source);
583 return STATUS_SUCCESS;
586 /******************************************************************************
587 * NtQuerySystemInformation [NTDLL.@]
588 * ZwQuerySystemInformation [NTDLL.@]
591 * SystemInformationClass Index to a certain information structure
592 * SystemTimeAdjustmentInformation SYSTEM_TIME_ADJUSTMENT
593 * SystemCacheInformation SYSTEM_CACHE_INFORMATION
594 * SystemConfigurationInformation CONFIGURATION_INFORMATION
595 * observed (class/len):
601 * SystemInformation caller supplies storage for the information structure
602 * Length size of the structure
603 * ResultLength Data written
605 NTSTATUS WINAPI NtQuerySystemInformation(
606 IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
607 OUT PVOID SystemInformation,
609 OUT PULONG ResultLength)
611 NTSTATUS ret = STATUS_SUCCESS;
614 TRACE("(0x%08x,%p,0x%08x,%p)\n",
615 SystemInformationClass,SystemInformation,Length,ResultLength);
617 switch (SystemInformationClass)
619 case SystemBasicInformation:
621 SYSTEM_BASIC_INFORMATION sbi;
624 sbi.uKeMaximumIncrement = 0;
625 sbi.uPageSize = 1024; /* FIXME */
626 sbi.uMmNumberOfPhysicalPages = 12345; /* FIXME */
627 sbi.uMmLowestPhysicalPage = 0; /* FIXME */
628 sbi.uMmHighestPhysicalPage = 12345; /* FIXME */
629 sbi.uAllocationGranularity = 65536; /* FIXME */
630 sbi.pLowestUserAddress = 0; /* FIXME */
631 sbi.pMmHighestUserAddress = (void*)~0; /* FIXME */
632 sbi.uKeActiveProcessors = 1; /* FIXME */
633 sbi.bKeNumberProcessors = 1; /* FIXME */
638 if (!SystemInformation) ret = STATUS_ACCESS_VIOLATION;
639 else memcpy( SystemInformation, &sbi, len);
641 else ret = STATUS_INFO_LENGTH_MISMATCH;
644 case SystemCpuInformation:
646 SYSTEM_CPU_INFORMATION sci;
648 /* FIXME: move some code from kernel/cpu.c to process this */
649 sci.Architecture = PROCESSOR_ARCHITECTURE_INTEL;
650 sci.Level = 6; /* 686, aka Pentium II+ */
653 sci.FeatureSet = 0x1fff;
658 if (!SystemInformation) ret = STATUS_ACCESS_VIOLATION;
659 else memcpy( SystemInformation, &sci, len);
661 else ret = STATUS_INFO_LENGTH_MISMATCH;
664 case SystemPerformanceInformation:
666 SYSTEM_PERFORMANCE_INFORMATION spi;
668 memset(&spi, 0 , sizeof(spi));
673 if (!SystemInformation) ret = STATUS_ACCESS_VIOLATION;
674 else memcpy( SystemInformation, &spi, len);
676 else ret = STATUS_INFO_LENGTH_MISMATCH;
679 case SystemTimeOfDayInformation:
681 SYSTEM_TIMEOFDAY_INFORMATION sti;
683 memset(&sti, 0 , sizeof(sti));
685 /* liKeSystemTime, liExpTimeZoneBias, uCurrentTimeZoneId */
686 NTDLL_from_server_abstime( &sti.liKeBootTime, &server_start_time );
688 if (Length <= sizeof(sti))
691 if (!SystemInformation) ret = STATUS_ACCESS_VIOLATION;
692 else memcpy( SystemInformation, &sti, Length);
694 else ret = STATUS_INFO_LENGTH_MISMATCH;
697 case SystemProcessInformation:
699 SYSTEM_PROCESS_INFORMATION* spi = (SYSTEM_PROCESS_INFORMATION*)SystemInformation;
700 SYSTEM_PROCESS_INFORMATION* last = NULL;
702 WCHAR procname[1024];
705 DWORD procstructlen = 0;
707 SERVER_START_REQ( create_snapshot )
709 req->flags = SNAP_PROCESS | SNAP_THREAD;
712 if (!(ret = wine_server_call( req ))) hSnap = reply->handle;
716 while (ret == STATUS_SUCCESS)
718 SERVER_START_REQ( next_process )
721 req->reset = (len == 0);
722 wine_server_set_reply( req, procname, sizeof(procname)-sizeof(WCHAR) );
723 if (!(ret = wine_server_call( req )))
725 /* Make sure procname is 0 terminated */
726 procname[wine_server_reply_size(reply) / sizeof(WCHAR)] = 0;
728 /* Get only the executable name, not the path */
729 if ((exename = strrchrW(procname, '\\')) != NULL) exename++;
730 else exename = procname;
732 wlen = (strlenW(exename) + 1) * sizeof(WCHAR);
734 procstructlen = sizeof(*spi) + wlen + ((reply->threads - 1) * sizeof(SYSTEM_THREAD_INFORMATION));
736 if (Length >= len + procstructlen)
738 /* ftCreationTime, ftUserTime, ftKernelTime;
739 * vmCounters, ioCounters
742 memset(spi, 0, sizeof(*spi));
744 spi->dwOffset = procstructlen - wlen;
745 spi->dwThreadCount = reply->threads;
747 /* spi->pszProcessName will be set later on */
749 spi->dwBasePriority = reply->priority;
750 spi->dwProcessID = (DWORD)reply->pid;
751 spi->dwParentProcessID = (DWORD)reply->ppid;
752 spi->dwHandleCount = reply->handles;
754 /* spi->ti will be set later on */
756 len += procstructlen;
758 else ret = STATUS_INFO_LENGTH_MISMATCH;
763 if (ret != STATUS_SUCCESS)
765 if (ret == STATUS_NO_MORE_FILES) ret = STATUS_SUCCESS;
768 else /* Length is already checked for */
772 /* set thread info */
774 while (ret == STATUS_SUCCESS)
776 SERVER_START_REQ( next_thread )
779 req->reset = (j == 0);
780 if (!(ret = wine_server_call( req )))
783 if (reply->pid == spi->dwProcessID)
785 /* ftKernelTime, ftUserTime, ftCreateTime;
786 * dwTickCount, dwStartAddress
789 memset(&spi->ti[i], 0, sizeof(spi->ti));
791 spi->ti[i].dwOwningPID = reply->pid;
792 spi->ti[i].dwThreadID = reply->tid;
793 spi->ti[i].dwCurrentPriority = reply->base_pri + reply->delta_pri;
794 spi->ti[i].dwBasePriority = reply->base_pri;
801 if (ret == STATUS_NO_MORE_FILES) ret = STATUS_SUCCESS;
803 /* now append process name */
804 spi->ProcessName.Buffer = (WCHAR*)((char*)spi + spi->dwOffset);
805 spi->ProcessName.Length = wlen - sizeof(WCHAR);
806 spi->ProcessName.MaximumLength = wlen;
807 memcpy( spi->ProcessName.Buffer, exename, wlen );
808 spi->dwOffset += wlen;
811 spi = (SYSTEM_PROCESS_INFORMATION*)((char*)spi + spi->dwOffset);
814 if (ret == STATUS_SUCCESS && last) last->dwOffset = 0;
815 if (hSnap) NtClose(hSnap);
818 case SystemProcessorPerformanceInformation:
820 SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION sppi;
822 memset(&sppi, 0 , sizeof(sppi)); /* FIXME */
827 if (!SystemInformation) ret = STATUS_ACCESS_VIOLATION;
828 else memcpy( SystemInformation, &sppi, len);
830 else ret = STATUS_INFO_LENGTH_MISMATCH;
833 case SystemModuleInformation:
835 SYSTEM_MODULE_INFORMATION smi;
837 memset(&smi, 0, sizeof(smi));
842 if (!SystemInformation) ret = STATUS_ACCESS_VIOLATION;
843 else memcpy( SystemInformation, &smi, len);
845 else ret = STATUS_INFO_LENGTH_MISMATCH;
848 case SystemHandleInformation:
850 SYSTEM_HANDLE_INFORMATION shi;
852 memset(&shi, 0, sizeof(shi));
857 if (!SystemInformation) ret = STATUS_ACCESS_VIOLATION;
858 else memcpy( SystemInformation, &shi, len);
860 else ret = STATUS_INFO_LENGTH_MISMATCH;
863 case SystemCacheInformation:
865 SYSTEM_CACHE_INFORMATION sci;
867 memset(&sci, 0, sizeof(sci)); /* FIXME */
872 if (!SystemInformation) ret = STATUS_ACCESS_VIOLATION;
873 else memcpy( SystemInformation, &sci, len);
875 else ret = STATUS_INFO_LENGTH_MISMATCH;
878 case SystemInterruptInformation:
880 SYSTEM_INTERRUPT_INFORMATION sii;
882 memset(&sii, 0, sizeof(sii));
887 if (!SystemInformation) ret = STATUS_ACCESS_VIOLATION;
888 else memcpy( SystemInformation, &sii, len);
890 else ret = STATUS_INFO_LENGTH_MISMATCH;
893 case SystemKernelDebuggerInformation:
895 SYSTEM_KERNEL_DEBUGGER_INFORMATION skdi;
897 skdi.DebuggerEnabled = FALSE;
898 skdi.DebuggerNotPresent = TRUE;
903 if (!SystemInformation) ret = STATUS_ACCESS_VIOLATION;
904 else memcpy( SystemInformation, &skdi, len);
906 else ret = STATUS_INFO_LENGTH_MISMATCH;
909 case SystemRegistryQuotaInformation:
911 /* Something to do with the size of the registry *
912 * Since we don't have a size limitation, fake it *
913 * This is almost certainly wrong. *
914 * This sets each of the three words in the struct to 32 MB, *
915 * which is enough to make the IE 5 installer happy. */
916 SYSTEM_REGISTRY_QUOTA_INFORMATION srqi;
918 srqi.RegistryQuotaAllowed = 0x2000000;
919 srqi.RegistryQuotaUsed = 0x200000;
920 srqi.Reserved1 = (void*)0x200000;
925 if (!SystemInformation) ret = STATUS_ACCESS_VIOLATION;
928 FIXME("SystemRegistryQuotaInformation: faking max registry size of 32 MB\n");
929 memcpy( SystemInformation, &srqi, len);
932 else ret = STATUS_INFO_LENGTH_MISMATCH;
936 FIXME("(0x%08x,%p,0x%08x,%p) stub\n",
937 SystemInformationClass,SystemInformation,Length,ResultLength);
939 /* Several Information Classes are not implemented on Windows and return 2 different values
940 * STATUS_NOT_IMPLEMENTED or STATUS_INVALID_INFO_CLASS
941 * in 95% of the cases it's STATUS_INVALID_INFO_CLASS, so use this as the default
943 ret = STATUS_INVALID_INFO_CLASS;
946 if (ResultLength) *ResultLength = len;
951 /******************************************************************************
952 * NtSetSystemInformation [NTDLL.@]
953 * ZwSetSystemInformation [NTDLL.@]
955 NTSTATUS WINAPI NtSetSystemInformation(SYSTEM_INFORMATION_CLASS SystemInformationClass, PVOID SystemInformation, ULONG Length)
957 FIXME("(0x%08x,%p,0x%08x) stub\n",SystemInformationClass,SystemInformation,Length);
958 return STATUS_SUCCESS;
961 /******************************************************************************
962 * NtCreatePagingFile [NTDLL.@]
963 * ZwCreatePagingFile [NTDLL.@]
965 NTSTATUS WINAPI NtCreatePagingFile(
966 PUNICODE_STRING PageFileName,
967 PLARGE_INTEGER MinimumSize,
968 PLARGE_INTEGER MaximumSize,
969 PLARGE_INTEGER ActualSize)
971 FIXME("(%p %p %p %p) stub\n", PageFileName, MinimumSize, MaximumSize, ActualSize);
972 return STATUS_SUCCESS;
975 /******************************************************************************
976 * NtDisplayString [NTDLL.@]
978 * writes a string to the nt-textmode screen eg. during startup
980 NTSTATUS WINAPI NtDisplayString ( PUNICODE_STRING string )
985 if (!(ret = RtlUnicodeStringToAnsiString( &stringA, string, TRUE )))
987 MESSAGE( "%.*s", stringA.Length, stringA.Buffer );
988 RtlFreeAnsiString( &stringA );
993 /******************************************************************************
994 * NtInitiatePowerAction [NTDLL.@]
997 NTSTATUS WINAPI NtInitiatePowerAction(
998 IN POWER_ACTION SystemAction,
999 IN SYSTEM_POWER_STATE MinSystemState,
1001 IN BOOLEAN Asynchronous)
1003 FIXME("(%d,%d,0x%08x,%d),stub\n",
1004 SystemAction,MinSystemState,Flags,Asynchronous);
1005 return STATUS_NOT_IMPLEMENTED;
1009 /******************************************************************************
1010 * NtPowerInformation [NTDLL.@]
1013 NTSTATUS WINAPI NtPowerInformation(
1014 IN POWER_INFORMATION_LEVEL InformationLevel,
1015 IN PVOID lpInputBuffer,
1016 IN ULONG nInputBufferSize,
1017 IN PVOID lpOutputBuffer,
1018 IN ULONG nOutputBufferSize)
1020 TRACE("(%d,%p,%d,%p,%d)\n",
1021 InformationLevel,lpInputBuffer,nInputBufferSize,lpOutputBuffer,nOutputBufferSize);
1022 switch(InformationLevel) {
1023 case SystemPowerCapabilities: {
1024 PSYSTEM_POWER_CAPABILITIES PowerCaps = (PSYSTEM_POWER_CAPABILITIES)lpOutputBuffer;
1025 FIXME("semi-stub: SystemPowerCapabilities\n");
1026 if (nOutputBufferSize < sizeof(SYSTEM_POWER_CAPABILITIES))
1027 return STATUS_BUFFER_TOO_SMALL;
1028 /* FIXME: These values are based off a native XP desktop, should probably use APM/ACPI to get the 'real' values */
1029 PowerCaps->PowerButtonPresent = TRUE;
1030 PowerCaps->SleepButtonPresent = FALSE;
1031 PowerCaps->LidPresent = FALSE;
1032 PowerCaps->SystemS1 = TRUE;
1033 PowerCaps->SystemS2 = FALSE;
1034 PowerCaps->SystemS3 = FALSE;
1035 PowerCaps->SystemS4 = TRUE;
1036 PowerCaps->SystemS5 = TRUE;
1037 PowerCaps->HiberFilePresent = TRUE;
1038 PowerCaps->FullWake = TRUE;
1039 PowerCaps->VideoDimPresent = FALSE;
1040 PowerCaps->ApmPresent = FALSE;
1041 PowerCaps->UpsPresent = FALSE;
1042 PowerCaps->ThermalControl = FALSE;
1043 PowerCaps->ProcessorThrottle = FALSE;
1044 PowerCaps->ProcessorMinThrottle = 100;
1045 PowerCaps->ProcessorMaxThrottle = 100;
1046 PowerCaps->DiskSpinDown = TRUE;
1047 PowerCaps->SystemBatteriesPresent = FALSE;
1048 PowerCaps->BatteriesAreShortTerm = FALSE;
1049 PowerCaps->BatteryScale[0].Granularity = 0;
1050 PowerCaps->BatteryScale[0].Capacity = 0;
1051 PowerCaps->BatteryScale[1].Granularity = 0;
1052 PowerCaps->BatteryScale[1].Capacity = 0;
1053 PowerCaps->BatteryScale[2].Granularity = 0;
1054 PowerCaps->BatteryScale[2].Capacity = 0;
1055 PowerCaps->AcOnLineWake = PowerSystemUnspecified;
1056 PowerCaps->SoftLidWake = PowerSystemUnspecified;
1057 PowerCaps->RtcWake = PowerSystemSleeping1;
1058 PowerCaps->MinDeviceWakeState = PowerSystemUnspecified;
1059 PowerCaps->DefaultLowLatencyWake = PowerSystemUnspecified;
1060 return STATUS_SUCCESS;
1063 FIXME("Unimplemented NtPowerInformation action: %d\n", InformationLevel);
1064 return STATUS_NOT_IMPLEMENTED;
1068 /******************************************************************************
1069 * NtShutdownSystem [NTDLL.@]
1072 NTSTATUS WINAPI NtShutdownSystem(SHUTDOWN_ACTION Action)
1074 FIXME("%d\n",Action);
1075 return STATUS_SUCCESS;
1078 /******************************************************************************
1079 * NtAllocateLocallyUniqueId (NTDLL.@)
1081 * FIXME: the server should do that
1083 NTSTATUS WINAPI NtAllocateLocallyUniqueId(PLUID Luid)
1085 static LUID luid = { SE_MAX_WELL_KNOWN_PRIVILEGE, 0 };
1087 FIXME("%p\n", Luid);
1090 return STATUS_ACCESS_VIOLATION;
1093 if (luid.LowPart==0)
1095 Luid->HighPart = luid.HighPart;
1096 Luid->LowPart = luid.LowPart;
1098 return STATUS_SUCCESS;
1101 /******************************************************************************
1102 * VerSetConditionMask (NTDLL.@)
1104 ULONGLONG WINAPI VerSetConditionMask( ULONGLONG dwlConditionMask, DWORD dwTypeBitMask,
1105 BYTE dwConditionMask)
1107 if(dwTypeBitMask == 0)
1108 return dwlConditionMask;
1109 dwConditionMask &= 0x07;
1110 if(dwConditionMask == 0)
1111 return dwlConditionMask;
1113 if(dwTypeBitMask & VER_PRODUCT_TYPE)
1114 dwlConditionMask |= dwConditionMask << 7*3;
1115 else if (dwTypeBitMask & VER_SUITENAME)
1116 dwlConditionMask |= dwConditionMask << 6*3;
1117 else if (dwTypeBitMask & VER_SERVICEPACKMAJOR)
1118 dwlConditionMask |= dwConditionMask << 5*3;
1119 else if (dwTypeBitMask & VER_SERVICEPACKMINOR)
1120 dwlConditionMask |= dwConditionMask << 4*3;
1121 else if (dwTypeBitMask & VER_PLATFORMID)
1122 dwlConditionMask |= dwConditionMask << 3*3;
1123 else if (dwTypeBitMask & VER_BUILDNUMBER)
1124 dwlConditionMask |= dwConditionMask << 2*3;
1125 else if (dwTypeBitMask & VER_MAJORVERSION)
1126 dwlConditionMask |= dwConditionMask << 1*3;
1127 else if (dwTypeBitMask & VER_MINORVERSION)
1128 dwlConditionMask |= dwConditionMask << 0*3;
1129 return dwlConditionMask;
1132 /******************************************************************************
1133 * NtAccessCheckAndAuditAlarm (NTDLL.@)
1134 * ZwAccessCheckAndAuditAlarm (NTDLL.@)
1136 NTSTATUS WINAPI NtAccessCheckAndAuditAlarm(PUNICODE_STRING SubsystemName, HANDLE HandleId, PUNICODE_STRING ObjectTypeName,
1137 PUNICODE_STRING ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor,
1138 ACCESS_MASK DesiredAccess, PGENERIC_MAPPING GenericMapping, BOOLEAN ObjectCreation,
1139 PACCESS_MASK GrantedAccess, PBOOLEAN AccessStatus, PBOOLEAN GenerateOnClose)
1141 FIXME("(%s, %p, %s, %p, 0x%08x, %p, %d, %p, %p, %p), stub\n", debugstr_us(SubsystemName), HandleId,
1142 debugstr_us(ObjectTypeName), SecurityDescriptor, DesiredAccess, GenericMapping, ObjectCreation,
1143 GrantedAccess, AccessStatus, GenerateOnClose);
1145 return STATUS_NOT_IMPLEMENTED;