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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29 #include "wine/debug.h"
30 #include "wine/unicode.h"
34 #include "ntdll_misc.h"
35 #include "wine/server.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(ntdll);
39 /* FIXME: fixed at 2005/2/22 */
40 static LONGLONG boottime = (LONGLONG)1275356510 * 100000000;
46 /******************************************************************************
47 * NtDuplicateToken [NTDLL.@]
48 * ZwDuplicateToken [NTDLL.@]
50 NTSTATUS WINAPI NtDuplicateToken(
51 IN HANDLE ExistingToken,
52 IN ACCESS_MASK DesiredAccess,
53 IN POBJECT_ATTRIBUTES ObjectAttributes,
54 IN SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
55 IN TOKEN_TYPE TokenType,
60 TRACE("(%p,0x%08lx,%p,0x%08x,0x%08x,%p)\n",
61 ExistingToken, DesiredAccess, ObjectAttributes,
62 ImpersonationLevel, TokenType, NewToken);
63 dump_ObjectAttributes(ObjectAttributes);
65 SERVER_START_REQ( duplicate_token )
67 req->handle = ExistingToken;
68 req->access = DesiredAccess;
69 req->inherit = ObjectAttributes && (ObjectAttributes->Attributes & OBJ_INHERIT);
70 req->primary = (TokenType == TokenPrimary);
71 req->impersonation_level = ImpersonationLevel;
72 status = wine_server_call( req );
73 if (!status) *NewToken = reply->new_handle;
80 /******************************************************************************
81 * NtOpenProcessToken [NTDLL.@]
82 * ZwOpenProcessToken [NTDLL.@]
84 NTSTATUS WINAPI NtOpenProcessToken(
91 TRACE("(%p,0x%08lx,%p)\n", ProcessHandle,DesiredAccess, TokenHandle);
93 SERVER_START_REQ( open_token )
95 req->handle = ProcessHandle;
97 ret = wine_server_call( req );
98 if (!ret) *TokenHandle = reply->token;
105 /******************************************************************************
106 * NtOpenThreadToken [NTDLL.@]
107 * ZwOpenThreadToken [NTDLL.@]
109 NTSTATUS WINAPI NtOpenThreadToken(
117 TRACE("(%p,0x%08lx,0x%08x,%p)\n",
118 ThreadHandle,DesiredAccess, OpenAsSelf, TokenHandle);
120 SERVER_START_REQ( open_token )
122 req->handle = ThreadHandle;
123 req->flags = OPEN_TOKEN_THREAD;
124 if (OpenAsSelf) req->flags |= OPEN_TOKEN_AS_SELF;
125 ret = wine_server_call( req );
126 if (!ret) *TokenHandle = reply->token;
133 /******************************************************************************
134 * NtAdjustPrivilegesToken [NTDLL.@]
135 * ZwAdjustPrivilegesToken [NTDLL.@]
137 * FIXME: parameters unsafe
139 NTSTATUS WINAPI NtAdjustPrivilegesToken(
140 IN HANDLE TokenHandle,
141 IN BOOLEAN DisableAllPrivileges,
142 IN PTOKEN_PRIVILEGES NewState,
143 IN DWORD BufferLength,
144 OUT PTOKEN_PRIVILEGES PreviousState,
145 OUT PDWORD ReturnLength)
149 TRACE("(%p,0x%08x,%p,0x%08lx,%p,%p)\n",
150 TokenHandle, DisableAllPrivileges, NewState, BufferLength, PreviousState, ReturnLength);
152 SERVER_START_REQ( adjust_token_privileges )
154 req->handle = TokenHandle;
155 req->disable_all = DisableAllPrivileges;
156 req->get_modified_state = (PreviousState != NULL);
157 if (!DisableAllPrivileges)
159 wine_server_add_data( req, &NewState->Privileges,
160 NewState->PrivilegeCount * sizeof(NewState->Privileges[0]) );
162 if (PreviousState && BufferLength >= FIELD_OFFSET( TOKEN_PRIVILEGES, Privileges ))
163 wine_server_set_reply( req, &PreviousState->Privileges,
164 BufferLength - FIELD_OFFSET( TOKEN_PRIVILEGES, Privileges ) );
165 ret = wine_server_call( req );
168 *ReturnLength = reply->len + FIELD_OFFSET( TOKEN_PRIVILEGES, Privileges );
169 PreviousState->PrivilegeCount = reply->len / sizeof(LUID_AND_ATTRIBUTES);
177 /******************************************************************************
178 * NtQueryInformationToken [NTDLL.@]
179 * ZwQueryInformationToken [NTDLL.@]
182 * Buffer for TokenUser:
183 * 0x00 TOKEN_USER the PSID field points to the SID
187 NTSTATUS WINAPI NtQueryInformationToken(
189 DWORD tokeninfoclass,
191 DWORD tokeninfolength,
194 unsigned int len = 0;
195 NTSTATUS status = STATUS_SUCCESS;
197 TRACE("(%p,%ld,%p,%ld,%p)\n",
198 token,tokeninfoclass,tokeninfo,tokeninfolength,retlen);
200 switch (tokeninfoclass)
203 len = sizeof(TOKEN_USER) + sizeof(SID);
206 len = sizeof(TOKEN_GROUPS);
209 len = sizeof(TOKEN_OWNER) + sizeof(SID);
211 case TokenPrimaryGroup:
212 len = sizeof(TOKEN_PRIMARY_GROUP);
214 case TokenDefaultDacl:
215 len = sizeof(TOKEN_DEFAULT_DACL);
218 len = sizeof(TOKEN_SOURCE);
221 len = sizeof (TOKEN_TYPE);
224 case TokenImpersonationLevel:
225 case TokenStatistics:
229 /* FIXME: what if retlen == NULL ? */
232 if (tokeninfolength < len)
233 return STATUS_BUFFER_TOO_SMALL;
235 switch (tokeninfoclass)
240 TOKEN_USER * tuser = tokeninfo;
241 PSID sid = (PSID) (tuser + 1);
242 SID_IDENTIFIER_AUTHORITY localSidAuthority = {SECURITY_NT_AUTHORITY};
243 RtlInitializeSid(sid, &localSidAuthority, 1);
244 *(RtlSubAuthoritySid(sid, 0)) = SECURITY_INTERACTIVE_RID;
245 tuser->User.Sid = sid;
251 TOKEN_GROUPS *tgroups = tokeninfo;
252 SID_IDENTIFIER_AUTHORITY sid = {SECURITY_NT_AUTHORITY};
254 /* we need to show admin privileges ! */
255 tgroups->GroupCount = 1;
256 tgroups->Groups->Attributes = SE_GROUP_ENABLED;
257 RtlAllocateAndInitializeSid( &sid,
259 SECURITY_BUILTIN_DOMAIN_RID,
260 DOMAIN_ALIAS_RID_ADMINS,
262 &(tgroups->Groups->Sid));
265 case TokenPrimaryGroup:
268 TOKEN_PRIMARY_GROUP *tgroup = tokeninfo;
269 SID_IDENTIFIER_AUTHORITY sid = {SECURITY_NT_AUTHORITY};
270 RtlAllocateAndInitializeSid( &sid,
272 SECURITY_BUILTIN_DOMAIN_RID,
273 DOMAIN_ALIAS_RID_ADMINS,
275 &(tgroup->PrimaryGroup));
278 case TokenPrivileges:
279 SERVER_START_REQ( get_token_privileges )
281 TOKEN_PRIVILEGES *tpriv = tokeninfo;
283 if (tpriv && tokeninfolength > FIELD_OFFSET( TOKEN_PRIVILEGES, Privileges ))
284 wine_server_set_reply( req, &tpriv->Privileges, tokeninfolength - FIELD_OFFSET( TOKEN_PRIVILEGES, Privileges ) );
285 status = wine_server_call( req );
286 *retlen = FIELD_OFFSET( TOKEN_PRIVILEGES, Privileges ) + reply->len;
287 if (tpriv) tpriv->PrivilegeCount = reply->len / sizeof(LUID_AND_ATTRIBUTES);
294 TOKEN_OWNER *owner = tokeninfo;
295 PSID sid = (PSID) (owner + 1);
296 SID_IDENTIFIER_AUTHORITY localSidAuthority = {SECURITY_NT_AUTHORITY};
297 RtlInitializeSid(sid, &localSidAuthority, 1);
298 *(RtlSubAuthoritySid(sid, 0)) = SECURITY_INTERACTIVE_RID;
304 ERR("Unhandled Token Information class %ld!\n", tokeninfoclass);
305 return STATUS_NOT_IMPLEMENTED;
311 /******************************************************************************
312 * NtSetInformationToken [NTDLL.@]
313 * ZwSetInformationToken [NTDLL.@]
315 NTSTATUS WINAPI NtSetInformationToken(
317 TOKEN_INFORMATION_CLASS TokenInformationClass,
318 PVOID TokenInformation,
319 ULONG TokenInformationLength)
321 FIXME("%p %d %p %lu\n", TokenHandle, TokenInformationClass,
322 TokenInformation, TokenInformationLength);
323 return STATUS_NOT_IMPLEMENTED;
326 /******************************************************************************
327 * NtAdjustGroupsToken [NTDLL.@]
328 * ZwAdjustGroupsToken [NTDLL.@]
330 NTSTATUS WINAPI NtAdjustGroupsToken(
332 BOOLEAN ResetToDefault,
333 PTOKEN_GROUPS NewState,
335 PTOKEN_GROUPS PreviousState,
338 FIXME("%p %d %p %lu %p %p\n", TokenHandle, ResetToDefault,
339 NewState, BufferLength, PreviousState, ReturnLength);
340 return STATUS_NOT_IMPLEMENTED;
343 /******************************************************************************
344 * NtPrivilegeCheck [NTDLL.@]
345 * ZwPrivilegeCheck [NTDLL.@]
347 NTSTATUS WINAPI NtPrivilegeCheck(
349 PPRIVILEGE_SET RequiredPrivileges,
353 SERVER_START_REQ( check_token_privileges )
355 req->handle = ClientToken;
356 req->all_required = ((RequiredPrivileges->Control & PRIVILEGE_SET_ALL_NECESSARY) ? TRUE : FALSE);
357 wine_server_add_data( req, &RequiredPrivileges->Privilege,
358 RequiredPrivileges->PrivilegeCount * sizeof(RequiredPrivileges->Privilege[0]) );
359 wine_server_set_reply( req, &RequiredPrivileges->Privilege,
360 RequiredPrivileges->PrivilegeCount * sizeof(RequiredPrivileges->Privilege[0]) );
362 status = wine_server_call( req );
364 if (status == STATUS_SUCCESS)
365 *Result = (reply->has_privileges ? TRUE : FALSE);
375 /******************************************************************************
376 * NtQuerySection [NTDLL.@]
378 NTSTATUS WINAPI NtQuerySection(
379 IN HANDLE SectionHandle,
380 IN SECTION_INFORMATION_CLASS SectionInformationClass,
381 OUT PVOID SectionInformation,
383 OUT PULONG ResultLength)
385 FIXME("(%p,%d,%p,0x%08lx,%p) stub!\n",
386 SectionHandle,SectionInformationClass,SectionInformation,Length,ResultLength);
394 /******************************************************************************
395 * NtCreatePort [NTDLL.@]
396 * ZwCreatePort [NTDLL.@]
398 NTSTATUS WINAPI NtCreatePort(PHANDLE PortHandle,POBJECT_ATTRIBUTES ObjectAttributes,
399 ULONG MaxConnectInfoLength,ULONG MaxDataLength,PULONG reserved)
401 FIXME("(%p,%p,%lu,%lu,%p),stub!\n",PortHandle,ObjectAttributes,
402 MaxConnectInfoLength,MaxDataLength,reserved);
406 /******************************************************************************
407 * NtConnectPort [NTDLL.@]
408 * ZwConnectPort [NTDLL.@]
410 NTSTATUS WINAPI NtConnectPort(
412 PUNICODE_STRING PortName,
413 PSECURITY_QUALITY_OF_SERVICE SecurityQos,
414 PLPC_SECTION_WRITE WriteSection,
415 PLPC_SECTION_READ ReadSection,
416 PULONG MaximumMessageLength,
418 PULONG pConnectInfoLength)
420 FIXME("(%p,%s,%p,%p,%p,%p,%p,%p),stub!\n",
421 PortHandle,debugstr_w(PortName->Buffer),SecurityQos,
422 WriteSection,ReadSection,MaximumMessageLength,ConnectInfo,
424 if (ConnectInfo && pConnectInfoLength)
425 TRACE("\tMessage = %s\n",debugstr_an(ConnectInfo,*pConnectInfoLength));
429 /******************************************************************************
430 * NtListenPort [NTDLL.@]
431 * ZwListenPort [NTDLL.@]
433 NTSTATUS WINAPI NtListenPort(HANDLE PortHandle,PLPC_MESSAGE pLpcMessage)
435 FIXME("(%p,%p),stub!\n",PortHandle,pLpcMessage);
439 /******************************************************************************
440 * NtAcceptConnectPort [NTDLL.@]
441 * ZwAcceptConnectPort [NTDLL.@]
443 NTSTATUS WINAPI NtAcceptConnectPort(
445 ULONG PortIdentifier,
446 PLPC_MESSAGE pLpcMessage,
448 PLPC_SECTION_WRITE WriteSection,
449 PLPC_SECTION_READ ReadSection)
451 FIXME("(%p,%lu,%p,%d,%p,%p),stub!\n",
452 PortHandle,PortIdentifier,pLpcMessage,Accept,WriteSection,ReadSection);
456 /******************************************************************************
457 * NtCompleteConnectPort [NTDLL.@]
458 * ZwCompleteConnectPort [NTDLL.@]
460 NTSTATUS WINAPI NtCompleteConnectPort(HANDLE PortHandle)
462 FIXME("(%p),stub!\n",PortHandle);
466 /******************************************************************************
467 * NtRegisterThreadTerminatePort [NTDLL.@]
468 * ZwRegisterThreadTerminatePort [NTDLL.@]
470 NTSTATUS WINAPI NtRegisterThreadTerminatePort(HANDLE PortHandle)
472 FIXME("(%p),stub!\n",PortHandle);
476 /******************************************************************************
477 * NtRequestWaitReplyPort [NTDLL.@]
478 * ZwRequestWaitReplyPort [NTDLL.@]
480 NTSTATUS WINAPI NtRequestWaitReplyPort(
482 PLPC_MESSAGE pLpcMessageIn,
483 PLPC_MESSAGE pLpcMessageOut)
485 FIXME("(%p,%p,%p),stub!\n",PortHandle,pLpcMessageIn,pLpcMessageOut);
488 TRACE("Message to send:\n");
489 TRACE("\tDataSize = %u\n",pLpcMessageIn->DataSize);
490 TRACE("\tMessageSize = %u\n",pLpcMessageIn->MessageSize);
491 TRACE("\tMessageType = %u\n",pLpcMessageIn->MessageType);
492 TRACE("\tVirtualRangesOffset = %u\n",pLpcMessageIn->VirtualRangesOffset);
493 TRACE("\tClientId.UniqueProcess = %p\n",pLpcMessageIn->ClientId.UniqueProcess);
494 TRACE("\tClientId.UniqueThread = %p\n",pLpcMessageIn->ClientId.UniqueThread);
495 TRACE("\tMessageId = %lu\n",pLpcMessageIn->MessageId);
496 TRACE("\tSectionSize = %lu\n",pLpcMessageIn->SectionSize);
497 TRACE("\tData = %s\n",
498 debugstr_an(pLpcMessageIn->Data,pLpcMessageIn->DataSize));
503 /******************************************************************************
504 * NtReplyWaitReceivePort [NTDLL.@]
505 * ZwReplyWaitReceivePort [NTDLL.@]
507 NTSTATUS WINAPI NtReplyWaitReceivePort(
509 PULONG PortIdentifier,
510 PLPC_MESSAGE ReplyMessage,
511 PLPC_MESSAGE Message)
513 FIXME("(%p,%p,%p,%p),stub!\n",PortHandle,PortIdentifier,ReplyMessage,Message);
521 /******************************************************************************
522 * NtSetIntervalProfile [NTDLL.@]
523 * ZwSetIntervalProfile [NTDLL.@]
525 NTSTATUS WINAPI NtSetIntervalProfile(
527 KPROFILE_SOURCE Source)
529 FIXME("%lu,%d\n", Interval, Source);
530 return STATUS_SUCCESS;
533 /******************************************************************************
534 * NtQueryPerformanceCounter [NTDLL.@]
536 * Note: Windows uses a timer clocked at a multiple of 1193182 Hz. There is a
537 * good number of applications that crash when the returned frequency is either
538 * lower or higher then what Windows gives. Also too high counter values are
539 * reported to give problems.
541 NTSTATUS WINAPI NtQueryPerformanceCounter(
542 OUT PLARGE_INTEGER Counter,
543 OUT PLARGE_INTEGER Frequency)
547 if (!Counter) return STATUS_ACCESS_VIOLATION;
548 NtQuerySystemTime( &time );
549 time.QuadPart -= boottime;
550 /* convert a counter that increments at a rate of 10 MHz
551 * to one of 1193182 Hz, with some care for arithmetic
552 * overflow ( will not overflow until 3396 or so ) and
553 * good accuracy ( 21/176 = 0.119318182) */
554 Counter->QuadPart = (time.QuadPart * 21) / 176;
556 Frequency->QuadPart = 1193182;
560 /******************************************************************************
561 * NtQuerySystemInformation [NTDLL.@]
562 * ZwQuerySystemInformation [NTDLL.@]
565 * SystemInformationClass Index to a certain information structure
566 * SystemTimeAdjustmentInformation SYSTEM_TIME_ADJUSTMENT
567 * SystemCacheInformation SYSTEM_CACHE_INFORMATION
568 * SystemConfigurationInformation CONFIGURATION_INFORMATION
569 * observed (class/len):
575 * SystemInformation caller supplies storage for the information structure
576 * Length size of the structure
577 * ResultLength Data written
579 NTSTATUS WINAPI NtQuerySystemInformation(
580 IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
581 OUT PVOID SystemInformation,
583 OUT PULONG ResultLength)
585 NTSTATUS ret = STATUS_SUCCESS;
588 TRACE("(0x%08x,%p,0x%08lx,%p)\n",
589 SystemInformationClass,SystemInformation,Length,ResultLength);
591 switch (SystemInformationClass)
593 case SystemBasicInformation:
595 SYSTEM_BASIC_INFORMATION sbi;
598 sbi.uKeMaximumIncrement = 0;
599 sbi.uPageSize = 1024; /* FIXME */
600 sbi.uMmNumberOfPhysicalPages = 12345; /* FIXME */
601 sbi.uMmLowestPhysicalPage = 0; /* FIXME */
602 sbi.uMmHighestPhysicalPage = 12345; /* FIXME */
603 sbi.uAllocationGranularity = 65536; /* FIXME */
604 sbi.pLowestUserAddress = 0; /* FIXME */
605 sbi.pMmHighestUserAddress = (void*)~0; /* FIXME */
606 sbi.uKeActiveProcessors = 1; /* FIXME */
607 sbi.bKeNumberProcessors = 1; /* FIXME */
612 if (!SystemInformation) ret = STATUS_ACCESS_VIOLATION;
613 else memcpy( SystemInformation, &sbi, len);
615 else ret = STATUS_INFO_LENGTH_MISMATCH;
618 case SystemCpuInformation:
620 SYSTEM_CPU_INFORMATION sci;
622 /* FIXME: move some code from kernel/cpu.c to process this */
623 sci.Architecture = PROCESSOR_ARCHITECTURE_INTEL;
624 sci.Level = 6; /* 686, aka Pentium II+ */
627 sci.FeatureSet = 0x1fff;
632 if (!SystemInformation) ret = STATUS_ACCESS_VIOLATION;
633 else memcpy( SystemInformation, &sci, len);
635 else ret = STATUS_INFO_LENGTH_MISMATCH;
638 case SystemPerformanceInformation:
640 SYSTEM_PERFORMANCE_INFORMATION* spi = (SYSTEM_PERFORMANCE_INFORMATION*)SystemInformation;
641 if (Length >= sizeof(*spi))
643 memset(spi, 0, sizeof(*spi)); /* FIXME */
646 else ret = STATUS_INFO_LENGTH_MISMATCH;
649 case SystemTimeOfDayInformation:
651 SYSTEM_TIMEOFDAY_INFORMATION sti;
653 memset(&sti, 0 , sizeof(sti));
655 /* liKeSystemTime, liExpTimeZoneBias, uCurrentTimeZoneId */
656 sti.liKeBootTime.QuadPart = boottime;
658 if (Length <= sizeof(sti))
661 if (!SystemInformation) ret = STATUS_ACCESS_VIOLATION;
662 else memcpy( SystemInformation, &sti, Length);
664 else ret = STATUS_INFO_LENGTH_MISMATCH;
667 case SystemProcessInformation:
669 SYSTEM_PROCESS_INFORMATION* spi = (SYSTEM_PROCESS_INFORMATION*)SystemInformation;
670 SYSTEM_PROCESS_INFORMATION* last = NULL;
672 WCHAR procname[1024];
675 DWORD procstructlen = 0;
677 SERVER_START_REQ( create_snapshot )
679 req->flags = SNAP_PROCESS | SNAP_THREAD;
680 req->inherit = FALSE;
682 if (!(ret = wine_server_call( req ))) hSnap = reply->handle;
686 while (ret == STATUS_SUCCESS)
688 SERVER_START_REQ( next_process )
691 req->reset = (len == 0);
692 wine_server_set_reply( req, procname, sizeof(procname)-sizeof(WCHAR) );
693 if (!(ret = wine_server_call( req )))
695 /* Make sure procname is 0 terminated */
696 procname[wine_server_reply_size(reply) / sizeof(WCHAR)] = 0;
698 /* Get only the executable name, not the path */
699 if ((exename = strrchrW(procname, '\\')) != NULL) exename++;
700 else exename = procname;
702 wlen = (strlenW(exename) + 1) * sizeof(WCHAR);
704 procstructlen = sizeof(*spi) + wlen + ((reply->threads - 1) * sizeof(SYSTEM_THREAD_INFORMATION));
706 if (Length >= len + procstructlen)
708 /* ftCreationTime, ftUserTime, ftKernelTime;
709 * vmCounters, ioCounters
712 memset(spi, 0, sizeof(*spi));
714 spi->dwOffset = procstructlen - wlen;
715 spi->dwThreadCount = reply->threads;
717 /* spi->pszProcessName will be set later on */
719 spi->dwBasePriority = reply->priority;
720 spi->dwProcessID = (DWORD)reply->pid;
721 spi->dwParentProcessID = (DWORD)reply->ppid;
722 spi->dwHandleCount = reply->handles;
724 /* spi->ti will be set later on */
726 len += procstructlen;
728 else ret = STATUS_INFO_LENGTH_MISMATCH;
733 if (ret != STATUS_SUCCESS)
735 if (ret == STATUS_NO_MORE_FILES) ret = STATUS_SUCCESS;
738 else /* Length is already checked for */
742 /* set thread info */
744 while (ret == STATUS_SUCCESS)
746 SERVER_START_REQ( next_thread )
749 req->reset = (j == 0);
750 if (!(ret = wine_server_call( req )))
753 if (reply->pid == spi->dwProcessID)
755 /* ftKernelTime, ftUserTime, ftCreateTime;
756 * dwTickCount, dwStartAddress
759 memset(&spi->ti[i], 0, sizeof(spi->ti));
761 spi->ti[i].dwOwningPID = reply->pid;
762 spi->ti[i].dwThreadID = reply->tid;
763 spi->ti[i].dwCurrentPriority = reply->base_pri + reply->delta_pri;
764 spi->ti[i].dwBasePriority = reply->base_pri;
771 if (ret == STATUS_NO_MORE_FILES) ret = STATUS_SUCCESS;
773 /* now append process name */
774 spi->ProcessName.Buffer = (WCHAR*)((char*)spi + spi->dwOffset);
775 spi->ProcessName.Length = wlen - sizeof(WCHAR);
776 spi->ProcessName.MaximumLength = wlen;
777 memcpy( spi->ProcessName.Buffer, exename, wlen );
778 spi->dwOffset += wlen;
781 spi = (SYSTEM_PROCESS_INFORMATION*)((char*)spi + spi->dwOffset);
784 if (ret == STATUS_SUCCESS && last) last->dwOffset = 0;
785 if (hSnap) NtClose(hSnap);
788 case SystemProcessorPerformanceInformation:
790 SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION* sppi = (SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION*)SystemInformation;
791 if (Length >= sizeof(*sppi))
793 memset(sppi, 0, sizeof(*sppi)); /* FIXME */
796 else ret = STATUS_INFO_LENGTH_MISMATCH;
799 case SystemModuleInformation:
801 SYSTEM_DRIVER_INFORMATION sdi;
803 memset(&sdi, 0, sizeof(sdi));
808 if (!SystemInformation) ret = STATUS_ACCESS_VIOLATION;
809 else memcpy( SystemInformation, &sdi, len);
811 else ret = STATUS_INFO_LENGTH_MISMATCH;
814 case SystemHandleInformation:
816 SYSTEM_HANDLE_INFORMATION shi;
818 memset(&shi, 0, sizeof(shi));
823 if (!SystemInformation) ret = STATUS_ACCESS_VIOLATION;
824 else memcpy( SystemInformation, &shi, len);
826 else ret = STATUS_INFO_LENGTH_MISMATCH;
829 case SystemCacheInformation:
831 SYSTEM_CACHE_INFORMATION* sci = (SYSTEM_CACHE_INFORMATION*)SystemInformation;
832 if (Length >= sizeof(*sci))
834 memset(sci, 0, sizeof(*sci)); /* FIXME */
837 else ret = STATUS_INFO_LENGTH_MISMATCH;
840 case SystemInterruptInformation:
842 SYSTEM_INTERRUPT_INFORMATION sii;
844 memset(&sii, 0, sizeof(sii));
849 if (!SystemInformation) ret = STATUS_ACCESS_VIOLATION;
850 else memcpy( SystemInformation, &sii, len);
852 else ret = STATUS_INFO_LENGTH_MISMATCH;
855 case SystemKernelDebuggerInformation:
857 PSYSTEM_KERNEL_DEBUGGER_INFORMATION pkdi;
858 if( Length >= sizeof(*pkdi))
860 pkdi = SystemInformation;
861 pkdi->DebuggerEnabled = FALSE;
862 pkdi->DebuggerNotPresent = TRUE;
865 else ret = STATUS_INFO_LENGTH_MISMATCH;
868 case SystemRegistryQuotaInformation:
869 /* Something to do with the size of the registry *
870 * Since we don't have a size limitation, fake it *
871 * This is almost certainly wrong. *
872 * This sets each of the three words in the struct to 32 MB, *
873 * which is enough to make the IE 5 installer happy. */
875 SYSTEM_REGISTRY_QUOTA_INFORMATION* srqi = (SYSTEM_REGISTRY_QUOTA_INFORMATION*)SystemInformation;
876 if (Length >= sizeof(*srqi))
878 FIXME("(0x%08x,%p,0x%08lx,%p) faking max registry size of 32 MB\n",
879 SystemInformationClass,SystemInformation,Length,ResultLength);
880 srqi->RegistryQuotaAllowed = 0x2000000;
881 srqi->RegistryQuotaUsed = 0x200000;
882 srqi->Reserved1 = (void*)0x200000;
885 else ret = STATUS_INFO_LENGTH_MISMATCH;
889 FIXME("(0x%08x,%p,0x%08lx,%p) stub\n",
890 SystemInformationClass,SystemInformation,Length,ResultLength);
892 /* Several Information Classes are not implemented on Windows and return 2 different values
893 * STATUS_NOT_IMPLEMENTED or STATUS_INVALID_INFO_CLASS
894 * in 95% of the cases it's STATUS_INVALID_INFO_CLASS, so use this as the default
896 ret = STATUS_INVALID_INFO_CLASS;
899 if (ResultLength) *ResultLength = len;
905 /******************************************************************************
906 * NtCreatePagingFile [NTDLL.@]
907 * ZwCreatePagingFile [NTDLL.@]
909 NTSTATUS WINAPI NtCreatePagingFile(
910 PUNICODE_STRING PageFileName,
911 PLARGE_INTEGER MiniumSize,
912 PLARGE_INTEGER MaxiumSize,
913 PLARGE_INTEGER ActualSize)
915 FIXME("%p %p %p %p\n", PageFileName, MiniumSize, MaxiumSize, ActualSize);
916 return STATUS_SUCCESS;
919 /******************************************************************************
920 * NtDisplayString [NTDLL.@]
922 * writes a string to the nt-textmode screen eg. during startup
924 NTSTATUS WINAPI NtDisplayString ( PUNICODE_STRING string )
929 if (!(ret = RtlUnicodeStringToAnsiString( &stringA, string, TRUE )))
931 MESSAGE( "%.*s", stringA.Length, stringA.Buffer );
932 RtlFreeAnsiString( &stringA );
937 /******************************************************************************
938 * NtInitiatePowerAction [NTDLL.@]
941 NTSTATUS WINAPI NtInitiatePowerAction(
942 IN POWER_ACTION SystemAction,
943 IN SYSTEM_POWER_STATE MinSystemState,
945 IN BOOLEAN Asynchronous)
947 FIXME("(%d,%d,0x%08lx,%d),stub\n",
948 SystemAction,MinSystemState,Flags,Asynchronous);
949 return STATUS_NOT_IMPLEMENTED;
953 /******************************************************************************
954 * NtPowerInformation [NTDLL.@]
957 NTSTATUS WINAPI NtPowerInformation(
958 IN POWER_INFORMATION_LEVEL InformationLevel,
959 IN PVOID lpInputBuffer,
960 IN ULONG nInputBufferSize,
961 IN PVOID lpOutputBuffer,
962 IN ULONG nOutputBufferSize)
964 TRACE("(%d,%p,%ld,%p,%ld)\n",
965 InformationLevel,lpInputBuffer,nInputBufferSize,lpOutputBuffer,nOutputBufferSize);
966 switch(InformationLevel) {
967 case SystemPowerCapabilities: {
968 PSYSTEM_POWER_CAPABILITIES PowerCaps = (PSYSTEM_POWER_CAPABILITIES)lpOutputBuffer;
969 FIXME("semi-stub: SystemPowerCapabilities\n");
970 if (nOutputBufferSize < sizeof(SYSTEM_POWER_CAPABILITIES))
971 return STATUS_BUFFER_TOO_SMALL;
972 /* FIXME: These values are based off a native XP desktop, should probably use APM/ACPI to get the 'real' values */
973 PowerCaps->PowerButtonPresent = TRUE;
974 PowerCaps->SleepButtonPresent = FALSE;
975 PowerCaps->LidPresent = FALSE;
976 PowerCaps->SystemS1 = TRUE;
977 PowerCaps->SystemS2 = FALSE;
978 PowerCaps->SystemS3 = FALSE;
979 PowerCaps->SystemS4 = TRUE;
980 PowerCaps->SystemS5 = TRUE;
981 PowerCaps->HiberFilePresent = TRUE;
982 PowerCaps->FullWake = TRUE;
983 PowerCaps->VideoDimPresent = FALSE;
984 PowerCaps->ApmPresent = FALSE;
985 PowerCaps->UpsPresent = FALSE;
986 PowerCaps->ThermalControl = FALSE;
987 PowerCaps->ProcessorThrottle = FALSE;
988 PowerCaps->ProcessorMinThrottle = 100;
989 PowerCaps->ProcessorMaxThrottle = 100;
990 PowerCaps->DiskSpinDown = TRUE;
991 PowerCaps->SystemBatteriesPresent = FALSE;
992 PowerCaps->BatteriesAreShortTerm = FALSE;
993 PowerCaps->BatteryScale[0].Granularity = 0;
994 PowerCaps->BatteryScale[0].Capacity = 0;
995 PowerCaps->BatteryScale[1].Granularity = 0;
996 PowerCaps->BatteryScale[1].Capacity = 0;
997 PowerCaps->BatteryScale[2].Granularity = 0;
998 PowerCaps->BatteryScale[2].Capacity = 0;
999 PowerCaps->AcOnLineWake = PowerSystemUnspecified;
1000 PowerCaps->SoftLidWake = PowerSystemUnspecified;
1001 PowerCaps->RtcWake = PowerSystemSleeping1;
1002 PowerCaps->MinDeviceWakeState = PowerSystemUnspecified;
1003 PowerCaps->DefaultLowLatencyWake = PowerSystemUnspecified;
1004 return STATUS_SUCCESS;
1007 FIXME("Unimplemented NtPowerInformation action: %d\n", InformationLevel);
1008 return STATUS_NOT_IMPLEMENTED;
1012 /******************************************************************************
1013 * NtShutdownSystem [NTDLL.@]
1016 NTSTATUS WINAPI NtShutdownSystem(SHUTDOWN_ACTION Action)
1018 FIXME("%d\n",Action);
1019 return STATUS_SUCCESS;
1022 /******************************************************************************
1023 * NtAllocateLocallyUniqueId (NTDLL.@)
1025 * FIXME: the server should do that
1027 NTSTATUS WINAPI NtAllocateLocallyUniqueId(PLUID Luid)
1029 static LUID luid = { SE_MAX_WELL_KNOWN_PRIVILEGE, 0 };
1031 FIXME("%p\n", Luid);
1034 return STATUS_ACCESS_VIOLATION;
1037 if (luid.LowPart==0)
1039 Luid->HighPart = luid.HighPart;
1040 Luid->LowPart = luid.LowPart;
1042 return STATUS_SUCCESS;
1045 /******************************************************************************
1046 * VerSetConditionMask (NTDLL.@)
1048 ULONGLONG WINAPI VerSetConditionMask( ULONGLONG dwlConditionMask, DWORD dwTypeBitMask,
1049 BYTE dwConditionMask)
1051 if(dwTypeBitMask == 0)
1052 return dwlConditionMask;
1053 dwConditionMask &= 0x07;
1054 if(dwConditionMask == 0)
1055 return dwlConditionMask;
1057 if(dwTypeBitMask & VER_PRODUCT_TYPE)
1058 dwlConditionMask |= dwConditionMask << 7*3;
1059 else if (dwTypeBitMask & VER_SUITENAME)
1060 dwlConditionMask |= dwConditionMask << 6*3;
1061 else if (dwTypeBitMask & VER_SERVICEPACKMAJOR)
1062 dwlConditionMask |= dwConditionMask << 5*3;
1063 else if (dwTypeBitMask & VER_SERVICEPACKMINOR)
1064 dwlConditionMask |= dwConditionMask << 4*3;
1065 else if (dwTypeBitMask & VER_PLATFORMID)
1066 dwlConditionMask |= dwConditionMask << 3*3;
1067 else if (dwTypeBitMask & VER_BUILDNUMBER)
1068 dwlConditionMask |= dwConditionMask << 2*3;
1069 else if (dwTypeBitMask & VER_MAJORVERSION)
1070 dwlConditionMask |= dwConditionMask << 1*3;
1071 else if (dwTypeBitMask & VER_MINORVERSION)
1072 dwlConditionMask |= dwConditionMask << 0*3;
1073 return dwlConditionMask;
1076 /******************************************************************************
1077 * NtAlertThread (NTDLL.@)
1079 NTSTATUS WINAPI NtAlertThread(HANDLE ThreadHandle)
1081 FIXME("%p\n", ThreadHandle);
1082 return STATUS_NOT_IMPLEMENTED;