/* The maximum size of an environment value (in bytes) */
#define MAX_ENVVAL_SIZE 1024
+extern LIST_ENTRY HandleTableListHead;
+extern EX_PUSH_LOCK HandleTableListLock;
+
FAST_MUTEX ExpEnvironmentLock;
ERESOURCE ExpFirmwareTableResource;
LIST_ENTRY ExpFirmwareTableProviderListHead;
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
ExFreePoolWithTag(Mdl, TAG_MDL);
- return _SEH2_GetExceptionCode();
+ _SEH2_YIELD(return _SEH2_GetExceptionCode());
}
_SEH2_END;
NTSTATUS
NTAPI
NtSetSystemEnvironmentValueEx(IN PUNICODE_STRING VariableName,
- IN LPGUID VendorGuid)
+ IN LPGUID VendorGuid,
+ IN PVOID Value,
+ IN OUT PULONG ReturnLength,
+ IN OUT PULONG Attributes)
{
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
{
SpiCurrent = (PSYSTEM_PROCESS_INFORMATION) Current;
+ /* Lock the Process */
+ KeEnterCriticalRegion();
+ ExAcquirePushLockShared(&Process->ProcessLock);
+
if ((Process->ProcessExiting) &&
(Process->Pcb.Header.SignalState) &&
!(Process->ActiveThreads) &&
Process, Process->ImageFileName, Process->UniqueProcessId);
CurrentSize = 0;
ImageNameMaximumLength = 0;
+
+ /* Unlock the Process */
+ ExReleasePushLockShared(&Process->ProcessLock);
+ KeLeaveCriticalRegion();
goto Skip;
}
ProcessImageName = NULL;
}
+ /* Unlock the Process */
+ ExReleasePushLockShared(&Process->ProcessLock);
+ KeLeaveCriticalRegion();
+
/* Handle idle process entry */
Skip:
if (Process == PsIdleProcess) Process = NULL;
/* Class 9 - Flags Information */
QSI_DEF(SystemFlagsInformation)
{
+#if (NTDDI_VERSION >= NTDDI_VISTA)
+ *ReqSize = sizeof(SYSTEM_FLAGS_INFORMATION);
+#endif
+
if (sizeof(SYSTEM_FLAGS_INFORMATION) != Size)
{
- *ReqSize = sizeof(SYSTEM_FLAGS_INFORMATION);
- return (STATUS_INFO_LENGTH_MISMATCH);
+ return STATUS_INFO_LENGTH_MISMATCH;
}
+
((PSYSTEM_FLAGS_INFORMATION) Buffer)->Flags = NtGlobalFlag;
+#if (NTDDI_VERSION < NTDDI_VISTA)
+ *ReqSize = sizeof(SYSTEM_FLAGS_INFORMATION);
+#endif
+
return STATUS_SUCCESS;
}
/* Class 16 - Handle Information */
QSI_DEF(SystemHandleInformation)
{
- PEPROCESS pr, syspr;
- ULONG curSize, i = 0;
- ULONG hCount = 0;
-
- PSYSTEM_HANDLE_INFORMATION Shi =
- (PSYSTEM_HANDLE_INFORMATION) Buffer;
+ PSYSTEM_HANDLE_INFORMATION HandleInformation;
+ PLIST_ENTRY NextTableEntry;
+ PHANDLE_TABLE HandleTable;
+ PHANDLE_TABLE_ENTRY HandleTableEntry;
+ EXHANDLE Handle;
+ ULONG Index = 0;
+ NTSTATUS Status;
+ PMDL Mdl;
+ PAGED_CODE();
DPRINT("NtQuerySystemInformation - SystemHandleInformation\n");
- if (Size < sizeof(SYSTEM_HANDLE_INFORMATION))
+ /* Set initial required buffer size */
+ *ReqSize = FIELD_OFFSET(SYSTEM_HANDLE_INFORMATION, Handles);
+
+ /* Check user's buffer size */
+ if (Size < *ReqSize)
{
- *ReqSize = sizeof(SYSTEM_HANDLE_INFORMATION);
return STATUS_INFO_LENGTH_MISMATCH;
}
- DPRINT("SystemHandleInformation 1\n");
+ /* We need to lock down the memory */
+ Status = ExLockUserBuffer(Buffer,
+ Size,
+ ExGetPreviousMode(),
+ IoWriteAccess,
+ (PVOID*)&HandleInformation,
+ &Mdl);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to lock the user buffer: 0x%lx\n", Status);
+ return Status;
+ }
- /* First Calc Size from Count. */
- syspr = PsGetNextProcess(NULL);
- pr = syspr;
+ /* Reset of count of handles */
+ HandleInformation->NumberOfHandles = 0;
- do
- {
- hCount = hCount + ObGetProcessHandleCount(pr);
- pr = PsGetNextProcess(pr);
+ /* Enter a critical region */
+ KeEnterCriticalRegion();
- if ((pr == syspr) || (pr == NULL)) break;
- }
- while ((pr != syspr) && (pr != NULL));
+ /* Acquire the handle table lock */
+ ExAcquirePushLockShared(&HandleTableListLock);
- if(pr != NULL)
+ /* Enumerate all system handles */
+ for (NextTableEntry = HandleTableListHead.Flink;
+ NextTableEntry != &HandleTableListHead;
+ NextTableEntry = NextTableEntry->Flink)
{
- ObDereferenceObject(pr);
- }
+ /* Get current handle table */
+ HandleTable = CONTAINING_RECORD(NextTableEntry, HANDLE_TABLE, HandleTableList);
+
+ /* Set the initial value and loop the entries */
+ Handle.Value = 0;
+ while ((HandleTableEntry = ExpLookupHandleTableEntry(HandleTable, Handle)))
+ {
+ /* Validate the entry */
+ if ((HandleTableEntry->Object) &&
+ (HandleTableEntry->NextFreeTableEntry != -2))
+ {
+ /* Increase of count of handles */
+ ++HandleInformation->NumberOfHandles;
- DPRINT("SystemHandleInformation 2\n");
+ /* Lock the entry */
+ if (ExpLockHandleTableEntry(HandleTable, HandleTableEntry))
+ {
+ /* Increase required buffer size */
+ *ReqSize += sizeof(SYSTEM_HANDLE_TABLE_ENTRY_INFO);
- curSize = sizeof(SYSTEM_HANDLE_INFORMATION) +
- ((sizeof(SYSTEM_HANDLE_TABLE_ENTRY_INFO) * hCount) -
- (sizeof(SYSTEM_HANDLE_TABLE_ENTRY_INFO)));
+ /* Check user's buffer size */
+ if (*ReqSize > Size)
+ {
+ Status = STATUS_INFO_LENGTH_MISMATCH;
+ }
+ else
+ {
+ POBJECT_HEADER ObjectHeader = ObpGetHandleObject(HandleTableEntry);
- Shi->NumberOfHandles = hCount;
+ /* Filling handle information */
+ HandleInformation->Handles[Index].UniqueProcessId =
+ (USHORT)(ULONG_PTR) HandleTable->UniqueProcessId;
- if (curSize > Size)
- {
- *ReqSize = curSize;
- return (STATUS_INFO_LENGTH_MISMATCH);
- }
+ HandleInformation->Handles[Index].CreatorBackTraceIndex = 0;
- DPRINT("SystemHandleInformation 3\n");
+#if 0 /* FIXME!!! Type field currupted */
+ HandleInformation->Handles[Index].ObjectTypeIndex =
+ (UCHAR) ObjectHeader->Type->Index;
+#else
+ HandleInformation->Handles[Index].ObjectTypeIndex = 0;
+#endif
- /* Now get Handles from all processes. */
- syspr = PsGetNextProcess(NULL);
- pr = syspr;
+ HandleInformation->Handles[Index].HandleAttributes =
+ HandleTableEntry->ObAttributes & OBJ_HANDLE_ATTRIBUTES;
- do
- {
- int Count = 0, HandleCount;
+ HandleInformation->Handles[Index].HandleValue =
+ (USHORT)(ULONG_PTR) Handle.GenericHandleOverlay;
- HandleCount = ObGetProcessHandleCount(pr);
+ HandleInformation->Handles[Index].Object = &ObjectHeader->Body;
- for (Count = 0; HandleCount > 0 ; HandleCount--)
- {
- Shi->Handles[i].UniqueProcessId = (USHORT)(ULONG_PTR)pr->UniqueProcessId;
- Count++;
- i++;
- }
+ HandleInformation->Handles[Index].GrantedAccess =
+ HandleTableEntry->GrantedAccess;
- pr = PsGetNextProcess(pr);
+ ++Index;
+ }
- if ((pr == syspr) || (pr == NULL)) break;
+ /* Unlock it */
+ ExUnlockHandleTableEntry(HandleTable, HandleTableEntry);
+ }
+ }
+
+ /* Go to the next entry */
+ Handle.Value += sizeof(HANDLE);
+ }
}
- while ((pr != syspr) && (pr != NULL));
- if(pr != NULL) ObDereferenceObject(pr);
+ /* Release the lock */
+ ExReleasePushLockShared(&HandleTableListLock);
- DPRINT("SystemHandleInformation 4\n");
- return STATUS_SUCCESS;
+ /* Leave the critical region */
+ KeLeaveCriticalRegion();
-}
-/*
-SSI_DEF(SystemHandleInformation)
-{
+ /* Release the locked user buffer */
+ ExUnlockUserBuffer(Mdl);
- return STATUS_SUCCESS;
+ return Status;
}
-*/
/* Class 17 - Information */
QSI_DEF(SystemObjectInformation)
{
PSYSTEM_KERNEL_DEBUGGER_INFORMATION skdi = (PSYSTEM_KERNEL_DEBUGGER_INFORMATION) Buffer;
+#if (NTDDI_VERSION >= NTDDI_VISTA)
*ReqSize = sizeof(SYSTEM_KERNEL_DEBUGGER_INFORMATION);
+#endif
+
if (Size < sizeof(SYSTEM_KERNEL_DEBUGGER_INFORMATION))
{
return STATUS_INFO_LENGTH_MISMATCH;
skdi->KernelDebuggerEnabled = KD_DEBUGGER_ENABLED;
skdi->KernelDebuggerNotPresent = KD_DEBUGGER_NOT_PRESENT;
+#if (NTDDI_VERSION < NTDDI_VISTA)
+ *ReqSize = sizeof(SYSTEM_KERNEL_DEBUGGER_INFORMATION);
+#endif
+
return STATUS_SUCCESS;
}
return STATUS_SUCCESS;
}
+/* Class 64 - Extended handle information */
+QSI_DEF(SystemExtendedHandleInformation)
+{
+ PSYSTEM_HANDLE_INFORMATION_EX HandleInformation = (PSYSTEM_HANDLE_INFORMATION_EX)Buffer;
+
+ DPRINT1("NtQuerySystemInformation - SystemExtendedHandleInformation not implemented\n");
+
+ /* Set initial required buffer size */
+ *ReqSize = FIELD_OFFSET(SYSTEM_HANDLE_INFORMATION_EX, Handle);
+
+ /* Validate input size */
+ if (Size < *ReqSize)
+ {
+ return STATUS_INFO_LENGTH_MISMATCH;
+ }
+
+ /* FIXME */
+ HandleInformation->Count = 0;
+ return STATUS_NOT_IMPLEMENTED;
+}
+
/* Query/Set Calls Table */
typedef
{
NTSTATUS (* Query) (PVOID,ULONG,PULONG);
NTSTATUS (* Set) (PVOID,ULONG);
-
} QSSI_CALLS;
// QS Query & Set
SI_QX(SystemExtendedProcessInformation),
SI_QX(SystemRecommendedSharedDataAlignment),
SI_XX(SystemComPlusPackage),
- SI_QX(SystemNumaAvailableMemory)
+ SI_QX(SystemNumaAvailableMemory),
+ SI_XX(SystemProcessorPowerInformation), /* FIXME: not implemented */
+ SI_XX(SystemEmulationBasicInformation), /* FIXME: not implemented */
+ SI_XX(SystemEmulationProcessorInformation), /* FIXME: not implemented */
+ SI_QX(SystemExtendedHandleInformation),
};
C_ASSERT(SystemBasicInformation == 0);
{
KPROCESSOR_MODE PreviousMode;
ULONG ResultLength = 0;
+ ULONG Alignment = TYPE_ALIGNMENT(ULONG);
NTSTATUS FStatus = STATUS_NOT_IMPLEMENTED;
PAGED_CODE();
_SEH2_TRY
{
+#if (NTDDI_VERSION >= NTDDI_VISTA)
+ /*
+ * Check if the request is valid.
+ */
+ if (SystemInformationClass >= MAX_SYSTEM_INFO_CLASS)
+ {
+ _SEH2_YIELD(return STATUS_INVALID_INFO_CLASS);
+ }
+#endif
+
if (PreviousMode != KernelMode)
{
/* SystemKernelDebuggerInformation needs only BOOLEAN alignment */
- ProbeForWrite(SystemInformation, Length, 1);
+ if (SystemInformationClass == SystemKernelDebuggerInformation)
+ Alignment = TYPE_ALIGNMENT(BOOLEAN);
+
+ ProbeForWrite(SystemInformation, Length, Alignment);
if (UnsafeResultLength != NULL)
ProbeForWriteUlong(UnsafeResultLength);
}
if (UnsafeResultLength)
*UnsafeResultLength = 0;
+#if (NTDDI_VERSION < NTDDI_VISTA)
/*
* Check if the request is valid.
*/
{
_SEH2_YIELD(return STATUS_INVALID_INFO_CLASS);
}
+#endif
if (NULL != CallQS [SystemInformationClass].Query)
{
return Status;
}
-NTSTATUS
-NTAPI
-NtFlushInstructionCache(
- _In_ HANDLE ProcessHandle,
- _In_opt_ PVOID BaseAddress,
- _In_ ULONG FlushSize)
-{
- KAPC_STATE ApcState;
- PKPROCESS Process;
- NTSTATUS Status;
- PAGED_CODE();
-
- /* Is a base address given? */
- if (BaseAddress != NULL)
- {
- /* If the requested size is 0, there is nothing to do */
- if (FlushSize == 0)
- {
- return STATUS_SUCCESS;
- }
-
- /* Is this a user mode call? */
- if (KeGetPreviousMode() != KernelMode)
- {
- /* Make sure the base address is in user space */
- if (BaseAddress > MmHighestUserAddress)
- {
- DPRINT1("Invalid BaseAddress 0x%p\n", BaseAddress);
- return STATUS_ACCESS_VIOLATION;
- }
- }
- }
-
- /* Is another process requested? */
- if (ProcessHandle != NtCurrentProcess())
- {
- /* Reference the process */
- Status = ObReferenceObjectByHandle(ProcessHandle,
- PROCESS_VM_WRITE,
- PsProcessType,
- KeGetPreviousMode(),
- (PVOID*)&Process,
- NULL);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Failed to reference the process %p\n", ProcessHandle);
- return Status;
- }
-
- /* Attach to the process */
- KeStackAttachProcess(Process, &ApcState);
- }
-
- /* FIXME: don't flush everything if a range is requested */
-#if defined(_M_IX86) || defined(_M_AMD64)
- __wbinvd();
-#elif defined(_M_PPC)
- __asm__ __volatile__("tlbsync");
-#elif defined(_M_MIPS)
- DPRINT1("NtFlushInstructionCache() is not implemented\n");
- DbgBreakPoint();
-#elif defined(_M_ARM)
- _MoveToCoprocessor(0, CP15_ICIALLU);
-#else
-#error Unknown architecture
-#endif
-
- /* Check if we attached */
- if (ProcessHandle != NtCurrentProcess())
- {
- /* Detach from the process */
- KeUnstackDetachProcess(&ApcState);
- }
-
- return STATUS_SUCCESS;
-}
-
ULONG
NTAPI
NtGetCurrentProcessorNumber(VOID)
{
- /* Just return the CPU */
+ /* Just use Ke */
return KeGetCurrentProcessorNumber();
}
-/*
- * @implemented
- */
#undef ExGetPreviousMode
KPROCESSOR_MODE
NTAPI
-ExGetPreviousMode (VOID)
+ExGetPreviousMode(VOID)
{
+ /* Just use Ke */
return KeGetPreviousMode();
}