diff --git a/reactos/include/ddk/cmtypes.h b/reactos/include/ddk/cmtypes.h index 6ecd3b23963..560502e72c1 100644 --- a/reactos/include/ddk/cmtypes.h +++ b/reactos/include/ddk/cmtypes.h @@ -20,14 +20,14 @@ typedef struct _KEY_OBJECT ULONG NumSubKeys; ULONG MaxSubNameLength; ULONG MaxSubClassLength; - PKEY_OBJECT *SubKeys; + struct _KEY_OBJECT *SubKeys; ULONG NumValues; ULONG MaxValueNameLength; ULONG MaxValueDataLength; PKEY_VALUE *Values; WCHAR *Name; WCHAR *Class; - PKEY_OBJECT *NextKey; + struct _KEY_OBJECT *NextKey; } KEY_OBJECT, *PKEY_OBJECT; /* key query information class */ diff --git a/reactos/include/ddk/ntddk.h b/reactos/include/ddk/ntddk.h index 4e9f30e1c3c..4f805ada2fc 100644 --- a/reactos/include/ddk/ntddk.h +++ b/reactos/include/ddk/ntddk.h @@ -26,7 +26,7 @@ extern "C" #include #include #include -#include +// #include #include #include #include diff --git a/reactos/include/ddk/types.h b/reactos/include/ddk/types.h index 8c03541be4d..ac63b3be0ac 100644 --- a/reactos/include/ddk/types.h +++ b/reactos/include/ddk/types.h @@ -100,8 +100,6 @@ typedef enum _FILE_INFORMATION_CLASS FileMaximumInformation, } FILE_INFORMATION_CLASS; -typedef ULONG KEY_INFORMATION_CLASS; -typedef ULONG KEY_VALUE_INFORMATION_CLASS; typedef LARGE_INTEGER PHYSICAL_ADDRESS; typedef PHYSICAL_ADDRESS* PPHYSICAL_ADDRESS; typedef ULONG WAIT_TYPE; diff --git a/reactos/include/internal/io.h b/reactos/include/internal/io.h index 19d6a5f539d..2a86cbedcc9 100644 --- a/reactos/include/internal/io.h +++ b/reactos/include/internal/io.h @@ -24,7 +24,7 @@ extern POBJECT_TYPE IoSymbolicLinkType; * entry = pointer to the driver initialization routine * RETURNS: Success or failure */ -NTSTATUS InitalizeLoadedDriver(PDRIVER_INITIALIZE entry); +NTSTATUS InitializeLoadedDriver(PDRIVER_INITIALIZE entry); diff --git a/reactos/include/internal/iomgr.h b/reactos/include/internal/iomgr.h index a7766704da0..1b3e1199b2a 100644 --- a/reactos/include/internal/iomgr.h +++ b/reactos/include/internal/iomgr.h @@ -19,7 +19,7 @@ * entry = pointer to the driver initialization routine * RETURNS: Success or failure */ -NTSTATUS InitalizeLoadedDriver(PDRIVER_INITIALIZE entry); +NTSTATUS InitializeLoadedDriver(PDRIVER_INITIALIZE entry); VOID IoInitCancelHandling(VOID); VOID IoInitSymbolicLinkImplementation(VOID); diff --git a/reactos/include/internal/ntoskrnl.h b/reactos/include/internal/ntoskrnl.h index 36322ecdc72..a38a2eb8968 100644 --- a/reactos/include/internal/ntoskrnl.h +++ b/reactos/include/internal/ntoskrnl.h @@ -77,7 +77,7 @@ typedef struct /* * Initalization functions (called once by main()) */ -void MmInitalize(boot_param* bp); +void MmInitialize(boot_param* bp); void HalInit(boot_param* bp); void IoInit(void); void ObInit(void); diff --git a/reactos/ntoskrnl/cm/registry.c b/reactos/ntoskrnl/cm/registry.c index 045b2511496..55faead8e48 100644 --- a/reactos/ntoskrnl/cm/registry.c +++ b/reactos/ntoskrnl/cm/registry.c @@ -24,6 +24,7 @@ PKEY_OBJECT RootKey = NULL; VOID CmInitializeRegistry(VOID) { +#if 0 ANSI_STRING AnsiString; CmKeyType = ExAllocatePool(NonPagedPool, sizeof(OBJECT_TYPE)); @@ -79,6 +80,7 @@ CmInitializeRegistry(VOID) /* FIXME: Create initial predefined symbolic links */ /* HKEY_LOCAL_MACHINE */ /* HKEY_USERS */ +#endif } NTSTATUS @@ -108,6 +110,7 @@ ZwCreateKey(PHANDLE KeyHandle, ULONG CreateOptions, PULONG Disposition) { +#if 0 /* FIXME: Should CurLevel be alloced to handle arbitrary size components? */ WCHAR *S, *T, CurLevel[255]; PKEY_OBJECT ParentKey, CurSubKey, NewKey; @@ -253,7 +256,7 @@ ZwCreateKey(PHANDLE KeyHandle, { return STATUS_UNSUCCESSFUL; } - +#endif UNIMPLEMENTED; } diff --git a/reactos/ntoskrnl/io/device.c b/reactos/ntoskrnl/io/device.c index f731aa12426..24fe0718b3f 100644 --- a/reactos/ntoskrnl/io/device.c +++ b/reactos/ntoskrnl/io/device.c @@ -113,7 +113,7 @@ VOID IoRegisterDriverReinitialization(PDRIVER_OBJECT DriverObject, } -NTSTATUS InitalizeLoadedDriver(PDRIVER_INITIALIZE entry) +NTSTATUS InitializeLoadedDriver(PDRIVER_INITIALIZE entry) /* * FUNCTION: Called to initalize a loaded driver * ARGUMENTS: @@ -131,21 +131,25 @@ NTSTATUS InitalizeLoadedDriver(PDRIVER_INITIALIZE entry) if (DriverObject==NULL) { DbgPrint("%s:%d\n",__FILE__,__LINE__); - return(STATUS_INSUFFICIENT_RESOURCES); + return STATUS_INSUFFICIENT_RESOURCES; } - memset(DriverObject,sizeof(DRIVER_OBJECT),0); + memset(DriverObject, '\0', sizeof(DRIVER_OBJECT)); + CHECKPOINT; /* * Initalize the driver * FIXME: Registry in general please */ - if ((ret=entry(DriverObject,NULL))!=STATUS_SUCCESS) + DPRINT("Calling driver entrypoint at %08lx\n", entry); + if ((ret=entry(DriverObject,NULL)) != STATUS_SUCCESS) { DPRINT("Failed to load driver (status %x)\n",ret); ExFreePool(DriverObject); - return(ret); + return ret; } - return(STATUS_SUCCESS); + CHECKPOINT; + + return STATUS_SUCCESS; } NTSTATUS IoAttachDevice(PDEVICE_OBJECT SourceDevice, diff --git a/reactos/ntoskrnl/io/irp.c b/reactos/ntoskrnl/io/irp.c index dc7a779f12d..3c8f2f32196 100644 --- a/reactos/ntoskrnl/io/irp.c +++ b/reactos/ntoskrnl/io/irp.c @@ -1,312 +1,313 @@ -/* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS kernel - * FILE: ntoskrnl/io/irp.c - * PURPOSE: Handle IRPs - * PROGRAMMER: David Welch (welch@mcmail.com) - * UPDATE HISTORY: - * 24/05/98: Created - */ - -/* NOTES ******************************************************************* - * - * Layout of an IRP - * - * ################ - * # Headers # - * ################ - * # # - * # Variable # - * # length list # - * # of io stack # - * # locations # - * # # - * ################ - * - * - * - */ - -/* INCLUDES ****************************************************************/ - -#include -#include -#include - -#define NDEBUG -#include - -/* FUNCTIONS ****************************************************************/ - -PDEVICE_OBJECT IoGetDeviceToVerify(PETHREAD Thread) -/* - * FUNCTION: Returns a pointer to the device, representing a removable-media - * device, that is the target of the given thread's I/O request - */ -{ - UNIMPLEMENTED; -} - -VOID IoFreeIrp(PIRP Irp) -/* - * FUNCTION: Releases a caller allocated irp - * ARGUMENTS: - * Irp = Irp to free - */ -{ - ExFreePool(Irp); -} - -PIRP IoMakeAssociatedIrp(PIRP Irp, CCHAR StackSize) -/* - * FUNCTION: Allocates and initializes an irp to associated with a master irp - * ARGUMENTS: - * Irp = Master irp - * StackSize = Number of stack locations to be allocated in the irp - * RETURNS: The irp allocated - */ -{ - PIRP AssocIrp; - - AssocIrp = IoAllocateIrp(StackSize,FALSE); - UNIMPLEMENTED; -} - -VOID IoMarkIrpPending(PIRP Irp) -/* - * FUNCTION: Marks the specified irp, indicating further processing will - * be required by other driver routines - * ARGUMENTS: - * Irp = Irp to mark - */ -{ - DPRINT("IoGetCurrentIrpStackLocation(Irp) %x\n", - IoGetCurrentIrpStackLocation(Irp)); - IoGetCurrentIrpStackLocation(Irp)->Control |= SL_PENDING_RETURNED; - Irp->Tail.Overlay.Thread = KeGetCurrentThread(); - DPRINT("IoGetCurrentIrpStackLocation(Irp)->Control %x\n", - IoGetCurrentIrpStackLocation(Irp)->Control); - DPRINT("SL_PENDING_RETURNED %x\n",SL_PENDING_RETURNED); -} - -USHORT IoSizeOfIrp(CCHAR StackSize) -/* - * FUNCTION: Determines the size of an IRP - * ARGUMENTS: - * StackSize = number of stack locations in the IRP - * RETURNS: The size of the IRP in bytes - */ -{ - return(sizeof(IRP)+((StackSize-1)*sizeof(IO_STACK_LOCATION))); -} - -VOID IoInitializeIrp(PIRP Irp, USHORT PacketSize, CCHAR StackSize) -/* - * FUNCTION: Initalizes an irp allocated by the caller - * ARGUMENTS: - * Irp = IRP to initalize - * PacketSize = Size in bytes of the IRP - * StackSize = Number of stack locations in the IRP - */ -{ - assert(Irp != NULL); - - memset(Irp,0,PacketSize); - Irp->StackCount=StackSize; - Irp->CurrentLocation=StackSize; - Irp->Tail.Overlay.CurrentStackLocation=IoGetCurrentIrpStackLocation(Irp); -} - -PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp) -/* - * FUNCTION: Gets a pointer to the callers location in the I/O stack in - * the given IRP - * ARGUMENTS: - * Irp = Points to the IRP - * RETURNS: A pointer to the stack location - */ -{ - DPRINT("IoGetCurrentIrpStackLocation: Irp %08lx CurLoc %d StkCnt %d\n", - Irp, - Irp->CurrentLocation, - Irp->StackCount); - - return &Irp->Stack[Irp->CurrentLocation]; -} - - -VOID IoSetNextIrpStackLocation(PIRP Irp) -{ - Irp->CurrentLocation--; - Irp->Tail.Overlay.CurrentStackLocation--; -} - -PIO_STACK_LOCATION IoGetNextIrpStackLocation(PIRP Irp) -/* - * FUNCTION: Gives a higher level driver access to the next lower driver's - * I/O stack location - * ARGUMENTS: - * Irp = points to the irp - * RETURNS: A pointer to the stack location - */ -{ - DPRINT("IoGetNextIrpStackLocation: Irp %08lx CurLoc %d StkCnt %d\n", - Irp, - Irp->CurrentLocation, - Irp->StackCount); - - assert(Irp!=NULL); - DPRINT("Irp %x Irp->StackPtr %x\n",Irp,Irp->CurrentLocation); - return(&Irp->Stack[Irp->CurrentLocation-1]); -} - -NTSTATUS IoCallDriver(PDEVICE_OBJECT DevObject, PIRP irp) -/* - * FUNCTION: Sends an IRP to the next lower driver - */ -{ - NTSTATUS Status; - PDRIVER_OBJECT drv = DevObject->DriverObject; - IO_STACK_LOCATION* param = IoGetNextIrpStackLocation(irp); - - DPRINT("Deviceobject %x\n",DevObject); - DPRINT("Irp %x\n",irp); - - irp->Tail.Overlay.CurrentStackLocation--; - irp->CurrentLocation--; - - DPRINT("Io stack address %x\n",param); - DPRINT("Function %d Routine %x\n",param->MajorFunction, - drv->MajorFunction[param->MajorFunction]); - - Status = drv->MajorFunction[param->MajorFunction](DevObject,irp); - return Status; -} - -PIRP IoAllocateIrp(CCHAR StackSize, BOOLEAN ChargeQuota) -/* - * FUNCTION: Allocates an IRP - * ARGUMENTS: - * StackSize = the size of the stack required for the irp - * ChargeQuota = Charge allocation to current threads quota - * RETURNS: Irp allocated - */ -{ - PIRP Irp; - - DPRINT("IoAllocateIrp(StackSize %d ChargeQuota %d)\n", - StackSize, - ChargeQuota); - if (ChargeQuota) - { - Irp = ExAllocatePoolWithQuota(NonPagedPool,IoSizeOfIrp(StackSize)); - } - else - { - Irp = ExAllocatePool(NonPagedPool,IoSizeOfIrp(StackSize)); - } - - if (Irp==NULL) - { - return(NULL); - } - - IoInitializeIrp(Irp, IoSizeOfIrp(StackSize), StackSize); - - DPRINT("Irp %x Irp->StackPtr %d\n", Irp, Irp->CurrentLocation); - - return Irp; -} - -VOID IoSetCompletionRoutine(PIRP Irp, - PIO_COMPLETION_ROUTINE CompletionRoutine, - PVOID Context, - BOOLEAN InvokeOnSuccess, - BOOLEAN InvokeOnError, - BOOLEAN InvokeOnCancel) -{ - IO_STACK_LOCATION* param = IoGetNextIrpStackLocation(Irp); - - param->CompletionRoutine=CompletionRoutine; - param->CompletionContext=Context; - if (InvokeOnSuccess) - { - param->Control = param->Control | SL_INVOKE_ON_SUCCESS; - } - if (InvokeOnError) - { - param->Control = param->Control | SL_INVOKE_ON_ERROR; - } - if (InvokeOnCancel) - { - param->Control = param->Control | SL_INVOKE_ON_CANCEL; - } -} - -VOID IopCompleteRequest(struct _KAPC* Apc, - PKNORMAL_ROUTINE* NormalRoutine, - PVOID* NormalContext, - PVOID* SystemArgument1, - PVOID* SystemArgument2) -{ - IoSecondStageCompletion((PIRP)(*NormalContext), - IO_NO_INCREMENT); -} - -VOID IoCompleteRequest(PIRP Irp, CCHAR PriorityBoost) -/* - * FUNCTION: Indicates the caller has finished all processing for a given - * I/O request and is returning the given IRP to the I/O manager - * ARGUMENTS: - * Irp = Irp to be cancelled - * PriorityBoost = Increment by which to boost the priority of the - * thread making the request - */ -{ - unsigned int i; - NTSTATUS Status; - - DPRINT("IoCompleteRequest(Irp %x, PriorityBoost %d)\n", - Irp,PriorityBoost); - - for (i=0;iStackCount;i++) - { - DPRINT("&Irp->Stack[%d].CompletionRoutine %08lx\n", - i, - Irp->Stack[i].CompletionRoutine); - if (Irp->Stack[i].CompletionRoutine != NULL) - { - Status = Irp->Stack[i].CompletionRoutine( - Irp->Stack[i].DeviceObject, - Irp, - Irp->Stack[i].CompletionContext); - if (Status == STATUS_MORE_PROCESSING_REQUIRED) - { - return; - } - } - DPRINT("Irp->Stack[%d].Control %08lx\n", i, Irp->Stack[i].Control); - if (Irp->Stack[i].Control & SL_PENDING_RETURNED) - { - DPRINT("Setting PendingReturned flag\n"); - Irp->PendingReturned = TRUE; - } - } - - if (Irp->PendingReturned) - { - KeInitializeApc(&Irp->Tail.Apc, - &Irp->Tail.Overlay.Thread->Tcb, - 0, - IopCompleteRequest, - NULL, - NULL, - 0, - Irp); - KeInsertQueueApc(&Irp->Tail.Apc,NULL,NULL,0); - } - else - { - IoSecondStageCompletion(Irp,PriorityBoost); - } -} +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * FILE: ntoskrnl/io/irp.c + * PURPOSE: Handle IRPs + * PROGRAMMER: David Welch (welch@mcmail.com) + * UPDATE HISTORY: + * 24/05/98: Created + */ + +/* NOTES ******************************************************************* + * + * Layout of an IRP + * + * ################ + * # Headers # + * ################ + * # # + * # Variable # + * # length list # + * # of io stack # + * # locations # + * # # + * ################ + * + * + * + */ + +/* INCLUDES ****************************************************************/ + +#include +#include +#include + +#define NDEBUG +#include + +/* FUNCTIONS ****************************************************************/ + +PDEVICE_OBJECT IoGetDeviceToVerify(PETHREAD Thread) +/* + * FUNCTION: Returns a pointer to the device, representing a removable-media + * device, that is the target of the given thread's I/O request + */ +{ + UNIMPLEMENTED; +} + +VOID IoFreeIrp(PIRP Irp) +/* + * FUNCTION: Releases a caller allocated irp + * ARGUMENTS: + * Irp = Irp to free + */ +{ + ExFreePool(Irp); +} + +PIRP IoMakeAssociatedIrp(PIRP Irp, CCHAR StackSize) +/* + * FUNCTION: Allocates and initializes an irp to associated with a master irp + * ARGUMENTS: + * Irp = Master irp + * StackSize = Number of stack locations to be allocated in the irp + * RETURNS: The irp allocated + */ +{ + PIRP AssocIrp; + + AssocIrp = IoAllocateIrp(StackSize,FALSE); + UNIMPLEMENTED; +} + +VOID IoMarkIrpPending(PIRP Irp) +/* + * FUNCTION: Marks the specified irp, indicating further processing will + * be required by other driver routines + * ARGUMENTS: + * Irp = Irp to mark + */ +{ + DPRINT("IoGetCurrentIrpStackLocation(Irp) %x\n", + IoGetCurrentIrpStackLocation(Irp)); + IoGetCurrentIrpStackLocation(Irp)->Control |= SL_PENDING_RETURNED; + Irp->Tail.Overlay.Thread = KeGetCurrentThread(); + DPRINT("IoGetCurrentIrpStackLocation(Irp)->Control %x\n", + IoGetCurrentIrpStackLocation(Irp)->Control); + DPRINT("SL_PENDING_RETURNED %x\n",SL_PENDING_RETURNED); +} + +USHORT IoSizeOfIrp(CCHAR StackSize) +/* + * FUNCTION: Determines the size of an IRP + * ARGUMENTS: + * StackSize = number of stack locations in the IRP + * RETURNS: The size of the IRP in bytes + */ +{ + return(sizeof(IRP)+((StackSize-1)*sizeof(IO_STACK_LOCATION))); +} + +VOID IoInitializeIrp(PIRP Irp, USHORT PacketSize, CCHAR StackSize) +/* + * FUNCTION: Initalizes an irp allocated by the caller + * ARGUMENTS: + * Irp = IRP to initalize + * PacketSize = Size in bytes of the IRP + * StackSize = Number of stack locations in the IRP + */ +{ + assert(Irp != NULL); + + memset(Irp,0,PacketSize); + Irp->StackCount=StackSize; + Irp->CurrentLocation=StackSize; + Irp->Tail.Overlay.CurrentStackLocation=IoGetCurrentIrpStackLocation(Irp); +} + +PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp) +/* + * FUNCTION: Gets a pointer to the callers location in the I/O stack in + * the given IRP + * ARGUMENTS: + * Irp = Points to the IRP + * RETURNS: A pointer to the stack location + */ +{ + DPRINT("IoGetCurrentIrpStackLocation: Irp %08lx CurLoc %d StkCnt %d\n", + Irp, + Irp->CurrentLocation, + Irp->StackCount); + + return &Irp->Stack[Irp->CurrentLocation]; +} + + +VOID IoSetNextIrpStackLocation(PIRP Irp) +{ + Irp->CurrentLocation--; + Irp->Tail.Overlay.CurrentStackLocation--; +} + +PIO_STACK_LOCATION IoGetNextIrpStackLocation(PIRP Irp) +/* + * FUNCTION: Gives a higher level driver access to the next lower driver's + * I/O stack location + * ARGUMENTS: + * Irp = points to the irp + * RETURNS: A pointer to the stack location + */ +{ + DPRINT("IoGetNextIrpStackLocation: Irp %08lx CurLoc %d StkCnt %d\n", + Irp, + Irp->CurrentLocation, + Irp->StackCount); + + assert(Irp!=NULL); + DPRINT("Irp %x Irp->StackPtr %x\n",Irp,Irp->CurrentLocation); + return(&Irp->Stack[Irp->CurrentLocation-1]); +} + +NTSTATUS IoCallDriver(PDEVICE_OBJECT DevObject, PIRP irp) +/* + * FUNCTION: Sends an IRP to the next lower driver + */ +{ + NTSTATUS Status; + PDRIVER_OBJECT drv = DevObject->DriverObject; + IO_STACK_LOCATION* param = IoGetNextIrpStackLocation(irp); + + DPRINT("Deviceobject %x\n",DevObject); + DPRINT("Irp %x\n",irp); + + irp->Tail.Overlay.CurrentStackLocation--; + irp->CurrentLocation--; + + DPRINT("Io stack address %x\n",param); + DPRINT("Function %d Routine %x\n",param->MajorFunction, + drv->MajorFunction[param->MajorFunction]); + + Status = drv->MajorFunction[param->MajorFunction](DevObject,irp); + return Status; +} + +PIRP IoAllocateIrp(CCHAR StackSize, BOOLEAN ChargeQuota) +/* + * FUNCTION: Allocates an IRP + * ARGUMENTS: + * StackSize = the size of the stack required for the irp + * ChargeQuota = Charge allocation to current threads quota + * RETURNS: Irp allocated + */ +{ + PIRP Irp; + + DPRINT("IoAllocateIrp(StackSize %d ChargeQuota %d)\n", + StackSize, + ChargeQuota); + if (ChargeQuota) + { + Irp = ExAllocatePoolWithQuota(NonPagedPool,IoSizeOfIrp(StackSize)); + } + else + { + Irp = ExAllocatePool(NonPagedPool,IoSizeOfIrp(StackSize)); + } + + if (Irp==NULL) + { + return(NULL); + } + + IoInitializeIrp(Irp, IoSizeOfIrp(StackSize), StackSize); + + DPRINT("Irp %x Irp->StackPtr %d\n", Irp, Irp->CurrentLocation); + + return Irp; +} + +VOID IoSetCompletionRoutine(PIRP Irp, + PIO_COMPLETION_ROUTINE CompletionRoutine, + PVOID Context, + BOOLEAN InvokeOnSuccess, + BOOLEAN InvokeOnError, + BOOLEAN InvokeOnCancel) +{ + IO_STACK_LOCATION* param = IoGetNextIrpStackLocation(Irp); + + param->CompletionRoutine=CompletionRoutine; + param->CompletionContext=Context; + if (InvokeOnSuccess) + { + param->Control = param->Control | SL_INVOKE_ON_SUCCESS; + } + if (InvokeOnError) + { + param->Control = param->Control | SL_INVOKE_ON_ERROR; + } + if (InvokeOnCancel) + { + param->Control = param->Control | SL_INVOKE_ON_CANCEL; + } +} + +VOID IopCompleteRequest(struct _KAPC* Apc, + PKNORMAL_ROUTINE* NormalRoutine, + PVOID* NormalContext, + PVOID* SystemArgument1, + PVOID* SystemArgument2) +{ + IoSecondStageCompletion((PIRP)(*NormalContext), + IO_NO_INCREMENT); +} + +VOID IoCompleteRequest(PIRP Irp, CCHAR PriorityBoost) +/* + * FUNCTION: Indicates the caller has finished all processing for a given + * I/O request and is returning the given IRP to the I/O manager + * ARGUMENTS: + * Irp = Irp to be cancelled + * PriorityBoost = Increment by which to boost the priority of the + * thread making the request + */ +{ + unsigned int i; + NTSTATUS Status; + + DPRINT("IoCompleteRequest(Irp %x, PriorityBoost %d)\n", + Irp,PriorityBoost); + + for (i=0;iStackCount;i++) + { + DPRINT("&Irp->Stack[%d].CompletionRoutine %08lx\n", + i, + Irp->Stack[i].CompletionRoutine); + if (Irp->Stack[i].CompletionRoutine != NULL) + { + Status = Irp->Stack[i].CompletionRoutine( + Irp->Stack[i].DeviceObject, + Irp, + Irp->Stack[i].CompletionContext); + if (Status == STATUS_MORE_PROCESSING_REQUIRED) + { + return; + } + } + DPRINT("Irp->Stack[%d].Control %08lx\n", i, Irp->Stack[i].Control); + if (Irp->Stack[i].Control & SL_PENDING_RETURNED) + { + DPRINT("Setting PendingReturned flag\n"); + Irp->PendingReturned = TRUE; + } + } + + if (Irp->PendingReturned) + { + KeInitializeApc(&Irp->Tail.Apc, + &Irp->Tail.Overlay.Thread->Tcb, + 0, + IopCompleteRequest, + NULL, + NULL, + 0, + Irp); + KeInsertQueueApc(&Irp->Tail.Apc,NULL,NULL,0); + } + else + { + IoSecondStageCompletion(Irp,PriorityBoost); + } +} + diff --git a/reactos/ntoskrnl/ke/main.c b/reactos/ntoskrnl/ke/main.c index 49722c66ca3..606d6002ee7 100644 --- a/reactos/ntoskrnl/ke/main.c +++ b/reactos/ntoskrnl/ke/main.c @@ -1,178 +1,356 @@ -/* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS kernel - * FILE: ntoskrnl/ke/main.c - * PURPOSE: Initalizes the kernel - * PROGRAMMER: David Welch (welch@mcmail.com) - * UPDATE HISTORY: - * 28/05/98: Created - */ - -/* INCLUDES *****************************************************************/ - -#include - -#include -#include -#include -#include -#include -#include - -#include -#include - -#define NDEBUG -#include - -/* FUNCTIONS ****************************************************************/ - -void set_breakpoint(unsigned int i, unsigned int addr, unsigned int type, - unsigned int len) -/* - * FUNCTION: Sets a hardware breakpoint - * ARGUMENTS: - * i = breakpoint to set (0 to 3) - * addr = linear address to break on - * type = Type of access to break on - * len = length of the variable to watch - * NOTES: - * The variable to watch must be aligned to its length (i.e. a dword - * breakpoint must be aligned to a dword boundary) - * - * A fatal exception will be generated on the access to the variable. - * It is (at the moment) only really useful for catching undefined - * pointers if you know the variable effected but not the buggy - * routine. - * - * FIXME: Extend to call out to kernel debugger on breakpoint - * Add support for I/O breakpoints - * REFERENCES: See the i386 programmer manual for more details - */ -{ - unsigned int mask; - - if (i>3) - { - printk("Invalid breakpoint index at %s:%d\n",__FILE__,__LINE__); - return; - } - - /* - * Load the linear address - */ - switch (i) - { - case 0: - __asm("movl %0,%%db0\n\t" - : /* no outputs */ - : "d" (addr)); - break; - - case 1: - __asm__("movl %0,%%db1\n\t" - : /* no outputs */ - : "d" (addr)); - break; - - case 2: - __asm__("movl %0,%%db2\n\t" - : /* no outputs */ - : "d" (addr)); - break; - - case 3: - __asm__("movl %0,%%db3\n\t" - : /* no outputs */ - : "d" (addr)); - break; - } - - /* - * Setup mask for dr7 - */ - mask = (len<<(16 + 2 + i*4)) + (type<<(16 + i*4)) + (1<<(i*2)); - __asm__("movl %%db7,%%eax\n\t" - "orl %0,%%eax\n\t" - "movl %%eax,%%db7\n\t" - : /* no outputs */ - : "d" (mask) - : "ax"); -} - -extern int edata; -extern int end; - -asmlinkage void _main(boot_param* _bp) -/* - * FUNCTION: Called by the boot loader to start the kernel - * ARGUMENTS: - * _bp = Pointer to boot parameters initialized by the boot loader - * NOTE: The boot parameters are stored in low memory which will become - * invalid after the memory managment is initialized so we make a local copy. - */ -{ - unsigned int i; - unsigned int start; - unsigned int start1; - boot_param bp; - - memset((void *)&edata,0,((int)&end)-((int)&edata)); - - /* - * Copy the parameters to a local buffer because lowmem will go away - */ - memcpy(&bp,_bp,sizeof(boot_param)); - - /* - * Initalize the console (before printing anything) - */ - HalInitConsole(&bp); - - DbgPrint("Starting ReactOS "KERNEL_VERSION"\n"); - - start = KERNEL_BASE + PAGE_ROUND_UP(bp.module_length[0]); - if (start < ((int)&end)) - { - DbgPrint("start %x end %x\n",start,(int)&end); - DbgPrint("Kernel booted incorrectly, aborting\n"); - DbgPrint("Reduce the amount of uninitialized data\n"); - for(;;); - } - start1 = start+PAGE_ROUND_UP(bp.module_length[1]); - - - /* - * Initalize various critical subsystems - */ - HalInit(&bp); - MmInitalize(&bp); - KeInit(); - ObInit(); - PsInit(); - IoInit(); - - /* - * Initalize services loaded at boot time - */ - DPRINT("%d files loaded\n",bp.nr_files); - - start = KERNEL_BASE + PAGE_ROUND_UP(bp.module_length[0]); - start1 = start+PAGE_ROUND_UP(bp.module_length[1]); - for (i=1;i + + + +#include + +#include + +#include + +#include + +#include + +#include + + + +#include + +#include + + + +#define NDEBUG + +#include + + + +/* FUNCTIONS ****************************************************************/ + + + +void set_breakpoint(unsigned int i, unsigned int addr, unsigned int type, + + unsigned int len) + +/* + + * FUNCTION: Sets a hardware breakpoint + + * ARGUMENTS: + + * i = breakpoint to set (0 to 3) + + * addr = linear address to break on + + * type = Type of access to break on + + * len = length of the variable to watch + + * NOTES: + + * The variable to watch must be aligned to its length (i.e. a dword + + * breakpoint must be aligned to a dword boundary) + + * + + * A fatal exception will be generated on the access to the variable. + + * It is (at the moment) only really useful for catching undefined + + * pointers if you know the variable effected but not the buggy + + * routine. + + * + + * FIXME: Extend to call out to kernel debugger on breakpoint + + * Add support for I/O breakpoints + + * REFERENCES: See the i386 programmer manual for more details + + */ + +{ + + unsigned int mask; + + + + if (i>3) + + { + + printk("Invalid breakpoint index at %s:%d\n",__FILE__,__LINE__); + + return; + + } + + + + /* + + * Load the linear address + + */ + + switch (i) + + { + + case 0: + + __asm("movl %0,%%db0\n\t" + + : /* no outputs */ + + : "d" (addr)); + + break; + + + + case 1: + + __asm__("movl %0,%%db1\n\t" + + : /* no outputs */ + + : "d" (addr)); + + break; + + + + case 2: + + __asm__("movl %0,%%db2\n\t" + + : /* no outputs */ + + : "d" (addr)); + + break; + + + + case 3: + + __asm__("movl %0,%%db3\n\t" + + : /* no outputs */ + + : "d" (addr)); + + break; + + } + + + + /* + + * Setup mask for dr7 + + */ + + mask = (len<<(16 + 2 + i*4)) + (type<<(16 + i*4)) + (1<<(i*2)); + + __asm__("movl %%db7,%%eax\n\t" + + "orl %0,%%eax\n\t" + + "movl %%eax,%%db7\n\t" + + : /* no outputs */ + + : "d" (mask) + + : "ax"); + +} + + + +extern int edata; + +extern int end; + + + +asmlinkage void _main(boot_param* _bp) + +/* + + * FUNCTION: Called by the boot loader to start the kernel + + * ARGUMENTS: + + * _bp = Pointer to boot parameters initialized by the boot loader + + * NOTE: The boot parameters are stored in low memory which will become + + * invalid after the memory managment is initialized so we make a local copy. + + */ + +{ + + unsigned int i; + + unsigned int start; + + unsigned int start1; + + boot_param bp; + + + + memset((void *)&edata,0,((int)&end)-((int)&edata)); + + + + /* + + * Copy the parameters to a local buffer because lowmem will go away + + */ + + memcpy(&bp,_bp,sizeof(boot_param)); + + + + /* + + * Initalize the console (before printing anything) + + */ + + HalInitConsole(&bp); + + + + DbgPrint("Starting ReactOS "KERNEL_VERSION"\n"); + + + + start = KERNEL_BASE + PAGE_ROUND_UP(bp.module_length[0]); + + if (start < ((int)&end)) + + { + + DbgPrint("start %x end %x\n",start,(int)&end); + + DbgPrint("Kernel booted incorrectly, aborting\n"); + + DbgPrint("Reduce the amount of uninitialized data\n"); + + for(;;); + + } + + start1 = start+PAGE_ROUND_UP(bp.module_length[1]); + + + + + + /* + + * Initalize various critical subsystems + + */ + + HalInit(&bp); + + MmInitialize(&bp); + + KeInit(); + + ObInit(); + + PsInit(); + + IoInit(); + + + + /* + + * Initalize services loaded at boot time + + */ + + DPRINT("%d files loaded\n",bp.nr_files); + + + + start = KERNEL_BASE + PAGE_ROUND_UP(bp.module_length[0]); + + start1 = start+PAGE_ROUND_UP(bp.module_length[1]); + + for (i=1;ibase + entry); - return(InitalizeLoadedDriver(func)); + return(InitializeLoadedDriver(func)); } diff --git a/reactos/ntoskrnl/ldr/loader.c b/reactos/ntoskrnl/ldr/loader.c index 24c0753b00a..0ebeabec484 100644 --- a/reactos/ntoskrnl/ldr/loader.c +++ b/reactos/ntoskrnl/ldr/loader.c @@ -40,6 +40,7 @@ NTSTATUS LdrProcessDriver(PVOID ModuleLoadBase); /* PE Driver load support */ static NTSTATUS LdrPEProcessDriver(PVOID ModuleLoadBase); +static unsigned int LdrGetKernelSymbolAddr(char *Name); /* COFF Driver load support */ static NTSTATUS LdrCOFFProcessDriver(PVOID ModuleLoadBase); @@ -48,7 +49,6 @@ static BOOLEAN LdrCOFFDoAddr32Reloc(module *Module, SCNHDR *Section, RELOC *Relo static BOOLEAN LdrCOFFDoReloc32Reloc(module *Module, SCNHDR *Section, RELOC *Relocation); static void LdrCOFFGetSymbolName(module *Module, unsigned int Idx, char *Name); static unsigned int LdrCOFFGetSymbolValue(module *Module, unsigned int Idx); -static unsigned int LdrCOFFGetKernelSymbolAddr(char *Name); static unsigned int LdrCOFFGetSymbolValueByName(module *Module, char *SymbolName, unsigned int Idx); /* Image loader forward delcarations */ @@ -188,7 +188,8 @@ LdrPEProcessDriver(PVOID ModuleLoadBase) { unsigned int DriverSize, Idx; long int RelocDelta, NumRelocs; - PVOID DriverBase, RelocBase; + DWORD CurrentSize; + PVOID DriverBase, CurrentBase, EntryPoint; PULONG PEMagic; PIMAGE_DOS_HEADER PEDosHeader; PIMAGE_FILE_HEADER PEFileHeader; @@ -196,7 +197,15 @@ LdrPEProcessDriver(PVOID ModuleLoadBase) PIMAGE_SECTION_HEADER PESectionHeaders; PRELOCATION_DIRECTORY RelocDir; PRELOCATION_ENTRY RelocEntry; + PMODULE Library; + PVOID *ImportAddressList; + PULONG FunctionNameList; + PCHAR pName, SymbolNameBuf; + PWORD pHint; + /* FIXME: this could be used to load kernel DLLs also, however */ + /* the image headers should be preserved in such a case */ + DPRINT("Processing PE Driver at module base:%08lx\n", ModuleLoadBase); /* Get header pointers */ @@ -249,10 +258,10 @@ LdrPEProcessDriver(PVOID ModuleLoadBase) /* Determine the size of the module */ DPRINT("Sections: (section align:%08lx)\n", PEOptionalHeader->SectionAlignment); - DriverSize = 0; + DriverSize = PESectionHeaders[0].PointerToRawData; for (Idx = 0; Idx < PEFileHeader->NumberOfSections; Idx++) { - DPRINT("Name: %-8.8s VA:%08lx RawSize:%6d Offset:%08lx CHAR:%08lx OfsAdr: %08lx\n", + DPRINT("Name:%-8.8s VA:%08lx RawSz:%6d Offs:%08lx CHAR:%08lx OfsA: %08lx\n", PESectionHeaders[Idx].Name, PESectionHeaders[Idx].VirtualAddress, PESectionHeaders[Idx].SizeOfRawData, @@ -266,7 +275,6 @@ LdrPEProcessDriver(PVOID ModuleLoadBase) DriverSize, DriverSize); -#if 0 /* Allocate a virtual section for the module */ DriverBase = MmAllocateSection(DriverSize); if (DriverBase == 0) @@ -276,10 +284,12 @@ LdrPEProcessDriver(PVOID ModuleLoadBase) } CHECKPOINT; - CurrentBase = ModuleLoadBase; + /* Copy image sections into virtual section */ + memcpy(DriverBase, ModuleLoadBase, PESectionHeaders[0].PointerToRawData); + CurrentBase = (PVOID) ((DWORD)DriverBase + PESectionHeaders[0].PointerToRawData); for (Idx = 0; Idx < PEFileHeader->NumberOfSections; Idx++) { - /* Copy current section into current offset of virtual section */ + /* Copy current section into current offset of virtual section */ if (PESectionHeaders[Idx].Characteristics & (IMAGE_SECTION_CHAR_CODE | IMAGE_SECTION_CHAR_DATA)) { @@ -293,19 +303,19 @@ LdrPEProcessDriver(PVOID ModuleLoadBase) } CurrentSize += ROUND_UP(PESectionHeaders[Idx].SizeOfRawData, PEOptionalHeader->SectionAlignment); + CurrentBase = (PVOID)((DWORD)CurrentBase + + ROUND_UP(PESectionHeaders[Idx].SizeOfRawData, + PEOptionalHeader->SectionAlignment)); } -#else - DriverBase = ModuleLoadBase; -#endif - - /* FIXME: Perform relocation fixups */ + /* Perform relocation fixups */ RelocDelta = (DWORD) DriverBase - PEOptionalHeader->ImageBase; RelocDir = (PRELOCATION_DIRECTORY) ((DWORD)ModuleLoadBase + PEOptionalHeader->DataDirectory[ IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress); - DPRINT("Relocs: ModuleLoadBase: %08lx RelocDelta %08lx\n", - ModuleLoadBase, + DPRINT("DrvrBase:%08lx ImgBase:%08lx RelocDelta:%08lx\n", + DriverBase, + PEOptionalHeader->ImageBase, RelocDelta); while (RelocDir->SizeOfBlock != 0) { @@ -328,21 +338,108 @@ LdrPEProcessDriver(PVOID ModuleLoadBase) (RelocEntry[Idx].TypeOffset & 0x0fff)), (*(PDWORD)((DWORD) DriverBase + RelocDir->VirtualAddress + (RelocEntry[Idx].TypeOffset & 0x0fff))) + RelocDelta); + if (((RelocEntry[Idx].TypeOffset >> 12) & 0xf) == 3) + { + (*(PDWORD)((DWORD) DriverBase + RelocDir->VirtualAddress + + (RelocEntry[Idx].TypeOffset & 0x0fff))) += RelocDelta; + } + else if (((RelocEntry[Idx].TypeOffset >> 12) & 0xf) != 0) + { + DPRINT("Unknown relocation type %x\n", + (RelocEntry[Idx].TypeOffset >> 12) & 0xf); + return STATUS_UNSUCCESSFUL; + } } RelocDir = (PRELOCATION_DIRECTORY)((DWORD)RelocDir + RelocDir->SizeOfBlock); -getchar(); } -#if 0 + /* Perform import fixups */ + if (PEOptionalHeader->DataDirectory[ + IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress) + { + PIMAGE_IMPORT_MODULE_DIRECTORY ImportModuleDirectory; - /* FIXME: perform import fixups */ - /* FIXME: compute address of entry point */ + SymbolNameBuf = ExAllocatePool(NonPagedPool, 512); -#endif + /* Process each import module */ + ImportModuleDirectory = (PIMAGE_IMPORT_MODULE_DIRECTORY) + ((DWORD)ModuleLoadBase + PEOptionalHeader-> + DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress); + while (ImportModuleDirectory->dwRVAModuleName) + { + /* FIXME: handle kernel mode DLLs */ - /* return InitializeLoadedDriver(EntryPoint); */ - return STATUS_NOT_IMPLEMENTED; + /* Check to make sure that import lib is kernel */ + Library = NULL; + pName = (PCHAR) ModuleLoadBase + + ImportModuleDirectory->dwRVAModuleName; + DPRINT("Import module: %s\n", pName); + if (strcmp(pName, "ntoskrnl.exe") && + strcmp(pName, "HAL.dll")) + { + DPRINT("Kernel mode DLLs are currently unsupported\n"); + } + + /* Get the import address list */ + ImportAddressList = (PVOID *) ((DWORD)ModuleLoadBase + + ImportModuleDirectory->dwRVAFunctionAddressList); + + /* Get the list of functions to import */ + if (ImportModuleDirectory->dwRVAFunctionNameList != 0) + { + FunctionNameList = (PULONG) ((DWORD)ModuleLoadBase + + ImportModuleDirectory->dwRVAFunctionNameList); + } + else + { + FunctionNameList = (PULONG) ((DWORD)ModuleLoadBase + + ImportModuleDirectory->dwRVAFunctionAddressList); + } + + /* Walk through function list and fixup addresses */ + while(*FunctionNameList != 0L) + { + if ((*FunctionNameList) & 0x80000000) // hint + { + DPRINT(" Hint: %08lx\n", *FunctionNameList); + if (Library == NULL) + { + DPRINT("Hints for kernel symbols are not handled.\n"); + *ImportAddressList = 0; + } + } + else // hint-name + { + pName = (PCHAR)((DWORD)ModuleLoadBase + + *FunctionNameList + 2); + pHint = (PWORD)((DWORD)ModuleLoadBase + *FunctionNameList); + DPRINT(" Hint:%04x Name:%s\n", pHint, pName); + + /* Get address for symbol */ + if (Library == NULL) + { + *SymbolNameBuf = '_'; + strcpy(SymbolNameBuf + 1, pName); + *ImportAddressList = (PVOID) LdrGetKernelSymbolAddr(SymbolNameBuf); if (*ImportAddressList == 0L) + { + DPRINT("Unresolved kernel symbol: %s\n", pName); + } + } + } + ImportAddressList++; + FunctionNameList++; + } + ImportModuleDirectory++; + } + + ExFreePool(SymbolNameBuf); + } + + /* Compute address of entry point */ + EntryPoint = (PVOID) ((DWORD)DriverBase + PEOptionalHeader->AddressOfEntryPoint); + + return InitializeLoadedDriver(EntryPoint); } NTSTATUS @@ -491,7 +588,7 @@ LdrCOFFProcessDriver(PVOID ModuleLoadBase) /* Cleanup */ ExFreePool(Module); - return InitalizeLoadedDriver(EntryRoutine); + return InitializeLoadedDriver(EntryRoutine); } /* LdrCOFFDoRelocations @@ -594,7 +691,7 @@ LdrCOFFDoReloc32Reloc(module *Module, SCNHDR *Section, RELOC *Relocation) memset(Name, 0, 255); LdrCOFFGetSymbolName(Module, Relocation->r_symndx, Name); - Value = (unsigned int) LdrCOFFGetKernelSymbolAddr(Name); + Value = (unsigned int) LdrGetKernelSymbolAddr(Name); if (Value == 0L) { Value = LdrCOFFGetSymbolValueByName(Module, Name, Relocation->r_symndx); @@ -691,7 +788,7 @@ LdrCOFFGetSymbolValue(module *Module, unsigned int Idx) */ static unsigned int -LdrCOFFGetKernelSymbolAddr(char *Name) +LdrGetKernelSymbolAddr(char *Name) { int i = 0; diff --git a/reactos/ntoskrnl/mm/mm.c b/reactos/ntoskrnl/mm/mm.c index 51985524987..a1ea644fb61 100644 --- a/reactos/ntoskrnl/mm/mm.c +++ b/reactos/ntoskrnl/mm/mm.c @@ -48,7 +48,7 @@ MM_SYSTEM_SIZE MmQuerySystemSize() UNIMPLEMENTED; } -void MmInitalize(boot_param* bp) +void MmInitialize(boot_param* bp) /* * FUNCTION: Initalize memory managment */ diff --git a/reactos/ntoskrnl/mm/npool.c b/reactos/ntoskrnl/mm/npool.c index ae44671b093..f12f425c202 100644 --- a/reactos/ntoskrnl/mm/npool.c +++ b/reactos/ntoskrnl/mm/npool.c @@ -1,676 +1,677 @@ -/* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS kernel - * FILE: ntoskrnl/mm/pool.c - * PURPOSE: Implements the kernel memory pool - * PROGRAMMER: David Welch (welch@mcmail.com) - * UPDATE HISTORY: - * 27/05/98: Created - * 10/06/98: Bug fixes by Iwan Fatahi (i_fatahi@hotmail.com) - * in take_block (if current bigger than required) - * in remove_from_used_list - * in ExFreePool - * 23/08/98: Fixes from Robert Bergkvist (fragdance@hotmail.com) - */ - -/* INCLUDES ****************************************************************/ - -#include -#include -#include -#include -#include -#include - -#define NDEBUG -#include - -#include - - -#if 0 -#define VALIDATE_POOL validate_kernel_pool() -#else -#define VALIDATE_POOL -#endif - -/* TYPES *******************************************************************/ - -#define BLOCK_HDR_MAGIC (0xdeadbeef) - -/* - * fields present at the start of a block (this is for internal use only) - */ -typedef struct _block_hdr -{ - ULONG magic; - ULONG size; - struct _block_hdr* previous; - struct _block_hdr* next; - ULONG tag; -} block_hdr; - -/* GLOBALS *****************************************************************/ - -/* - * Memory managment initalized symbol for the base of the pool - */ -static unsigned int kernel_pool_base = 0; - -/* - * Pointer to the first block in the free list - */ -static block_hdr* free_list_head = NULL; -static block_hdr* used_list_head = NULL; -static ULONG nr_free_blocks; -ULONG EiNrUsedBlocks = 0; - -#define ALLOC_MAP_SIZE (NONPAGED_POOL_SIZE / PAGESIZE) - -/* - * One bit for each page in the kmalloc region - * If set then the page is used by a kmalloc block - */ -static unsigned int alloc_map[ALLOC_MAP_SIZE/32]={0,}; - -static unsigned int pool_free_mem = 0; - -unsigned int EiFreeNonPagedPool = 0; -unsigned int EiUsedNonPagedPool = 0; - -/* FUNCTIONS ***************************************************************/ - -VOID ExInitNonPagedPool(ULONG BaseAddress) -{ - kernel_pool_base=BaseAddress; -} - -static void validate_free_list(void) -/* - * FUNCTION: Validate the integrity of the list of free blocks - */ -{ - block_hdr* current=free_list_head; - unsigned int blocks_seen=0; - - while (current!=NULL) - { - unsigned int base_addr = (int)current; - - if (current->magic != BLOCK_HDR_MAGIC) - { - DbgPrint("Bad block magic (probable pool corruption) at %x\n", - current); - KeBugCheck(KBUG_POOL_FREE_LIST_CORRUPT); - } - - if (base_addr < (kernel_pool_base) || - (base_addr+current->size) > - (kernel_pool_base)+NONPAGED_POOL_SIZE) - { - printk("Block %x found outside pool area\n",current); - printk("Size %d\n",current->size); - printk("Limits are %x %x\n",kernel_pool_base, - kernel_pool_base+NONPAGED_POOL_SIZE); - KeBugCheck(KBUG_POOL_FREE_LIST_CORRUPT); - } - blocks_seen++; - if (blocks_seen > nr_free_blocks) - { - printk("Too many blocks on list\n"); - KeBugCheck(KBUG_POOL_FREE_LIST_CORRUPT); - } -// verify_for_write(base_addr,current->size); - if (current->next!=NULL&¤t->next->previous!=current) - { - printk("%s:%d:Break in list (current %x next %x " - "current->next->previous %x)\n", - __FILE__,__LINE__,current,current->next, - current->next->previous); - KeBugCheck(KBUG_POOL_FREE_LIST_CORRUPT); - } - current=current->next; - } -} - -static void validate_used_list(void) -/* - * FUNCTION: Validate the integrity of the list of used blocks - */ -{ - block_hdr* current=used_list_head; - unsigned int blocks_seen=0; - - while (current!=NULL) - { - unsigned int base_addr = (int)current; - - if (current->magic != BLOCK_HDR_MAGIC) - { - DbgPrint("Bad block magic (probable pool corruption) at %x\n", - current); - KeBugCheck(KBUG_POOL_FREE_LIST_CORRUPT); - } - if (base_addr < (kernel_pool_base) || - (base_addr+current->size) > - (kernel_pool_base)+NONPAGED_POOL_SIZE) - { - printk("Block %x found outside pool area\n",current); - for(;;); - } - blocks_seen++; - if (blocks_seen > EiNrUsedBlocks) - { - printk("Too many blocks on list\n"); - for(;;); - } - // verify_for_write(base_addr,current->size); - if (current->next!=NULL&¤t->next->previous!=current) - { - printk("Break in list (current %x next %x)\n", - current,current->next); - for(;;); - } - current=current->next; - } -} - -static void check_duplicates(block_hdr* blk) -/* - * FUNCTION: Check a block has no duplicates - * ARGUMENTS: - * blk = block to check - * NOTE: Bug checks if duplicates are found - */ -{ - unsigned int base = (int)blk; - unsigned int last = ((int)blk) + +sizeof(block_hdr) + blk->size; - - block_hdr* current=free_list_head; - while (current!=NULL) - { - if (current->magic != BLOCK_HDR_MAGIC) - { - DbgPrint("Bad block magic (probable pool corruption) at %x\n", - current); - KeBugCheck(KBUG_POOL_FREE_LIST_CORRUPT); - } - - if ( (int)current > base && (int)current < last ) - { - printk("intersecting blocks on list\n"); - for(;;); - } - if ( (int)current < base && - ((int)current + current->size + sizeof(block_hdr)) - > base ) - { - printk("intersecting blocks on list\n"); - for(;;); - } - current=current->next; - } - current=used_list_head; - while (current!=NULL) - { - if ( (int)current > base && (int)current < last ) - { - printk("intersecting blocks on list\n"); - for(;;); - } - if ( (int)current < base && - ((int)current + current->size + sizeof(block_hdr)) - > base ) - { - printk("intersecting blocks on list\n"); - for(;;); - } - current=current->next; - } - -} - -static void validate_kernel_pool(void) -/* - * FUNCTION: Checks the integrity of the kernel memory heap - */ -{ - block_hdr* current=NULL; - - validate_free_list(); - validate_used_list(); - - current=free_list_head; - while (current!=NULL) - { - check_duplicates(current); - current=current->next; - } - current=used_list_head; - while (current!=NULL) - { - check_duplicates(current); - current=current->next; - } -} - -static void add_to_free_list(block_hdr* blk) -/* - * FUNCTION: add the block to the free list (internal) - */ -{ - blk->next=free_list_head; - blk->previous=NULL; - if (free_list_head!=NULL) - { - free_list_head->previous=blk; - } - free_list_head=blk; - nr_free_blocks++; -} - -static void add_to_used_list(block_hdr* blk) -/* - * FUNCTION: add the block to the used list (internal) - */ -{ - blk->next=used_list_head; - blk->previous=NULL; - if (used_list_head!=NULL) - { - used_list_head->previous=blk; - } - used_list_head=blk; - EiNrUsedBlocks++; -} - - -static void remove_from_free_list(block_hdr* current) -{ - if (current->next==NULL&¤t->previous==NULL) - { - free_list_head=NULL; - } - else - { - if (current->next==NULL) - { - current->previous->next=NULL; - } - else if (current->previous==NULL) - { - current->next->previous=NULL; - free_list_head=current->next; - } - else - { - current->next->previous=current->previous; - current->previous->next=current->next; - } - } - nr_free_blocks--; -} - - -static void remove_from_used_list(block_hdr* current) -{ - if (current->next==NULL&¤t->previous==NULL) - { - used_list_head=NULL; - } - else - { - if (current->previous==NULL) - { - current->next->previous=NULL; - used_list_head=current->next; - } - else - { - current->previous->next=current->next; - } - if (current->next!=NULL) - { - current->next->previous=current->previous; - } - else - { - current->previous->next=NULL; - } - } - EiNrUsedBlocks--; -} - - -inline static void* block_to_address(block_hdr* blk) -/* - * FUNCTION: Translate a block header address to the corresponding block - * address (internal) - */ -{ - return ( (void *) ((int)blk + sizeof(block_hdr)) ); -} - -inline static block_hdr* address_to_block(void* addr) -{ - return (block_hdr *) - ( ((int)addr) - sizeof(block_hdr) ); -} - -static unsigned int alloc_pool_region(unsigned int nr_pages) -/* - * FUNCTION: Allocates a region of pages within the nonpaged pool area - */ -{ - unsigned int start = 0; - unsigned int length = 0; - unsigned int i,j; - - OLD_DPRINT("alloc_pool_region(nr_pages = %d)\n",nr_pages); - - for (i=1; i(2*sizeof(block_hdr))) - { - used_blk = (struct _block_hdr *)start; - OLD_DPRINT("Creating block at %x\n",start); - used_blk->magic = BLOCK_HDR_MAGIC; - used_blk->size = size; - add_to_used_list(used_blk); - - free_blk = (block_hdr *)(start + sizeof(block_hdr) + size); - OLD_DPRINT("Creating block at %x\n",free_blk); - free_blk->magic = BLOCK_HDR_MAGIC; - free_blk->size = (nr_pages * PAGESIZE) -((sizeof(block_hdr)*2) + size); - add_to_free_list(free_blk); - - EiFreeNonPagedPool = EiFreeNonPagedPool + free_blk->size; - EiUsedNonPagedPool = EiUsedNonPagedPool + used_blk->size; - } - else - { - used_blk = (struct _block_hdr *)start; - used_blk->magic = BLOCK_HDR_MAGIC; - used_blk->size = nr_pages * PAGESIZE; - add_to_used_list(used_blk); - - EiUsedNonPagedPool = EiUsedNonPagedPool + used_blk->size; - } - - VALIDATE_POOL; - return(used_blk); -} - -static void* take_block(block_hdr* current, unsigned int size) -/* - * FUNCTION: Allocate a used block of least 'size' from the specified - * free block - * RETURNS: The address of the created memory block - */ -{ - /* - * If the block is much bigger than required then split it and - * return a pointer to the allocated section. If the difference - * between the sizes is marginal it makes no sense to have the - * extra overhead - */ - if (current->size > (1 + size + sizeof(block_hdr))) - { - block_hdr* free_blk; - - EiFreeNonPagedPool = EiFreeNonPagedPool - current->size; - - /* - * Replace the bigger block with a smaller block in the - * same position in the list - */ - free_blk = (block_hdr *)(((int)current) - + sizeof(block_hdr) + size); - free_blk->magic = BLOCK_HDR_MAGIC; - free_blk->next = current->next; - free_blk->previous = current->previous; - if (current->next) - { - current->next->previous = free_blk; - } - if (current->previous) - { - current->previous->next = free_blk; - } - free_blk->size = current->size - (sizeof(block_hdr) + size); - if (current==free_list_head) - { - free_list_head=free_blk; - } - - current->size=size; - add_to_used_list(current); - - EiUsedNonPagedPool = EiUsedNonPagedPool + current->size; - EiFreeNonPagedPool = EiFreeNonPagedPool + free_blk->size; - - VALIDATE_POOL; - return(block_to_address(current)); - } - - /* - * Otherwise allocate the whole block - */ - remove_from_free_list(current); - add_to_used_list(current); - - EiFreeNonPagedPool = EiFreeNonPagedPool - current->size; - EiUsedNonPagedPool = EiUsedNonPagedPool + current->size; - - VALIDATE_POOL; - return(block_to_address(current)); -} - -asmlinkage VOID ExFreePool(PVOID block) -/* - * FUNCTION: Releases previously allocated memory - * ARGUMENTS: - * block = block to free - */ -{ - block_hdr* blk=address_to_block(block); - OLD_DPRINT("(%s:%d) freeing block %x\n",__FILE__,__LINE__,blk); - -// DbgPrint("ExFreePool(block %x), size %d, caller %x\n",block,blk->size, -// ((PULONG)&block)[-1]); - - VALIDATE_POOL; - - if (blk->magic != BLOCK_HDR_MAGIC) - { - DbgPrint("ExFreePool of non-allocated address %x\n",block); - KeBugCheck(0); - return; - } - - /* - * Please don't change the order - */ - remove_from_used_list(blk); - add_to_free_list(blk); - - EiUsedNonPagedPool = EiUsedNonPagedPool - blk->size; - EiFreeNonPagedPool = EiFreeNonPagedPool + blk->size; - - VALIDATE_POOL; -} - -static void defrag_free_list(void) -/* - * FUNCTION: defrag the list of free blocks - */ -{ - block_hdr* current=free_list_head,*current2; - ULONG addr1,addr2,max=0; - - DPRINT("Begin defrag free,tot free=%d,tot used=%d\n" - ,EiFreeNonPagedPool - ,EiUsedNonPagedPool); - while (current) - { - addr1=(ULONG)current; - current2=current->next; - while(current2) - { - addr2=(ULONG)current2; - if(addr2==addr1+current->size+sizeof(block_hdr)) - { - remove_from_free_list(current2); - current->size+=current2->size+sizeof(block_hdr); - if(current->size>max)max=current->size; - } - else if(addr1==addr2+current2->size+sizeof(block_hdr)) - { - remove_from_free_list(current); - current2->size+=current->size+sizeof(block_hdr); - if(current2->size>max)max=current2->size; - break; - } - current2=current2->next; - } - current=current->next; - } - DPRINT("Finish To defrag free blocks,max=%d\n",max); -} - -PVOID ExAllocateNonPagedPoolWithTag(ULONG type, ULONG size, ULONG Tag) -{ - block_hdr* current=NULL; - void* block; - -// DbgPrint("Blocks on free list %d\n",nr_free_blocks); -// DbgPrint("Blocks on used list %d\n",eiNrUsedblocks); -// OLD_DPRINT("ExAllocateNonPagedPool(type %d, size %d)\n",type,size); - VALIDATE_POOL; - - /* - * accomodate this useful idiom - */ - if (size==0) - { - return(NULL); - } - - /* - * Look for an already created block of sufficent size - */ - current=free_list_head; - - while (current!=NULL) - { - OLD_DPRINT("current %x size %x next %x\n",current,current->size, - current->next); - if (current->magic != BLOCK_HDR_MAGIC) - { - DbgPrint("Bad block magic (probable pool corruption) at %x\n", - current); - KeBugCheck(KBUG_POOL_FREE_LIST_CORRUPT); - } - if (current->size>=size) - { - OLD_DPRINT("found block %x of size %d\n",current,size); - block=take_block(current,size); - VALIDATE_POOL; - memset(block,0,size); - return(block); - } - current=current->next; - } - if(EiFreeNonPagedPool>size+32*PAGESIZE) - {//try defrag free list before growing kernel pool - defrag_free_list(); - /* - * reLook after defrag - */ - current=free_list_head; - - while (current!=NULL) - { - OLD_DPRINT("current %x size %x next %x\n",current,current->size, - current->next); - if (current->magic != BLOCK_HDR_MAGIC) - { - DbgPrint("Bad block magic (probable pool corruption)\n"); - KeBugCheck(KBUG_POOL_FREE_LIST_CORRUPT); - } - if (current->size>=size) - { - OLD_DPRINT("found block %x of size %d\n",current,size); - block=take_block(current,size); - memset(block,0,size); - return(block); - } - current=current->next; - } - } - /* - * Otherwise create a new block - */ - block=block_to_address(grow_kernel_pool(size)); - VALIDATE_POOL; - memset(block,0,size); - return(block); -} +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * FILE: ntoskrnl/mm/pool.c + * PURPOSE: Implements the kernel memory pool + * PROGRAMMER: David Welch (welch@mcmail.com) + * UPDATE HISTORY: + * 27/05/98: Created + * 10/06/98: Bug fixes by Iwan Fatahi (i_fatahi@hotmail.com) + * in take_block (if current bigger than required) + * in remove_from_used_list + * in ExFreePool + * 23/08/98: Fixes from Robert Bergkvist (fragdance@hotmail.com) + */ + +/* INCLUDES ****************************************************************/ + +#include +#include +#include +#include +#include +#include + +#define NDEBUG +#include + +#include + + +#if 0 +#define VALIDATE_POOL validate_kernel_pool() +#else +#define VALIDATE_POOL +#endif + +/* TYPES *******************************************************************/ + +#define BLOCK_HDR_MAGIC (0xdeadbeef) + +/* + * fields present at the start of a block (this is for internal use only) + */ +typedef struct _block_hdr +{ + ULONG magic; + ULONG size; + struct _block_hdr* previous; + struct _block_hdr* next; + ULONG tag; +} block_hdr; + +/* GLOBALS *****************************************************************/ + +/* + * Memory managment initalized symbol for the base of the pool + */ +static unsigned int kernel_pool_base = 0; + +/* + * Pointer to the first block in the free list + */ +static block_hdr* free_list_head = NULL; +static block_hdr* used_list_head = NULL; +static ULONG nr_free_blocks; +ULONG EiNrUsedBlocks = 0; + +#define ALLOC_MAP_SIZE (NONPAGED_POOL_SIZE / PAGESIZE) + +/* + * One bit for each page in the kmalloc region + * If set then the page is used by a kmalloc block + */ +static unsigned int alloc_map[ALLOC_MAP_SIZE/32]={0,}; + +static unsigned int pool_free_mem = 0; + +unsigned int EiFreeNonPagedPool = 0; +unsigned int EiUsedNonPagedPool = 0; + +/* FUNCTIONS ***************************************************************/ + +VOID ExInitNonPagedPool(ULONG BaseAddress) +{ + kernel_pool_base=BaseAddress; +} + +static void validate_free_list(void) +/* + * FUNCTION: Validate the integrity of the list of free blocks + */ +{ + block_hdr* current=free_list_head; + unsigned int blocks_seen=0; + + while (current!=NULL) + { + unsigned int base_addr = (int)current; + + if (current->magic != BLOCK_HDR_MAGIC) + { + DbgPrint("Bad block magic (probable pool corruption) at %x\n", + current); + KeBugCheck(KBUG_POOL_FREE_LIST_CORRUPT); + } + + if (base_addr < (kernel_pool_base) || + (base_addr+current->size) > + (kernel_pool_base)+NONPAGED_POOL_SIZE) + { + printk("Block %x found outside pool area\n",current); + printk("Size %d\n",current->size); + printk("Limits are %x %x\n",kernel_pool_base, + kernel_pool_base+NONPAGED_POOL_SIZE); + KeBugCheck(KBUG_POOL_FREE_LIST_CORRUPT); + } + blocks_seen++; + if (blocks_seen > nr_free_blocks) + { + printk("Too many blocks on list\n"); + KeBugCheck(KBUG_POOL_FREE_LIST_CORRUPT); + } +// verify_for_write(base_addr,current->size); + if (current->next!=NULL&¤t->next->previous!=current) + { + printk("%s:%d:Break in list (current %x next %x " + "current->next->previous %x)\n", + __FILE__,__LINE__,current,current->next, + current->next->previous); + KeBugCheck(KBUG_POOL_FREE_LIST_CORRUPT); + } + current=current->next; + } +} + +static void validate_used_list(void) +/* + * FUNCTION: Validate the integrity of the list of used blocks + */ +{ + block_hdr* current=used_list_head; + unsigned int blocks_seen=0; + + while (current!=NULL) + { + unsigned int base_addr = (int)current; + + if (current->magic != BLOCK_HDR_MAGIC) + { + DbgPrint("Bad block magic (probable pool corruption) at %x\n", + current); + KeBugCheck(KBUG_POOL_FREE_LIST_CORRUPT); + } + if (base_addr < (kernel_pool_base) || + (base_addr+current->size) > + (kernel_pool_base)+NONPAGED_POOL_SIZE) + { + printk("Block %x found outside pool area\n",current); + for(;;); + } + blocks_seen++; + if (blocks_seen > EiNrUsedBlocks) + { + printk("Too many blocks on list\n"); + for(;;); + } + // verify_for_write(base_addr,current->size); + if (current->next!=NULL&¤t->next->previous!=current) + { + printk("Break in list (current %x next %x)\n", + current,current->next); + for(;;); + } + current=current->next; + } +} + +static void check_duplicates(block_hdr* blk) +/* + * FUNCTION: Check a block has no duplicates + * ARGUMENTS: + * blk = block to check + * NOTE: Bug checks if duplicates are found + */ +{ + unsigned int base = (int)blk; + unsigned int last = ((int)blk) + +sizeof(block_hdr) + blk->size; + + block_hdr* current=free_list_head; + while (current!=NULL) + { + if (current->magic != BLOCK_HDR_MAGIC) + { + DbgPrint("Bad block magic (probable pool corruption) at %x\n", + current); + KeBugCheck(KBUG_POOL_FREE_LIST_CORRUPT); + } + + if ( (int)current > base && (int)current < last ) + { + printk("intersecting blocks on list\n"); + for(;;); + } + if ( (int)current < base && + ((int)current + current->size + sizeof(block_hdr)) + > base ) + { + printk("intersecting blocks on list\n"); + for(;;); + } + current=current->next; + } + current=used_list_head; + while (current!=NULL) + { + if ( (int)current > base && (int)current < last ) + { + printk("intersecting blocks on list\n"); + for(;;); + } + if ( (int)current < base && + ((int)current + current->size + sizeof(block_hdr)) + > base ) + { + printk("intersecting blocks on list\n"); + for(;;); + } + current=current->next; + } + +} + +static void validate_kernel_pool(void) +/* + * FUNCTION: Checks the integrity of the kernel memory heap + */ +{ + block_hdr* current=NULL; + + validate_free_list(); + validate_used_list(); + + current=free_list_head; + while (current!=NULL) + { + check_duplicates(current); + current=current->next; + } + current=used_list_head; + while (current!=NULL) + { + check_duplicates(current); + current=current->next; + } +} + +static void add_to_free_list(block_hdr* blk) +/* + * FUNCTION: add the block to the free list (internal) + */ +{ + blk->next=free_list_head; + blk->previous=NULL; + if (free_list_head!=NULL) + { + free_list_head->previous=blk; + } + free_list_head=blk; + nr_free_blocks++; +} + +static void add_to_used_list(block_hdr* blk) +/* + * FUNCTION: add the block to the used list (internal) + */ +{ + blk->next=used_list_head; + blk->previous=NULL; + if (used_list_head!=NULL) + { + used_list_head->previous=blk; + } + used_list_head=blk; + EiNrUsedBlocks++; +} + + +static void remove_from_free_list(block_hdr* current) +{ + if (current->next==NULL&¤t->previous==NULL) + { + free_list_head=NULL; + } + else + { + if (current->next==NULL) + { + current->previous->next=NULL; + } + else if (current->previous==NULL) + { + current->next->previous=NULL; + free_list_head=current->next; + } + else + { + current->next->previous=current->previous; + current->previous->next=current->next; + } + } + nr_free_blocks--; +} + + +static void remove_from_used_list(block_hdr* current) +{ + if (current->next==NULL&¤t->previous==NULL) + { + used_list_head=NULL; + } + else + { + if (current->previous==NULL) + { + current->next->previous=NULL; + used_list_head=current->next; + } + else + { + current->previous->next=current->next; + } + if (current->next!=NULL) + { + current->next->previous=current->previous; + } + else + { + current->previous->next=NULL; + } + } + EiNrUsedBlocks--; +} + + +inline static void* block_to_address(block_hdr* blk) +/* + * FUNCTION: Translate a block header address to the corresponding block + * address (internal) + */ +{ + return ( (void *) ((int)blk + sizeof(block_hdr)) ); +} + +inline static block_hdr* address_to_block(void* addr) +{ + return (block_hdr *) + ( ((int)addr) - sizeof(block_hdr) ); +} + +static unsigned int alloc_pool_region(unsigned int nr_pages) +/* + * FUNCTION: Allocates a region of pages within the nonpaged pool area + */ +{ + unsigned int start = 0; + unsigned int length = 0; + unsigned int i,j; + + OLD_DPRINT("alloc_pool_region(nr_pages = %d)\n",nr_pages); + + for (i=1; i(2*sizeof(block_hdr))) + { + used_blk = (struct _block_hdr *)start; + OLD_DPRINT("Creating block at %x\n",start); + used_blk->magic = BLOCK_HDR_MAGIC; + used_blk->size = size; + add_to_used_list(used_blk); + + free_blk = (block_hdr *)(start + sizeof(block_hdr) + size); + OLD_DPRINT("Creating block at %x\n",free_blk); + free_blk->magic = BLOCK_HDR_MAGIC; + free_blk->size = (nr_pages * PAGESIZE) -((sizeof(block_hdr)*2) + size); + add_to_free_list(free_blk); + + EiFreeNonPagedPool = EiFreeNonPagedPool + free_blk->size; + EiUsedNonPagedPool = EiUsedNonPagedPool + used_blk->size; + } + else + { + used_blk = (struct _block_hdr *)start; + used_blk->magic = BLOCK_HDR_MAGIC; + used_blk->size = nr_pages * PAGESIZE; + add_to_used_list(used_blk); + + EiUsedNonPagedPool = EiUsedNonPagedPool + used_blk->size; + } + + VALIDATE_POOL; + return(used_blk); +} + +static void* take_block(block_hdr* current, unsigned int size) +/* + * FUNCTION: Allocate a used block of least 'size' from the specified + * free block + * RETURNS: The address of the created memory block + */ +{ + /* + * If the block is much bigger than required then split it and + * return a pointer to the allocated section. If the difference + * between the sizes is marginal it makes no sense to have the + * extra overhead + */ + if (current->size > (1 + size + sizeof(block_hdr))) + { + block_hdr* free_blk; + + EiFreeNonPagedPool = EiFreeNonPagedPool - current->size; + + /* + * Replace the bigger block with a smaller block in the + * same position in the list + */ + free_blk = (block_hdr *)(((int)current) + + sizeof(block_hdr) + size); + free_blk->magic = BLOCK_HDR_MAGIC; + free_blk->next = current->next; + free_blk->previous = current->previous; + if (current->next) + { + current->next->previous = free_blk; + } + if (current->previous) + { + current->previous->next = free_blk; + } + free_blk->size = current->size - (sizeof(block_hdr) + size); + if (current==free_list_head) + { + free_list_head=free_blk; + } + + current->size=size; + add_to_used_list(current); + + EiUsedNonPagedPool = EiUsedNonPagedPool + current->size; + EiFreeNonPagedPool = EiFreeNonPagedPool + free_blk->size; + + VALIDATE_POOL; + return(block_to_address(current)); + } + + /* + * Otherwise allocate the whole block + */ + remove_from_free_list(current); + add_to_used_list(current); + + EiFreeNonPagedPool = EiFreeNonPagedPool - current->size; + EiUsedNonPagedPool = EiUsedNonPagedPool + current->size; + + VALIDATE_POOL; + return(block_to_address(current)); +} + +asmlinkage VOID ExFreePool(PVOID block) +/* + * FUNCTION: Releases previously allocated memory + * ARGUMENTS: + * block = block to free + */ +{ + block_hdr* blk=address_to_block(block); + OLD_DPRINT("(%s:%d) freeing block %x\n",__FILE__,__LINE__,blk); + +// DbgPrint("ExFreePool(block %x), size %d, caller %x\n",block,blk->size, +// ((PULONG)&block)[-1]); + + VALIDATE_POOL; + + if (blk->magic != BLOCK_HDR_MAGIC) + { + DbgPrint("ExFreePool of non-allocated address %x\n",block); + KeBugCheck(0); + return; + } + + /* + * Please don't change the order + */ + remove_from_used_list(blk); + add_to_free_list(blk); + + EiUsedNonPagedPool = EiUsedNonPagedPool - blk->size; + EiFreeNonPagedPool = EiFreeNonPagedPool + blk->size; + + VALIDATE_POOL; +} + +static void defrag_free_list(void) +/* + * FUNCTION: defrag the list of free blocks + */ +{ + block_hdr* current=free_list_head,*current2; + ULONG addr1,addr2,max=0; + + DPRINT("Begin defrag free,tot free=%d,tot used=%d\n" + ,EiFreeNonPagedPool + ,EiUsedNonPagedPool); + while (current) + { + addr1=(ULONG)current; + current2=current->next; + while(current2) + { + addr2=(ULONG)current2; + if(addr2==addr1+current->size+sizeof(block_hdr)) + { + remove_from_free_list(current2); + current->size+=current2->size+sizeof(block_hdr); + if(current->size>max)max=current->size; + } + else if(addr1==addr2+current2->size+sizeof(block_hdr)) + { + remove_from_free_list(current); + current2->size+=current->size+sizeof(block_hdr); + if(current2->size>max)max=current2->size; + break; + } + current2=current2->next; + } + current=current->next; + } + DPRINT("Finish To defrag free blocks,max=%d\n",max); +} + +PVOID ExAllocateNonPagedPoolWithTag(ULONG type, ULONG size, ULONG Tag) +{ + block_hdr* current=NULL; + void* block; + +// DbgPrint("Blocks on free list %d\n",nr_free_blocks); +// DbgPrint("Blocks on used list %d\n",eiNrUsedblocks); +// OLD_DPRINT("ExAllocateNonPagedPool(type %d, size %d)\n",type,size); + VALIDATE_POOL; + + /* + * accomodate this useful idiom + */ + if (size==0) + { + return(NULL); + } + + /* + * Look for an already created block of sufficent size + */ + current=free_list_head; + + while (current!=NULL) + { + OLD_DPRINT("current %x size %x next %x\n",current,current->size, + current->next); + if (current->magic != BLOCK_HDR_MAGIC) + { + DbgPrint("Bad block magic (probable pool corruption) at %x\n", + current); + KeBugCheck(KBUG_POOL_FREE_LIST_CORRUPT); + } + if (current->size>=size) + { + OLD_DPRINT("found block %x of size %d\n",current,size); + block=take_block(current,size); + VALIDATE_POOL; + memset(block,0,size); + return(block); + } + current=current->next; + } + if(EiFreeNonPagedPool>size+32*PAGESIZE) + {//try defrag free list before growing kernel pool + defrag_free_list(); + /* + * reLook after defrag + */ + current=free_list_head; + + while (current!=NULL) + { + OLD_DPRINT("current %x size %x next %x\n",current,current->size, + current->next); + if (current->magic != BLOCK_HDR_MAGIC) + { + DbgPrint("Bad block magic (probable pool corruption)\n"); + KeBugCheck(KBUG_POOL_FREE_LIST_CORRUPT); + } + if (current->size>=size) + { + OLD_DPRINT("found block %x of size %d\n",current,size); + block=take_block(current,size); + memset(block,0,size); + return(block); + } + current=current->next; + } + } + /* + * Otherwise create a new block + */ + block=block_to_address(grow_kernel_pool(size)); + VALIDATE_POOL; + memset(block,0,size); + return(block); +} +