diff --git a/reactos/include/ddk/ketypes.h b/reactos/include/ddk/ketypes.h index b4e897d238c..549be03befc 100644 --- a/reactos/include/ddk/ketypes.h +++ b/reactos/include/ddk/ketypes.h @@ -238,7 +238,7 @@ typedef struct _KDPC PVOID DeferredContext; PVOID SystemArgument1; PVOID SystemArgument2; - PULONG Lock; + PVOID DpcData; } KDPC, *PKDPC; #include diff --git a/reactos/include/napi/shared_data.h b/reactos/include/napi/shared_data.h index f8de59ab801..43e14d87073 100644 --- a/reactos/include/napi/shared_data.h +++ b/reactos/include/napi/shared_data.h @@ -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 */ diff --git a/reactos/include/ntos/haltypes.h b/reactos/include/ntos/haltypes.h index b50a0e87882..3d498fdf393 100755 --- a/reactos/include/ntos/haltypes.h +++ b/reactos/include/ntos/haltypes.h @@ -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 diff --git a/reactos/include/ntos/obtypes.h b/reactos/include/ntos/obtypes.h index 958b61f31c3..08079c1c338 100755 --- a/reactos/include/ntos/obtypes.h +++ b/reactos/include/ntos/obtypes.h @@ -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 */ diff --git a/reactos/include/ntos/zwtypes.h b/reactos/include/ntos/zwtypes.h index b7b33197db4..613d92c3dca 100755 --- a/reactos/include/ntos/zwtypes.h +++ b/reactos/include/ntos/zwtypes.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 diff --git a/reactos/lib/kernel32/file/volume.c b/reactos/lib/kernel32/file/volume.c index dcc3ab0e60a..a2105fd3899 100644 --- a/reactos/lib/kernel32/file/volume.c +++ b/reactos/lib/kernel32/file/volume.c @@ -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; + } } diff --git a/reactos/lib/kernel32/misc/time.c b/reactos/lib/kernel32/misc/time.c index 736cc0660b9..ba990d8223f 100644 --- a/reactos/lib/kernel32/misc/time.c +++ b/reactos/lib/kernel32/misc/time.c @@ -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); } diff --git a/reactos/ntoskrnl/include/internal/i386/ps.h b/reactos/ntoskrnl/include/internal/i386/ps.h index 63d3361a7c4..6fb73b77d7f 100644 --- a/reactos/ntoskrnl/include/internal/i386/ps.h +++ b/reactos/ntoskrnl/include/internal/i386/ps.h @@ -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) diff --git a/reactos/ntoskrnl/include/internal/ob.h b/reactos/ntoskrnl/include/internal/ob.h index ed02c4423a3..7c0548d0e0a 100644 --- a/reactos/ntoskrnl/include/internal/ob.h +++ b/reactos/ntoskrnl/include/internal/ob.h @@ -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 */ diff --git a/reactos/ntoskrnl/io/xhaldisp.c b/reactos/ntoskrnl/io/xhaldisp.c index 1d10b08d235..381c615a15b 100644 --- a/reactos/ntoskrnl/io/xhaldisp.c +++ b/reactos/ntoskrnl/io/xhaldisp.c @@ -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; }; diff --git a/reactos/ntoskrnl/io/xhaldrv.c b/reactos/ntoskrnl/io/xhaldrv.c index db3f727056d..7bb9ad62efa 100644 --- a/reactos/ntoskrnl/io/xhaldrv.c +++ b/reactos/ntoskrnl/io/xhaldrv.c @@ -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, diff --git a/reactos/ntoskrnl/ke/apc.c b/reactos/ntoskrnl/ke/apc.c index 882aada2001..36c0965d5c4 100644 --- a/reactos/ntoskrnl/ke/apc.c +++ b/reactos/ntoskrnl/ke/apc.c @@ -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 *****************************************************************/ diff --git a/reactos/ntoskrnl/ke/dpc.c b/reactos/ntoskrnl/ke/dpc.c index 8d11fc8bec3..0047b3ab6b1 100644 --- a/reactos/ntoskrnl/ke/dpc.c +++ b/reactos/ntoskrnl/ke/dpc.c @@ -3,6 +3,7 @@ * Copyright (C) 2000, 1999, 1998 David Welch , * Philip Susi , * Eric Kohl + * Alex Ionescu * * 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 */ diff --git a/reactos/ntoskrnl/ke/timer.c b/reactos/ntoskrnl/ke/timer.c index 628a22c167c..ee66fb69047 100644 --- a/reactos/ntoskrnl/ke/timer.c +++ b/reactos/ntoskrnl/ke/timer.c @@ -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; diff --git a/reactos/ntoskrnl/ob/namespc.c b/reactos/ntoskrnl/ob/namespc.c index 30e0313f875..8ccb9aa6281 100644 --- a/reactos/ntoskrnl/ob/namespc.c +++ b/reactos/ntoskrnl/ob/namespc.c @@ -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)); } diff --git a/reactos/ntoskrnl/ps/process.c b/reactos/ntoskrnl/ps/process.c index e20d13aeb96..d4ac3075bd3 100644 --- a/reactos/ntoskrnl/ps/process.c +++ b/reactos/ntoskrnl/ps/process.c @@ -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 - /* 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: