mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 01:55:19 +00:00
1) Updated KUSER_SHARED_DATA to NT5+ exported documented defintiion, which meant the removal of DosDevices. Used proper NT _DEVICE_MAP Structure for this, but did it in a "hack" way, ie, not a fully implementation, but enough to keep the basic old functionality as before. This will need an review once the Ob Manager is overhaulted. Modified kernel32 to request the _DEVICE_MAP for the current process, implemented the query routine (but made it return the default systme device map intead of per process) and changed the kernel code to use the default device map instead.
2) Updated the HalDispatchTable to Version 3.0. Not a huge change, just added/updated some functions. 3) Rewrote most of the DPC Code to take advantage of the CPU/Importance "laws". Stress testing on my machine revealed no issues on CVS HEAD. Still needs some review to make it so that idle threads can call dpcs (so that low importance dpcs will be dispatched by the idle thread). I will modify this later. svn path=/trunk/; revision=11731
This commit is contained in:
parent
5fea7dac8b
commit
2a42da87f2
16 changed files with 703 additions and 339 deletions
|
@ -238,7 +238,7 @@ typedef struct _KDPC
|
|||
PVOID DeferredContext;
|
||||
PVOID SystemArgument1;
|
||||
PVOID SystemArgument2;
|
||||
PULONG Lock;
|
||||
PVOID DpcData;
|
||||
} KDPC, *PKDPC;
|
||||
|
||||
#include <poppack.h>
|
||||
|
|
|
@ -29,9 +29,9 @@ typedef struct _KSYSTEM_TIME
|
|||
LONG High2Time;
|
||||
} KSYSTEM_TIME, *PKSYSTEM_TIME;
|
||||
|
||||
typedef struct _KUSER_SHARED_DATA
|
||||
{
|
||||
volatile ULONG TickCountLow;
|
||||
#define PROCESSOR_FEATURE_MAX 64
|
||||
typedef struct _KUSER_SHARED_DATA {
|
||||
ULONG TickCountLowDeprecated;
|
||||
ULONG TickCountMultiplier;
|
||||
volatile KSYSTEM_TIME InterruptTime;
|
||||
volatile KSYSTEM_TIME SystemTime;
|
||||
|
@ -39,27 +39,36 @@ typedef struct _KUSER_SHARED_DATA
|
|||
USHORT ImageNumberLow;
|
||||
USHORT ImageNumberHigh;
|
||||
WCHAR NtSystemRoot[260];
|
||||
ULONG DosDeviceMap;
|
||||
ULONG MaxStackTraceDepth;
|
||||
ULONG CryptoExponent;
|
||||
ULONG TimeZoneId;
|
||||
UCHAR DosDeviceDriveType[32];
|
||||
ULONG LargePageMinimum;
|
||||
ULONG Reserved2[7];
|
||||
NT_PRODUCT_TYPE NtProductType;
|
||||
BOOLEAN ProductTypeIsValid;
|
||||
ULONG NtMajorVersion;
|
||||
ULONG NtMinorVersion;
|
||||
BOOLEAN ProcessorFeatures[PROCESSOR_FEATURES_MAX];
|
||||
|
||||
/* NT5 / Win2k specific ?? */
|
||||
BOOLEAN ProcessorFeatures[PROCESSOR_FEATURE_MAX];
|
||||
ULONG Reserved1;
|
||||
ULONG Reserved3;
|
||||
volatile ULONG TimeSlip;
|
||||
ALTERNATIVE_ARCHITECTURE_TYPE AlternativeArchitecture;
|
||||
LARGE_INTEGER SystemExpirationDate;
|
||||
ULONG SuiteMask;
|
||||
#ifdef REMOTE_BOOT
|
||||
ULONG SystemFlags;
|
||||
UCHAR RemoteBootServerPath[260];
|
||||
#endif
|
||||
BOOLEAN KdDebuggerEnabled;
|
||||
volatile ULONG ActiveConsoleId;
|
||||
volatile ULONG DismountCount;
|
||||
ULONG ComPlusPackage;
|
||||
ULONG LastSystemRITEventTickCount;
|
||||
ULONG NumberOfPhysicalPages;
|
||||
BOOLEAN SafeBootMode;
|
||||
ULONG TraceLogging;
|
||||
ULONGLONG Fill0;
|
||||
ULONGLONG SystemCall[4];
|
||||
union {
|
||||
volatile KSYSTEM_TIME TickCount;
|
||||
volatile ULONG64 TickCountQuad;
|
||||
};
|
||||
} KUSER_SHARED_DATA, *PKUSER_SHARED_DATA;
|
||||
|
||||
/* Values for DosDeviceDriveType */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: haltypes.h,v 1.8 2004/08/20 13:29:14 ekohl Exp $
|
||||
/* $Id: haltypes.h,v 1.9 2004/11/21 06:51:17 ion Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -358,6 +358,38 @@ typedef struct _PCI_SLOT_NUMBER
|
|||
} u;
|
||||
} PCI_SLOT_NUMBER, *PPCI_SLOT_NUMBER;
|
||||
|
||||
typedef enum _RESOURCE_TRANSLATION_DIRECTION {
|
||||
TranslateChildToParent,
|
||||
TranslateParentToChild
|
||||
} RESOURCE_TRANSLATION_DIRECTION;
|
||||
|
||||
typedef NTSTATUS STDCALL
|
||||
(*PTRANSLATE_RESOURCE_HANDLER)(IN PVOID Context,
|
||||
IN PCM_PARTIAL_RESOURCE_DESCRIPTOR Source,
|
||||
IN RESOURCE_TRANSLATION_DIRECTION Direction,
|
||||
IN ULONG AlternativesCount, OPTIONAL
|
||||
IN IO_RESOURCE_DESCRIPTOR Alternatives[], OPTIONAL
|
||||
IN PDEVICE_OBJECT PhysicalDeviceObject,
|
||||
OUT PCM_PARTIAL_RESOURCE_DESCRIPTOR Target
|
||||
);
|
||||
|
||||
typedef NTSTATUS STDCALL
|
||||
(*PTRANSLATE_RESOURCE_REQUIREMENTS_HANDLER)(IN PVOID Context,
|
||||
IN PIO_RESOURCE_DESCRIPTOR Source,
|
||||
IN PDEVICE_OBJECT PhysicalDeviceObject,
|
||||
OUT PULONG TargetCount,
|
||||
OUT PIO_RESOURCE_DESCRIPTOR *Target);
|
||||
|
||||
typedef struct _TRANSLATOR_INTERFACE {
|
||||
USHORT Size;
|
||||
USHORT Version;
|
||||
PVOID Context;
|
||||
PINTERFACE_REFERENCE InterfaceReference;
|
||||
PINTERFACE_DEREFERENCE InterfaceDereference;
|
||||
PTRANSLATE_RESOURCE_HANDLER TranslateResources;
|
||||
PTRANSLATE_RESOURCE_REQUIREMENTS_HANDLER TranslateResourceRequirements;
|
||||
} TRANSLATOR_INTERFACE, *PTRANSLATOR_INTERFACE;
|
||||
|
||||
#endif /* __USE_W32API */
|
||||
|
||||
/* Hal dispatch table */
|
||||
|
@ -393,25 +425,6 @@ typedef struct _DEVICE_HANDLER_OBJECT *PDEVICE_HANDLER_OBJECT;
|
|||
typedef BOOLEAN STDCALL_FUNC
|
||||
(*PHAL_RESET_DISPLAY_PARAMETERS)(ULONG Columns, ULONG Rows);
|
||||
|
||||
typedef NTSTATUS STDCALL_FUNC
|
||||
(*pHalQuerySystemInformation)(IN HAL_QUERY_INFORMATION_CLASS InformationClass,
|
||||
IN ULONG BufferSize,
|
||||
IN OUT PVOID Buffer,
|
||||
OUT PULONG ReturnedLength);
|
||||
|
||||
|
||||
typedef NTSTATUS STDCALL_FUNC
|
||||
(*pHalSetSystemInformation)(IN HAL_SET_INFORMATION_CLASS InformationClass,
|
||||
IN ULONG BufferSize,
|
||||
IN PVOID Buffer);
|
||||
|
||||
|
||||
typedef NTSTATUS STDCALL_FUNC
|
||||
(*pHalQueryBusSlots)(IN PBUS_HANDLER BusHandler,
|
||||
IN ULONG BufferSize,
|
||||
OUT PULONG SlotNumbers,
|
||||
OUT PULONG ReturnedLength);
|
||||
|
||||
|
||||
/* Control codes of HalDeviceControl function */
|
||||
#define BCTL_EJECT 0x0001
|
||||
|
@ -448,12 +461,16 @@ typedef struct _DEVICE_CONTROL_CONTEXT
|
|||
PVOID Context;
|
||||
} DEVICE_CONTROL_CONTEXT, *PDEVICE_CONTROL_CONTEXT;
|
||||
|
||||
typedef struct _PM_DISPATCH_TABLE {
|
||||
ULONG Signature;
|
||||
ULONG Version;
|
||||
PVOID Function[1];
|
||||
} PM_DISPATCH_TABLE, *PPM_DISPATCH_TABLE;
|
||||
|
||||
typedef VOID STDCALL_FUNC
|
||||
(*PDEVICE_CONTROL_COMPLETION)(IN PDEVICE_CONTROL_CONTEXT ControlContext);
|
||||
|
||||
|
||||
typedef NTSTATUS STDCALL_FUNC
|
||||
typedef NTSTATUS STDCALL
|
||||
(*pHalDeviceControl)(IN PDEVICE_HANDLER_OBJECT DeviceHandler,
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN ULONG ControlCode,
|
||||
|
@ -462,60 +479,128 @@ typedef NTSTATUS STDCALL_FUNC
|
|||
IN PVOID Context,
|
||||
IN PDEVICE_CONTROL_COMPLETION CompletionRoutine);
|
||||
|
||||
typedef VOID FASTCALL_FUNC
|
||||
typedef VOID FASTCALL
|
||||
(*pHalExamineMBR)(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN ULONG SectorSize,
|
||||
IN ULONG MBRTypeIdentifier,
|
||||
OUT PVOID *Buffer);
|
||||
|
||||
typedef VOID FASTCALL_FUNC
|
||||
(*pHalIoAssignDriveLetters)(IN PLOADER_PARAMETER_BLOCK LoaderBlock,
|
||||
typedef VOID FASTCALL
|
||||
(*pHalIoAssignDriveLetters)(IN struct _LOADER_PARAMETER_BLOCK *LoaderBlock,
|
||||
IN PSTRING NtDeviceName,
|
||||
OUT PUCHAR NtSystemPath,
|
||||
OUT PSTRING NtSystemPathString);
|
||||
|
||||
typedef NTSTATUS FASTCALL_FUNC
|
||||
typedef NTSTATUS FASTCALL
|
||||
(*pHalIoReadPartitionTable)(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN ULONG SectorSize,
|
||||
IN BOOLEAN ReturnRecognizedPartitions,
|
||||
OUT PDRIVE_LAYOUT_INFORMATION *PartitionBuffer);
|
||||
|
||||
typedef NTSTATUS FASTCALL_FUNC
|
||||
typedef NTSTATUS FASTCALL
|
||||
(*pHalIoSetPartitionInformation)(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN ULONG SectorSize,
|
||||
IN ULONG PartitionNumber,
|
||||
IN ULONG PartitionType);
|
||||
|
||||
typedef NTSTATUS FASTCALL_FUNC
|
||||
typedef NTSTATUS FASTCALL
|
||||
(*pHalIoWritePartitionTable)(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN ULONG SectorSize,
|
||||
IN ULONG SectorsPerTrack,
|
||||
IN ULONG NumberOfHeads,
|
||||
IN PDRIVE_LAYOUT_INFORMATION PartitionBuffer);
|
||||
|
||||
typedef PBUS_HANDLER FASTCALL_FUNC
|
||||
typedef PBUS_HANDLER FASTCALL
|
||||
(*pHalHandlerForBus)(IN INTERFACE_TYPE InterfaceType,
|
||||
IN ULONG BusNumber);
|
||||
|
||||
typedef VOID FASTCALL_FUNC
|
||||
typedef VOID FASTCALL
|
||||
(*pHalReferenceBusHandler)(IN PBUS_HANDLER BusHandler);
|
||||
|
||||
typedef NTSTATUS STDCALL
|
||||
(*pHalQuerySystemInformation)(IN HAL_QUERY_INFORMATION_CLASS InformationClass,
|
||||
IN ULONG BufferSize,
|
||||
IN OUT PVOID Buffer,
|
||||
OUT PULONG ReturnedLength);
|
||||
|
||||
typedef struct _HAL_DISPATCH
|
||||
{
|
||||
|
||||
typedef NTSTATUS STDCALL
|
||||
(*pHalSetSystemInformation)(IN HAL_SET_INFORMATION_CLASS InformationClass,
|
||||
IN ULONG BufferSize,
|
||||
IN PVOID Buffer);
|
||||
|
||||
|
||||
typedef NTSTATUS STDCALL
|
||||
(*pHalQueryBusSlots)(IN PBUS_HANDLER BusHandler,
|
||||
IN ULONG BufferSize,
|
||||
OUT PULONG SlotNumbers,
|
||||
OUT PULONG ReturnedLength);
|
||||
|
||||
typedef NTSTATUS STDCALL
|
||||
(*pHalInitPnpDriver)(VOID);
|
||||
|
||||
typedef NTSTATUS STDCALL
|
||||
(*pHalInitPowerManagement)(IN PPM_DISPATCH_TABLE PmDriverDispatchTable,
|
||||
OUT PPM_DISPATCH_TABLE *PmHalDispatchTable);
|
||||
|
||||
typedef struct _DMA_ADAPTER * STDCALL
|
||||
(*pHalGetDmaAdapter)(IN PVOID Context,
|
||||
IN struct _DEVICE_DESCRIPTION *DeviceDescriptor,
|
||||
OUT PULONG NumberOfMapRegisters);
|
||||
|
||||
typedef NTSTATUS STDCALL
|
||||
(*pHalGetInterruptTranslator)(IN INTERFACE_TYPE ParentInterfaceType,
|
||||
IN ULONG ParentBusNumber,
|
||||
IN INTERFACE_TYPE BridgeInterfaceType,
|
||||
IN USHORT Size,
|
||||
IN USHORT Version,
|
||||
OUT PTRANSLATOR_INTERFACE Translator,
|
||||
OUT PULONG BridgeBusNumber);
|
||||
|
||||
typedef NTSTATUS STDCALL (*pHalStartMirroring)(VOID);
|
||||
|
||||
typedef NTSTATUS STDCALL (*pHalEndMirroring)(IN ULONG PassNumber);
|
||||
|
||||
typedef NTSTATUS STDCALL
|
||||
(*pHalMirrorPhysicalMemory)(IN PHYSICAL_ADDRESS PhysicalAddress,
|
||||
IN LARGE_INTEGER NumberOfBytes);
|
||||
|
||||
typedef NTSTATUS STDCALL
|
||||
(*pHalMirrorVerify)(IN PHYSICAL_ADDRESS PhysicalAddress,
|
||||
IN LARGE_INTEGER NumberOfBytes);
|
||||
|
||||
typedef VOID STDCALL
|
||||
(*pHalEndOfBoot)(VOID);
|
||||
|
||||
|
||||
typedef struct {
|
||||
ULONG Version;
|
||||
pHalQuerySystemInformation HalQuerySystemInformation;
|
||||
pHalSetSystemInformation HalSetSystemInformation;
|
||||
pHalQueryBusSlots HalQueryBusSlots;
|
||||
pHalDeviceControl HalDeviceControl;
|
||||
ULONG Spare1;
|
||||
pHalExamineMBR HalExamineMBR;
|
||||
pHalIoAssignDriveLetters HalIoAssignDriveLetters;
|
||||
pHalIoReadPartitionTable HalIoReadPartitionTable;
|
||||
pHalIoSetPartitionInformation HalIoSetPartitionInformation;
|
||||
pHalIoWritePartitionTable HalIoWritePartitionTable;
|
||||
|
||||
pHalHandlerForBus HalReferenceHandlerForBus;
|
||||
pHalReferenceBusHandler HalReferenceBusHandler;
|
||||
pHalReferenceBusHandler HalDereferenceBusHandler;
|
||||
|
||||
pHalInitPnpDriver HalInitPnpDriver;
|
||||
pHalInitPowerManagement HalInitPowerManagement;
|
||||
|
||||
pHalGetDmaAdapter HalGetDmaAdapter;
|
||||
pHalGetInterruptTranslator HalGetInterruptTranslator;
|
||||
|
||||
pHalStartMirroring HalStartMirroring;
|
||||
pHalEndMirroring HalEndMirroring;
|
||||
pHalMirrorPhysicalMemory HalMirrorPhysicalMemory;
|
||||
pHalEndOfBoot HalEndOfBoot;
|
||||
pHalMirrorVerify HalMirrorVerify;
|
||||
|
||||
} HAL_DISPATCH, *PHAL_DISPATCH;
|
||||
|
||||
#ifndef __USE_W32API
|
||||
|
@ -535,7 +620,7 @@ extern PHAL_DISPATCH IMPORTED HalDispatchTable;
|
|||
#endif
|
||||
|
||||
|
||||
#define HAL_DISPATCH_VERSION 1
|
||||
#define HAL_DISPATCH_VERSION 3
|
||||
#define HalDispatchTableVersion HALDISPATCH->Version
|
||||
#define HalQuerySystemInformation HALDISPATCH->HalQuerySystemInformation
|
||||
#define HalSetSystemInformation HALDISPATCH->HalSetSystemInformation
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#ifndef _INCLUDE_DDK_OBTYPES_H
|
||||
#define _INCLUDE_DDK_OBTYPES_H
|
||||
/* $Id: obtypes.h,v 1.8 2004/07/07 17:20:16 ekohl Exp $ */
|
||||
/* $Id: obtypes.h,v 1.9 2004/11/21 06:51:17 ion Exp $ */
|
||||
struct _DIRECTORY_OBJECT;
|
||||
struct _OBJECT_ATTRIBUTES;
|
||||
|
||||
|
@ -253,8 +253,36 @@ typedef struct _HANDLE_TABLE
|
|||
|
||||
typedef struct _HANDLE_TABLE *PHANDLE_TABLE;
|
||||
|
||||
/*
|
||||
* FIXME: These will eventually become centerfold in the compliant Ob Manager
|
||||
* For now, they are only here so Device Map is properly defined before the header
|
||||
* changes
|
||||
*/
|
||||
typedef struct _OBJECT_DIRECTORY_ENTRY {
|
||||
struct _OBJECT_DIRECTORY_ENTRY *ChainLink;
|
||||
PVOID Object;
|
||||
ULONG HashValue;
|
||||
} OBJECT_DIRECTORY_ENTRY, *POBJECT_DIRECTORY_ENTRY;
|
||||
|
||||
#define NUMBER_HASH_BUCKETS 37
|
||||
typedef struct _OBJECT_DIRECTORY {
|
||||
struct _OBJECT_DIRECTORY_ENTRY *HashBuckets[NUMBER_HASH_BUCKETS];
|
||||
struct _EX_PUSH_LOCK *Lock;
|
||||
struct _DEVICE_MAP *DeviceMap;
|
||||
ULONG SessionId;
|
||||
} OBJECT_DIRECTORY, *POBJECT_DIRECTORY;
|
||||
|
||||
typedef struct _DEVICE_MAP {
|
||||
POBJECT_DIRECTORY DosDevicesDirectory;
|
||||
POBJECT_DIRECTORY GlobalDosDevicesDirectory;
|
||||
ULONG ReferenceCount;
|
||||
ULONG DriveMap;
|
||||
UCHAR DriveType[32];
|
||||
} DEVICE_MAP, *PDEVICE_MAP;
|
||||
|
||||
#endif /* __USE_W32API */
|
||||
|
||||
extern POBJECT_TYPE ObDirectoryType;
|
||||
extern PDEVICE_MAP ObSystemDeviceMap;
|
||||
|
||||
#endif /* ndef _INCLUDE_DDK_OBTYPES_H */
|
||||
|
|
|
@ -782,7 +782,7 @@ typedef struct _PROCESS_DEVICEMAP_INFORMATION
|
|||
UCHAR DriveType[32];
|
||||
} Query;
|
||||
};
|
||||
} PROCESS_DEVICEMAP_INFORMATION, *pPROCESS_DEVICEMAP_INFORMATION;
|
||||
} PROCESS_DEVICEMAP_INFORMATION, *PPROCESS_DEVICEMAP_INFORMATION;
|
||||
|
||||
// Information class 24
|
||||
typedef struct _PROCESS_SESSION_INFORMATION
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: volume.c,v 1.42 2004/10/05 07:51:11 gvg Exp $
|
||||
/* $Id: volume.c,v 1.43 2004/11/21 06:51:17 ion Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS system libraries
|
||||
|
@ -87,7 +87,7 @@ GetLogicalDriveStringsA(DWORD nBufferLength,
|
|||
DWORD drive, count;
|
||||
DWORD dwDriveMap;
|
||||
|
||||
dwDriveMap = SharedUserData->DosDeviceMap;
|
||||
dwDriveMap = GetLogicalDrives();
|
||||
|
||||
for (drive = count = 0; drive < MAX_DOS_DRIVES; drive++)
|
||||
{
|
||||
|
@ -124,7 +124,7 @@ GetLogicalDriveStringsW(DWORD nBufferLength,
|
|||
DWORD drive, count;
|
||||
DWORD dwDriveMap;
|
||||
|
||||
dwDriveMap = SharedUserData->DosDeviceMap;
|
||||
dwDriveMap = GetLogicalDrives();
|
||||
|
||||
for (drive = count = 0; drive < MAX_DOS_DRIVES; drive++)
|
||||
{
|
||||
|
@ -155,7 +155,22 @@ GetLogicalDriveStringsW(DWORD nBufferLength,
|
|||
DWORD STDCALL
|
||||
GetLogicalDrives(VOID)
|
||||
{
|
||||
return(SharedUserData->DosDeviceMap);
|
||||
NTSTATUS Status;
|
||||
PROCESS_DEVICEMAP_INFORMATION ProcessDeviceMapInfo;
|
||||
|
||||
/* Get the Device Map for this Process */
|
||||
Status = NtQueryInformationProcess(NtCurrentProcess(),
|
||||
ProcessDeviceMap,
|
||||
&ProcessDeviceMapInfo.Query,
|
||||
sizeof(ProcessDeviceMapInfo.Query),
|
||||
NULL);
|
||||
|
||||
/* Return the Drive Map */
|
||||
if (!NT_SUCCESS(Status)) {
|
||||
return 0;
|
||||
} else {
|
||||
return ProcessDeviceMapInfo.Query.DriveMap;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: time.c,v 1.31 2004/11/14 18:53:11 hbirr Exp $
|
||||
/* $Id: time.c,v 1.32 2004/11/21 06:51:17 ion Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS system libraries
|
||||
|
@ -377,7 +377,7 @@ SetTimeZoneInformation(CONST TIME_ZONE_INFORMATION *lpTimeZoneInformation)
|
|||
DWORD STDCALL
|
||||
GetTickCount(VOID)
|
||||
{
|
||||
return (DWORD)((ULONGLONG)SharedUserData->TickCountLow * SharedUserData->TickCountMultiplier / 16777216);
|
||||
return (DWORD)((ULONGLONG)SharedUserData->TickCountLowDeprecated * SharedUserData->TickCountMultiplier / 16777216);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -187,7 +187,7 @@ typedef struct _KPRCB {
|
|||
LARGE_INTEGER SpareField1;
|
||||
FX_SAVE_AREA NpxSaveArea;
|
||||
PROCESSOR_POWER_STATE PowerState;
|
||||
} KPRCB, *PKRCB;
|
||||
} KPRCB, *PKPRCB;
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
|
|
|
@ -36,7 +36,6 @@ typedef struct _DIRECTORY_OBJECT
|
|||
KSPIN_LOCK Lock;
|
||||
} DIRECTORY_OBJECT, *PDIRECTORY_OBJECT;
|
||||
|
||||
|
||||
typedef struct _SYMLINK_OBJECT
|
||||
{
|
||||
CSHORT Type;
|
||||
|
@ -138,6 +137,9 @@ ObDuplicateObject(PEPROCESS SourceProcess,
|
|||
ULONG
|
||||
ObpGetHandleCountByHandleTable(PHANDLE_TABLE HandleTable);
|
||||
|
||||
VOID
|
||||
STDCALL
|
||||
ObQueryDeviceMapInformation(PEPROCESS Process, PPROCESS_DEVICEMAP_INFORMATION DeviceMapInfo);
|
||||
|
||||
/* Security descriptor cache functions */
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: xhaldisp.c,v 1.11 2004/08/21 20:55:40 tamlin Exp $
|
||||
/* $Id: xhaldisp.c,v 1.12 2004/11/21 06:51:18 ion Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -25,7 +25,7 @@ HAL_DISPATCH EXPORTED HalDispatchTable =
|
|||
(pHalQuerySystemInformation) NULL, // HalQuerySystemInformation
|
||||
(pHalSetSystemInformation) NULL, // HalSetSystemInformation
|
||||
(pHalQueryBusSlots) NULL, // HalQueryBusSlots
|
||||
(pHalDeviceControl) NULL, // HalDeviceControl
|
||||
0,
|
||||
(pHalExamineMBR) xHalExamineMBR,
|
||||
(pHalIoAssignDriveLetters) xHalIoAssignDriveLetters,
|
||||
(pHalIoReadPartitionTable) xHalIoReadPartitionTable,
|
||||
|
@ -33,7 +33,16 @@ HAL_DISPATCH EXPORTED HalDispatchTable =
|
|||
(pHalIoWritePartitionTable) xHalIoWritePartitionTable,
|
||||
(pHalHandlerForBus) NULL, // HalReferenceHandlerForBus
|
||||
(pHalReferenceBusHandler) NULL, // HalReferenceBusHandler
|
||||
(pHalReferenceBusHandler) NULL // HalDereferenceBusHandler
|
||||
(pHalReferenceBusHandler) NULL, // HalDereferenceBusHandler
|
||||
(pHalInitPnpDriver) NULL, //HalInitPnpDriver;
|
||||
(pHalInitPowerManagement) NULL, //HalInitPowerManagement;
|
||||
(pHalGetDmaAdapter) NULL, //HalGetDmaAdapter;
|
||||
(pHalGetInterruptTranslator) NULL, //HalGetInterruptTranslator;
|
||||
(pHalStartMirroring) NULL, //HalStartMirroring;
|
||||
(pHalEndMirroring) NULL, //HalEndMirroring;
|
||||
(pHalMirrorPhysicalMemory) NULL, //HalMirrorPhysicalMemory;
|
||||
(pHalEndOfBoot) NULL, //HalEndOfBoot;
|
||||
(pHalMirrorVerify) NULL //HalMirrorVerify;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: xhaldrv.c,v 1.49 2004/10/22 20:25:54 ekohl Exp $
|
||||
/* $Id: xhaldrv.c,v 1.50 2004/11/21 06:51:18 ion Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -60,7 +60,6 @@ typedef enum _DISK_MANAGER
|
|||
EZ_Drive
|
||||
} DISK_MANAGER;
|
||||
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
NTSTATUS
|
||||
|
@ -354,7 +353,7 @@ HalpAssignDrive(IN PUNICODE_STRING PartitionName,
|
|||
if ((DriveNumber != AUTO_DRIVE) && (DriveNumber < 24))
|
||||
{
|
||||
/* Force assignment */
|
||||
if ((SharedUserData->DosDeviceMap & (1 << DriveNumber)) != 0)
|
||||
if ((ObSystemDeviceMap->DriveMap & (1 << DriveNumber)) != 0)
|
||||
{
|
||||
DbgPrint("Drive letter already used!\n");
|
||||
return;
|
||||
|
@ -367,7 +366,7 @@ HalpAssignDrive(IN PUNICODE_STRING PartitionName,
|
|||
|
||||
for (i = 2; i < 24; i++)
|
||||
{
|
||||
if ((SharedUserData->DosDeviceMap & (1 << i)) == 0)
|
||||
if ((ObSystemDeviceMap->DriveMap & (1 << i)) == 0)
|
||||
{
|
||||
DriveNumber = i;
|
||||
break;
|
||||
|
@ -383,9 +382,9 @@ HalpAssignDrive(IN PUNICODE_STRING PartitionName,
|
|||
|
||||
DPRINT("DriveNumber %d\n", DriveNumber);
|
||||
|
||||
/* Update the shared user page */
|
||||
SharedUserData->DosDeviceMap |= (1 << DriveNumber);
|
||||
SharedUserData->DosDeviceDriveType[DriveNumber] = DriveType;
|
||||
/* Update the System Device Map */
|
||||
ObSystemDeviceMap->DriveMap |= (1 << DriveNumber);
|
||||
ObSystemDeviceMap->DriveType[DriveNumber] = DriveType;
|
||||
|
||||
/* Build drive name */
|
||||
swprintf(DriveNameBuffer,
|
||||
|
|
|
@ -19,12 +19,13 @@
|
|||
/*
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: ntoskrnl/ke/apc.c
|
||||
* PURPOSE: Possible implementation of APCs
|
||||
* PROGRAMMER: David Welch (welch@cwcom.net)
|
||||
* PURPOSE: NT Implementation of APCs
|
||||
* PROGRAMMER: Alex Ionescu (alex@relsoft.net)
|
||||
* PORTABILITY: Unchecked
|
||||
* UPDATE HISTORY:
|
||||
* Created 22/05/98
|
||||
* 12/11/99: Phillip Susi: Reworked the APC code
|
||||
* 11/11/04: Alex Ionescu - Total Rewrite
|
||||
*/
|
||||
|
||||
/* INCLUDES *****************************************************************/
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
* Copyright (C) 2000, 1999, 1998 David Welch <welch@cwcom.net>,
|
||||
* Philip Susi <phreak@iag.net>,
|
||||
* Eric Kohl <ekohl@abo.rhein-zeitung.de>
|
||||
* Alex Ionescu <alex@relsoft.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -18,7 +19,7 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
/* $Id: dpc.c,v 1.45 2004/10/31 21:22:06 navaraf Exp $
|
||||
/* $Id: dpc.c,v 1.46 2004/11/21 06:51:18 ion Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -28,6 +29,7 @@
|
|||
* UPDATE HISTORY:
|
||||
* 28/05/98: Created
|
||||
* 12/3/99: Phillip Susi: Fixed IRQL problem
|
||||
* 12/11/04: Alex Ionescu - Major rewrite.
|
||||
*/
|
||||
|
||||
/*
|
||||
|
@ -42,132 +44,292 @@
|
|||
|
||||
/* TYPES *******************************************************************/
|
||||
|
||||
#define MAX_QUANTUM 0x7F
|
||||
/* GLOBALS ******************************************************************/
|
||||
|
||||
/* FUNCTIONS ****************************************************************/
|
||||
|
||||
VOID INIT_FUNCTION
|
||||
KeInitDpc(PKPCR Pcr)
|
||||
/*
|
||||
* FUNCTION: Initialize DPC handling
|
||||
*/
|
||||
{
|
||||
InitializeListHead(&Pcr->PrcbData.DpcData[0].DpcListHead);
|
||||
KeInitializeEvent(Pcr->PrcbData.DpcEvent, 0, 0);
|
||||
KeInitializeSpinLock(&Pcr->PrcbData.DpcData[0].DpcLock);
|
||||
Pcr->PrcbData.MaximumDpcQueueDepth = 4;
|
||||
Pcr->PrcbData.MinimumDpcRate = 3;
|
||||
Pcr->PrcbData.DpcData[0].DpcQueueDepth = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
VOID STDCALL
|
||||
VOID
|
||||
STDCALL
|
||||
KeInitializeThreadedDpc(PKDPC Dpc,
|
||||
PKDEFERRED_ROUTINE DeferredRoutine,
|
||||
PVOID DeferredContext)
|
||||
/*
|
||||
* FUNCTION:
|
||||
* Initalizes a Threaded DPC and registers the DeferredRoutine for it.
|
||||
* ARGUMENTS:
|
||||
* Dpc = Pointer to a caller supplied DPC to be initialized. The caller must allocate this memory.
|
||||
* DeferredRoutine = Pointer to associated DPC callback routine.
|
||||
* DeferredContext = Parameter to be passed to the callback routine.
|
||||
* NOTE: Callers can be running at any IRQL.
|
||||
*/
|
||||
{
|
||||
DPRINT("Threaded DPC Initializing: %x with Routine: %x\n", Dpc, DeferredRoutine);
|
||||
//Dpc->Type = KThreadedDpc;
|
||||
Dpc->Number= 0;
|
||||
Dpc->Importance= MediumImportance;
|
||||
Dpc->DeferredRoutine = DeferredRoutine;
|
||||
Dpc->DeferredContext = DeferredContext;
|
||||
Dpc->DpcData = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
VOID
|
||||
STDCALL
|
||||
KeInitializeDpc (PKDPC Dpc,
|
||||
PKDEFERRED_ROUTINE DeferredRoutine,
|
||||
PVOID DeferredContext)
|
||||
/*
|
||||
* FUNCTION: Initalizes a DPC
|
||||
* FUNCTION:
|
||||
* Initalizes a DPC and registers the DeferredRoutine for it.
|
||||
* ARGUMENTS:
|
||||
* Dpc = Caller supplied DPC to be initialized
|
||||
* DeferredRoutine = Associated DPC callback
|
||||
* DeferredContext = Parameter to be passed to the callback
|
||||
* NOTE: Callers must be running at IRQL PASSIVE_LEVEL
|
||||
* Dpc = Pointer to a caller supplied DPC to be initialized. The caller must allocate this memory.
|
||||
* DeferredRoutine = Pointer to associated DPC callback routine.
|
||||
* DeferredContext = Parameter to be passed to the callback routine.
|
||||
* NOTE: Callers can be running at any IRQL.
|
||||
*/
|
||||
{
|
||||
Dpc->Type = 0;
|
||||
Dpc->Number=0;
|
||||
Dpc->Importance=MediumImportance;
|
||||
DPRINT("DPC Initializing: %x with Routine: %x\n", Dpc, DeferredRoutine);
|
||||
Dpc->Type = KDpc;
|
||||
Dpc->Number= 0;
|
||||
Dpc->Importance= MediumImportance;
|
||||
Dpc->DeferredRoutine = DeferredRoutine;
|
||||
Dpc->DeferredContext = DeferredContext;
|
||||
Dpc->Lock = 0;
|
||||
Dpc->DpcData = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
VOID STDCALL
|
||||
KiDispatchInterrupt(VOID)
|
||||
BOOLEAN STDCALL
|
||||
KeInsertQueueDpc (PKDPC Dpc,
|
||||
PVOID SystemArgument1,
|
||||
PVOID SystemArgument2)
|
||||
/*
|
||||
* FUNCTION: Called to execute queued dpcs
|
||||
* FUNCTION:
|
||||
* Queues a DPC for execution when the IRQL of a processor
|
||||
* drops below DISPATCH_LEVEL
|
||||
* ARGUMENTS:
|
||||
* Dpc = Pointed to a DPC Object Initalized by KeInitializeDpc.
|
||||
* SystemArgument1 = Driver Determined context data
|
||||
* SystemArgument2 = Driver Determined context data
|
||||
* RETURNS:
|
||||
* TRUE if the DPC object wasn't already in the queue
|
||||
* FALSE otherwise
|
||||
* NOTES:
|
||||
* If there is currently a DPC active on the target processor, or a DPC
|
||||
* interrupt has already been requested on the target processor when a
|
||||
* DPC is queued, then no further action is necessary. The DPC will be
|
||||
* executed on the target processor when its queue entry is processed.
|
||||
*
|
||||
* If there is not a DPC active on the target processor and a DPC interrupt
|
||||
* has not been requested on the target processor, then the exact treatment
|
||||
* of the DPC is dependent on whether the host system is a UP system or an
|
||||
* MP system.
|
||||
*
|
||||
* UP system.
|
||||
* ----------
|
||||
* If the DPC is of medium or high importance, the current DPC queue depth
|
||||
* is greater than the maximum target depth, or current DPC request rate is
|
||||
* less the minimum target rate, then a DPC interrupt is requested on the
|
||||
* host processor and the DPC will be processed when the interrupt occurs.
|
||||
* Otherwise, no DPC interupt is requested and the DPC execution will be
|
||||
* delayed until the DPC queue depth is greater that the target depth or the
|
||||
* minimum DPC rate is less than the target rate.
|
||||
*
|
||||
* MP system.
|
||||
* ----------
|
||||
* If the DPC is being queued to another processor and the depth of the DPC
|
||||
* queue on the target processor is greater than the maximum target depth or
|
||||
* the DPC is of high importance, then a DPC interrupt is requested on the
|
||||
* target processor and the DPC will be processed when the interrupt occurs.
|
||||
* Otherwise, the DPC execution will be delayed on the target processor until
|
||||
* the DPC queue depth on the target processor is greater that the maximum
|
||||
* target depth or the minimum DPC rate on the target processor is less than
|
||||
* the target mimimum rate.
|
||||
*
|
||||
* If the DPC is being queued to the current processor and the DPC is not of
|
||||
* low importance, the current DPC queue depth is greater than the maximum
|
||||
* target depth, or the minimum DPC rate is less than the minimum target rate,
|
||||
* then a DPC interrupt is request on the current processor and the DPV will
|
||||
* be processed whne the interrupt occurs. Otherwise, no DPC interupt is
|
||||
* requested and the DPC execution will be delayed until the DPC queue depth
|
||||
* is greater that the target depth or the minimum DPC rate is less than the
|
||||
* target rate.
|
||||
*/
|
||||
{
|
||||
PLIST_ENTRY current_entry;
|
||||
PKDPC current;
|
||||
KIRQL oldlvl;
|
||||
KIRQL OldIrql;
|
||||
PKPCR Pcr;
|
||||
PKTHREAD CurrentThread;
|
||||
PKPROCESS CurrentProcess;
|
||||
|
||||
ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
|
||||
DPRINT("KeInsertQueueDpc(DPC %x, SystemArgument1 %x, SystemArgument2 %x)\n",
|
||||
Dpc, SystemArgument1, SystemArgument2);
|
||||
|
||||
/* Check IRQL and Raise it to HIGH_LEVEL */
|
||||
ASSERT(KeGetCurrentIrql()>=DISPATCH_LEVEL);
|
||||
KeRaiseIrql(HIGH_LEVEL, &OldIrql);
|
||||
|
||||
/* Check if this is a Thread DPC, which we don't support (yet) */
|
||||
//if (Dpc->Type == KThreadedDpc) {
|
||||
// return FALSE;
|
||||
// KeLowerIrql(OldIrql);
|
||||
//}
|
||||
|
||||
#ifdef MP
|
||||
/* Get the right PCR for this CPU */
|
||||
if (Dpc->Number >= MAXIMUM_PROCESSORS) {
|
||||
ASSERT (Dpc->Number - MAXIMUM_PROCESSORS < KeNumberProcessors);
|
||||
Pcr = (PKPCR)(KPCR_BASE + (Dpc->Number - MAXIMUM_PROCESSORS) * PAGE_SIZE);
|
||||
} else {
|
||||
ASSERT (Dpc->Number < KeNumberProcessors);
|
||||
Pcr = KeGetCurrentKPCR();
|
||||
Dpc->Number = KeGetCurrentProcessorNumber();
|
||||
}
|
||||
#else
|
||||
Pcr = (PKPCR)KPCR_BASE;
|
||||
#endif
|
||||
|
||||
if (Pcr->PrcbData.DpcData[0].DpcQueueDepth > 0)
|
||||
{
|
||||
/* Get the DPC Data */
|
||||
if (InterlockedCompareExchange((LONG*)&Dpc->DpcData, (LONG)&Pcr->PrcbData.DpcData[0].DpcLock, 0)) {
|
||||
DPRINT("DPC Already Inserted");
|
||||
KeLowerIrql(OldIrql);
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
KeRaiseIrql(HIGH_LEVEL, &oldlvl);
|
||||
KiAcquireSpinLock(&Pcr->PrcbData.DpcData[0].DpcLock);
|
||||
|
||||
while (!IsListEmpty(&Pcr->PrcbData.DpcData[0].DpcListHead))
|
||||
{
|
||||
ASSERT(Pcr->PrcbData.DpcData[0].DpcQueueDepth > 0);
|
||||
|
||||
current_entry = RemoveHeadList(&Pcr->PrcbData.DpcData[0].DpcListHead);
|
||||
Pcr->PrcbData.DpcData[0].DpcQueueDepth--;
|
||||
/* Now we can play with the DPC safely */
|
||||
Dpc->SystemArgument1=SystemArgument1;
|
||||
Dpc->SystemArgument2=SystemArgument2;
|
||||
Pcr->PrcbData.DpcData[0].DpcQueueDepth++;
|
||||
Pcr->PrcbData.DpcData[0].DpcCount++;
|
||||
|
||||
if (Pcr->PrcbData.DpcData[0].DpcQueueDepth == 0)
|
||||
{
|
||||
/* Make sure the lists are free if the Queue is 0 */
|
||||
if (Pcr->PrcbData.DpcData[0].DpcQueueDepth == 0) {
|
||||
ASSERT(IsListEmpty(&Pcr->PrcbData.DpcData[0].DpcListHead));
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
ASSERT(!IsListEmpty(&Pcr->PrcbData.DpcData[0].DpcListHead));
|
||||
}
|
||||
|
||||
current = CONTAINING_RECORD(current_entry,KDPC,DpcListEntry);
|
||||
current->Lock=FALSE;
|
||||
Pcr->PrcbData.DpcRoutineActive++;
|
||||
KiReleaseSpinLock(&Pcr->PrcbData.DpcData[0].DpcLock);
|
||||
KeLowerIrql(oldlvl);
|
||||
current->DeferredRoutine(current,current->DeferredContext,
|
||||
current->SystemArgument1,
|
||||
current->SystemArgument2);
|
||||
/* Insert the DPC into the list. HighImportance DPCs go at the beginning */
|
||||
if (Dpc->Importance == HighImportance) {
|
||||
InsertHeadList(&Pcr->PrcbData.DpcData[0].DpcListHead, &Dpc->DpcListEntry);
|
||||
} else {
|
||||
InsertTailList(&Pcr->PrcbData.DpcData[0].DpcListHead, &Dpc->DpcListEntry);
|
||||
}
|
||||
DPRINT("New DPC Added. Dpc->DpcListEntry.Flink %x\n", Dpc->DpcListEntry.Flink);
|
||||
|
||||
/* Make sure a DPC isn't executing already and respect rules outlined above. */
|
||||
if ((!Pcr->PrcbData.DpcRoutineActive) && (!Pcr->PrcbData.DpcInterruptRequested)) {
|
||||
|
||||
KeRaiseIrql(HIGH_LEVEL, &oldlvl);
|
||||
KiAcquireSpinLock(&Pcr->PrcbData.DpcData[0].DpcLock);
|
||||
Pcr->PrcbData.DpcRoutineActive--;
|
||||
#ifdef MP
|
||||
/*
|
||||
* If the dpc routine drops the irql below DISPATCH_LEVEL,
|
||||
* a thread switch can occur and after the next thread switch
|
||||
* the execution may start on an other processor.
|
||||
*/
|
||||
if (Pcr != KeGetCurrentKPCR())
|
||||
{
|
||||
KiReleaseSpinLock(&Pcr->PrcbData.DpcData[0].DpcLock);
|
||||
Pcr = KeGetCurrentKPCR();
|
||||
KiAcquireSpinLock(&Pcr->PrcbData.DpcData[0].DpcLock);
|
||||
/* Check if this is the same CPU */
|
||||
if (Pcr != KeGetCurrentKPCR()) {
|
||||
/* Send IPI if High Importance */
|
||||
if ((Dpc->Importance == HighImportance) ||
|
||||
(Pcr->PrcbData.DpcData[0].DpcQueueDepth >= Pcr->PrcbData.MaximumDpcQueueDepth)) {
|
||||
|
||||
/* FIXME: USE IPI */
|
||||
Pcr->PrcbData.DpcInterruptRequested = TRUE;
|
||||
HalRequestSoftwareInterrupt(DISPATCH_LEVEL);
|
||||
}
|
||||
} else {
|
||||
/* Request an Interrupt only if the DPC isn't low priority */
|
||||
if ((Dpc->Importance != LowImportance) ||
|
||||
(Pcr->PrcbData.DpcData[0].DpcQueueDepth >= Pcr->PrcbData.MaximumDpcQueueDepth) ||
|
||||
(Pcr->PrcbData.DpcRequestRate < Pcr->PrcbData.MinimumDpcRate)) {
|
||||
|
||||
/* Request Interrupt */
|
||||
HalRequestSoftwareInterrupt(DISPATCH_LEVEL);
|
||||
Pcr->PrcbData.DpcInterruptRequested = TRUE;
|
||||
}
|
||||
}
|
||||
#else
|
||||
DPRINT("Requesting Interrupt. Importance: %x. QueueDepth: %x. MaxQueue: %x . RequestRate: %x. MinRate:%x \n", Dpc->Importance, Pcr->PrcbData.DpcData[0].DpcQueueDepth, Pcr->PrcbData.MaximumDpcQueueDepth, Pcr->PrcbData.DpcRequestRate, Pcr->PrcbData.MinimumDpcRate);
|
||||
/* Request an Interrupt only if the DPC isn't low priority */
|
||||
if ((Dpc->Importance != LowImportance) ||
|
||||
(Pcr->PrcbData.DpcData[0].DpcQueueDepth >= Pcr->PrcbData.MaximumDpcQueueDepth) ||
|
||||
(Pcr->PrcbData.DpcRequestRate < Pcr->PrcbData.MinimumDpcRate)) {
|
||||
|
||||
/* Request Interrupt */
|
||||
DPRINT("Requesting Interrupt\n");
|
||||
HalRequestSoftwareInterrupt(DISPATCH_LEVEL);
|
||||
Pcr->PrcbData.DpcInterruptRequested = TRUE;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
KiReleaseSpinLock(&Pcr->PrcbData.DpcData[0].DpcLock);
|
||||
KeLowerIrql(oldlvl);
|
||||
}
|
||||
if (Pcr->PrcbData.QuantumEnd)
|
||||
{
|
||||
/*
|
||||
* FIXME: Various special cases should be handled here. The scripts
|
||||
* from David B. Probert that describe it under KiQuantumEnd.
|
||||
*/
|
||||
CurrentThread = /* Pcr->PcrbData.CurrentThread */ KeGetCurrentThread();
|
||||
CurrentProcess = CurrentThread->ApcState.Process;
|
||||
CurrentThread->Quantum = CurrentProcess->ThreadQuantum;
|
||||
Pcr->PrcbData.QuantumEnd = FALSE;
|
||||
PsDispatchThread(THREAD_STATE_READY);
|
||||
}
|
||||
|
||||
/* Lower IRQL */
|
||||
KeLowerIrql(OldIrql);
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
* @implemented
|
||||
*/
|
||||
BOOLEAN STDCALL
|
||||
KeRemoveQueueDpc (PKDPC Dpc)
|
||||
/*
|
||||
* FUNCTION:
|
||||
* Removes DPC object from the system dpc queue
|
||||
* ARGUMENTS:
|
||||
* Dpc = Pointer to DPC to remove from the queue.
|
||||
* RETURNS:
|
||||
* TRUE if the DPC was in the queue
|
||||
* FALSE otherwise
|
||||
*/
|
||||
{
|
||||
BOOLEAN WasInQueue;
|
||||
KIRQL OldIrql;
|
||||
|
||||
/* Raise IRQL */
|
||||
DPRINT("Removing DPC: %x\n", Dpc);
|
||||
KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
|
||||
|
||||
/* First make sure the DPC lock isn't being held */
|
||||
WasInQueue = Dpc->DpcData ? TRUE : FALSE;
|
||||
if (Dpc->DpcData) {
|
||||
|
||||
/* Remove the DPC */
|
||||
((PKDPC_DATA)Dpc->DpcData)->DpcQueueDepth--;
|
||||
RemoveEntryList(&Dpc->DpcListEntry);
|
||||
|
||||
}
|
||||
|
||||
/* Return if the DPC was in the queue or not */
|
||||
KeLowerIrql(OldIrql);
|
||||
return WasInQueue;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
VOID
|
||||
STDCALL
|
||||
KeFlushQueuedDpcs(
|
||||
VOID
|
||||
)
|
||||
KeFlushQueuedDpcs(VOID)
|
||||
/*
|
||||
* FUNCTION:
|
||||
* Called to Deliver DPCs if any are pending.
|
||||
* NOTES:
|
||||
* Called when deleting a Driver.
|
||||
*/
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
if (KeGetCurrentKPCR()->PrcbData.DpcData[0].DpcQueueDepth) HalRequestSoftwareInterrupt(DISPATCH_LEVEL);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -182,136 +344,6 @@ KeIsExecutingDpc(
|
|||
return KeGetCurrentKPCR()->PrcbData.DpcRoutineActive;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
BOOLEAN STDCALL
|
||||
KeRemoveQueueDpc (PKDPC Dpc)
|
||||
/*
|
||||
* FUNCTION: Removes DPC object from the system dpc queue
|
||||
* ARGUMENTS:
|
||||
* Dpc = DPC to remove
|
||||
* RETURNS: TRUE if the DPC was in the queue
|
||||
* FALSE otherwise
|
||||
*/
|
||||
{
|
||||
KIRQL oldIrql;
|
||||
BOOLEAN WasInQueue;
|
||||
PKPCR Pcr;
|
||||
|
||||
KeRaiseIrql(HIGH_LEVEL, &oldIrql);
|
||||
#ifdef MP
|
||||
if (Dpc->Number >= MAXIMUM_PROCESSORS)
|
||||
{
|
||||
ASSERT (Dpc->Number - MAXIMUM_PROCESSORS < KeNumberProcessors);
|
||||
Pcr = (PKPCR)(KPCR_BASE + (Dpc->Number - MAXIMUM_PROCESSORS) * PAGE_SIZE);
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT (Dpc->Number < KeNumberProcessors);
|
||||
Pcr = (PKPCR)(KPCR_BASE + Dpc->Number * PAGE_SIZE);
|
||||
}
|
||||
#else
|
||||
Pcr = KeGetCurrentKPCR();
|
||||
#endif
|
||||
KiAcquireSpinLock(&Pcr->PrcbData.DpcData[0].DpcLock);
|
||||
WasInQueue = Dpc->Lock ? TRUE : FALSE;
|
||||
if (WasInQueue)
|
||||
{
|
||||
RemoveEntryList(&Dpc->DpcListEntry);
|
||||
Pcr->PrcbData.DpcData[0].DpcQueueDepth--;
|
||||
Dpc->Lock=0;
|
||||
}
|
||||
|
||||
if (Pcr->PrcbData.DpcData[0].DpcQueueDepth == 0)
|
||||
{
|
||||
ASSERT(IsListEmpty(&Pcr->PrcbData.DpcData[0].DpcListHead));
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT(!IsListEmpty(&Pcr->PrcbData.DpcData[0].DpcListHead));
|
||||
}
|
||||
|
||||
KiReleaseSpinLock(&Pcr->PrcbData.DpcData[0].DpcLock);
|
||||
KeLowerIrql(oldIrql);
|
||||
|
||||
return WasInQueue;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
BOOLEAN STDCALL
|
||||
KeInsertQueueDpc (PKDPC Dpc,
|
||||
PVOID SystemArgument1,
|
||||
PVOID SystemArgument2)
|
||||
/*
|
||||
* FUNCTION: Queues a DPC for execution when the IRQL of a processor
|
||||
* drops below DISPATCH_LEVEL
|
||||
* ARGUMENTS:
|
||||
* Dpc = Initalizes DPC
|
||||
* SystemArguments[1-2] = Undocumented
|
||||
* RETURNS: TRUE if the DPC object wasn't already in the queue
|
||||
* FALSE otherwise
|
||||
*/
|
||||
{
|
||||
KIRQL oldlvl;
|
||||
PKPCR Pcr;
|
||||
|
||||
DPRINT("KeInsertQueueDpc(dpc %x, SystemArgument1 %x, SystemArgument2 %x)\n",
|
||||
Dpc, SystemArgument1, SystemArgument2);
|
||||
|
||||
ASSERT(KeGetCurrentIrql()>=DISPATCH_LEVEL);
|
||||
|
||||
Dpc->SystemArgument1=SystemArgument1;
|
||||
Dpc->SystemArgument2=SystemArgument2;
|
||||
if (Dpc->Lock)
|
||||
{
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
KeRaiseIrql(HIGH_LEVEL, &oldlvl);
|
||||
#ifdef MP
|
||||
if (Dpc->Number >= MAXIMUM_PROCESSORS)
|
||||
{
|
||||
ASSERT (Dpc->Number - MAXIMUM_PROCESSORS < KeNumberProcessors);
|
||||
Pcr = (PKPCR)(KPCR_BASE + (Dpc->Number - MAXIMUM_PROCESSORS) * PAGE_SIZE);
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT (Dpc->Number < KeNumberProcessors);
|
||||
Pcr = KeGetCurrentKPCR();
|
||||
Dpc->Number = KeGetCurrentProcessorNumber();
|
||||
}
|
||||
#else
|
||||
Pcr = KeGetCurrentKPCR();
|
||||
#endif
|
||||
|
||||
KiAcquireSpinLock(&Pcr->PrcbData.DpcData[0].DpcLock);
|
||||
if (Pcr->PrcbData.DpcData[0].DpcQueueDepth == 0)
|
||||
{
|
||||
ASSERT(IsListEmpty(&Pcr->PrcbData.DpcData[0].DpcListHead));
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT(!IsListEmpty(&Pcr->PrcbData.DpcData[0].DpcListHead));
|
||||
}
|
||||
InsertHeadList(&Pcr->PrcbData.DpcData[0].DpcListHead,&Dpc->DpcListEntry);
|
||||
DPRINT("Dpc->DpcListEntry.Flink %x\n", Dpc->DpcListEntry.Flink);
|
||||
Pcr->PrcbData.DpcData[0].DpcQueueDepth++;
|
||||
Dpc->Lock=(PULONG)1;
|
||||
if (Pcr->PrcbData.MaximumDpcQueueDepth < Pcr->PrcbData.DpcData[0].DpcQueueDepth)
|
||||
{
|
||||
Pcr->PrcbData.MaximumDpcQueueDepth = Pcr->PrcbData.DpcData[0].DpcQueueDepth;
|
||||
}
|
||||
HalRequestSoftwareInterrupt(DISPATCH_LEVEL);
|
||||
KiReleaseSpinLock(&Pcr->PrcbData.DpcData[0].DpcLock);
|
||||
KeLowerIrql(oldlvl);
|
||||
DPRINT("DpcQueueHead.Flink %x\n", Pcr->PrcbData.DpcData[0].DpcListHead.Flink);
|
||||
DPRINT("Leaving KeInsertQueueDpc()\n",0);
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
/*
|
||||
* FUNCTION: Specifies the DPCs importance
|
||||
* ARGUMENTS:
|
||||
|
@ -321,7 +353,8 @@ KeInsertQueueDpc (PKDPC Dpc,
|
|||
*
|
||||
* @implemented
|
||||
*/
|
||||
VOID STDCALL
|
||||
VOID
|
||||
STDCALL
|
||||
KeSetImportanceDpc (IN PKDPC Dpc,
|
||||
IN KDPC_IMPORTANCE Importance)
|
||||
{
|
||||
|
@ -335,7 +368,7 @@ KeSetImportanceDpc (IN PKDPC Dpc,
|
|||
* Number = Processor number
|
||||
* RETURNS: None
|
||||
*
|
||||
* @unimplemented
|
||||
* @implemented
|
||||
*/
|
||||
VOID STDCALL
|
||||
KeSetTargetProcessorDpc (IN PKDPC Dpc,
|
||||
|
@ -352,16 +385,162 @@ KeSetTargetProcessorDpc (IN PKDPC Dpc,
|
|||
}
|
||||
}
|
||||
|
||||
VOID INIT_FUNCTION
|
||||
KeInitDpc(PKPCR Pcr)
|
||||
VOID
|
||||
STDCALL
|
||||
KiQuantumEnd(VOID)
|
||||
/*
|
||||
* FUNCTION: Initialize DPC handling
|
||||
* FUNCTION:
|
||||
* Called when a quantum end occurs to check if priority should be changed
|
||||
* and wether a new thread should be dispatched.
|
||||
* NOTES:
|
||||
* Called when deleting a Driver.
|
||||
*/
|
||||
{
|
||||
InitializeListHead(&Pcr->PrcbData.DpcData[0].DpcListHead);
|
||||
KeInitializeSpinLock(&Pcr->PrcbData.DpcData[0].DpcLock);
|
||||
Pcr->PrcbData.MaximumDpcQueueDepth = 0;
|
||||
Pcr->PrcbData.DpcData[0].DpcQueueDepth = 0;
|
||||
KPRCB Prcb;
|
||||
PKTHREAD CurrentThread;
|
||||
KIRQL OldIrql;
|
||||
PKPROCESS Process;
|
||||
KPRIORITY OldPriority;
|
||||
KPRIORITY NewPriority;
|
||||
|
||||
/* Lock dispatcher, get current thread */
|
||||
Prcb = KeGetCurrentKPCR()->PrcbData;
|
||||
CurrentThread = KeGetCurrentThread();
|
||||
OldIrql = KeRaiseIrqlToSynchLevel();
|
||||
|
||||
/* Get the Thread's Process */
|
||||
Process = CurrentThread->ApcState.Process;
|
||||
|
||||
/* Set DPC Event if requested */
|
||||
if (Prcb.DpcSetEventRequest) {
|
||||
KeSetEvent(Prcb.DpcEvent, 0, 0);
|
||||
}
|
||||
|
||||
/* Check if Quantum expired */
|
||||
if (CurrentThread->Quantum <= 0) {
|
||||
/* Set the new Quantum */
|
||||
CurrentThread->Quantum = Process->ThreadQuantum;
|
||||
|
||||
/* Calculate new priority */
|
||||
OldPriority = CurrentThread->Priority;
|
||||
if (OldPriority < LOW_REALTIME_PRIORITY) {
|
||||
NewPriority = OldPriority - CurrentThread->PriorityDecrement - 1;
|
||||
if (NewPriority < CurrentThread->BasePriority) {
|
||||
NewPriority = CurrentThread->BasePriority;
|
||||
}
|
||||
CurrentThread->PriorityDecrement = 0;
|
||||
if (OldPriority != NewPriority) {
|
||||
/* Set new Priority */
|
||||
CurrentThread->Priority = NewPriority;
|
||||
} else {
|
||||
/* Queue new thread if none is already */
|
||||
if (Prcb.NextThread == NULL) {
|
||||
/* FIXME: Schedule a New Thread, when ROS will have NT Scheduler */
|
||||
} else {
|
||||
/* Make the current thread non-premeptive if a new thread is queued */
|
||||
CurrentThread->Preempted = FALSE;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Set the Quantum back to Maximum */
|
||||
//if (CurrentThread->DisableQuantum) {
|
||||
// CurrentThread->Quantum = MAX_QUANTUM;
|
||||
//}
|
||||
}
|
||||
}
|
||||
/* Dispatch the Thread */
|
||||
KeLowerIrql(DISPATCH_LEVEL);
|
||||
PsDispatchThread(THREAD_STATE_READY);
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
VOID
|
||||
STDCALL
|
||||
KiDispatchInterrupt(VOID)
|
||||
/*
|
||||
* FUNCTION:
|
||||
* Called whenever a system interrupt is generated at DISPATCH_LEVEL.
|
||||
* It delivers queued DPCs and dispatches a new thread if need be.
|
||||
*/
|
||||
{
|
||||
PLIST_ENTRY DpcEntry;
|
||||
PKDPC Dpc;
|
||||
KIRQL OldIrql;
|
||||
PKPCR Pcr;
|
||||
|
||||
DPRINT("Dispatching Interrupts\n");
|
||||
ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
|
||||
|
||||
/* Set DPC Deliver to Active */
|
||||
Pcr = KeGetCurrentKPCR();
|
||||
Pcr->PrcbData.DpcRoutineActive = TRUE;
|
||||
|
||||
if (Pcr->PrcbData.DpcData[0].DpcQueueDepth > 0) {
|
||||
/* Raise IRQL */
|
||||
KeRaiseIrql(HIGH_LEVEL, &OldIrql);
|
||||
#ifdef MP
|
||||
KiAcquireSpinLock(&Pcr->PrcbData.DpcData[0].DpcLock);
|
||||
#endif
|
||||
|
||||
DPRINT("&Pcr->PrcbData.DpcData[0].DpcListHead: %x\n", &Pcr->PrcbData.DpcData[0].DpcListHead);
|
||||
/* Loop while we have entries */
|
||||
while (!IsListEmpty(&Pcr->PrcbData.DpcData[0].DpcListHead)) {
|
||||
ASSERT(Pcr->PrcbData.DpcData[0].DpcQueueDepth > 0);
|
||||
DPRINT("Queue Depth: %x\n", Pcr->PrcbData.DpcData[0].DpcQueueDepth);
|
||||
|
||||
/* Get the DPC call it */
|
||||
DpcEntry = RemoveHeadList(&Pcr->PrcbData.DpcData[0].DpcListHead);
|
||||
Dpc = CONTAINING_RECORD(DpcEntry, KDPC, DpcListEntry);
|
||||
DPRINT("Dpc->DpcListEntry.Flink %x\n", Dpc->DpcListEntry.Flink);
|
||||
Dpc->DpcData = NULL;
|
||||
Pcr->PrcbData.DpcData[0].DpcQueueDepth--;
|
||||
#ifdef MP
|
||||
KiReleaseSpinLock(&Pcr->PrcbData.DpcData[0].DpcLock);
|
||||
#endif
|
||||
/* Disable/Enabled Interrupts and Call the DPC */
|
||||
KeLowerIrql(OldIrql);
|
||||
DPRINT("Calling DPC: %x\n", Dpc);
|
||||
Dpc->DeferredRoutine(Dpc,
|
||||
Dpc->DeferredContext,
|
||||
Dpc->SystemArgument1,
|
||||
Dpc->SystemArgument2);
|
||||
KeRaiseIrql(HIGH_LEVEL, &OldIrql);
|
||||
#ifdef MP
|
||||
KiAcquireSpinLock(&Pcr->PrcbData.DpcData[0].DpcLock);
|
||||
#endif
|
||||
|
||||
#ifdef MP
|
||||
/*
|
||||
* If the dpc routine drops the irql below DISPATCH_LEVEL,
|
||||
* a thread switch can occur and after the next thread switch
|
||||
* the execution may start on an other processor.
|
||||
*/
|
||||
if (Pcr != KeGetCurrentKPCR()) {
|
||||
KiReleaseSpinLock(&Pcr->PrcbData.DpcData[0].DpcLock);
|
||||
Pcr = KeGetCurrentKPCR();
|
||||
KiAcquireSpinLock(&Pcr->PrcbData.DpcData[0].DpcLock);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#ifdef MP
|
||||
KiReleaseSpinLock(&Pcr->PrcbData.DpcData[0].DpcLock);
|
||||
#endif
|
||||
/* Clear DPC Flags */
|
||||
Pcr->PrcbData.DpcRoutineActive = FALSE;
|
||||
Pcr->PrcbData.DpcInterruptRequested = FALSE;
|
||||
|
||||
/* DPC Dispatching Ended, re-enable interrupts */
|
||||
KeLowerIrql(OldIrql);
|
||||
}
|
||||
|
||||
DPRINT("Checking for Quantum End\n");
|
||||
/* If we have Quantum End, call the function */
|
||||
if (Pcr->PrcbData.QuantumEnd) {
|
||||
Pcr->PrcbData.QuantumEnd = FALSE;
|
||||
KiQuantumEnd();
|
||||
}
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: timer.c,v 1.88 2004/11/06 16:05:49 ekohl Exp $
|
||||
/* $Id: timer.c,v 1.89 2004/11/21 06:51:18 ion Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -649,7 +649,7 @@ KeInitializeTimerImpl(VOID)
|
|||
HalQueryRealTimeClock(&TimeFields);
|
||||
RtlTimeFieldsToTime(&TimeFields, &SystemBootTime);
|
||||
|
||||
SharedUserData->TickCountLow = 0;
|
||||
SharedUserData->TickCountLowDeprecated = 0;
|
||||
SharedUserData->TickCountMultiplier = 167783691; // 2^24 * 1193182 / 119310
|
||||
SharedUserData->InterruptTime.High2Time = 0;
|
||||
SharedUserData->InterruptTime.LowPart = 0;
|
||||
|
@ -795,7 +795,7 @@ KeUpdateSystemTime(
|
|||
* Increment the number of timers ticks
|
||||
*/
|
||||
KeTickCount++;
|
||||
SharedUserData->TickCountLow++;
|
||||
SharedUserData->TickCountLowDeprecated++;
|
||||
KiAcquireSpinLock(&TimerValueLock);
|
||||
|
||||
Time.u.LowPart = SharedUserData->InterruptTime.LowPart;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: namespc.c,v 1.48 2004/09/05 22:25:36 hbirr Exp $
|
||||
/* $Id: namespc.c,v 1.49 2004/11/21 06:51:18 ion Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -22,6 +22,8 @@ POBJECT_TYPE ObDirectoryType = NULL;
|
|||
POBJECT_TYPE ObTypeObjectType = NULL;
|
||||
|
||||
PDIRECTORY_OBJECT NameSpaceRoot = NULL;
|
||||
/* FIXME: Move this somewhere else once devicemap support is in */
|
||||
PDEVICE_MAP ObSystemDeviceMap = NULL;
|
||||
|
||||
static GENERIC_MAPPING ObpDirectoryMapping = {
|
||||
STANDARD_RIGHTS_READ|DIRECTORY_QUERY|DIRECTORY_TRAVERSE,
|
||||
|
@ -157,6 +159,29 @@ ObOpenObjectByName(IN POBJECT_ATTRIBUTES ObjectAttributes,
|
|||
return Status;
|
||||
}
|
||||
|
||||
VOID
|
||||
STDCALL
|
||||
ObQueryDeviceMapInformation(PEPROCESS Process,
|
||||
PPROCESS_DEVICEMAP_INFORMATION DeviceMapInfo)
|
||||
{
|
||||
PDEVICE_MAP DeviceMap;
|
||||
//KIRQL OldIrql ;
|
||||
|
||||
/*
|
||||
* FIXME: This is an ugly hack for now, to always return the System Device Map
|
||||
* instead of returning the Process Device Map. Not important yet since we don't use it
|
||||
*/
|
||||
DeviceMap = ObSystemDeviceMap;
|
||||
|
||||
/* FIXME: Acquire the DeviceMap Spinlock */
|
||||
// KeAcquireSpinLock(DeviceMap->Lock, &OldIrql);
|
||||
|
||||
/* Make a copy */
|
||||
RtlMoveMemory(DeviceMapInfo, &DeviceMap->DriveMap, sizeof(DeviceMapInfo->Query));
|
||||
|
||||
/* FIXME: Release the DeviceMap Spinlock */
|
||||
// KeReleasepinLock(DeviceMap->Lock, OldIrql);
|
||||
}
|
||||
|
||||
VOID
|
||||
ObpAddEntryDirectory(PDIRECTORY_OBJECT Parent,
|
||||
|
@ -452,6 +477,10 @@ ObInit(VOID)
|
|||
|
||||
/* Create 'symbolic link' object type */
|
||||
ObInitSymbolicLinkImplementation();
|
||||
|
||||
/* FIXME: Hack Hack! */
|
||||
ObSystemDeviceMap = ExAllocatePoolWithTag(NonPagedPool, sizeof(*ObSystemDeviceMap), TAG('O', 'b', 'D', 'm'));
|
||||
RtlZeroMemory(ObSystemDeviceMap, sizeof(*ObSystemDeviceMap));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: process.c,v 1.152 2004/11/20 16:46:05 weiden Exp $
|
||||
/* $Id: process.c,v 1.153 2004/11/21 06:51:18 ion Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -15,7 +15,6 @@
|
|||
#define NDEBUG
|
||||
#include <internal/debug.h>
|
||||
|
||||
|
||||
/* GLOBALS ******************************************************************/
|
||||
|
||||
PEPROCESS EXPORTED PsInitialSystemProcess = NULL;
|
||||
|
@ -1225,7 +1224,16 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle,
|
|||
break;
|
||||
|
||||
case ProcessDeviceMap:
|
||||
Status = STATUS_NOT_IMPLEMENTED;
|
||||
if (ProcessInformationLength != sizeof(PROCESS_DEVICEMAP_INFORMATION)) {
|
||||
Status = STATUS_INFO_LENGTH_MISMATCH;
|
||||
} else {
|
||||
PPROCESS_DEVICEMAP_INFORMATION DeviceMapInfo;
|
||||
DeviceMapInfo = (PPROCESS_DEVICEMAP_INFORMATION)ProcessInformation;
|
||||
ObQueryDeviceMapInformation(Process, DeviceMapInfo);
|
||||
if (ReturnLength) {
|
||||
*ReturnLength = sizeof(PROCESS_DEVICEMAP_INFORMATION);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ProcessPriorityClass:
|
||||
|
|
Loading…
Reference in a new issue