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:
Alex Ionescu 2004-11-21 06:51:18 +00:00
parent 5fea7dac8b
commit 2a42da87f2
16 changed files with 703 additions and 339 deletions

View file

@ -238,7 +238,7 @@ typedef struct _KDPC
PVOID DeferredContext;
PVOID SystemArgument1;
PVOID SystemArgument2;
PULONG Lock;
PVOID DpcData;
} KDPC, *PKDPC;
#include <poppack.h>

View file

@ -29,37 +29,46 @@ typedef struct _KSYSTEM_TIME
LONG High2Time;
} KSYSTEM_TIME, *PKSYSTEM_TIME;
typedef struct _KUSER_SHARED_DATA
{
volatile ULONG TickCountLow;
ULONG TickCountMultiplier;
volatile KSYSTEM_TIME InterruptTime;
volatile KSYSTEM_TIME SystemTime;
volatile KSYSTEM_TIME TimeZoneBias;
USHORT ImageNumberLow;
USHORT ImageNumberHigh;
WCHAR NtSystemRoot[260];
ULONG DosDeviceMap;
ULONG CryptoExponent;
ULONG TimeZoneId;
UCHAR DosDeviceDriveType[32];
NT_PRODUCT_TYPE NtProductType;
BOOLEAN ProductTypeIsValid;
ULONG NtMajorVersion;
ULONG NtMinorVersion;
BOOLEAN ProcessorFeatures[PROCESSOR_FEATURES_MAX];
/* NT5 / Win2k specific ?? */
ULONG Reserved1;
ULONG Reserved3;
volatile ULONG TimeSlip;
ALTERNATIVE_ARCHITECTURE_TYPE AlternativeArchitecture;
ULONG SuiteMask;
#ifdef REMOTE_BOOT
ULONG SystemFlags;
UCHAR RemoteBootServerPath[260];
#endif
BOOLEAN KdDebuggerEnabled;
#define PROCESSOR_FEATURE_MAX 64
typedef struct _KUSER_SHARED_DATA {
ULONG TickCountLowDeprecated;
ULONG TickCountMultiplier;
volatile KSYSTEM_TIME InterruptTime;
volatile KSYSTEM_TIME SystemTime;
volatile KSYSTEM_TIME TimeZoneBias;
USHORT ImageNumberLow;
USHORT ImageNumberHigh;
WCHAR NtSystemRoot[260];
ULONG MaxStackTraceDepth;
ULONG CryptoExponent;
ULONG TimeZoneId;
ULONG LargePageMinimum;
ULONG Reserved2[7];
NT_PRODUCT_TYPE NtProductType;
BOOLEAN ProductTypeIsValid;
ULONG NtMajorVersion;
ULONG NtMinorVersion;
BOOLEAN ProcessorFeatures[PROCESSOR_FEATURE_MAX];
ULONG Reserved1;
ULONG Reserved3;
volatile ULONG TimeSlip;
ALTERNATIVE_ARCHITECTURE_TYPE AlternativeArchitecture;
LARGE_INTEGER SystemExpirationDate;
ULONG SuiteMask;
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 */

View file

@ -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 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;
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;
typedef struct _HAL_DISPATCH
{
ULONG Version;
pHalQuerySystemInformation HalQuerySystemInformation;
pHalSetSystemInformation HalSetSystemInformation;
pHalQueryBusSlots HalQueryBusSlots;
pHalDeviceControl HalDeviceControl;
pHalExamineMBR HalExamineMBR;
pHalIoAssignDriveLetters HalIoAssignDriveLetters;
pHalIoReadPartitionTable HalIoReadPartitionTable;
pHalIoSetPartitionInformation HalIoSetPartitionInformation;
pHalIoWritePartitionTable HalIoWritePartitionTable;
pHalHandlerForBus HalReferenceHandlerForBus;
pHalReferenceBusHandler HalReferenceBusHandler;
pHalReferenceBusHandler HalDereferenceBusHandler;
} 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

View file

@ -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 */

View file

@ -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

View file

@ -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;
}
}

View file

@ -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);
}

View file

@ -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)

View file

@ -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 */

View file

@ -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;
};

View file

@ -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,

View file

@ -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 *****************************************************************/

View file

@ -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;
Dpc->DeferredRoutine = DeferredRoutine;
Dpc->DeferredContext = DeferredContext;
Dpc->Lock = 0;
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->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;
PKPCR Pcr;
PKTHREAD CurrentThread;
PKPROCESS CurrentProcess;
KIRQL OldIrql;
PKPCR Pcr;
ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
DPRINT("KeInsertQueueDpc(DPC %x, SystemArgument1 %x, SystemArgument2 %x)\n",
Dpc, SystemArgument1, SystemArgument2);
Pcr = KeGetCurrentKPCR();
/* 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);
//}
if (Pcr->PrcbData.DpcData[0].DpcQueueDepth > 0)
{
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--;
Pcr->PrcbData.DpcData[0].DpcCount++;
if (Pcr->PrcbData.DpcData[0].DpcQueueDepth == 0)
{
ASSERT(IsListEmpty(&Pcr->PrcbData.DpcData[0].DpcListHead));
}
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);
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);
}
/* 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
}
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);
}
/* Get the DPC Data */
if (InterlockedCompareExchange((LONG*)&Dpc->DpcData, (LONG)&Pcr->PrcbData.DpcData[0].DpcLock, 0)) {
DPRINT("DPC Already Inserted");
KeLowerIrql(OldIrql);
return(FALSE);
}
/* Now we can play with the DPC safely */
Dpc->SystemArgument1=SystemArgument1;
Dpc->SystemArgument2=SystemArgument2;
Pcr->PrcbData.DpcData[0].DpcQueueDepth++;
Pcr->PrcbData.DpcData[0].DpcCount++;
/* 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 {
ASSERT(!IsListEmpty(&Pcr->PrcbData.DpcData[0].DpcListHead));
}
/* 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)) {
#ifdef MP
/* 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
}
/* 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 */

View file

@ -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;

View file

@ -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,7 +159,30 @@ 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,
POBJECT_HEADER Header,
@ -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));
}

View file

@ -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: