mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 01:24:38 +00:00
Fix longstanding bug in keyboard driver
svn path=/trunk/; revision=1775
This commit is contained in:
parent
8d1e0c87b3
commit
b7437fe01a
11 changed files with 834 additions and 691 deletions
|
@ -7,20 +7,10 @@
|
|||
HANDLE OutputHandle;
|
||||
HANDLE InputHandle;
|
||||
|
||||
void debug_printf(char* fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
char buffer[255];
|
||||
|
||||
va_start(args,fmt);
|
||||
vsprintf(buffer,fmt,args);
|
||||
WriteConsoleA(OutputHandle, buffer, strlen(buffer), NULL, NULL);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
VOID STDCALL ApcRoutine(PVOID Context,
|
||||
PIO_STATUS_BLOCK IoStatus,
|
||||
ULONG Reserved)
|
||||
VOID STDCALL
|
||||
ApcRoutine(PVOID Context,
|
||||
PIO_STATUS_BLOCK IoStatus,
|
||||
ULONG Reserved)
|
||||
{
|
||||
printf("(apc.exe) ApcRoutine(Context %p)\n", Context);
|
||||
}
|
||||
|
|
|
@ -695,26 +695,18 @@ NTSTATUS STDCALL KbdDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
|||
case IRP_MJ_READ:
|
||||
DPRINT("Handling Read request\n");
|
||||
DPRINT("Queueing packet\n");
|
||||
IoMarkIrpPending(Irp);
|
||||
IoStartPacket(DeviceObject,Irp,NULL,NULL);
|
||||
Status = STATUS_PENDING;
|
||||
break;
|
||||
return(STATUS_PENDING);
|
||||
|
||||
default:
|
||||
Status = STATUS_NOT_IMPLEMENTED;
|
||||
break;
|
||||
}
|
||||
|
||||
if (Status==STATUS_PENDING)
|
||||
{
|
||||
DPRINT("Marking irp pending\n");
|
||||
IoMarkIrpPending(Irp);
|
||||
}
|
||||
else
|
||||
{
|
||||
Irp->IoStatus.Status = Status;
|
||||
Irp->IoStatus.Information = 0;
|
||||
IoCompleteRequest(Irp,IO_NO_INCREMENT);
|
||||
}
|
||||
Irp->IoStatus.Status = Status;
|
||||
Irp->IoStatus.Information = 0;
|
||||
IoCompleteRequest(Irp,IO_NO_INCREMENT);
|
||||
DPRINT("Status %d\n",Status);
|
||||
return(Status);
|
||||
}
|
||||
|
|
|
@ -27,17 +27,19 @@
|
|||
#define FIELD_OFFSET(type,fld) ((LONG)&(((type *)0)->fld))
|
||||
#endif
|
||||
|
||||
|
||||
/* GLOBAL VARIABLES ***********************************************************/
|
||||
/* GLOBAL VARIABLES **********************************************************/
|
||||
|
||||
extern WINBOOL bIsFileApiAnsi;
|
||||
extern HANDLE hProcessHeap;
|
||||
extern HANDLE hBaseDir;
|
||||
|
||||
/* FUNCTION PROTOTYPES ********************************************************/
|
||||
extern CRITICAL_SECTION DllLock;
|
||||
|
||||
/* FUNCTION PROTOTYPES *******************************************************/
|
||||
|
||||
BOOLEAN STDCALL IsConsoleHandle(HANDLE Handle);
|
||||
|
||||
WINBOOL STDCALL CloseConsoleHandle(HANDLE Handle);
|
||||
|
||||
#endif /* ndef _INCLUDE_KERNEL32_KERNEL32_H */
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,4 +1,4 @@
|
|||
/* $Id: dllmain.c,v 1.17 2001/01/20 18:37:08 ekohl Exp $
|
||||
/* $Id: dllmain.c,v 1.18 2001/04/04 22:21:30 dwelch Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS system libraries
|
||||
|
@ -9,6 +9,8 @@
|
|||
* Created 01/11/98
|
||||
*/
|
||||
|
||||
/* INCLUDES ******************************************************************/
|
||||
|
||||
#include <ddk/ntddk.h>
|
||||
#include <ntdll/csr.h>
|
||||
#include <ntdll/ldr.h>
|
||||
|
@ -19,6 +21,7 @@
|
|||
#define NDEBUG
|
||||
#include <kernel32/kernel32.h>
|
||||
|
||||
/* GLOBALS *******************************************************************/
|
||||
|
||||
extern UNICODE_STRING SystemDirectory;
|
||||
extern UNICODE_STRING WindowsDirectory;
|
||||
|
@ -32,8 +35,13 @@ WINBOOL STDCALL DllMain (HANDLE hInst,
|
|||
ULONG ul_reason_for_call,
|
||||
LPVOID lpReserved);
|
||||
|
||||
/* Critical section for various kernel32 data structures */
|
||||
CRITICAL_SECTION DllLock;
|
||||
|
||||
static NTSTATUS OpenBaseDirectory(PHANDLE DirHandle)
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
static NTSTATUS
|
||||
OpenBaseDirectory(PHANDLE DirHandle)
|
||||
{
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
UNICODE_STRING Name;
|
||||
|
@ -68,15 +76,16 @@ static NTSTATUS OpenBaseDirectory(PHANDLE DirHandle)
|
|||
}
|
||||
|
||||
|
||||
BOOL WINAPI DllMainCRTStartup(HANDLE hDll, DWORD dwReason, LPVOID lpReserved)
|
||||
BOOL WINAPI
|
||||
DllMainCRTStartup(HANDLE hDll, DWORD dwReason, LPVOID lpReserved)
|
||||
{
|
||||
return(DllMain(hDll,dwReason,lpReserved));
|
||||
}
|
||||
|
||||
|
||||
WINBOOL STDCALL DllMain(HANDLE hInst,
|
||||
ULONG ul_reason_for_call,
|
||||
LPVOID lpReserved)
|
||||
WINBOOL STDCALL
|
||||
DllMain(HANDLE hInst,
|
||||
ULONG ul_reason_for_call,
|
||||
LPVOID lpReserved)
|
||||
{
|
||||
DPRINT("DllMain(hInst %x, ul_reason_for_call %d)\n",
|
||||
hInst, ul_reason_for_call);
|
||||
|
@ -127,6 +136,9 @@ WINBOOL STDCALL DllMain(HANDLE hInst,
|
|||
DbgPrint("Failed to open object base directory: expect trouble\n");
|
||||
}
|
||||
|
||||
/* Initialize the DLL critical section */
|
||||
RtlInitializeCriticalSection(&DllLock);
|
||||
|
||||
/* Insert more dll attach stuff here! */
|
||||
|
||||
DllInitialized = TRUE;
|
||||
|
@ -138,13 +150,16 @@ WINBOOL STDCALL DllMain(HANDLE hInst,
|
|||
DPRINT("DLL_PROCESS_DETACH\n");
|
||||
if (DllInitialized == TRUE)
|
||||
{
|
||||
/* Insert more dll detach stuff here! */
|
||||
/* Insert more dll detach stuff here! */
|
||||
|
||||
/* Delete DLL critical section */
|
||||
RtlDeleteCriticalSection (&DllLock);
|
||||
|
||||
/* Close object base directory */
|
||||
NtClose(hBaseDir);
|
||||
|
||||
RtlFreeUnicodeString (&SystemDirectory);
|
||||
RtlFreeUnicodeString (&WindowsDirectory);
|
||||
/* Close object base directory */
|
||||
NtClose(hBaseDir);
|
||||
|
||||
RtlFreeUnicodeString (&SystemDirectory);
|
||||
RtlFreeUnicodeString (&WindowsDirectory);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -389,6 +389,11 @@ MmGetReferenceCountPage(PVOID PhysicalAddress);
|
|||
BOOLEAN
|
||||
MmIsUsablePage(PVOID PhysicalAddress);
|
||||
|
||||
#define MM_PAGEOP_PAGEIN (1)
|
||||
#define MM_PAGEOP_PAGEOUT (2)
|
||||
#define MM_PAGEOP_PAGESYNCH (3)
|
||||
#define MM_PAGEOP_ACCESSFAULT (4)
|
||||
|
||||
typedef struct _MM_PAGEOP
|
||||
{
|
||||
/* Type of operation. */
|
||||
|
@ -425,7 +430,7 @@ MmReleasePageOp(PMM_PAGEOP PageOp);
|
|||
|
||||
PMM_PAGEOP
|
||||
MmGetPageOp(PMEMORY_AREA MArea, ULONG Pid, PVOID Address,
|
||||
PMM_SECTION_SEGMENT Segment, ULONG Offset);
|
||||
PMM_SECTION_SEGMENT Segment, ULONG Offset, ULONG OpType);
|
||||
|
||||
VOID
|
||||
MiDebugDumpNonPagedPool(BOOLEAN NewOnly);
|
||||
|
@ -455,4 +460,6 @@ MmIsAccessedAndResetAccessPage(struct _EPROCESS* Process, PVOID Address);
|
|||
SWAPENTRY
|
||||
MmGetSavedSwapEntryPage(PVOID PhysicalAddress);
|
||||
|
||||
#define STATUS_MM_RESTART_OPERATION (0xD0000001)
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,6 +1,23 @@
|
|||
/* $Id: resource.c,v 1.4 2000/04/05 15:50:29 ekohl Exp $
|
||||
/*
|
||||
* ReactOS kernel
|
||||
* Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team
|
||||
*
|
||||
* 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
/* $Id: resource.c,v 1.5 2001/04/04 22:21:31 dwelch Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: ntoskrnl/io/resource.c
|
||||
* PURPOSE: Hardware resource managment
|
||||
|
@ -23,64 +40,79 @@ static CONFIGURATION_INFORMATION SystemConfigurationInformation =
|
|||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
PCONFIGURATION_INFORMATION
|
||||
STDCALL
|
||||
PCONFIGURATION_INFORMATION STDCALL
|
||||
IoGetConfigurationInformation(VOID)
|
||||
{
|
||||
return(&SystemConfigurationInformation);
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
STDCALL
|
||||
NTSTATUS STDCALL
|
||||
IoReportResourceUsage(PUNICODE_STRING DriverClassName,
|
||||
PDRIVER_OBJECT DriverObject,
|
||||
PCM_RESOURCE_LIST DriverList,
|
||||
ULONG DriverListSize,
|
||||
PDEVICE_OBJECT DeviceObject,
|
||||
PCM_RESOURCE_LIST DeviceList,
|
||||
ULONG DeviceListSize,
|
||||
BOOLEAN OverrideConflict,
|
||||
PBOOLEAN ConflictDetected)
|
||||
PDRIVER_OBJECT DriverObject,
|
||||
PCM_RESOURCE_LIST DriverList,
|
||||
ULONG DriverListSize,
|
||||
PDEVICE_OBJECT DeviceObject,
|
||||
PCM_RESOURCE_LIST DeviceList,
|
||||
ULONG DeviceListSize,
|
||||
BOOLEAN OverrideConflict,
|
||||
PBOOLEAN ConflictDetected)
|
||||
/*
|
||||
* FUNCTION: Reports hardware resources in the
|
||||
* \Registry\Machine\Hardware\ResourceMap tree, so that a subsequently
|
||||
* loaded driver cannot attempt to use the same resources.
|
||||
* ARGUMENTS:
|
||||
* DriverClassName - The class of driver under which the resource
|
||||
* information should be stored.
|
||||
* DriverObject - The driver object that was input to the
|
||||
* DriverEntry.
|
||||
* DriverList - Resources that claimed for the driver rather than
|
||||
* per-device.
|
||||
* DriverListSize - Size in bytes of the DriverList.
|
||||
* DeviceObject - The device object for which resources should be
|
||||
* claimed.
|
||||
* DeviceList - List of resources which should be claimed for the
|
||||
* device.
|
||||
* DeviceListSize - Size of the per-device resource list in bytes.
|
||||
* OverrideConflict - True if the resources should be cliamed
|
||||
* even if a conflict is found.
|
||||
* ConflictDetected - Points to a variable that receives TRUE if
|
||||
* a conflict is detected with another driver.
|
||||
*/
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
STDCALL
|
||||
NTSTATUS STDCALL
|
||||
IoAssignResources(PUNICODE_STRING RegistryPath,
|
||||
PUNICODE_STRING DriverClassName,
|
||||
PDRIVER_OBJECT DriverObject,
|
||||
PDEVICE_OBJECT DeviceObject,
|
||||
PIO_RESOURCE_REQUIREMENTS_LIST RequestedResources,
|
||||
PCM_RESOURCE_LIST* AllocatedResources)
|
||||
PUNICODE_STRING DriverClassName,
|
||||
PDRIVER_OBJECT DriverObject,
|
||||
PDEVICE_OBJECT DeviceObject,
|
||||
PIO_RESOURCE_REQUIREMENTS_LIST RequestedResources,
|
||||
PCM_RESOURCE_LIST* AllocatedResources)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
STDCALL
|
||||
NTSTATUS STDCALL
|
||||
IoQueryDeviceDescription(PINTERFACE_TYPE BusType,
|
||||
PULONG BusNumber,
|
||||
PCONFIGURATION_TYPE ControllerType,
|
||||
PULONG ControllerNumber,
|
||||
PCONFIGURATION_TYPE PeripheralType,
|
||||
PULONG PeripheralNumber,
|
||||
PIO_QUERY_DEVICE_ROUTINE CalloutRoutine,
|
||||
PVOID Context)
|
||||
PULONG BusNumber,
|
||||
PCONFIGURATION_TYPE ControllerType,
|
||||
PULONG ControllerNumber,
|
||||
PCONFIGURATION_TYPE PeripheralType,
|
||||
PULONG PeripheralNumber,
|
||||
PIO_QUERY_DEVICE_ROUTINE CalloutRoutine,
|
||||
PVOID Context)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
STDCALL
|
||||
IoReportHalResourceUsage (
|
||||
PUNICODE_STRING HalDescription,
|
||||
ULONG Unknown1,
|
||||
ULONG Unknown2,
|
||||
ULONG Unknown3
|
||||
)
|
||||
NTSTATUS STDCALL
|
||||
IoReportHalResourceUsage (PUNICODE_STRING HalDescription,
|
||||
ULONG Unknown1,
|
||||
ULONG Unknown2,
|
||||
ULONG Unknown3)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
/* $Id: mm.c,v 1.46 2001/03/16 18:11:23 dwelch Exp $
|
||||
/* $Id: mm.c,v 1.47 2001/04/04 22:21:31 dwelch Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -285,49 +285,60 @@ NTSTATUS MmNotPresentFault(KPROCESSOR_MODE Mode,
|
|||
{
|
||||
MmLockAddressSpace(AddressSpace);
|
||||
}
|
||||
MemoryArea = MmOpenMemoryAreaByAddress(AddressSpace, (PVOID)Address);
|
||||
if (MemoryArea == NULL)
|
||||
|
||||
/*
|
||||
* Call the memory area specific fault handler
|
||||
*/
|
||||
do
|
||||
{
|
||||
DbgPrint("%s:%d\n",__FILE__,__LINE__);
|
||||
if (!FromMdl)
|
||||
{
|
||||
MmUnlockAddressSpace(AddressSpace);
|
||||
}
|
||||
return(STATUS_UNSUCCESSFUL);
|
||||
}
|
||||
|
||||
switch (MemoryArea->Type)
|
||||
{
|
||||
case MEMORY_AREA_SYSTEM:
|
||||
Status = STATUS_UNSUCCESSFUL;
|
||||
break;
|
||||
|
||||
case MEMORY_AREA_SECTION_VIEW_COMMIT:
|
||||
Status = MmNotPresentFaultSectionView(AddressSpace,
|
||||
MemoryArea,
|
||||
(PVOID)Address,
|
||||
Locked);
|
||||
break;
|
||||
|
||||
case MEMORY_AREA_VIRTUAL_MEMORY:
|
||||
Status = MmNotPresentFaultVirtualMemory(AddressSpace,
|
||||
MemoryArea,
|
||||
(PVOID)Address,
|
||||
Locked);
|
||||
break;
|
||||
|
||||
case MEMORY_AREA_SHARED_DATA:
|
||||
Status =
|
||||
MmCreateVirtualMapping(PsGetCurrentProcess(),
|
||||
(PVOID)PAGE_ROUND_DOWN(Address),
|
||||
PAGE_READONLY,
|
||||
(ULONG)MmSharedDataPagePhysicalAddress);
|
||||
break;
|
||||
|
||||
default:
|
||||
Status = STATUS_UNSUCCESSFUL;
|
||||
break;
|
||||
MemoryArea = MmOpenMemoryAreaByAddress(AddressSpace, (PVOID)Address);
|
||||
if (MemoryArea == NULL)
|
||||
{
|
||||
DbgPrint("%s:%d\n",__FILE__,__LINE__);
|
||||
if (!FromMdl)
|
||||
{
|
||||
MmUnlockAddressSpace(AddressSpace);
|
||||
}
|
||||
Status = STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (MemoryArea->Type)
|
||||
{
|
||||
case MEMORY_AREA_SYSTEM:
|
||||
Status = STATUS_UNSUCCESSFUL;
|
||||
break;
|
||||
|
||||
case MEMORY_AREA_SECTION_VIEW_COMMIT:
|
||||
Status = MmNotPresentFaultSectionView(AddressSpace,
|
||||
MemoryArea,
|
||||
(PVOID)Address,
|
||||
Locked);
|
||||
break;
|
||||
|
||||
case MEMORY_AREA_VIRTUAL_MEMORY:
|
||||
Status = MmNotPresentFaultVirtualMemory(AddressSpace,
|
||||
MemoryArea,
|
||||
(PVOID)Address,
|
||||
Locked);
|
||||
break;
|
||||
|
||||
case MEMORY_AREA_SHARED_DATA:
|
||||
Status =
|
||||
MmCreateVirtualMapping(PsGetCurrentProcess(),
|
||||
(PVOID)PAGE_ROUND_DOWN(Address),
|
||||
PAGE_READONLY,
|
||||
(ULONG)MmSharedDataPagePhysicalAddress);
|
||||
break;
|
||||
|
||||
default:
|
||||
Status = STATUS_UNSUCCESSFUL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
while (Status == STATUS_MM_RESTART_OPERATION);
|
||||
|
||||
DPRINT("Completed page fault handling\n");
|
||||
if (!FromMdl)
|
||||
{
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: pageop.c,v 1.4 2001/03/16 18:11:23 dwelch Exp $
|
||||
/* $Id: pageop.c,v 1.5 2001/04/04 22:21:31 dwelch Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -71,7 +71,7 @@ MmReleasePageOp(PMM_PAGEOP PageOp)
|
|||
|
||||
PMM_PAGEOP
|
||||
MmGetPageOp(PMEMORY_AREA MArea, ULONG Pid, PVOID Address,
|
||||
PMM_SECTION_SEGMENT Segment, ULONG Offset)
|
||||
PMM_SECTION_SEGMENT Segment, ULONG Offset, ULONG OpType)
|
||||
/*
|
||||
* FUNCTION: Get a page operation descriptor corresponding to
|
||||
* the memory area and either the segment, offset pair or the
|
||||
|
@ -160,6 +160,7 @@ MmGetPageOp(PMEMORY_AREA MArea, ULONG Pid, PVOID Address,
|
|||
PageOp->Thread = PsGetCurrentThread();
|
||||
PageOp->Abandoned = FALSE;
|
||||
PageOp->Status = STATUS_PENDING;
|
||||
PageOp->OpType = OpType;
|
||||
KeInitializeEvent(&PageOp->CompletionEvent, NotificationEvent, FALSE);
|
||||
MmPageOpHashTable[Hash] = PageOp;
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
/* $Id: section.c,v 1.55 2001/04/03 17:25:49 dwelch Exp $
|
||||
/* $Id: section.c,v 1.56 2001/04/04 22:21:31 dwelch Exp $
|
||||
*
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: ntoskrnl/mm/section.c
|
||||
|
@ -388,7 +388,8 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
|
|||
/*
|
||||
* Get or create a page operation descriptor
|
||||
*/
|
||||
PageOp = MmGetPageOp(MemoryArea, 0, 0, Segment, Offset.u.LowPart);
|
||||
PageOp = MmGetPageOp(MemoryArea, 0, 0, Segment, Offset.u.LowPart,
|
||||
MM_PAGEOP_PAGEIN);
|
||||
if (PageOp == NULL)
|
||||
{
|
||||
DPRINT1("MmGetPageOp failed\n");
|
||||
|
@ -422,11 +423,21 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
|
|||
DPRINT1("Woke for page op before completion\n");
|
||||
KeBugCheck(0);
|
||||
}
|
||||
/*
|
||||
* If this wasn't a pagein then restart the operation
|
||||
*/
|
||||
if (PageOp->OpType != MM_PAGEOP_PAGEIN)
|
||||
{
|
||||
MmLockAddressSpace(AddressSpace);
|
||||
MmReleasePageOp(PageOp);
|
||||
return(STATUS_MM_RESTART_OPERATION);
|
||||
}
|
||||
/*
|
||||
* If the thread handling this fault has failed then we don't retry
|
||||
*/
|
||||
if (!NT_SUCCESS(PageOp->Status))
|
||||
{
|
||||
MmLockAddressSpace(AddressSpace);
|
||||
return(PageOp->Status);
|
||||
}
|
||||
MmLockAddressSpace(AddressSpace);
|
||||
|
@ -670,6 +681,9 @@ MmAccessFaultSectionView(PMADDRESS_SPACE AddressSpace,
|
|||
PVOID NewPage;
|
||||
PVOID NewAddress;
|
||||
NTSTATUS Status;
|
||||
ULONG PAddress;
|
||||
LARGE_INTEGER Offset;
|
||||
PMM_PAGEOP PageOp;
|
||||
|
||||
/*
|
||||
* Check if the page has been paged out or has already been set readwrite
|
||||
|
@ -680,6 +694,13 @@ MmAccessFaultSectionView(PMADDRESS_SPACE AddressSpace,
|
|||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
/*
|
||||
* Find the offset of the page
|
||||
*/
|
||||
PAddress = (ULONG)PAGE_ROUND_DOWN(((ULONG)Address));
|
||||
Offset.QuadPart = (PAddress - (ULONG)MemoryArea->BaseAddress) +
|
||||
MemoryArea->Data.SectionData.ViewOffset;
|
||||
|
||||
/*
|
||||
* Lock the segment
|
||||
*/
|
||||
|
@ -688,6 +709,9 @@ MmAccessFaultSectionView(PMADDRESS_SPACE AddressSpace,
|
|||
MmLockSection(Section);
|
||||
MmLockSectionSegment(Segment);
|
||||
|
||||
/*
|
||||
* Check if we are doing COW
|
||||
*/
|
||||
if (!(Segment->Characteristics & IMAGE_SECTION_CHAR_DATA))
|
||||
{
|
||||
MmUnlockSection(Section);
|
||||
|
@ -695,34 +719,81 @@ MmAccessFaultSectionView(PMADDRESS_SPACE AddressSpace,
|
|||
return(STATUS_UNSUCCESSFUL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get or create a pageop
|
||||
*/
|
||||
PageOp = MmGetPageOp(MemoryArea, 0, 0, Segment, Offset.u.LowPart,
|
||||
MM_PAGEOP_ACCESSFAULT);
|
||||
if (PageOp == NULL)
|
||||
{
|
||||
DPRINT1("MmGetPageOp failed\n");
|
||||
KeBugCheck(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Wait for any other operations to complete
|
||||
*/
|
||||
if (PageOp->Thread != PsGetCurrentThread())
|
||||
{
|
||||
MmUnlockSectionSegment(Segment);
|
||||
MmUnlockSection(Section);
|
||||
MmUnlockAddressSpace(AddressSpace);
|
||||
Status = KeWaitForSingleObject(&PageOp->CompletionEvent,
|
||||
0,
|
||||
KernelMode,
|
||||
FALSE,
|
||||
NULL);
|
||||
/*
|
||||
* Check for various strange conditions
|
||||
*/
|
||||
if (Status != STATUS_SUCCESS)
|
||||
{
|
||||
DPRINT1("Failed to wait for page op\n");
|
||||
KeBugCheck(0);
|
||||
}
|
||||
if (PageOp->Status == STATUS_PENDING)
|
||||
{
|
||||
DPRINT1("Woke for page op before completion\n");
|
||||
KeBugCheck(0);
|
||||
}
|
||||
/*
|
||||
* Restart the operation
|
||||
*/
|
||||
MmLockAddressSpace(AddressSpace);
|
||||
MmReleasePageOp(PageOp);
|
||||
return(STATUS_MM_RESTART_OPERATION);
|
||||
}
|
||||
|
||||
/*
|
||||
* Release locks now we have the pageop
|
||||
*/
|
||||
MmUnlockSectionSegment(Segment);
|
||||
MmUnlockSection(Section);
|
||||
MmUnlockAddressSpace(AddressSpace);
|
||||
|
||||
/*
|
||||
* Allocate a page
|
||||
*/
|
||||
NewPage = MmAllocPage(0);
|
||||
while (NewPage == NULL)
|
||||
{
|
||||
MmUnlockSectionSegment(Segment);
|
||||
MmUnlockSection(Section);
|
||||
MmUnlockAddressSpace(AddressSpace);
|
||||
MmWaitForFreePages();
|
||||
MmLockAddressSpace(AddressSpace);
|
||||
if (!MmIsPagePresent(NULL, Address) ||
|
||||
MmGetPageProtect(NULL, Address) & PAGE_READWRITE)
|
||||
{
|
||||
MmUnlockAddressSpace(AddressSpace);
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
MmLockSection(Section);
|
||||
MmLockSectionSegment(Segment);
|
||||
NewPage = MmAllocPage(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy the old page
|
||||
*/
|
||||
OldPage = MmGetPhysicalAddressForProcess(NULL, Address);
|
||||
|
||||
NewAddress = ExAllocatePageWithPhysPage((ULONG)NewPage);
|
||||
memcpy(NewAddress, (PVOID)PAGE_ROUND_DOWN(Address), PAGESIZE);
|
||||
ExUnmapPage(NewAddress);
|
||||
|
||||
/*
|
||||
* Set the PTE to point to the new page
|
||||
*/
|
||||
MmLockAddressSpace(AddressSpace);
|
||||
Status = MmCreateVirtualMapping(PsGetCurrentProcess(),
|
||||
Address,
|
||||
MemoryArea->Attributes,
|
||||
|
@ -736,8 +807,9 @@ MmAccessFaultSectionView(PMADDRESS_SPACE AddressSpace,
|
|||
{
|
||||
MmLockPage((PVOID)MmGetPhysicalAddressForProcess(NULL, Address));
|
||||
}
|
||||
MmUnlockSectionSegment(Segment);
|
||||
MmUnlockSection(Section);
|
||||
PageOp->Status = STATUS_SUCCESS;
|
||||
KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
|
||||
MmReleasePageOp(PageOp);
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: virtual.c,v 1.45 2001/03/25 02:34:29 dwelch Exp $
|
||||
/* $Id: virtual.c,v 1.46 2001/04/04 22:21:31 dwelch Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -91,90 +91,7 @@ MmWritePageVirtualMemory(PMADDRESS_SPACE AddressSpace,
|
|||
PMEMORY_AREA MArea,
|
||||
PVOID Address)
|
||||
{
|
||||
SWAPENTRY se;
|
||||
ULONG Flags;
|
||||
PHYSICAL_ADDRESS PhysicalAddress;
|
||||
PMDL Mdl;
|
||||
NTSTATUS Status;
|
||||
|
||||
/*
|
||||
* FIXME: What should we do if an i/o operation is pending on
|
||||
* this page
|
||||
*/
|
||||
|
||||
/*
|
||||
* If the memory area is readonly then there is nothing to do
|
||||
*/
|
||||
if (MArea->Attributes & PAGE_READONLY ||
|
||||
MArea->Attributes & PAGE_EXECUTE_READ)
|
||||
{
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
/*
|
||||
* Set the page to readonly. This ensures the current contents aren't
|
||||
* modified while we are writing it to swap.
|
||||
*/
|
||||
MmSetPageProtect(AddressSpace->Process,
|
||||
Address,
|
||||
PAGE_READONLY);
|
||||
/*
|
||||
* If the page isn't dirty then there is nothing to do.
|
||||
*/
|
||||
if (!MmIsPageDirty(AddressSpace->Process, Address))
|
||||
{
|
||||
MmSetPageProtect(AddressSpace->Process,
|
||||
Address,
|
||||
MArea->Attributes);
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
PhysicalAddress = MmGetPhysicalAddress(Address);
|
||||
/*
|
||||
* If we haven't already allocated a swap entry for this page
|
||||
* then allocate one
|
||||
*/
|
||||
if ((se = MmGetSavedSwapEntryPage((PVOID)PhysicalAddress.u.LowPart)) != 0)
|
||||
{
|
||||
se = MmAllocSwapPage();
|
||||
if (se == 0)
|
||||
{
|
||||
MmSetPageProtect(AddressSpace->Process,
|
||||
Address,
|
||||
MArea->Attributes);
|
||||
return(STATUS_UNSUCCESSFUL);
|
||||
}
|
||||
MmSetSavedSwapEntryPage((PVOID)PhysicalAddress.u.LowPart, se);
|
||||
}
|
||||
/*
|
||||
* Set the flags so other threads will know what we are doing
|
||||
*/
|
||||
Flags = MmGetFlagsPage((PVOID)PhysicalAddress.u.LowPart);
|
||||
Flags = Flags | MM_PHYSICAL_PAGE_MPW_PENDING;
|
||||
MmSetFlagsPage((PVOID)PhysicalAddress.u.LowPart, Flags);
|
||||
/*
|
||||
* Build an mdl to hold the page for writeout
|
||||
*/
|
||||
Mdl = MmCreateMdl(NULL, NULL, PAGESIZE);
|
||||
MmBuildMdlFromPages(Mdl, (PULONG)&PhysicalAddress.u.LowPart);
|
||||
/*
|
||||
* Unlock the address space and write out the page to swap.
|
||||
*/
|
||||
MmUnlockAddressSpace(AddressSpace);
|
||||
Status = MmWriteToSwapPage(se, Mdl);
|
||||
/*
|
||||
* Cleanup
|
||||
*/
|
||||
MmLockAddressSpace(AddressSpace);
|
||||
Flags = MmGetFlagsPage((PVOID)PhysicalAddress.u.LowPart);
|
||||
Flags = Flags & (~MM_PHYSICAL_PAGE_MPW_PENDING);
|
||||
MmSetFlagsPage((PVOID)PhysicalAddress.u.LowPart,Flags);
|
||||
/*
|
||||
* If we successfully wrote the page then reset the dirty bit
|
||||
*/
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
MmSetCleanPage(AddressSpace->Process, Address);
|
||||
}
|
||||
return(Status);
|
||||
return(STATUS_UNSUCCESSFUL);
|
||||
}
|
||||
|
||||
|
||||
|
@ -188,6 +105,24 @@ ULONG MmPageOutVirtualMemory(PMADDRESS_SPACE AddressSpace,
|
|||
SWAPENTRY SwapEntry;
|
||||
NTSTATUS Status;
|
||||
PMDL Mdl;
|
||||
PMM_PAGEOP PageOp;
|
||||
|
||||
/*
|
||||
* Get or create a pageop
|
||||
*/
|
||||
PageOp = MmGetPageOp(MemoryArea, AddressSpace->Process->UniqueProcessId,
|
||||
(PVOID)PAGE_ROUND_DOWN(Address), NULL, 0,
|
||||
MM_PAGEOP_PAGEOUT);
|
||||
if (PageOp->Thread != PsGetCurrentThread())
|
||||
{
|
||||
/*
|
||||
* On the assumption that handling pageouts speedly rather than
|
||||
* in strict order is better abandon this one.
|
||||
*/
|
||||
(*Ul) = FALSE;
|
||||
MmReleasePageOp(PageOp);
|
||||
return(STATUS_UNSUCCESSFUL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Paging out code or readonly data is easy.
|
||||
|
@ -199,7 +134,11 @@ ULONG MmPageOutVirtualMemory(PMADDRESS_SPACE AddressSpace,
|
|||
MmDeleteVirtualMapping(PsGetCurrentProcess(), Address, FALSE,
|
||||
NULL, &PhysicalAddress);
|
||||
MmDereferencePage((PVOID)PhysicalAddress);
|
||||
|
||||
*Ul = TRUE;
|
||||
PageOp->Status = STATUS_SUCCESS;
|
||||
KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
|
||||
MmReleasePageOp(PageOp);
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
@ -213,6 +152,9 @@ ULONG MmPageOutVirtualMemory(PMADDRESS_SPACE AddressSpace,
|
|||
MmRemovePageFromWorkingSet(AddressSpace->Process, Address);
|
||||
MmDereferencePage((PVOID)PhysicalAddress);
|
||||
*Ul = TRUE;
|
||||
PageOp->Status = STATUS_SUCCESS;
|
||||
KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
|
||||
MmReleasePageOp(PageOp);
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
@ -230,6 +172,9 @@ ULONG MmPageOutVirtualMemory(PMADDRESS_SPACE AddressSpace,
|
|||
MemoryArea->Attributes,
|
||||
PhysicalAddress);
|
||||
*Ul = FALSE;
|
||||
PageOp->Status = STATUS_UNSUCCESSFUL;
|
||||
KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
|
||||
MmReleasePageOp(PageOp);
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
|
@ -248,6 +193,9 @@ ULONG MmPageOutVirtualMemory(PMADDRESS_SPACE AddressSpace,
|
|||
MemoryArea->Attributes,
|
||||
PhysicalAddress);
|
||||
*Ul = FALSE;
|
||||
PageOp->Status = STATUS_UNSUCCESSFUL;
|
||||
KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
|
||||
MmReleasePageOp(PageOp);
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
@ -257,6 +205,9 @@ ULONG MmPageOutVirtualMemory(PMADDRESS_SPACE AddressSpace,
|
|||
MmRemovePageFromWorkingSet(AddressSpace->Process, Address);
|
||||
MmDereferencePage((PVOID)PhysicalAddress);
|
||||
*Ul = TRUE;
|
||||
PageOp->Status = STATUS_SUCCESS;
|
||||
KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
|
||||
MmReleasePageOp(PageOp);
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
@ -312,7 +263,8 @@ MmNotPresentFaultVirtualMemory(PMADDRESS_SPACE AddressSpace,
|
|||
* Get or create a page operation
|
||||
*/
|
||||
PageOp = MmGetPageOp(MemoryArea, (ULONG)PsGetCurrentProcessId(),
|
||||
(PVOID)PAGE_ROUND_DOWN(Address), NULL, 0);
|
||||
(PVOID)PAGE_ROUND_DOWN(Address), NULL, 0,
|
||||
MM_PAGEOP_PAGEIN);
|
||||
if (PageOp == NULL)
|
||||
{
|
||||
DPRINT1("MmGetPageOp failed");
|
||||
|
@ -344,6 +296,14 @@ MmNotPresentFaultVirtualMemory(PMADDRESS_SPACE AddressSpace,
|
|||
DPRINT1("Woke for page op before completion\n");
|
||||
KeBugCheck(0);
|
||||
}
|
||||
/*
|
||||
* If this wasn't a pagein then we need to restart the handling
|
||||
*/
|
||||
if (PageOp->OpType != MM_PAGEOP_PAGEIN)
|
||||
{
|
||||
MmReleasePageOp(PageOp);
|
||||
return(STATUS_MM_RESTART_OPERATION);
|
||||
}
|
||||
/*
|
||||
* If the thread handling this fault has failed then we don't retry
|
||||
*/
|
||||
|
|
Loading…
Reference in a new issue