mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 01:55:19 +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 OutputHandle;
|
||||||
HANDLE InputHandle;
|
HANDLE InputHandle;
|
||||||
|
|
||||||
void debug_printf(char* fmt, ...)
|
VOID STDCALL
|
||||||
{
|
ApcRoutine(PVOID Context,
|
||||||
va_list args;
|
PIO_STATUS_BLOCK IoStatus,
|
||||||
char buffer[255];
|
ULONG Reserved)
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
printf("(apc.exe) ApcRoutine(Context %p)\n", Context);
|
printf("(apc.exe) ApcRoutine(Context %p)\n", Context);
|
||||||
}
|
}
|
||||||
|
|
|
@ -695,26 +695,18 @@ NTSTATUS STDCALL KbdDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||||
case IRP_MJ_READ:
|
case IRP_MJ_READ:
|
||||||
DPRINT("Handling Read request\n");
|
DPRINT("Handling Read request\n");
|
||||||
DPRINT("Queueing packet\n");
|
DPRINT("Queueing packet\n");
|
||||||
|
IoMarkIrpPending(Irp);
|
||||||
IoStartPacket(DeviceObject,Irp,NULL,NULL);
|
IoStartPacket(DeviceObject,Irp,NULL,NULL);
|
||||||
Status = STATUS_PENDING;
|
return(STATUS_PENDING);
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
Status = STATUS_NOT_IMPLEMENTED;
|
Status = STATUS_NOT_IMPLEMENTED;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Status==STATUS_PENDING)
|
Irp->IoStatus.Status = Status;
|
||||||
{
|
Irp->IoStatus.Information = 0;
|
||||||
DPRINT("Marking irp pending\n");
|
IoCompleteRequest(Irp,IO_NO_INCREMENT);
|
||||||
IoMarkIrpPending(Irp);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Irp->IoStatus.Status = Status;
|
|
||||||
Irp->IoStatus.Information = 0;
|
|
||||||
IoCompleteRequest(Irp,IO_NO_INCREMENT);
|
|
||||||
}
|
|
||||||
DPRINT("Status %d\n",Status);
|
DPRINT("Status %d\n",Status);
|
||||||
return(Status);
|
return(Status);
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,17 +27,19 @@
|
||||||
#define FIELD_OFFSET(type,fld) ((LONG)&(((type *)0)->fld))
|
#define FIELD_OFFSET(type,fld) ((LONG)&(((type *)0)->fld))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* GLOBAL VARIABLES **********************************************************/
|
||||||
/* GLOBAL VARIABLES ***********************************************************/
|
|
||||||
|
|
||||||
extern WINBOOL bIsFileApiAnsi;
|
extern WINBOOL bIsFileApiAnsi;
|
||||||
extern HANDLE hProcessHeap;
|
extern HANDLE hProcessHeap;
|
||||||
extern HANDLE hBaseDir;
|
extern HANDLE hBaseDir;
|
||||||
|
|
||||||
/* FUNCTION PROTOTYPES ********************************************************/
|
extern CRITICAL_SECTION DllLock;
|
||||||
|
|
||||||
|
/* FUNCTION PROTOTYPES *******************************************************/
|
||||||
|
|
||||||
BOOLEAN STDCALL IsConsoleHandle(HANDLE Handle);
|
BOOLEAN STDCALL IsConsoleHandle(HANDLE Handle);
|
||||||
|
|
||||||
WINBOOL STDCALL CloseConsoleHandle(HANDLE Handle);
|
WINBOOL STDCALL CloseConsoleHandle(HANDLE Handle);
|
||||||
|
|
||||||
#endif /* ndef _INCLUDE_KERNEL32_KERNEL32_H */
|
#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
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS system libraries
|
* PROJECT: ReactOS system libraries
|
||||||
|
@ -9,6 +9,8 @@
|
||||||
* Created 01/11/98
|
* Created 01/11/98
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* INCLUDES ******************************************************************/
|
||||||
|
|
||||||
#include <ddk/ntddk.h>
|
#include <ddk/ntddk.h>
|
||||||
#include <ntdll/csr.h>
|
#include <ntdll/csr.h>
|
||||||
#include <ntdll/ldr.h>
|
#include <ntdll/ldr.h>
|
||||||
|
@ -19,6 +21,7 @@
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include <kernel32/kernel32.h>
|
#include <kernel32/kernel32.h>
|
||||||
|
|
||||||
|
/* GLOBALS *******************************************************************/
|
||||||
|
|
||||||
extern UNICODE_STRING SystemDirectory;
|
extern UNICODE_STRING SystemDirectory;
|
||||||
extern UNICODE_STRING WindowsDirectory;
|
extern UNICODE_STRING WindowsDirectory;
|
||||||
|
@ -32,8 +35,13 @@ WINBOOL STDCALL DllMain (HANDLE hInst,
|
||||||
ULONG ul_reason_for_call,
|
ULONG ul_reason_for_call,
|
||||||
LPVOID lpReserved);
|
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;
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||||
UNICODE_STRING Name;
|
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));
|
return(DllMain(hDll,dwReason,lpReserved));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WINBOOL STDCALL
|
||||||
WINBOOL STDCALL DllMain(HANDLE hInst,
|
DllMain(HANDLE hInst,
|
||||||
ULONG ul_reason_for_call,
|
ULONG ul_reason_for_call,
|
||||||
LPVOID lpReserved)
|
LPVOID lpReserved)
|
||||||
{
|
{
|
||||||
DPRINT("DllMain(hInst %x, ul_reason_for_call %d)\n",
|
DPRINT("DllMain(hInst %x, ul_reason_for_call %d)\n",
|
||||||
hInst, ul_reason_for_call);
|
hInst, ul_reason_for_call);
|
||||||
|
@ -127,6 +136,9 @@ WINBOOL STDCALL DllMain(HANDLE hInst,
|
||||||
DbgPrint("Failed to open object base directory: expect trouble\n");
|
DbgPrint("Failed to open object base directory: expect trouble\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Initialize the DLL critical section */
|
||||||
|
RtlInitializeCriticalSection(&DllLock);
|
||||||
|
|
||||||
/* Insert more dll attach stuff here! */
|
/* Insert more dll attach stuff here! */
|
||||||
|
|
||||||
DllInitialized = TRUE;
|
DllInitialized = TRUE;
|
||||||
|
@ -138,13 +150,16 @@ WINBOOL STDCALL DllMain(HANDLE hInst,
|
||||||
DPRINT("DLL_PROCESS_DETACH\n");
|
DPRINT("DLL_PROCESS_DETACH\n");
|
||||||
if (DllInitialized == TRUE)
|
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 */
|
/* Close object base directory */
|
||||||
NtClose(hBaseDir);
|
NtClose(hBaseDir);
|
||||||
|
|
||||||
RtlFreeUnicodeString (&SystemDirectory);
|
RtlFreeUnicodeString (&SystemDirectory);
|
||||||
RtlFreeUnicodeString (&WindowsDirectory);
|
RtlFreeUnicodeString (&WindowsDirectory);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -389,6 +389,11 @@ MmGetReferenceCountPage(PVOID PhysicalAddress);
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
MmIsUsablePage(PVOID PhysicalAddress);
|
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
|
typedef struct _MM_PAGEOP
|
||||||
{
|
{
|
||||||
/* Type of operation. */
|
/* Type of operation. */
|
||||||
|
@ -425,7 +430,7 @@ MmReleasePageOp(PMM_PAGEOP PageOp);
|
||||||
|
|
||||||
PMM_PAGEOP
|
PMM_PAGEOP
|
||||||
MmGetPageOp(PMEMORY_AREA MArea, ULONG Pid, PVOID Address,
|
MmGetPageOp(PMEMORY_AREA MArea, ULONG Pid, PVOID Address,
|
||||||
PMM_SECTION_SEGMENT Segment, ULONG Offset);
|
PMM_SECTION_SEGMENT Segment, ULONG Offset, ULONG OpType);
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
MiDebugDumpNonPagedPool(BOOLEAN NewOnly);
|
MiDebugDumpNonPagedPool(BOOLEAN NewOnly);
|
||||||
|
@ -455,4 +460,6 @@ MmIsAccessedAndResetAccessPage(struct _EPROCESS* Process, PVOID Address);
|
||||||
SWAPENTRY
|
SWAPENTRY
|
||||||
MmGetSavedSwapEntryPage(PVOID PhysicalAddress);
|
MmGetSavedSwapEntryPage(PVOID PhysicalAddress);
|
||||||
|
|
||||||
|
#define STATUS_MM_RESTART_OPERATION (0xD0000001)
|
||||||
|
|
||||||
#endif
|
#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
|
* PROJECT: ReactOS kernel
|
||||||
* FILE: ntoskrnl/io/resource.c
|
* FILE: ntoskrnl/io/resource.c
|
||||||
* PURPOSE: Hardware resource managment
|
* PURPOSE: Hardware resource managment
|
||||||
|
@ -23,64 +40,79 @@ static CONFIGURATION_INFORMATION SystemConfigurationInformation =
|
||||||
|
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
|
||||||
PCONFIGURATION_INFORMATION
|
PCONFIGURATION_INFORMATION STDCALL
|
||||||
STDCALL
|
|
||||||
IoGetConfigurationInformation(VOID)
|
IoGetConfigurationInformation(VOID)
|
||||||
{
|
{
|
||||||
return(&SystemConfigurationInformation);
|
return(&SystemConfigurationInformation);
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS STDCALL
|
||||||
STDCALL
|
|
||||||
IoReportResourceUsage(PUNICODE_STRING DriverClassName,
|
IoReportResourceUsage(PUNICODE_STRING DriverClassName,
|
||||||
PDRIVER_OBJECT DriverObject,
|
PDRIVER_OBJECT DriverObject,
|
||||||
PCM_RESOURCE_LIST DriverList,
|
PCM_RESOURCE_LIST DriverList,
|
||||||
ULONG DriverListSize,
|
ULONG DriverListSize,
|
||||||
PDEVICE_OBJECT DeviceObject,
|
PDEVICE_OBJECT DeviceObject,
|
||||||
PCM_RESOURCE_LIST DeviceList,
|
PCM_RESOURCE_LIST DeviceList,
|
||||||
ULONG DeviceListSize,
|
ULONG DeviceListSize,
|
||||||
BOOLEAN OverrideConflict,
|
BOOLEAN OverrideConflict,
|
||||||
PBOOLEAN ConflictDetected)
|
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;
|
UNIMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS STDCALL
|
||||||
STDCALL
|
|
||||||
IoAssignResources(PUNICODE_STRING RegistryPath,
|
IoAssignResources(PUNICODE_STRING RegistryPath,
|
||||||
PUNICODE_STRING DriverClassName,
|
PUNICODE_STRING DriverClassName,
|
||||||
PDRIVER_OBJECT DriverObject,
|
PDRIVER_OBJECT DriverObject,
|
||||||
PDEVICE_OBJECT DeviceObject,
|
PDEVICE_OBJECT DeviceObject,
|
||||||
PIO_RESOURCE_REQUIREMENTS_LIST RequestedResources,
|
PIO_RESOURCE_REQUIREMENTS_LIST RequestedResources,
|
||||||
PCM_RESOURCE_LIST* AllocatedResources)
|
PCM_RESOURCE_LIST* AllocatedResources)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED;
|
UNIMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS STDCALL
|
||||||
STDCALL
|
|
||||||
IoQueryDeviceDescription(PINTERFACE_TYPE BusType,
|
IoQueryDeviceDescription(PINTERFACE_TYPE BusType,
|
||||||
PULONG BusNumber,
|
PULONG BusNumber,
|
||||||
PCONFIGURATION_TYPE ControllerType,
|
PCONFIGURATION_TYPE ControllerType,
|
||||||
PULONG ControllerNumber,
|
PULONG ControllerNumber,
|
||||||
PCONFIGURATION_TYPE PeripheralType,
|
PCONFIGURATION_TYPE PeripheralType,
|
||||||
PULONG PeripheralNumber,
|
PULONG PeripheralNumber,
|
||||||
PIO_QUERY_DEVICE_ROUTINE CalloutRoutine,
|
PIO_QUERY_DEVICE_ROUTINE CalloutRoutine,
|
||||||
PVOID Context)
|
PVOID Context)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED;
|
UNIMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS STDCALL
|
||||||
STDCALL
|
IoReportHalResourceUsage (PUNICODE_STRING HalDescription,
|
||||||
IoReportHalResourceUsage (
|
ULONG Unknown1,
|
||||||
PUNICODE_STRING HalDescription,
|
ULONG Unknown2,
|
||||||
ULONG Unknown1,
|
ULONG Unknown3)
|
||||||
ULONG Unknown2,
|
|
||||||
ULONG Unknown3
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED;
|
UNIMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* 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
|
* COPYRIGHT: See COPYING in the top directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -285,49 +285,60 @@ NTSTATUS MmNotPresentFault(KPROCESSOR_MODE Mode,
|
||||||
{
|
{
|
||||||
MmLockAddressSpace(AddressSpace);
|
MmLockAddressSpace(AddressSpace);
|
||||||
}
|
}
|
||||||
MemoryArea = MmOpenMemoryAreaByAddress(AddressSpace, (PVOID)Address);
|
|
||||||
if (MemoryArea == NULL)
|
/*
|
||||||
|
* Call the memory area specific fault handler
|
||||||
|
*/
|
||||||
|
do
|
||||||
{
|
{
|
||||||
DbgPrint("%s:%d\n",__FILE__,__LINE__);
|
MemoryArea = MmOpenMemoryAreaByAddress(AddressSpace, (PVOID)Address);
|
||||||
if (!FromMdl)
|
if (MemoryArea == NULL)
|
||||||
{
|
{
|
||||||
MmUnlockAddressSpace(AddressSpace);
|
DbgPrint("%s:%d\n",__FILE__,__LINE__);
|
||||||
}
|
if (!FromMdl)
|
||||||
return(STATUS_UNSUCCESSFUL);
|
{
|
||||||
}
|
MmUnlockAddressSpace(AddressSpace);
|
||||||
|
}
|
||||||
switch (MemoryArea->Type)
|
Status = STATUS_UNSUCCESSFUL;
|
||||||
{
|
}
|
||||||
case MEMORY_AREA_SYSTEM:
|
else
|
||||||
Status = STATUS_UNSUCCESSFUL;
|
{
|
||||||
break;
|
switch (MemoryArea->Type)
|
||||||
|
{
|
||||||
case MEMORY_AREA_SECTION_VIEW_COMMIT:
|
case MEMORY_AREA_SYSTEM:
|
||||||
Status = MmNotPresentFaultSectionView(AddressSpace,
|
Status = STATUS_UNSUCCESSFUL;
|
||||||
MemoryArea,
|
break;
|
||||||
(PVOID)Address,
|
|
||||||
Locked);
|
case MEMORY_AREA_SECTION_VIEW_COMMIT:
|
||||||
break;
|
Status = MmNotPresentFaultSectionView(AddressSpace,
|
||||||
|
MemoryArea,
|
||||||
case MEMORY_AREA_VIRTUAL_MEMORY:
|
(PVOID)Address,
|
||||||
Status = MmNotPresentFaultVirtualMemory(AddressSpace,
|
Locked);
|
||||||
MemoryArea,
|
break;
|
||||||
(PVOID)Address,
|
|
||||||
Locked);
|
case MEMORY_AREA_VIRTUAL_MEMORY:
|
||||||
break;
|
Status = MmNotPresentFaultVirtualMemory(AddressSpace,
|
||||||
|
MemoryArea,
|
||||||
case MEMORY_AREA_SHARED_DATA:
|
(PVOID)Address,
|
||||||
Status =
|
Locked);
|
||||||
MmCreateVirtualMapping(PsGetCurrentProcess(),
|
break;
|
||||||
(PVOID)PAGE_ROUND_DOWN(Address),
|
|
||||||
PAGE_READONLY,
|
case MEMORY_AREA_SHARED_DATA:
|
||||||
(ULONG)MmSharedDataPagePhysicalAddress);
|
Status =
|
||||||
break;
|
MmCreateVirtualMapping(PsGetCurrentProcess(),
|
||||||
|
(PVOID)PAGE_ROUND_DOWN(Address),
|
||||||
default:
|
PAGE_READONLY,
|
||||||
Status = STATUS_UNSUCCESSFUL;
|
(ULONG)MmSharedDataPagePhysicalAddress);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
Status = STATUS_UNSUCCESSFUL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
while (Status == STATUS_MM_RESTART_OPERATION);
|
||||||
|
|
||||||
DPRINT("Completed page fault handling\n");
|
DPRINT("Completed page fault handling\n");
|
||||||
if (!FromMdl)
|
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
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -71,7 +71,7 @@ MmReleasePageOp(PMM_PAGEOP PageOp)
|
||||||
|
|
||||||
PMM_PAGEOP
|
PMM_PAGEOP
|
||||||
MmGetPageOp(PMEMORY_AREA MArea, ULONG Pid, PVOID Address,
|
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
|
* FUNCTION: Get a page operation descriptor corresponding to
|
||||||
* the memory area and either the segment, offset pair or the
|
* 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->Thread = PsGetCurrentThread();
|
||||||
PageOp->Abandoned = FALSE;
|
PageOp->Abandoned = FALSE;
|
||||||
PageOp->Status = STATUS_PENDING;
|
PageOp->Status = STATUS_PENDING;
|
||||||
|
PageOp->OpType = OpType;
|
||||||
KeInitializeEvent(&PageOp->CompletionEvent, NotificationEvent, FALSE);
|
KeInitializeEvent(&PageOp->CompletionEvent, NotificationEvent, FALSE);
|
||||||
MmPageOpHashTable[Hash] = PageOp;
|
MmPageOpHashTable[Hash] = PageOp;
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* 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
|
* PROJECT: ReactOS kernel
|
||||||
* FILE: ntoskrnl/mm/section.c
|
* FILE: ntoskrnl/mm/section.c
|
||||||
|
@ -388,7 +388,8 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
/*
|
/*
|
||||||
* Get or create a page operation descriptor
|
* 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)
|
if (PageOp == NULL)
|
||||||
{
|
{
|
||||||
DPRINT1("MmGetPageOp failed\n");
|
DPRINT1("MmGetPageOp failed\n");
|
||||||
|
@ -422,11 +423,21 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
DPRINT1("Woke for page op before completion\n");
|
DPRINT1("Woke for page op before completion\n");
|
||||||
KeBugCheck(0);
|
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 the thread handling this fault has failed then we don't retry
|
||||||
*/
|
*/
|
||||||
if (!NT_SUCCESS(PageOp->Status))
|
if (!NT_SUCCESS(PageOp->Status))
|
||||||
{
|
{
|
||||||
|
MmLockAddressSpace(AddressSpace);
|
||||||
return(PageOp->Status);
|
return(PageOp->Status);
|
||||||
}
|
}
|
||||||
MmLockAddressSpace(AddressSpace);
|
MmLockAddressSpace(AddressSpace);
|
||||||
|
@ -670,6 +681,9 @@ MmAccessFaultSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
PVOID NewPage;
|
PVOID NewPage;
|
||||||
PVOID NewAddress;
|
PVOID NewAddress;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
ULONG PAddress;
|
||||||
|
LARGE_INTEGER Offset;
|
||||||
|
PMM_PAGEOP PageOp;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check if the page has been paged out or has already been set readwrite
|
* 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);
|
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
|
* Lock the segment
|
||||||
*/
|
*/
|
||||||
|
@ -688,6 +709,9 @@ MmAccessFaultSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
MmLockSection(Section);
|
MmLockSection(Section);
|
||||||
MmLockSectionSegment(Segment);
|
MmLockSectionSegment(Segment);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check if we are doing COW
|
||||||
|
*/
|
||||||
if (!(Segment->Characteristics & IMAGE_SECTION_CHAR_DATA))
|
if (!(Segment->Characteristics & IMAGE_SECTION_CHAR_DATA))
|
||||||
{
|
{
|
||||||
MmUnlockSection(Section);
|
MmUnlockSection(Section);
|
||||||
|
@ -695,34 +719,81 @@ MmAccessFaultSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
return(STATUS_UNSUCCESSFUL);
|
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
|
* Allocate a page
|
||||||
*/
|
*/
|
||||||
NewPage = MmAllocPage(0);
|
NewPage = MmAllocPage(0);
|
||||||
while (NewPage == NULL)
|
while (NewPage == NULL)
|
||||||
{
|
{
|
||||||
MmUnlockSectionSegment(Segment);
|
|
||||||
MmUnlockSection(Section);
|
|
||||||
MmUnlockAddressSpace(AddressSpace);
|
|
||||||
MmWaitForFreePages();
|
MmWaitForFreePages();
|
||||||
MmLockAddressSpace(AddressSpace);
|
|
||||||
if (!MmIsPagePresent(NULL, Address) ||
|
|
||||||
MmGetPageProtect(NULL, Address) & PAGE_READWRITE)
|
|
||||||
{
|
|
||||||
MmUnlockAddressSpace(AddressSpace);
|
|
||||||
return(STATUS_SUCCESS);
|
|
||||||
}
|
|
||||||
MmLockSection(Section);
|
|
||||||
MmLockSectionSegment(Segment);
|
|
||||||
NewPage = MmAllocPage(0);
|
NewPage = MmAllocPage(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copy the old page
|
||||||
|
*/
|
||||||
OldPage = MmGetPhysicalAddressForProcess(NULL, Address);
|
OldPage = MmGetPhysicalAddressForProcess(NULL, Address);
|
||||||
|
|
||||||
NewAddress = ExAllocatePageWithPhysPage((ULONG)NewPage);
|
NewAddress = ExAllocatePageWithPhysPage((ULONG)NewPage);
|
||||||
memcpy(NewAddress, (PVOID)PAGE_ROUND_DOWN(Address), PAGESIZE);
|
memcpy(NewAddress, (PVOID)PAGE_ROUND_DOWN(Address), PAGESIZE);
|
||||||
ExUnmapPage(NewAddress);
|
ExUnmapPage(NewAddress);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set the PTE to point to the new page
|
||||||
|
*/
|
||||||
|
MmLockAddressSpace(AddressSpace);
|
||||||
Status = MmCreateVirtualMapping(PsGetCurrentProcess(),
|
Status = MmCreateVirtualMapping(PsGetCurrentProcess(),
|
||||||
Address,
|
Address,
|
||||||
MemoryArea->Attributes,
|
MemoryArea->Attributes,
|
||||||
|
@ -736,8 +807,9 @@ MmAccessFaultSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
{
|
{
|
||||||
MmLockPage((PVOID)MmGetPhysicalAddressForProcess(NULL, Address));
|
MmLockPage((PVOID)MmGetPhysicalAddressForProcess(NULL, Address));
|
||||||
}
|
}
|
||||||
MmUnlockSectionSegment(Segment);
|
PageOp->Status = STATUS_SUCCESS;
|
||||||
MmUnlockSection(Section);
|
KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
|
||||||
|
MmReleasePageOp(PageOp);
|
||||||
return(STATUS_SUCCESS);
|
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
|
* COPYRIGHT: See COPYING in the top directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -91,90 +91,7 @@ MmWritePageVirtualMemory(PMADDRESS_SPACE AddressSpace,
|
||||||
PMEMORY_AREA MArea,
|
PMEMORY_AREA MArea,
|
||||||
PVOID Address)
|
PVOID Address)
|
||||||
{
|
{
|
||||||
SWAPENTRY se;
|
return(STATUS_UNSUCCESSFUL);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -188,6 +105,24 @@ ULONG MmPageOutVirtualMemory(PMADDRESS_SPACE AddressSpace,
|
||||||
SWAPENTRY SwapEntry;
|
SWAPENTRY SwapEntry;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
PMDL Mdl;
|
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.
|
* Paging out code or readonly data is easy.
|
||||||
|
@ -199,7 +134,11 @@ ULONG MmPageOutVirtualMemory(PMADDRESS_SPACE AddressSpace,
|
||||||
MmDeleteVirtualMapping(PsGetCurrentProcess(), Address, FALSE,
|
MmDeleteVirtualMapping(PsGetCurrentProcess(), Address, FALSE,
|
||||||
NULL, &PhysicalAddress);
|
NULL, &PhysicalAddress);
|
||||||
MmDereferencePage((PVOID)PhysicalAddress);
|
MmDereferencePage((PVOID)PhysicalAddress);
|
||||||
|
|
||||||
*Ul = TRUE;
|
*Ul = TRUE;
|
||||||
|
PageOp->Status = STATUS_SUCCESS;
|
||||||
|
KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
|
||||||
|
MmReleasePageOp(PageOp);
|
||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -213,6 +152,9 @@ ULONG MmPageOutVirtualMemory(PMADDRESS_SPACE AddressSpace,
|
||||||
MmRemovePageFromWorkingSet(AddressSpace->Process, Address);
|
MmRemovePageFromWorkingSet(AddressSpace->Process, Address);
|
||||||
MmDereferencePage((PVOID)PhysicalAddress);
|
MmDereferencePage((PVOID)PhysicalAddress);
|
||||||
*Ul = TRUE;
|
*Ul = TRUE;
|
||||||
|
PageOp->Status = STATUS_SUCCESS;
|
||||||
|
KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
|
||||||
|
MmReleasePageOp(PageOp);
|
||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -230,6 +172,9 @@ ULONG MmPageOutVirtualMemory(PMADDRESS_SPACE AddressSpace,
|
||||||
MemoryArea->Attributes,
|
MemoryArea->Attributes,
|
||||||
PhysicalAddress);
|
PhysicalAddress);
|
||||||
*Ul = FALSE;
|
*Ul = FALSE;
|
||||||
|
PageOp->Status = STATUS_UNSUCCESSFUL;
|
||||||
|
KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
|
||||||
|
MmReleasePageOp(PageOp);
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -248,6 +193,9 @@ ULONG MmPageOutVirtualMemory(PMADDRESS_SPACE AddressSpace,
|
||||||
MemoryArea->Attributes,
|
MemoryArea->Attributes,
|
||||||
PhysicalAddress);
|
PhysicalAddress);
|
||||||
*Ul = FALSE;
|
*Ul = FALSE;
|
||||||
|
PageOp->Status = STATUS_UNSUCCESSFUL;
|
||||||
|
KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
|
||||||
|
MmReleasePageOp(PageOp);
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -257,6 +205,9 @@ ULONG MmPageOutVirtualMemory(PMADDRESS_SPACE AddressSpace,
|
||||||
MmRemovePageFromWorkingSet(AddressSpace->Process, Address);
|
MmRemovePageFromWorkingSet(AddressSpace->Process, Address);
|
||||||
MmDereferencePage((PVOID)PhysicalAddress);
|
MmDereferencePage((PVOID)PhysicalAddress);
|
||||||
*Ul = TRUE;
|
*Ul = TRUE;
|
||||||
|
PageOp->Status = STATUS_SUCCESS;
|
||||||
|
KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
|
||||||
|
MmReleasePageOp(PageOp);
|
||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -312,7 +263,8 @@ MmNotPresentFaultVirtualMemory(PMADDRESS_SPACE AddressSpace,
|
||||||
* Get or create a page operation
|
* Get or create a page operation
|
||||||
*/
|
*/
|
||||||
PageOp = MmGetPageOp(MemoryArea, (ULONG)PsGetCurrentProcessId(),
|
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)
|
if (PageOp == NULL)
|
||||||
{
|
{
|
||||||
DPRINT1("MmGetPageOp failed");
|
DPRINT1("MmGetPageOp failed");
|
||||||
|
@ -344,6 +296,14 @@ MmNotPresentFaultVirtualMemory(PMADDRESS_SPACE AddressSpace,
|
||||||
DPRINT1("Woke for page op before completion\n");
|
DPRINT1("Woke for page op before completion\n");
|
||||||
KeBugCheck(0);
|
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
|
* If the thread handling this fault has failed then we don't retry
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in a new issue