Represent page-in operations by descriptors

svn path=/trunk/; revision=1682
This commit is contained in:
David Welch 2001-03-13 16:25:55 +00:00
parent c20f2479b6
commit 47ea39add9
18 changed files with 854 additions and 943 deletions

View file

@ -51,3 +51,4 @@ int main()
printf("VirtualAlloc failed 5\n"); printf("VirtualAlloc failed 5\n");
} }
} }

View file

@ -1,4 +1,4 @@
/* $Id: create.c,v 1.21 2001/03/07 08:57:09 dwelch Exp $ /* $Id: create.c,v 1.22 2001/03/13 16:25:55 dwelch Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -19,7 +19,14 @@
#include "vfat.h" #include "vfat.h"
/* FUNCTIONS ****************************************************************/ /* GLOBALS *******************************************************************/
#define TAG(A, B, C, D) (ULONG)(((A)<<0) + ((B)<<8) + ((C)<<16) + ((D)<<24))
#define TAG_FCB TAG('V', 'F', 'C', 'B')
#define TAG_CCB TAG('V', 'C', 'C', 'B')
/* FUNCTIONS *****************************************************************/
BOOLEAN BOOLEAN
IsLastEntry (PVOID Block, ULONG Offset) IsLastEntry (PVOID Block, ULONG Offset)
@ -448,7 +455,8 @@ VfatOpenFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
Fcb->RefCount++; Fcb->RefCount++;
KeReleaseSpinLock (&DeviceExt->FcbListLock, oldIrql); KeReleaseSpinLock (&DeviceExt->FcbListLock, oldIrql);
FileObject->FsContext = (PVOID)&Fcb->RFCB; FileObject->FsContext = (PVOID)&Fcb->RFCB;
newCCB = ExAllocatePool (NonPagedPool, sizeof (VFATCCB)); newCCB =
ExAllocatePoolWithTag (NonPagedPool, sizeof (VFATCCB), TAG_CCB);
memset (newCCB, 0, sizeof (VFATCCB)); memset (newCCB, 0, sizeof (VFATCCB));
FileObject->Flags = FileObject->Flags | FileObject->Flags = FileObject->Flags |
FO_FCB_IS_VALID | FO_DIRECT_CACHE_PAGING_READ; FO_FCB_IS_VALID | FO_DIRECT_CACHE_PAGING_READ;
@ -471,7 +479,7 @@ VfatOpenFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
string = FileName; string = FileName;
ParentFcb = NULL; ParentFcb = NULL;
Fcb = ExAllocatePool (NonPagedPool, sizeof (VFATFCB)); Fcb = ExAllocatePoolWithTag (NonPagedPool, sizeof (VFATFCB), TAG_FCB);
memset (Fcb, 0, sizeof (VFATFCB)); memset (Fcb, 0, sizeof (VFATFCB));
Fcb->ObjectName = &Fcb->PathName[1]; Fcb->ObjectName = &Fcb->PathName[1];
Fcb->PathName[0]='\\'; Fcb->PathName[0]='\\';
@ -532,7 +540,8 @@ VfatOpenFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
if (ParentFcb == NULL) if (ParentFcb == NULL)
{ {
CHECKPOINT; CHECKPOINT;
Fcb = ExAllocatePool (NonPagedPool, sizeof (VFATFCB)); Fcb = ExAllocatePoolWithTag (NonPagedPool, sizeof (VFATFCB),
TAG_FCB);
memset (Fcb, 0, sizeof (VFATFCB)); memset (Fcb, 0, sizeof (VFATFCB));
Fcb->ObjectName = &Fcb->PathName[1]; Fcb->ObjectName = &Fcb->PathName[1];
Fcb->PathName[0] = '\\'; Fcb->PathName[0] = '\\';
@ -594,7 +603,7 @@ VfatOpenFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
memset(FileObject->SectionObjectPointers, 0, memset(FileObject->SectionObjectPointers, 0,
sizeof(SECTION_OBJECT_POINTERS)); sizeof(SECTION_OBJECT_POINTERS));
FileObject->FsContext = (PVOID)&ParentFcb->RFCB; FileObject->FsContext = (PVOID)&ParentFcb->RFCB;
newCCB = ExAllocatePool (NonPagedPool, sizeof (VFATCCB)); newCCB = ExAllocatePoolWithTag (NonPagedPool, sizeof (VFATCCB), TAG_CCB);
memset (newCCB, 0, sizeof (VFATCCB)); memset (newCCB, 0, sizeof (VFATCCB));
FileObject->FsContext2 = newCCB; FileObject->FsContext2 = newCCB;
newCCB->pFcb = ParentFcb; newCCB->pFcb = ParentFcb;

View file

@ -1,4 +1,4 @@
/* $Id: proc.c,v 1.38 2001/02/10 22:01:50 ea Exp $ /* $Id: proc.c,v 1.39 2001/03/13 16:25:51 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
@ -35,65 +35,50 @@ WaitForInputIdleType lpfnGlobalRegisterWaitForInputIdle;
LPSTARTUPINFO lpLocalStartupInfo = NULL; LPSTARTUPINFO lpLocalStartupInfo = NULL;
VOID VOID STDCALL
STDCALL RegisterWaitForInputIdle (WaitForInputIdleType lpfnRegisterWaitForInputIdle);
RegisterWaitForInputIdle (
WaitForInputIdleType lpfnRegisterWaitForInputIdle
);
/* FUNCTIONS ****************************************************************/ /* FUNCTIONS ****************************************************************/
WINBOOL WINBOOL STDCALL
STDCALL GetProcessId (HANDLE hProcess, LPDWORD lpProcessId);
GetProcessId (
HANDLE hProcess,
LPDWORD lpProcessId
);
WINBOOL STDCALL
GetProcessTimes (HANDLE hProcess,
LPFILETIME lpCreationTime,
LPFILETIME lpExitTime,
WINBOOL LPFILETIME lpKernelTime,
STDCALL LPFILETIME lpUserTime)
GetProcessTimes (
HANDLE hProcess,
LPFILETIME lpCreationTime,
LPFILETIME lpExitTime,
LPFILETIME lpKernelTime,
LPFILETIME lpUserTime
)
{ {
NTSTATUS Status; NTSTATUS Status;
KERNEL_USER_TIMES Kut; KERNEL_USER_TIMES Kut;
Status = NtQueryInformationProcess ( Status = NtQueryInformationProcess (hProcess,
hProcess, ProcessTimes,
ProcessTimes, &Kut,
& Kut, sizeof(Kut),
sizeof Kut, NULL
NULL );
); if (!NT_SUCCESS(Status))
if (!NT_SUCCESS(Status)) {
{ SetLastErrorByStatus (Status);
SetLastErrorByStatus (Status); return (FALSE);
return (FALSE); }
}
lpCreationTime->dwLowDateTime = Kut.CreateTime.u.LowPart;
lpCreationTime->dwLowDateTime = Kut.CreateTime.u.LowPart; lpCreationTime->dwHighDateTime = Kut.CreateTime.u.HighPart;
lpCreationTime->dwHighDateTime = Kut.CreateTime.u.HighPart;
lpExitTime->dwLowDateTime = Kut.ExitTime.u.LowPart;
lpExitTime->dwHighDateTime = Kut.ExitTime.u.HighPart;
lpExitTime->dwLowDateTime = Kut.ExitTime.u.LowPart; lpKernelTime->dwLowDateTime = Kut.KernelTime.u.LowPart;
lpExitTime->dwHighDateTime = Kut.ExitTime.u.HighPart; lpKernelTime->dwHighDateTime = Kut.KernelTime.u.HighPart;
lpKernelTime->dwLowDateTime = Kut.KernelTime.u.LowPart; lpUserTime->dwLowDateTime = Kut.UserTime.u.LowPart;
lpKernelTime->dwHighDateTime = Kut.KernelTime.u.HighPart; lpUserTime->dwHighDateTime = Kut.UserTime.u.HighPart;
lpUserTime->dwLowDateTime = Kut.UserTime.u.LowPart; return (TRUE);
lpUserTime->dwHighDateTime = Kut.UserTime.u.HighPart;
return (TRUE);
} }

View file

@ -1,4 +1,4 @@
/* $Id: tls.c,v 1.6 2000/11/19 16:01:29 ekohl Exp $ /* $Id: tls.c,v 1.7 2001/03/13 16:25:52 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
@ -24,28 +24,28 @@
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/
DWORD STDCALL TlsAlloc(VOID) DWORD STDCALL
TlsAlloc(VOID)
{ {
ULONG Index; ULONG Index;
RtlAcquirePebLock(); RtlAcquirePebLock();
Index = RtlFindClearBitsAndSet (NtCurrentPeb()->TlsBitmap, Index = RtlFindClearBitsAndSet (NtCurrentPeb()->TlsBitmap, 1, 0);
1,
0);
if (Index == (ULONG)-1) if (Index == (ULONG)-1)
{ {
SetLastErrorByStatus(STATUS_NO_MEMORY); SetLastErrorByStatus(STATUS_NO_MEMORY);
} }
else else
{ {
NtCurrentTeb()->TlsSlots[Index] = 0; NtCurrentTeb()->TlsSlots[Index] = 0;
} }
RtlReleasePebLock(); RtlReleasePebLock();
return Index; return(Index);
} }
WINBOOL STDCALL TlsFree(DWORD dwTlsIndex) WINBOOL STDCALL
TlsFree(DWORD dwTlsIndex)
{ {
if (dwTlsIndex >= TLS_MINIMUM_AVAILABLE) if (dwTlsIndex >= TLS_MINIMUM_AVAILABLE)
{ {
@ -73,7 +73,8 @@ WINBOOL STDCALL TlsFree(DWORD dwTlsIndex)
return(TRUE); return(TRUE);
} }
LPVOID STDCALL TlsGetValue(DWORD dwTlsIndex) LPVOID STDCALL
TlsGetValue(DWORD dwTlsIndex)
{ {
if (dwTlsIndex >= TLS_MINIMUM_AVAILABLE) if (dwTlsIndex >= TLS_MINIMUM_AVAILABLE)
{ {
@ -83,7 +84,8 @@ LPVOID STDCALL TlsGetValue(DWORD dwTlsIndex)
return(NtCurrentTeb()->TlsSlots[dwTlsIndex]); return(NtCurrentTeb()->TlsSlots[dwTlsIndex]);
} }
WINBOOL STDCALL TlsSetValue(DWORD dwTlsIndex, LPVOID lpTlsValue) WINBOOL STDCALL
TlsSetValue(DWORD dwTlsIndex, LPVOID lpTlsValue)
{ {
if (dwTlsIndex >= TLS_MINIMUM_AVAILABLE) if (dwTlsIndex >= TLS_MINIMUM_AVAILABLE)
{ {

View file

@ -239,12 +239,8 @@ RtlInitializeContext(HANDLE ProcessHandle,
} }
NTSTATUS NTSTATUS STDCALL
STDCALL RtlFreeUserThreadStack (HANDLE ProcessHandle, HANDLE ThreadHandle)
RtlFreeUserThreadStack (
HANDLE ProcessHandle,
HANDLE ThreadHandle
)
{ {
THREAD_BASIC_INFORMATION ThreadInfo; THREAD_BASIC_INFORMATION ThreadInfo;
NTSTATUS Status; NTSTATUS Status;

View file

@ -1,6 +1,6 @@
/* /*
* ReactOS kernel * ReactOS kernel
* Copyright (C) 1998, 1999, 2000, 2001 David Welch <welch@cwcom.net> * Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@ -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: view.c,v 1.18 2001/03/09 14:40:27 dwelch Exp $ /* $Id: view.c,v 1.19 2001/03/13 16:25:52 dwelch Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel

View file

@ -1,4 +1,4 @@
/* $Id: registry.c,v 1.54 2001/02/10 22:51:08 dwelch Exp $ /* $Id: registry.c,v 1.55 2001/03/13 16:25:53 dwelch Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -15,6 +15,7 @@
#include <internal/ob.h> #include <internal/ob.h>
#include <limits.h> #include <limits.h>
#include <string.h> #include <string.h>
#include <internal/pool.h>
#define NDEBUG #define NDEBUG
#include <internal/debug.h> #include <internal/debug.h>
@ -301,7 +302,6 @@ static NTSTATUS
CmiAddFree(PREGISTRY_FILE RegistryFile, CmiAddFree(PREGISTRY_FILE RegistryFile,
PFREE_SUB_BLOCK FreeBlock,BLOCK_OFFSET FreeOffset); PFREE_SUB_BLOCK FreeBlock,BLOCK_OFFSET FreeOffset);
/* --------------------------------------------- Public Interface */ /* --------------------------------------------- Public Interface */
VOID VOID

View file

@ -34,12 +34,6 @@ typedef ULONG SWAPENTRY;
#define NR_SECTION_PAGE_TABLES (1024) #define NR_SECTION_PAGE_TABLES (1024)
#define NR_SECTION_PAGE_ENTRIES (1024) #define NR_SECTION_PAGE_ENTRIES (1024)
#define SPE_PAGEIN_PENDING (0x1)
#define SPE_MPW_PENDING (0x2)
#define SPE_PAGEOUT_PENDING (0x4)
#define SPE_DIRTY (0x8)
#define SPE_IN_PAGEFILE (0x10)
/* /*
* Flags for section objects * Flags for section objects
*/ */
@ -398,7 +392,9 @@ typedef struct _MM_PAGEOP
BOOLEAN Abandoned; BOOLEAN Abandoned;
/* The memory area to be affected by the operation. */ /* The memory area to be affected by the operation. */
PMEMORY_AREA MArea; PMEMORY_AREA MArea;
ULONG Hash;
struct _MM_PAGEOP* Next; struct _MM_PAGEOP* Next;
struct _ETHREAD* Thread;
/* /*
* These fields are used to identify the operation if it is against a * These fields are used to identify the operation if it is against a
* virtual memory area. * virtual memory area.
@ -413,6 +409,13 @@ typedef struct _MM_PAGEOP
ULONG Offset; ULONG Offset;
} MM_PAGEOP, *PMM_PAGEOP; } MM_PAGEOP, *PMM_PAGEOP;
VOID
MmReleasePageOp(PMM_PAGEOP PageOp);
PMM_PAGEOP
MmGetPageOp(PMEMORY_AREA MArea, ULONG Pid, PVOID Address,
PMM_SECTION_SEGMENT Segment, ULONG Offset);
VOID VOID
MiDebugDumpNonPagedPool(BOOLEAN NewOnly); MiDebugDumpNonPagedPool(BOOLEAN NewOnly);
VOID VOID
@ -430,4 +433,7 @@ typedef struct _MM_IMAGE_SECTION_OBJECT
MM_SECTION_SEGMENT Segments[0]; MM_SECTION_SEGMENT Segments[0];
} MM_IMAGE_SECTION_OBJECT, *PMM_IMAGE_SECTION_OBJECT; } MM_IMAGE_SECTION_OBJECT, *PMM_IMAGE_SECTION_OBJECT;
VOID
MmFreeVirtualMemory(struct _EPROCESS* Process, PMEMORY_AREA MemoryArea);
#endif #endif

View file

@ -16,11 +16,13 @@
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/
NTSTATUS STDCALL
NtSetLdtEntries(HANDLE Thread, ULONG FirstEntry, PULONG Entries)
NTSTATUS STDCALL NtSetLdtEntries(HANDLE Thread,
ULONG FirstEntry,
PULONG Entries)
{ {
UNIMPLEMENTED; UNIMPLEMENTED;
} }

View file

@ -1,4 +1,4 @@
/* $Id: close.c,v 1.3 2000/12/10 23:42:00 dwelch Exp $ /* $Id: close.c,v 1.4 2001/03/13 16:25:54 dwelch Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -33,42 +33,41 @@
* *
*/ */
VOID VOID
NiClosePort (PVOID ObjectBody, NiClosePort (PVOID ObjectBody, ULONG HandleCount)
ULONG HandleCount)
{ {
PEPORT Port = (PEPORT) ObjectBody; PEPORT Port = (PEPORT)ObjectBody;
LPC_MESSAGE Message; LPC_MESSAGE Message;
// DPRINT1("NiClosePort(ObjectBody %x, HandleCount %d) RefCount %d\n", /*
// ObjectBody, HandleCount, ObGetReferenceCount(Port)); * If the client has just closed its handle then tell the server what
* happened and disconnect this port.
if ((HandleCount == 0) && */
(Port->State == EPORT_CONNECTED_CLIENT) && if (HandleCount == 0 && Port->State == EPORT_CONNECTED_CLIENT &&
(ObGetReferenceCount(Port) == 2)) ObGetReferenceCount(Port) == 2)
{ {
// DPRINT1("All handles closed to client port\n"); Message.MessageSize = sizeof(LPC_MESSAGE);
Message.DataSize = 0;
Message.MessageSize = sizeof(LPC_MESSAGE);
Message.DataSize = 0; EiReplyOrRequestPort (Port->OtherPort,
&Message,
EiReplyOrRequestPort (Port->OtherPort, LPC_PORT_CLOSED,
&Message, Port);
LPC_PORT_CLOSED, KeSetEvent (&Port->OtherPort->Event,
Port); IO_NO_INCREMENT,
KeSetEvent (&Port->OtherPort->Event, FALSE);
IO_NO_INCREMENT,
FALSE); Port->OtherPort->OtherPort = NULL;
Port->OtherPort->State = EPORT_DISCONNECTED;
ObDereferenceObject (Port);
}
Port->OtherPort->OtherPort = NULL; /*
Port->OtherPort->State = EPORT_DISCONNECTED; * If the server has closed all of its handles then disconnect the port,
ObDereferenceObject (Port); * don't actually notify the client until it attempts an operation.
} */
if ((HandleCount == 0) && if (HandleCount == 0 && Port->State == EPORT_CONNECTED_SERVER &&
(Port->State == EPORT_CONNECTED_SERVER) && ObGetReferenceCount(Port) == 2)
(ObGetReferenceCount(Port) == 2)) {
{
// DPRINT("All handles closed to server\n");
Port->OtherPort->OtherPort = NULL; Port->OtherPort->OtherPort = NULL;
Port->OtherPort->State = EPORT_DISCONNECTED; Port->OtherPort->State = EPORT_DISCONNECTED;
ObDereferenceObject(Port->OtherPort); ObDereferenceObject(Port->OtherPort);

View file

@ -32,7 +32,6 @@ typedef struct _PHYSICAL_PAGE
ULONG Flags; ULONG Flags;
LIST_ENTRY ListEntry; LIST_ENTRY ListEntry;
ULONG ReferenceCount; ULONG ReferenceCount;
KEVENT Event;
SWAPENTRY SavedSwapEntry; SWAPENTRY SavedSwapEntry;
ULONG LockCount; ULONG LockCount;
ULONG MapCount; ULONG MapCount;
@ -187,9 +186,6 @@ PVOID MmInitializePageList(PVOID FirstPhysKernelAddress,
{ {
MmPageArray[i].Flags = MM_PHYSICAL_PAGE_FREE; MmPageArray[i].Flags = MM_PHYSICAL_PAGE_FREE;
MmPageArray[i].ReferenceCount = 0; MmPageArray[i].ReferenceCount = 0;
KeInitializeEvent(&MmPageArray[i].Event,
NotificationEvent,
FALSE);
InsertTailList(&FreePageListHead, InsertTailList(&FreePageListHead,
&MmPageArray[i].ListEntry); &MmPageArray[i].ListEntry);
} }
@ -199,9 +195,6 @@ PVOID MmInitializePageList(PVOID FirstPhysKernelAddress,
{ {
MmPageArray[i].Flags = MM_PHYSICAL_PAGE_USED; MmPageArray[i].Flags = MM_PHYSICAL_PAGE_USED;
MmPageArray[i].ReferenceCount = 1; MmPageArray[i].ReferenceCount = 1;
KeInitializeEvent(&MmPageArray[i].Event,
NotificationEvent,
FALSE);
InsertTailList(&UsedPageListHead, InsertTailList(&UsedPageListHead,
&MmPageArray[i].ListEntry); &MmPageArray[i].ListEntry);
} }
@ -210,9 +203,6 @@ PVOID MmInitializePageList(PVOID FirstPhysKernelAddress,
{ {
MmPageArray[i].Flags = MM_PHYSICAL_PAGE_FREE; MmPageArray[i].Flags = MM_PHYSICAL_PAGE_FREE;
MmPageArray[i].ReferenceCount = 0; MmPageArray[i].ReferenceCount = 0;
KeInitializeEvent(&MmPageArray[i].Event,
NotificationEvent,
FALSE);
InsertTailList(&FreePageListHead, InsertTailList(&FreePageListHead,
&MmPageArray[i].ListEntry); &MmPageArray[i].ListEntry);
} }
@ -221,9 +211,6 @@ PVOID MmInitializePageList(PVOID FirstPhysKernelAddress,
{ {
MmPageArray[i].Flags = MM_PHYSICAL_PAGE_BIOS; MmPageArray[i].Flags = MM_PHYSICAL_PAGE_BIOS;
MmPageArray[i].ReferenceCount = 1; MmPageArray[i].ReferenceCount = 1;
KeInitializeEvent(&MmPageArray[i].Event,
NotificationEvent,
FALSE);
InsertTailList(&BiosPageListHead, InsertTailList(&BiosPageListHead,
&MmPageArray[i].ListEntry); &MmPageArray[i].ListEntry);
} }
@ -235,9 +222,6 @@ PVOID MmInitializePageList(PVOID FirstPhysKernelAddress,
{ {
MmPageArray[i].Flags = MM_PHYSICAL_PAGE_FREE; MmPageArray[i].Flags = MM_PHYSICAL_PAGE_FREE;
MmPageArray[i].ReferenceCount = 0; MmPageArray[i].ReferenceCount = 0;
KeInitializeEvent(&MmPageArray[i].Event,
NotificationEvent,
FALSE);
InsertTailList(&FreePageListHead, InsertTailList(&FreePageListHead,
&MmPageArray[i].ListEntry); &MmPageArray[i].ListEntry);
} }
@ -246,9 +230,6 @@ PVOID MmInitializePageList(PVOID FirstPhysKernelAddress,
{ {
MmPageArray[i].Flags = MM_PHYSICAL_PAGE_BIOS; MmPageArray[i].Flags = MM_PHYSICAL_PAGE_BIOS;
MmPageArray[i].ReferenceCount = 1; MmPageArray[i].ReferenceCount = 1;
KeInitializeEvent(&MmPageArray[i].Event,
NotificationEvent,
FALSE);
InsertTailList(&BiosPageListHead, InsertTailList(&BiosPageListHead,
&MmPageArray[i].ListEntry); &MmPageArray[i].ListEntry);
} }
@ -257,9 +238,6 @@ PVOID MmInitializePageList(PVOID FirstPhysKernelAddress,
{ {
MmPageArray[i].Flags = MM_PHYSICAL_PAGE_FREE; MmPageArray[i].Flags = MM_PHYSICAL_PAGE_FREE;
MmPageArray[i].ReferenceCount = 0; MmPageArray[i].ReferenceCount = 0;
KeInitializeEvent(&MmPageArray[i].Event,
NotificationEvent,
FALSE);
InsertTailList(&FreePageListHead, InsertTailList(&FreePageListHead,
&MmPageArray[i].ListEntry); &MmPageArray[i].ListEntry);
} }
@ -269,9 +247,6 @@ PVOID MmInitializePageList(PVOID FirstPhysKernelAddress,
{ {
MmPageArray[i].Flags = MM_PHYSICAL_PAGE_USED; MmPageArray[i].Flags = MM_PHYSICAL_PAGE_USED;
MmPageArray[i].ReferenceCount = 1; MmPageArray[i].ReferenceCount = 1;
KeInitializeEvent(&MmPageArray[i].Event,
NotificationEvent,
FALSE);
InsertTailList(&UsedPageListHead, InsertTailList(&UsedPageListHead,
&MmPageArray[i].ListEntry); &MmPageArray[i].ListEntry);
} }
@ -282,9 +257,6 @@ PVOID MmInitializePageList(PVOID FirstPhysKernelAddress,
{ {
MmPageArray[i].Flags = MM_PHYSICAL_PAGE_FREE; MmPageArray[i].Flags = MM_PHYSICAL_PAGE_FREE;
MmPageArray[i].ReferenceCount = 0; MmPageArray[i].ReferenceCount = 0;
KeInitializeEvent(&MmPageArray[i].Event,
NotificationEvent,
FALSE);
InsertTailList(&FreePageListHead, InsertTailList(&FreePageListHead,
&MmPageArray[i].ListEntry); &MmPageArray[i].ListEntry);
} }
@ -638,39 +610,3 @@ MmAllocPageMaybeSwap(SWAPENTRY SavedSwapEntry)
return(Page); return(Page);
} }
NTSTATUS
MmWaitForPage(PVOID PhysicalAddress)
{
NTSTATUS Status;
ULONG Start;
Start = (ULONG)PhysicalAddress / PAGESIZE;
Status = KeWaitForSingleObject(&MmPageArray[Start].Event,
UserRequest,
KernelMode,
FALSE,
NULL);
return(Status);
}
VOID
MmClearWaitPage(PVOID PhysicalAddress)
{
ULONG Start;
Start = (ULONG)PhysicalAddress / PAGESIZE;
KeClearEvent(&MmPageArray[Start].Event);
}
VOID
MmSetWaitPage(PVOID PhysicalAddress)
{
ULONG Start;
Start = (ULONG)PhysicalAddress / PAGESIZE;
KeSetEvent(&MmPageArray[Start].Event,
IO_DISK_INCREMENT,
FALSE);
}

View file

@ -1,4 +1,4 @@
/* $Id: mdl.c,v 1.29 2001/02/14 02:53:53 dwelch Exp $ /* $Id: mdl.c,v 1.30 2001/03/13 16:25:54 dwelch Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -15,13 +15,19 @@
#include <internal/mm.h> #include <internal/mm.h>
#include <internal/mmhal.h> #include <internal/mmhal.h>
#include <internal/ps.h> #include <internal/ps.h>
#include <internal/pool.h>
#define NDEBUG #define NDEBUG
#include <internal/debug.h> #include <internal/debug.h>
/* FUNCTIONS ***************************************************************/ /* GLOBALS *******************************************************************/
PVOID MmGetMdlPageAddress(PMDL Mdl, PVOID Offset) #define TAG_MDL TAG('M', 'M', 'D', 'L')
/* FUNCTIONS *****************************************************************/
PVOID
MmGetMdlPageAddress(PMDL Mdl, PVOID Offset)
{ {
PULONG MdlPages; PULONG MdlPages;
@ -318,7 +324,8 @@ PMDL STDCALL MmCreateMdl (PMDL MemoryDescriptorList,
ULONG Size; ULONG Size;
Size = MmSizeOfMdl(Base,Length); Size = MmSizeOfMdl(Base,Length);
MemoryDescriptorList = (PMDL)ExAllocatePool(NonPagedPool,Size); MemoryDescriptorList =
(PMDL)ExAllocatePoolWithTag(NonPagedPool, Size, TAG_MDL);
if (MemoryDescriptorList == NULL) if (MemoryDescriptorList == NULL)
{ {
return(NULL); return(NULL);

View file

@ -1,4 +1,22 @@
/* $Id: mm.c,v 1.44 2001/03/08 22:06:01 dwelch 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: mm.c,v 1.45 2001/03/13 16:25:54 dwelch Exp $
* *
* COPYRIGHT: See COPYING in the top directory * COPYRIGHT: See COPYING in the top directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -32,20 +50,6 @@ extern PVOID MmSharedDataPagePhysicalAddress;
/* FUNCTIONS ****************************************************************/ /* FUNCTIONS ****************************************************************/
VOID STATIC
MmFreeVirtualMemoryPage(PVOID Context, PVOID Address, ULONG PhysicalAddr)
{
PEPROCESS Process = (PEPROCESS)Context;
if (PhysicalAddr != 0)
{
DPRINT("Freeing page at 0x%x (pa 0x%x)\n",
Address, PhysicalAddr);
MmRemovePageFromWorkingSet(Process, Address);
MmDereferencePage((PVOID)PhysicalAddr);
}
}
NTSTATUS MmReleaseMemoryArea(PEPROCESS Process, PMEMORY_AREA Marea) NTSTATUS MmReleaseMemoryArea(PEPROCESS Process, PMEMORY_AREA Marea)
{ {
NTSTATUS Status; NTSTATUS Status;
@ -64,13 +68,8 @@ NTSTATUS MmReleaseMemoryArea(PEPROCESS Process, PMEMORY_AREA Marea)
assert(Status == STATUS_SUCCESS); assert(Status == STATUS_SUCCESS);
return(STATUS_SUCCESS); return(STATUS_SUCCESS);
case MEMORY_AREA_VIRTUAL_MEMORY: case MEMORY_AREA_VIRTUAL_MEMORY:
Status = MmFreeMemoryArea(&Process->AddressSpace, MmFreeVirtualMemory(Process, Marea);
Marea->BaseAddress,
0,
MmFreeVirtualMemoryPage,
(PVOID)Process);
assert(Status == STATUS_SUCCESS);
break; break;
case MEMORY_AREA_SHARED_DATA: case MEMORY_AREA_SHARED_DATA:

View file

@ -1,4 +1,4 @@
/* $Id: pageop.c,v 1.2 2001/03/07 16:48:44 dwelch Exp $ /* $Id: pageop.c,v 1.3 2001/03/13 16:25:54 dwelch Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -14,6 +14,7 @@
#include <internal/ps.h> #include <internal/ps.h>
#include <internal/mm.h> #include <internal/mm.h>
#include <internal/mmhal.h> #include <internal/mmhal.h>
#include <internal/pool.h>
#define NDEBUG #define NDEBUG
#include <internal/debug.h> #include <internal/debug.h>
@ -31,10 +32,12 @@ PMM_PAGEOP MmPageOpHashTable[PAGEOP_HASH_TABLE_SIZE];
VOID VOID
MmReleasePageOp(PMM_PAGEOP PageOp) MmReleasePageOp(PMM_PAGEOP PageOp)
/*
* FUNCTION: Release a reference to a page operation descriptor
*/
{ {
ULONG h;
KIRQL oldIrql; KIRQL oldIrql;
PMM_PAGEOP PPageOp; PMM_PAGEOP PrevPageOp;
PageOp->ReferenceCount--; PageOp->ReferenceCount--;
if (PageOp->ReferenceCount > 0) if (PageOp->ReferenceCount > 0)
@ -42,38 +45,26 @@ MmReleasePageOp(PMM_PAGEOP PageOp)
return; return;
} }
/*
* Calcuate the hash value for pageop structure
*/
if (MArea->Type == MEMORY_AREA_SECTION_VIEW_COMMIT)
{
h = (((ULONG)Segment) | Offset) % PAGEOP_HASH_TABLE_SIZE;
}
else
{
h = (((ULONG)Pid) | (ULONG)Address) % PAGEOP_HASH_TABLE_SIZE;
}
KeAcquireSpinLock(&MmPageOpHashTableLock, &oldIrql); KeAcquireSpinLock(&MmPageOpHashTableLock, &oldIrql);
PPageOp = MmPageOpHashTable[h]; PrevPageOp = MmPageOpHashTable[PageOp->Hash];
if (PPageOp == PageOp) if (PrevPageOp == PageOp)
{ {
MmPageOpHashTable[h] = PageOp->Next; MmPageOpHashTable[PageOp->Hash] = PageOp->Next;
KeReleaseSpinLock(&MmPageOpHashTableLock, oldIrql); KeReleaseSpinLock(&MmPageOpHashTableLock, oldIrql);
ExFreePool(PageOp); ExFreePool(PageOp);
return; return;
} }
PPageOp = PPageOp->Next; PrevPageOp = PrevPageOp->Next;
while (PPageOp != NULL) while (PrevPageOp != NULL)
{ {
if (PPageOp == PageOp) if (PrevPageOp == PageOp)
{ {
PPageOp->Next = PageOp->Next; PrevPageOp->Next = PageOp->Next;
KeReleaseSpinLock(&MmPageOpHashTableLock, oldIrql); KeReleaseSpinLock(&MmPageOpHashTableLock, oldIrql);
ExFreePool(PageOp); ExFreePool(PageOp);
return; return;
} }
PPageOp = PPageOp->Next; PrevPageOp = PrevPageOp->Next;
} }
KeReleaseSpinLock(&MmPageOpHashTableLock, oldIrql); KeReleaseSpinLock(&MmPageOpHashTableLock, oldIrql);
KeBugCheck(0); KeBugCheck(0);
@ -82,8 +73,13 @@ 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)
/*
* FUNCTION: Get a page operation descriptor corresponding to
* the memory area and either the segment, offset pair or the
* pid, address pair.
*/
{ {
ULONG h; ULONG Hash;
KIRQL oldIrql; KIRQL oldIrql;
PMM_PAGEOP PageOp; PMM_PAGEOP PageOp;
@ -92,19 +88,20 @@ MmGetPageOp(PMEMORY_AREA MArea, ULONG Pid, PVOID Address,
*/ */
if (MArea->Type == MEMORY_AREA_SECTION_VIEW_COMMIT) if (MArea->Type == MEMORY_AREA_SECTION_VIEW_COMMIT)
{ {
h = (((ULONG)Segment) | Offset) % PAGEOP_HASH_TABLE_SIZE; Hash = (((ULONG)Segment) | (((ULONG)Offset) / PAGESIZE));
} }
else else
{ {
h = (((ULONG)Pid) | (ULONG)Address) % PAGEOP_HASH_TABLE_SIZE; Hash = (((ULONG)Pid) | (((ULONG)Address) / PAGESIZE));
} }
Hash = Hash % PAGEOP_HASH_TABLE_SIZE;
KeAcquireSpinLock(&MmPageOpHashTableLock, &oldIrql); KeAcquireSpinLock(&MmPageOpHashTableLock, &oldIrql);
/* /*
* Check for an existing pageop structure * Check for an existing pageop structure
*/ */
PageOp = MmPageOpHashTable[h]; PageOp = MmPageOpHashTable[Hash];
while (PageOp != NULL) while (PageOp != NULL)
{ {
if (MArea->Type == MEMORY_AREA_SECTION_VIEW_COMMIT) if (MArea->Type == MEMORY_AREA_SECTION_VIEW_COMMIT)
@ -140,7 +137,7 @@ MmGetPageOp(PMEMORY_AREA MArea, ULONG Pid, PVOID Address,
/* /*
* Otherwise add a new pageop. * Otherwise add a new pageop.
*/ */
PageOp = ExAllocatePoolWithTag(NonPagedPool, sizeof(MM_PAGEOP), PageOp = ExAllocatePoolWithTag(NonPagedPool, sizeof(MM_PAGEOP),
TAG_MM_PAGEOP); TAG_MM_PAGEOP);
if (PageOp == NULL) if (PageOp == NULL)
{ {
@ -148,7 +145,7 @@ MmGetPageOp(PMEMORY_AREA MArea, ULONG Pid, PVOID Address,
return(NULL); return(NULL);
} }
if (MArea->Type == MEMORY_AREA_SECTION_VIEW_COMMIT) if (MArea->Type != MEMORY_AREA_SECTION_VIEW_COMMIT)
{ {
PageOp->Pid = Pid; PageOp->Pid = Pid;
PageOp->Address = Address; PageOp->Address = Address;
@ -159,9 +156,22 @@ MmGetPageOp(PMEMORY_AREA MArea, ULONG Pid, PVOID Address,
PageOp->Offset = Offset; PageOp->Offset = Offset;
} }
PageOp->ReferenceCount = 1; PageOp->ReferenceCount = 1;
PageOp->Next = MmPageOpHashTable[h]; PageOp->Next = MmPageOpHashTable[Hash];
MmPageOpHashTable[h] = PageOp; PageOp->Hash = Hash;
PageOp->Thread = PsGetCurrentThread();
PageOp->Abandoned = FALSE;
PageOp->Status = STATUS_PENDING;
KeInitializeEvent(&PageOp->CompletionEvent, NotificationEvent, FALSE);
MmPageOpHashTable[Hash] = PageOp;
KeReleaseSpinLock(&MmPageOpHashTableLock, oldIrql); KeReleaseSpinLock(&MmPageOpHashTableLock, oldIrql);
return(PageOp); return(PageOp);
} }

View file

@ -1,4 +1,4 @@
/* $Id: section.c,v 1.50 2001/03/09 14:40:28 dwelch Exp $ /* $Id: section.c,v 1.51 2001/03/13 16:25:54 dwelch Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -184,123 +184,6 @@ MmGetPageEntrySectionSegment(PMM_SECTION_SEGMENT Segment,
return(Entry); return(Entry);
} }
NTSTATUS
MmWaitForPendingOperationSection(PMADDRESS_SPACE AddressSpace,
PMEMORY_AREA MemoryArea,
PVOID Address,
PSECTION_OBJECT Section,
PMM_SECTION_SEGMENT Segment,
LARGE_INTEGER Offset,
ULONG Entry,
ULONG Attributes,
BOOLEAN Locked)
{
PVOID Page;
NTSTATUS Status;
/*
* If a page-in on that section offset is pending that wait for
* it to finish.
*/
do
{
/*
* Release all our locks and wait for the pending operation
* to complete
*/
MmUnlockSectionSegment(Segment);
MmUnlockSection(Section);
MmUnlockAddressSpace(AddressSpace);
/*
* FIXME: What if the event is set and cleared after we
* unlock the section but before we wait.
*/
Status = MmWaitForPage((PVOID)(Entry & (~SPE_PAGEIN_PENDING)));
if (!NT_SUCCESS(Status))
{
/*
* FIXME: What do we do in this case? Maybe the thread
* has terminated.
*/
DbgPrint("Failed to wait for page\n");
KeBugCheck(0);
return(STATUS_UNSUCCESSFUL);
}
/*
* Relock the address space, section and segment
*/
MmLockAddressSpace(AddressSpace);
MmLockSection(Section);
MmLockSectionSegment(Segment);
/*
* Get the entry for the section offset. If the entry is still
* pending that means another thread is already trying the
* page-in again so we have to wait again.
*/
Entry = MmGetPageEntrySectionSegment(Segment, Offset.u.LowPart);
} while (Entry & SPE_PAGEIN_PENDING);
/*
* Setting the entry to null means the read failing.
* FIXME: We should retry it (unless that filesystem has gone
* entirely e.g. the network died).
*/
if (Entry == 0)
{
DbgPrint("Entry set to null while we slept\n");
KeBugCheck(0);
}
/*
* Maybe the thread did the page-in took the fault on the
* same address-space/address as we did. If so we can just
* return success.
*/
if (MmIsPagePresent(NULL, Address))
{
if (Locked)
{
MmLockPage((PVOID)MmGetPhysicalAddressForProcess(NULL, Address));
}
MmUnlockSectionSegment(Segment);
MmUnlockSection(Section);
return(STATUS_SUCCESS);
}
/*
* Get a reference to the page containing the data for the page.
*/
Page = (PVOID)Entry;
MmReferencePage(Page);
/*
* When we reach here, we have the address space, section and segment locked
* and have a reference to a page containing valid data for the
* section offset. Set the page and return success.
*/
Status = MmCreateVirtualMapping(PsGetCurrentProcess(),
Address,
Attributes,
(ULONG)Page);
if (!NT_SUCCESS(Status))
{
DbgPrint("Unable to create virtual mapping\n");
KeBugCheck(0);
}
if (Locked)
{
MmLockPage((PVOID)MmGetPhysicalAddressForProcess(NULL, Address));
}
MmUnlockSectionSegment(Segment);
MmUnlockSection(Section);
return(STATUS_SUCCESS);
}
NTSTATUS NTSTATUS
MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace, MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
MEMORY_AREA* MemoryArea, MEMORY_AREA* MemoryArea,
@ -318,10 +201,7 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
ULONG Entry; ULONG Entry;
ULONG Entry1; ULONG Entry1;
ULONG Attributes; ULONG Attributes;
PMM_PAGEOP PageOp;
DPRINT("MmSectionHandleFault(MemoryArea %x, Address %x)\n",
MemoryArea,Address);
/* /*
* There is a window between taking the page fault and locking the * There is a window between taking the page fault and locking the
@ -330,7 +210,6 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
*/ */
if (MmIsPagePresent(NULL, Address)) if (MmIsPagePresent(NULL, Address))
{ {
DbgPrint("Page is already present\n");
if (Locked) if (Locked)
{ {
MmLockPage((PVOID)MmGetPhysicalAddressForProcess(NULL, Address)); MmLockPage((PVOID)MmGetPhysicalAddressForProcess(NULL, Address));
@ -350,6 +229,84 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
MmLockSection(Section); MmLockSection(Section);
MmLockSectionSegment(Segment); MmLockSectionSegment(Segment);
/*
* Get or create a page operation descriptor
*/
PageOp = MmGetPageOp(MemoryArea, 0, 0, Segment, Offset.u.LowPart);
if (PageOp == NULL)
{
DPRINT1("MmGetPageOp failed\n");
KeBugCheck(0);
}
/*
* Check if someone else is already handling this fault, if so wait
* for them
*/
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);
}
/*
* If the thread handling this fault has failed then we don't retry
*/
if (!NT_SUCCESS(PageOp->Status))
{
return(Status);
}
MmLockAddressSpace(AddressSpace);
MmLockSection(Section);
MmLockSectionSegment(Segment);
/*
* If the completed fault was for another address space then set the
* page in this one.
*/
if (!MmIsPagePresent(NULL, Address))
{
Entry = MmGetPageEntrySectionSegment(Segment, Offset.u.LowPart);
Page = (PVOID)(Entry & 0xFFFFF000);
MmReferencePage(Page);
Status = MmCreateVirtualMapping(PsGetCurrentProcess(),
Address,
Attributes,
(ULONG)Page);
if (!NT_SUCCESS(Status))
{
DbgPrint("Unable to create virtual mapping\n");
KeBugCheck(0);
}
}
if (Locked)
{
MmLockPage((PVOID)MmGetPhysicalAddressForProcess(NULL, Address));
}
MmUnlockSectionSegment(Segment);
MmUnlockSection(Section);
MmReleasePageOp(PageOp);
return(STATUS_SUCCESS);
}
/* /*
* Satisfying a page fault on a map of /Device/PhysicalMemory is easy * Satisfying a page fault on a map of /Device/PhysicalMemory is easy
*/ */
@ -366,6 +323,13 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
{ {
MmLockPage((PVOID)MmGetPhysicalAddressForProcess(NULL, Address)); MmLockPage((PVOID)MmGetPhysicalAddressForProcess(NULL, Address));
} }
/*
* Cleanup and release locks
*/
PageOp->Status = STATUS_SUCCESS;
KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
MmReleasePageOp(PageOp);
MmUnlockSectionSegment(Segment); MmUnlockSectionSegment(Segment);
MmUnlockSection(Section); MmUnlockSection(Section);
return(STATUS_SUCCESS); return(STATUS_SUCCESS);
@ -384,11 +348,6 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
MmUnlockAddressSpace(AddressSpace); MmUnlockAddressSpace(AddressSpace);
MmWaitForFreePages(); MmWaitForFreePages();
MmLockAddressSpace(AddressSpace); MmLockAddressSpace(AddressSpace);
if (MmIsPagePresent(NULL, Address))
{
MmUnlockAddressSpace(AddressSpace);
return(STATUS_SUCCESS);
}
MmLockSection(Section); MmLockSection(Section);
MmLockSectionSegment(Segment); MmLockSectionSegment(Segment);
Page = MmAllocPage(0); Page = MmAllocPage(0);
@ -401,10 +360,21 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
{ {
MmLockPage((PVOID)MmGetPhysicalAddressForProcess(NULL, Address)); MmLockPage((PVOID)MmGetPhysicalAddressForProcess(NULL, Address));
} }
/*
* Cleanup and release locks
*/
PageOp->Status = STATUS_SUCCESS;
KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
MmReleasePageOp(PageOp);
MmUnlockSectionSegment(Segment); MmUnlockSectionSegment(Segment);
MmUnlockSection(Section); MmUnlockSection(Section);
return(STATUS_SUCCESS); return(STATUS_SUCCESS);
} }
/*
* Check if this page needs to be mapped COW
*/
if (Segment->Characteristics & IMAGE_SECTION_CHAR_DATA) if (Segment->Characteristics & IMAGE_SECTION_CHAR_DATA)
{ {
Attributes = PAGE_READONLY; Attributes = PAGE_READONLY;
@ -419,8 +389,6 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
*/ */
Entry = MmGetPageEntrySectionSegment(Segment, Offset.u.LowPart); Entry = MmGetPageEntrySectionSegment(Segment, Offset.u.LowPart);
DPRINT("Entry %x\n", Entry);
if (Entry == 0) if (Entry == 0)
{ {
/* /*
@ -440,55 +408,8 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
MmUnlockAddressSpace(AddressSpace); MmUnlockAddressSpace(AddressSpace);
MmWaitForFreePages(); MmWaitForFreePages();
MmLockAddressSpace(AddressSpace); MmLockAddressSpace(AddressSpace);
if (MmIsPagePresent(NULL, Address))
{
MmUnlockAddressSpace(AddressSpace);
return(STATUS_SUCCESS);
}
MmLockSection(Section); MmLockSection(Section);
MmLockSectionSegment(Segment); MmLockSectionSegment(Segment);
/*
* Check if page fault handling has already been started on
* this offset by another thread
*/
Entry1 = MmGetPageEntrySectionSegment(Segment, Offset.u.LowPart);
if (Entry1 & SPE_PAGEIN_PENDING)
{
return(MmWaitForPendingOperationSection(AddressSpace,
MemoryArea,
Address,
Section,
Segment,
Offset,
Entry1,
Attributes,
Locked));
}
else if (Entry1 != 0)
{
Page = (PVOID)Entry;
MmReferencePage(Page);
Status = MmCreateVirtualMapping(PsGetCurrentProcess(),
Address,
Attributes,
(ULONG)Page);
if (!NT_SUCCESS(Status))
{
DbgPrint("Unable to create virtual mapping\n");
KeBugCheck(0);
}
if (Locked)
{
MmLockPage((PVOID)MmGetPhysicalAddressForProcess(NULL,
Address));
}
MmUnlockSectionSegment(Segment);
MmUnlockSection(Section);
return(STATUS_SUCCESS);
}
Page = MmAllocPage(0); Page = MmAllocPage(0);
} }
@ -498,26 +419,12 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
Mdl = MmCreateMdl(NULL, NULL, PAGESIZE); Mdl = MmCreateMdl(NULL, NULL, PAGESIZE);
MmBuildMdlFromPages(Mdl, (PULONG)&Page); MmBuildMdlFromPages(Mdl, (PULONG)&Page);
/*
* Clear the wait state (Since we are holding the only reference to
* page this is safe)
*/
MmClearWaitPage(Page);
/*
* Notify any other threads that fault on the same section offset
* that a page-in is pending.
*/
Entry = ((ULONG)Page) | SPE_PAGEIN_PENDING;
MmSetPageEntrySectionSegment(Segment, Offset.u.LowPart, Entry);
/* /*
* Release all our locks and read in the page from disk * Release all our locks and read in the page from disk
*/ */
MmUnlockSectionSegment(Segment); MmUnlockSectionSegment(Segment);
MmUnlockSection(Section); MmUnlockSection(Section);
MmUnlockAddressSpace(AddressSpace); MmUnlockAddressSpace(AddressSpace);
DPRINT("Reading file offset %x\n", Offset.QuadPart);
Status = IoPageRead(MemoryArea->Data.SectionData.Section->FileObject, Status = IoPageRead(MemoryArea->Data.SectionData.Section->FileObject,
Mdl, Mdl,
&Offset, &Offset,
@ -529,6 +436,13 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
* FIXME: What do we know in this case? * FIXME: What do we know in this case?
*/ */
DPRINT("IoPageRead failed (Status %x)\n", Status); DPRINT("IoPageRead failed (Status %x)\n", Status);
/*
* Cleanup and release locks
*/
PageOp->Status = Status;
KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
MmReleasePageOp(PageOp);
MmLockAddressSpace(AddressSpace); MmLockAddressSpace(AddressSpace);
return(Status); return(Status);
} }
@ -558,12 +472,6 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
Entry = (ULONG)Page; Entry = (ULONG)Page;
MmSetPageEntrySectionSegment(Segment, Offset.QuadPart, Entry); MmSetPageEntrySectionSegment(Segment, Offset.QuadPart, Entry);
/*
* Set the event associated with the page so other threads that
* may be waiting know that valid data is now in-memory.
*/
MmSetWaitPage(Page);
Status = MmCreateVirtualMapping(PsGetCurrentProcess(), Status = MmCreateVirtualMapping(PsGetCurrentProcess(),
Address, Address,
Attributes, Attributes,
@ -577,23 +485,13 @@ MmNotPresentFaultSectionView(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);
DPRINT("MmNotPresentFaultSectionView succeeded\n"); MmReleasePageOp(PageOp);
return(STATUS_SUCCESS); MmUnlockSectionSegment(Segment);
MmUnlockSection(Section);
} DPRINT("MmNotPresentFaultSectionView succeeded\n");
else if (Entry & SPE_PAGEIN_PENDING) return(STATUS_SUCCESS);
{
return(MmWaitForPendingOperationSection(AddressSpace,
MemoryArea,
Address,
Section,
Segment,
Offset,
Entry,
Attributes,
Locked));
} }
else else
{ {
@ -618,10 +516,12 @@ MmNotPresentFaultSectionView(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); MmUnlockSectionSegment(Segment);
MmUnlockSection(Section);
return(STATUS_SUCCESS);
} }
} }

View file

@ -1,4 +1,4 @@
/* $Id: virtual.c,v 1.41 2001/03/08 22:06:02 dwelch Exp $ /* $Id: virtual.c,v 1.42 2001/03/13 16:25:54 dwelch Exp $
* *
* COPYRIGHT: See COPYING in the top directory * COPYRIGHT: See COPYING in the top directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -222,7 +222,22 @@ MmNotPresentFaultVirtualMemory(PMADDRESS_SPACE AddressSpace,
NTSTATUS Status; NTSTATUS Status;
PMM_SEGMENT Segment; PMM_SEGMENT Segment;
PVOID CurrentAddress; PVOID CurrentAddress;
PMM_PAGEOP PageOp;
/*
* There is a window between taking the page fault and locking the
* address space when another thread could load the page so we check
* that.
*/
if (MmIsPagePresent(NULL, Address))
{
if (Locked)
{
MmLockPage((PVOID)MmGetPhysicalAddressForProcess(NULL, Address));
}
return(STATUS_SUCCESS);
}
/* /*
* Get the segment corresponding to the virtual address * Get the segment corresponding to the virtual address
*/ */
@ -235,13 +250,56 @@ MmNotPresentFaultVirtualMemory(PMADDRESS_SPACE AddressSpace,
{ {
return(STATUS_UNSUCCESSFUL); return(STATUS_UNSUCCESSFUL);
} }
if (MmIsPagePresent(NULL, Address)) /*
{ * Get or create a page operation
*/
PageOp = MmGetPageOp(MemoryArea, (ULONG)PsGetCurrentProcessId(),
(PVOID)PAGE_ROUND_DOWN(Address), NULL, 0);
if (PageOp == NULL)
{
DPRINT1("MmGetPageOp failed");
KeBugCheck(0);
}
/*
* Check if someone else is already handling this fault, if so wait
* for them
*/
if (PageOp->Thread != PsGetCurrentThread())
{
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);
}
/*
* If the thread handling this fault has failed then we don't retry
*/
if (!NT_SUCCESS(PageOp->Status))
{
return(Status);
}
MmLockAddressSpace(AddressSpace);
if (Locked) if (Locked)
{ {
MmLockPage((PVOID)MmGetPhysicalAddressForProcess(NULL, Address)); MmLockPage((PVOID)MmGetPhysicalAddressForProcess(NULL, Address));
} }
MmReleasePageOp(PageOp);
return(STATUS_SUCCESS); return(STATUS_SUCCESS);
} }
@ -254,18 +312,9 @@ MmNotPresentFaultVirtualMemory(PMADDRESS_SPACE AddressSpace,
MmUnlockAddressSpace(AddressSpace); MmUnlockAddressSpace(AddressSpace);
MmWaitForFreePages(); MmWaitForFreePages();
MmLockAddressSpace(AddressSpace); MmLockAddressSpace(AddressSpace);
if (MmIsPagePresent(NULL, Address))
{
if (Locked)
{
MmLockPage((PVOID)MmGetPhysicalAddressForProcess(NULL,
Address));
}
return(STATUS_SUCCESS);
}
Page = MmAllocPage(0); Page = MmAllocPage(0);
} }
/* /*
* Add the page to the process's working set * Add the page to the process's working set
*/ */
@ -285,16 +334,6 @@ MmNotPresentFaultVirtualMemory(PMADDRESS_SPACE AddressSpace,
MmUnlockAddressSpace(AddressSpace); MmUnlockAddressSpace(AddressSpace);
MmWaitForFreePages(); MmWaitForFreePages();
MmLockAddressSpace(AddressSpace); MmLockAddressSpace(AddressSpace);
if (MmIsPagePresent(NULL, Address))
{
if (Locked)
{
MmLockPage((PVOID)MmGetPhysicalAddressForProcess(NULL,
Address));
}
MmDereferencePage(Page);
return(STATUS_SUCCESS);
}
Status = MmCreateVirtualMapping(PsGetCurrentProcess(), Status = MmCreateVirtualMapping(PsGetCurrentProcess(),
Address, Address,
MemoryArea->Attributes, MemoryArea->Attributes,
@ -302,16 +341,22 @@ MmNotPresentFaultVirtualMemory(PMADDRESS_SPACE AddressSpace,
} }
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
return(Status); DPRINT1("MmCreateVirtualMapping failed, not out of memory\n");
KeBugCheck(0);
return(Status);
} }
else
/*
* Finish the operation
*/
if (Locked)
{ {
if (Locked) MmLockPage((PVOID)MmGetPhysicalAddressForProcess(NULL, Address));
{ }
MmLockPage((PVOID)MmGetPhysicalAddressForProcess(NULL, Address)); PageOp->Status = STATUS_SUCCESS;
} KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
return(STATUS_SUCCESS); MmReleasePageOp(PageOp);
} return(STATUS_SUCCESS);
} }
VOID STATIC VOID STATIC
@ -960,6 +1005,27 @@ MmFreeVirtualMemoryPage(PVOID Context, PVOID Address, ULONG PhysicalAddr)
} }
} }
VOID
MmFreeVirtualMemory(PEPROCESS Process, PMEMORY_AREA MemoryArea)
{
PLIST_ENTRY current_entry;
PMM_SEGMENT current;
current_entry = MemoryArea->Data.VirtualMemoryData.SegmentListHead.Flink;
while (current_entry != &MemoryArea->Data.VirtualMemoryData.SegmentListHead)
{
current = CONTAINING_RECORD(current_entry, MM_SEGMENT, SegmentListEntry);
current_entry = current_entry->Flink;
ExFreePool(current);
}
MmFreeMemoryArea(&Process->AddressSpace,
MemoryArea->BaseAddress,
0,
MmFreeVirtualMemoryPage,
(PVOID)Process);
}
NTSTATUS STDCALL NTSTATUS STDCALL
NtFreeVirtualMemory(IN HANDLE ProcessHandle, NtFreeVirtualMemory(IN HANDLE ProcessHandle,
IN PVOID* PBaseAddress, IN PVOID* PBaseAddress,
@ -1033,12 +1099,8 @@ NtFreeVirtualMemory(IN HANDLE ProcessHandle,
MmDereserveSwapPages(PAGE_ROUND_UP(MemoryArea->Length)); MmDereserveSwapPages(PAGE_ROUND_UP(MemoryArea->Length));
} }
#endif #endif
MmFreeMemoryArea(&Process->AddressSpace, MmFreeVirtualMemory(Process, MemoryArea);
BaseAddress,
0,
MmFreeVirtualMemoryPage,
(PVOID)Process);
MmUnlockAddressSpace(AddressSpace); MmUnlockAddressSpace(AddressSpace);
ObDereferenceObject(Process); ObDereferenceObject(Process);
return(STATUS_SUCCESS); return(STATUS_SUCCESS);

View file

@ -1,4 +1,4 @@
/* $Id: ntsem.c,v 1.10 2001/03/07 16:48:44 dwelch Exp $ /* $Id: ntsem.c,v 1.11 2001/03/13 16:25:55 dwelch Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -16,6 +16,7 @@
#include <internal/ob.h> #include <internal/ob.h>
#include <ntos/synch.h> #include <ntos/synch.h>
#include <internal/pool.h> #include <internal/pool.h>
#include <internal/ps.h>
#define NDEBUG #define NDEBUG
#include <internal/debug.h> #include <internal/debug.h>
@ -87,7 +88,6 @@ NtCreateSemaphore(OUT PHANDLE SemaphoreHandle,
{ {
PKSEMAPHORE Semaphore; PKSEMAPHORE Semaphore;
DPRINT("NtCreateSemaphore()\n");
Semaphore = ObCreateObject(SemaphoreHandle, Semaphore = ObCreateObject(SemaphoreHandle,
DesiredAccess, DesiredAccess,
ObjectAttributes, ObjectAttributes,

View file

@ -1,4 +1,4 @@
/* $Id: unicode.c,v 1.17 2001/02/25 12:51:43 chorns Exp $ /* $Id: unicode.c,v 1.18 2001/03/13 16:25:55 dwelch Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -13,15 +13,20 @@
//#include <internal/nls.h> //#include <internal/nls.h>
#include <ctype.h> #include <ctype.h>
#include <ntos/minmax.h> #include <ntos/minmax.h>
#include <internal/pool.h>
#define NDEBUG #define NDEBUG
#include <internal/debug.h> #include <internal/debug.h>
/* GLOBALS *******************************************************************/
#define TAG_USTR TAG('U', 'S', 'T', 'R')
#define TAG_ASTR TAG('A', 'S', 'T', 'R')
#define TAG_OSTR TAG('O', 'S', 'T', 'R')
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/
WCHAR WCHAR STDCALL
STDCALL
RtlAnsiCharToUnicodeChar(CHAR AnsiChar) RtlAnsiCharToUnicodeChar(CHAR AnsiChar)
{ {
ULONG Size; ULONG Size;
@ -79,8 +84,9 @@ RtlAnsiStringToUnicodeString (
{ {
DestinationString->MaximumLength = Length + sizeof(WCHAR); DestinationString->MaximumLength = Length + sizeof(WCHAR);
DestinationString->Buffer = DestinationString->Buffer =
ExAllocatePool (NonPagedPool, ExAllocatePoolWithTag (NonPagedPool,
DestinationString->MaximumLength); DestinationString->MaximumLength,
TAG_USTR);
if (DestinationString->Buffer == NULL) if (DestinationString->Buffer == NULL)
return STATUS_NO_MEMORY; return STATUS_NO_MEMORY;
} }
@ -444,8 +450,9 @@ RtlCreateUnicodeString (
Length = (wcslen (Source) + 1) * sizeof(WCHAR); Length = (wcslen (Source) + 1) * sizeof(WCHAR);
Destination->Buffer = ExAllocatePool (NonPagedPool, Destination->Buffer = ExAllocatePoolWithTag (NonPagedPool,
Length); Length,
TAG_USTR);
if (Destination->Buffer == NULL) if (Destination->Buffer == NULL)
return FALSE; return FALSE;
@ -481,56 +488,55 @@ RtlCreateUnicodeStringFromAsciiz (
} }
NTSTATUS NTSTATUS STDCALL
STDCALL RtlDowncaseUnicodeString (IN OUT PUNICODE_STRING DestinationString,
RtlDowncaseUnicodeString ( IN PUNICODE_STRING SourceString,
IN OUT PUNICODE_STRING DestinationString, IN BOOLEAN AllocateDestinationString)
IN PUNICODE_STRING SourceString,
IN BOOLEAN AllocateDestinationString
)
{ {
ULONG i; ULONG i;
PWCHAR Src, Dest; PWCHAR Src, Dest;
if (AllocateDestinationString == TRUE) if (AllocateDestinationString == TRUE)
{
DestinationString->MaximumLength = SourceString->Length + sizeof(WCHAR);
DestinationString->Buffer =
ExAllocatePoolWithTag (NonPagedPool,
SourceString->Length + sizeof(WCHAR),
TAG_USTR);
if (DestinationString->Buffer == NULL)
return STATUS_NO_MEMORY;
}
else
{
if (SourceString->Length >= DestinationString->MaximumLength)
return STATUS_BUFFER_TOO_SMALL;
}
DestinationString->Length = SourceString->Length;
Src = SourceString->Buffer;
Dest = DestinationString->Buffer;
for (i=0; i < SourceString->Length / sizeof(WCHAR); i++)
{
if (*Src < L'A')
{ {
DestinationString->MaximumLength = SourceString->Length + sizeof(WCHAR); *Dest = *Src;
DestinationString->Buffer = ExAllocatePool (NonPagedPool,
SourceString->Length + sizeof(WCHAR));
if (DestinationString->Buffer == NULL)
return STATUS_NO_MEMORY;
} }
else else if (*Src <= L'Z')
{ {
if (SourceString->Length >= DestinationString->MaximumLength) *Dest = (*Src + (L'a' - L'A'));
return STATUS_BUFFER_TOO_SMALL;
} }
DestinationString->Length = SourceString->Length; else
Src = SourceString->Buffer;
Dest = DestinationString->Buffer;
for (i=0; i < SourceString->Length / sizeof(WCHAR); i++)
{ {
if (*Src < L'A') /* FIXME: characters above 'Z' */
{ *Dest = *Src;
*Dest = *Src;
}
else if (*Src <= L'Z')
{
*Dest = (*Src + (L'a' - L'A'));
}
else
{
/* FIXME: characters above 'Z' */
*Dest = *Src;
}
Dest++;
Src++;
} }
*Dest = 0;
Dest++;
return STATUS_SUCCESS; Src++;
}
*Dest = 0;
return STATUS_SUCCESS;
} }
@ -829,60 +835,58 @@ RtlIntegerToUnicodeString (
} }
NTSTATUS NTSTATUS STDCALL
STDCALL RtlOemStringToCountedUnicodeString (IN OUT PUNICODE_STRING DestinationString,
RtlOemStringToCountedUnicodeString ( IN POEM_STRING SourceString,
IN OUT PUNICODE_STRING DestinationString, IN BOOLEAN AllocateDestinationString)
IN POEM_STRING SourceString,
IN BOOLEAN AllocateDestinationString
)
{ {
NTSTATUS Status; NTSTATUS Status;
ULONG Length; ULONG Length;
if (NlsMbCodePageTag == TRUE)
Length = RtlAnsiStringToUnicodeSize (SourceString);
else
Length = SourceString->Length * sizeof(WCHAR);
if (Length > 65535)
return STATUS_INVALID_PARAMETER_2;
if (AllocateDestinationString == TRUE)
{
DestinationString->MaximumLength = Length + sizeof(WCHAR);
DestinationString->Buffer =
ExAllocatePoolWithTag (NonPagedPool,
DestinationString->MaximumLength,
TAG_USTR);
if (DestinationString->Buffer == NULL)
return STATUS_NO_MEMORY;
}
else
{
if (Length > DestinationString->MaximumLength)
return STATUS_BUFFER_TOO_SMALL;
}
DestinationString->Length = Length;
RtlZeroMemory (DestinationString->Buffer,
DestinationString->Length);
Status = RtlOemToUnicodeN (DestinationString->Buffer,
DestinationString->Length,
NULL,
SourceString->Buffer,
SourceString->Length);
if (!NT_SUCCESS(Status))
{
if (AllocateDestinationString)
ExFreePool (DestinationString->Buffer);
return Status;
}
if (NlsMbCodePageTag == TRUE) DestinationString->Buffer[Length / sizeof(WCHAR)] = 0;
Length = RtlAnsiStringToUnicodeSize (SourceString);
else return STATUS_SUCCESS;
Length = SourceString->Length * sizeof(WCHAR);
if (Length > 65535)
return STATUS_INVALID_PARAMETER_2;
if (AllocateDestinationString == TRUE)
{
DestinationString->MaximumLength = Length + sizeof(WCHAR);
DestinationString->Buffer =
ExAllocatePool (NonPagedPool,
DestinationString->MaximumLength);
if (DestinationString->Buffer == NULL)
return STATUS_NO_MEMORY;
}
else
{
if (Length > DestinationString->MaximumLength)
return STATUS_BUFFER_TOO_SMALL;
}
DestinationString->Length = Length;
RtlZeroMemory (DestinationString->Buffer,
DestinationString->Length);
Status = RtlOemToUnicodeN (DestinationString->Buffer,
DestinationString->Length,
NULL,
SourceString->Buffer,
SourceString->Length);
if (!NT_SUCCESS(Status))
{
if (AllocateDestinationString)
ExFreePool (DestinationString->Buffer);
return Status;
}
DestinationString->Buffer[Length / sizeof(WCHAR)] = 0;
return STATUS_SUCCESS;
} }
@ -902,59 +906,57 @@ RtlOemStringToUnicodeSize (
} }
NTSTATUS NTSTATUS STDCALL
STDCALL RtlOemStringToUnicodeString (IN OUT PUNICODE_STRING DestinationString,
RtlOemStringToUnicodeString ( IN POEM_STRING SourceString,
IN OUT PUNICODE_STRING DestinationString, IN BOOLEAN AllocateDestinationString)
IN POEM_STRING SourceString,
IN BOOLEAN AllocateDestinationString
)
{ {
NTSTATUS Status; NTSTATUS Status;
ULONG Length; ULONG Length;
if (NlsMbCodePageTag == TRUE) if (NlsMbCodePageTag == TRUE)
Length = RtlAnsiStringToUnicodeSize (SourceString); Length = RtlAnsiStringToUnicodeSize (SourceString);
else else
Length = SourceString->Length * sizeof(WCHAR); Length = SourceString->Length * sizeof(WCHAR);
if (Length > 65535) if (Length > 65535)
return STATUS_INVALID_PARAMETER_2; return STATUS_INVALID_PARAMETER_2;
if (AllocateDestinationString == TRUE) if (AllocateDestinationString == TRUE)
{ {
DestinationString->MaximumLength = Length + sizeof(WCHAR); DestinationString->MaximumLength = Length + sizeof(WCHAR);
DestinationString->Buffer = DestinationString->Buffer =
ExAllocatePool (NonPagedPool, ExAllocatePoolWithTag (NonPagedPool,
DestinationString->MaximumLength); DestinationString->MaximumLength,
if (DestinationString->Buffer == NULL) TAG_USTR);
return STATUS_NO_MEMORY; if (DestinationString->Buffer == NULL)
} return STATUS_NO_MEMORY;
else }
{ else
if (Length >= DestinationString->MaximumLength) {
return STATUS_BUFFER_TOO_SMALL; if (Length >= DestinationString->MaximumLength)
} return STATUS_BUFFER_TOO_SMALL;
DestinationString->Length = Length; }
DestinationString->Length = Length;
RtlZeroMemory (DestinationString->Buffer,
DestinationString->Length); RtlZeroMemory (DestinationString->Buffer,
DestinationString->Length);
Status = RtlOemToUnicodeN (DestinationString->Buffer,
DestinationString->Length, Status = RtlOemToUnicodeN (DestinationString->Buffer,
NULL, DestinationString->Length,
SourceString->Buffer, NULL,
SourceString->Buffer,
SourceString->Length); SourceString->Length);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
if (AllocateDestinationString) if (AllocateDestinationString)
ExFreePool (DestinationString->Buffer); ExFreePool (DestinationString->Buffer);
return Status; return Status;
} }
DestinationString->Buffer[Length / sizeof(WCHAR)] = 0; DestinationString->Buffer[Length / sizeof(WCHAR)] = 0;
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
@ -1061,118 +1063,116 @@ RtlUnicodeStringToAnsiSize(IN PUNICODE_STRING UnicodeString)
NTSTATUS NTSTATUS
STDCALL STDCALL
RtlUnicodeStringToAnsiString ( RtlUnicodeStringToAnsiString (IN OUT PANSI_STRING DestinationString,
IN OUT PANSI_STRING DestinationString, IN PUNICODE_STRING SourceString,
IN PUNICODE_STRING SourceString, IN BOOLEAN AllocateDestinationString)
IN BOOLEAN AllocateDestinationString
)
{ {
NTSTATUS Status; NTSTATUS Status;
ULONG Length; ULONG Length;
if (NlsMbCodePageTag == TRUE) if (NlsMbCodePageTag == TRUE)
Length = RtlUnicodeStringToAnsiSize (SourceString); Length = RtlUnicodeStringToAnsiSize (SourceString);
else else
Length = SourceString->Length / sizeof(WCHAR); Length = SourceString->Length / sizeof(WCHAR);
if (AllocateDestinationString == TRUE) if (AllocateDestinationString == TRUE)
{ {
DestinationString->MaximumLength = Length + sizeof(CHAR); DestinationString->MaximumLength = Length + sizeof(CHAR);
DestinationString->Buffer = DestinationString->Buffer =
ExAllocatePool (NonPagedPool, ExAllocatePoolWithTag (NonPagedPool,
DestinationString->MaximumLength); DestinationString->MaximumLength,
if (DestinationString->Buffer == NULL) TAG_ASTR);
return STATUS_NO_MEMORY; if (DestinationString->Buffer == NULL)
} return STATUS_NO_MEMORY;
else }
{ else
if (Length >= DestinationString->MaximumLength) {
return STATUS_BUFFER_TOO_SMALL; if (Length >= DestinationString->MaximumLength)
} return STATUS_BUFFER_TOO_SMALL;
DestinationString->Length = Length; }
DestinationString->Length = Length;
RtlZeroMemory (DestinationString->Buffer,
DestinationString->Length); RtlZeroMemory (DestinationString->Buffer,
DestinationString->Length);
Status = RtlUnicodeToMultiByteN (DestinationString->Buffer,
DestinationString->Length, Status = RtlUnicodeToMultiByteN (DestinationString->Buffer,
NULL, DestinationString->Length,
SourceString->Buffer, NULL,
SourceString->Length); SourceString->Buffer,
if (!NT_SUCCESS(Status)) SourceString->Length);
{ if (!NT_SUCCESS(Status))
if (AllocateDestinationString) {
ExFreePool (DestinationString->Buffer); if (AllocateDestinationString)
ExFreePool (DestinationString->Buffer);
return Status; return Status;
} }
DestinationString->Buffer[Length] = 0; DestinationString->Buffer[Length] = 0;
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
NTSTATUS NTSTATUS
STDCALL STDCALL
RtlUnicodeStringToCountedOemString ( RtlUnicodeStringToCountedOemString (IN OUT POEM_STRING DestinationString,
IN OUT POEM_STRING DestinationString, IN PUNICODE_STRING SourceString,
IN PUNICODE_STRING SourceString, IN BOOLEAN AllocateDestinationString)
IN BOOLEAN AllocateDestinationString
)
{ {
NTSTATUS Status; NTSTATUS Status;
ULONG Length; ULONG Length;
ULONG Size; ULONG Size;
if (NlsMbOemCodePageTag == TRUE) if (NlsMbOemCodePageTag == TRUE)
Length = RtlUnicodeStringToAnsiSize (SourceString) + 1; Length = RtlUnicodeStringToAnsiSize (SourceString) + 1;
else else
Length = SourceString->Length / sizeof(WCHAR) + 1; Length = SourceString->Length / sizeof(WCHAR) + 1;
if (Length > 0x0000FFFF) if (Length > 0x0000FFFF)
return STATUS_INVALID_PARAMETER_2; return STATUS_INVALID_PARAMETER_2;
DestinationString->Length = (WORD)(Length - 1); DestinationString->Length = (WORD)(Length - 1);
if (AllocateDestinationString) if (AllocateDestinationString)
{ {
DestinationString->Buffer = ExAllocatePool (NonPagedPool, DestinationString->Buffer = ExAllocatePoolWithTag (NonPagedPool,
Length); Length,
TAG_ASTR);
if (DestinationString->Buffer == NULL)
return STATUS_NO_MEMORY; if (DestinationString->Buffer == NULL)
return STATUS_NO_MEMORY;
RtlZeroMemory (DestinationString->Buffer,
Length); RtlZeroMemory (DestinationString->Buffer,
DestinationString->MaximumLength = (WORD)Length; Length);
DestinationString->MaximumLength = (WORD)Length;
} }
else else
{
if (Length > DestinationString->MaximumLength)
{ {
if (Length > DestinationString->MaximumLength) if (DestinationString->MaximumLength == 0)
{ return STATUS_BUFFER_OVERFLOW;
if (DestinationString->MaximumLength == 0) DestinationString->Length =
return STATUS_BUFFER_OVERFLOW; DestinationString->MaximumLength - 1;
DestinationString->Length =
DestinationString->MaximumLength - 1;
}
} }
}
Status = RtlUnicodeToOemN (DestinationString->Buffer,
DestinationString->Length,
&Size,
SourceString->Buffer,
SourceString->Length);
if (!NT_SUCCESS(Status))
{
if (AllocateDestinationString)
ExFreePool (DestinationString->Buffer);
Status = RtlUnicodeToOemN (DestinationString->Buffer, return Status;
DestinationString->Length, }
&Size,
SourceString->Buffer, DestinationString->Buffer[Size] = 0;
SourceString->Length);
if (!NT_SUCCESS(Status)) return STATUS_SUCCESS;
{
if (AllocateDestinationString)
ExFreePool (DestinationString->Buffer);
return Status;
}
DestinationString->Buffer[Size] = 0;
return STATUS_SUCCESS;
} }
@ -1282,56 +1282,54 @@ RtlUnicodeStringToOemSize (
} }
NTSTATUS NTSTATUS STDCALL
STDCALL RtlUnicodeStringToOemString (IN OUT POEM_STRING DestinationString,
RtlUnicodeStringToOemString ( IN PUNICODE_STRING SourceString,
IN OUT POEM_STRING DestinationString, IN BOOLEAN AllocateDestinationString)
IN PUNICODE_STRING SourceString,
IN BOOLEAN AllocateDestinationString
)
{ {
NTSTATUS Status; NTSTATUS Status;
ULONG Length; ULONG Length;
if (NlsMbOemCodePageTag == TRUE) if (NlsMbOemCodePageTag == TRUE)
Length = RtlUnicodeStringToAnsiSize (SourceString); Length = RtlUnicodeStringToAnsiSize (SourceString);
else else
Length = SourceString->Length / sizeof(WCHAR); Length = SourceString->Length / sizeof(WCHAR);
if (AllocateDestinationString == TRUE) if (AllocateDestinationString == TRUE)
{ {
DestinationString->MaximumLength = Length + sizeof(CHAR); DestinationString->MaximumLength = Length + sizeof(CHAR);
DestinationString->Buffer = DestinationString->Buffer =
ExAllocatePool (NonPagedPool, ExAllocatePoolWithTag (NonPagedPool,
DestinationString->MaximumLength); DestinationString->MaximumLength,
if (DestinationString->Buffer == NULL) TAG_OSTR);
return STATUS_NO_MEMORY; if (DestinationString->Buffer == NULL)
} return STATUS_NO_MEMORY;
else }
{ else
if (Length >= DestinationString->MaximumLength) {
return STATUS_BUFFER_TOO_SMALL; if (Length >= DestinationString->MaximumLength)
} return STATUS_BUFFER_TOO_SMALL;
DestinationString->Length = Length; }
DestinationString->Length = Length;
RtlZeroMemory (DestinationString->Buffer,
DestinationString->Length); RtlZeroMemory (DestinationString->Buffer,
DestinationString->Length);
Status = RtlUnicodeToOemN (DestinationString->Buffer,
DestinationString->Length, Status = RtlUnicodeToOemN (DestinationString->Buffer,
NULL, DestinationString->Length,
SourceString->Buffer, NULL,
SourceString->Length); SourceString->Buffer,
if (!NT_SUCCESS(Status)) SourceString->Length);
{ if (!NT_SUCCESS(Status))
if (AllocateDestinationString) {
ExFreePool (DestinationString->Buffer); if (AllocateDestinationString)
return Status; ExFreePool (DestinationString->Buffer);
} return Status;
}
DestinationString->Buffer[Length] = 0;
DestinationString->Buffer[Length] = 0;
return STATUS_SUCCESS;
return STATUS_SUCCESS;
} }
@ -1353,43 +1351,42 @@ RtlUpcaseUnicodeChar (
} }
NTSTATUS NTSTATUS STDCALL
STDCALL RtlUpcaseUnicodeString (IN OUT PUNICODE_STRING DestinationString,
RtlUpcaseUnicodeString ( IN PUNICODE_STRING SourceString,
IN OUT PUNICODE_STRING DestinationString, IN BOOLEAN AllocateDestinationString)
IN PUNICODE_STRING SourceString,
IN BOOLEAN AllocateDestinationString
)
{ {
ULONG i; ULONG i;
PWCHAR Src, Dest; PWCHAR Src, Dest;
if (AllocateDestinationString == TRUE) if (AllocateDestinationString == TRUE)
{ {
DestinationString->MaximumLength = SourceString->Length + sizeof(WCHAR); DestinationString->MaximumLength = SourceString->Length + sizeof(WCHAR);
DestinationString->Buffer = ExAllocatePool (NonPagedPool, DestinationString->Buffer =
SourceString->Length + sizeof(WCHAR)); ExAllocatePoolWithTag (NonPagedPool,
if (DestinationString->Buffer == NULL) SourceString->Length + sizeof(WCHAR),
return STATUS_NO_MEMORY; TAG_USTR);
} if (DestinationString->Buffer == NULL)
else return STATUS_NO_MEMORY;
{ }
if (SourceString->Length >= DestinationString->MaximumLength) else
return STATUS_BUFFER_TOO_SMALL; {
} if (SourceString->Length >= DestinationString->MaximumLength)
DestinationString->Length = SourceString->Length; return STATUS_BUFFER_TOO_SMALL;
}
Src = SourceString->Buffer; DestinationString->Length = SourceString->Length;
Dest = DestinationString->Buffer;
for (i=0; i < SourceString->Length / sizeof(WCHAR); i++) Src = SourceString->Buffer;
{ Dest = DestinationString->Buffer;
*Dest = RtlUpcaseUnicodeChar (*Src); for (i=0; i < SourceString->Length / sizeof(WCHAR); i++)
Dest++; {
Src++; *Dest = RtlUpcaseUnicodeChar (*Src);
} Dest++;
*Dest = 0; Src++;
}
return STATUS_SUCCESS; *Dest = 0;
return STATUS_SUCCESS;
} }
@ -1401,111 +1398,111 @@ RtlUpcaseUnicodeStringToAnsiString (
IN BOOLEAN AllocateDestinationString IN BOOLEAN AllocateDestinationString
) )
{ {
NTSTATUS Status; NTSTATUS Status;
ULONG Length; ULONG Length;
if (NlsMbCodePageTag == TRUE) if (NlsMbCodePageTag == TRUE)
Length = RtlUnicodeStringToAnsiSize (SourceString); Length = RtlUnicodeStringToAnsiSize (SourceString);
else else
Length = SourceString->Length / sizeof(WCHAR); Length = SourceString->Length / sizeof(WCHAR);
if (AllocateDestinationString == TRUE) if (AllocateDestinationString == TRUE)
{ {
DestinationString->MaximumLength = Length + sizeof(CHAR); DestinationString->MaximumLength = Length + sizeof(CHAR);
DestinationString->Buffer = ExAllocatePool (NonPagedPool, DestinationString->Buffer =
DestinationString->MaximumLength); ExAllocatePoolWithTag (NonPagedPool,
if (DestinationString->Buffer == NULL) DestinationString->MaximumLength,
return STATUS_NO_MEMORY; TAG_ASTR);
} if (DestinationString->Buffer == NULL)
else return STATUS_NO_MEMORY;
{ }
if (Length >= DestinationString->MaximumLength) else
return STATUS_BUFFER_TOO_SMALL; {
} if (Length >= DestinationString->MaximumLength)
DestinationString->Length = Length; return STATUS_BUFFER_TOO_SMALL;
}
RtlZeroMemory (DestinationString->Buffer, DestinationString->Length = Length;
DestinationString->Length);
RtlZeroMemory (DestinationString->Buffer,
Status = RtlUpcaseUnicodeToMultiByteN (DestinationString->Buffer, DestinationString->Length);
DestinationString->Length,
NULL, Status = RtlUpcaseUnicodeToMultiByteN (DestinationString->Buffer,
SourceString->Buffer, DestinationString->Length,
SourceString->Length); NULL,
if (!NT_SUCCESS(Status)) SourceString->Buffer,
{ SourceString->Length);
if (AllocateDestinationString) if (!NT_SUCCESS(Status))
ExFreePool (DestinationString->Buffer); {
return Status; if (AllocateDestinationString)
} ExFreePool (DestinationString->Buffer);
return Status;
DestinationString->Buffer[Length] = 0; }
return STATUS_SUCCESS; DestinationString->Buffer[Length] = 0;
return STATUS_SUCCESS;
} }
NTSTATUS NTSTATUS STDCALL
STDCALL RtlUpcaseUnicodeStringToCountedOemString (IN OUT POEM_STRING DestinationString,
RtlUpcaseUnicodeStringToCountedOemString ( IN PUNICODE_STRING SourceString,
IN OUT POEM_STRING DestinationString, IN BOOLEAN AllocateDestinationString)
IN PUNICODE_STRING SourceString,
IN BOOLEAN AllocateDestinationString
)
{ {
NTSTATUS Status; NTSTATUS Status;
ULONG Length; ULONG Length;
ULONG Size; ULONG Size;
if (NlsMbCodePageTag == TRUE)
Length = RtlUnicodeStringToAnsiSize (SourceString) + 1;
else
Length = SourceString->Length / sizeof(WCHAR) + 1;
if (Length > 0x0000FFFF)
return STATUS_INVALID_PARAMETER_2;
DestinationString->Length = (WORD)(Length - 1);
if (NlsMbCodePageTag == TRUE) if (AllocateDestinationString == TRUE)
Length = RtlUnicodeStringToAnsiSize (SourceString) + 1; {
else DestinationString->Buffer = ExAllocatePoolWithTag (NonPagedPool,
Length = SourceString->Length / sizeof(WCHAR) + 1; Length,
TAG_OSTR);
if (Length > 0x0000FFFF)
return STATUS_INVALID_PARAMETER_2; if (DestinationString->Buffer == NULL)
return STATUS_NO_MEMORY;
DestinationString->Length = (WORD)(Length - 1);
RtlZeroMemory (DestinationString->Buffer,
if (AllocateDestinationString == TRUE) Length);
DestinationString->MaximumLength = (WORD)Length;
}
else
{
if (Length > DestinationString->MaximumLength)
{ {
DestinationString->Buffer = ExAllocatePool (NonPagedPool, if (DestinationString->MaximumLength == 0)
Length); return STATUS_BUFFER_OVERFLOW;
DestinationString->Length =
if (DestinationString->Buffer == NULL) DestinationString->MaximumLength - 1;
return STATUS_NO_MEMORY;
RtlZeroMemory (DestinationString->Buffer,
Length);
DestinationString->MaximumLength = (WORD)Length;
} }
else }
{
if (Length > DestinationString->MaximumLength) Status = RtlUpcaseUnicodeToOemN (DestinationString->Buffer,
{ DestinationString->Length,
if (DestinationString->MaximumLength == 0) &Size,
return STATUS_BUFFER_OVERFLOW; SourceString->Buffer,
DestinationString->Length = SourceString->Length);
DestinationString->MaximumLength - 1; if (!NT_SUCCESS(Status))
} {
} if (AllocateDestinationString)
ExFreePool (DestinationString->Buffer);
Status = RtlUpcaseUnicodeToOemN (DestinationString->Buffer,
DestinationString->Length, return Status;
&Size, }
SourceString->Buffer,
SourceString->Length); DestinationString->Buffer[Size] = 0;
if (!NT_SUCCESS(Status))
{ return STATUS_SUCCESS;
if (AllocateDestinationString)
ExFreePool (DestinationString->Buffer);
return Status;
}
DestinationString->Buffer[Size] = 0;
return STATUS_SUCCESS;
} }
@ -1528,8 +1525,8 @@ RtlUpcaseUnicodeStringToOemString (
if (AllocateDestinationString == TRUE) if (AllocateDestinationString == TRUE)
{ {
DestinationString->MaximumLength = Length + sizeof(CHAR); DestinationString->MaximumLength = Length + sizeof(CHAR);
DestinationString->Buffer = ExAllocatePool (NonPagedPool, DestinationString->Buffer = ExAllocatePoolWithTag (NonPagedPool,
DestinationString->MaximumLength); DestinationString->MaximumLength, TAG_OSTR);
if (DestinationString->Buffer == NULL) if (DestinationString->Buffer == NULL)
return STATUS_NO_MEMORY; return STATUS_NO_MEMORY;
} }