Fix longstanding bug in keyboard driver

svn path=/trunk/; revision=1775
This commit is contained in:
David Welch 2001-04-04 22:21:32 +00:00
parent 8d1e0c87b3
commit b7437fe01a
11 changed files with 834 additions and 691 deletions

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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