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

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
* PROJECT: ReactOS kernel
@ -19,7 +19,14 @@
#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
IsLastEntry (PVOID Block, ULONG Offset)
@ -448,7 +455,8 @@ VfatOpenFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
Fcb->RefCount++;
KeReleaseSpinLock (&DeviceExt->FcbListLock, oldIrql);
FileObject->FsContext = (PVOID)&Fcb->RFCB;
newCCB = ExAllocatePool (NonPagedPool, sizeof (VFATCCB));
newCCB =
ExAllocatePoolWithTag (NonPagedPool, sizeof (VFATCCB), TAG_CCB);
memset (newCCB, 0, sizeof (VFATCCB));
FileObject->Flags = FileObject->Flags |
FO_FCB_IS_VALID | FO_DIRECT_CACHE_PAGING_READ;
@ -471,7 +479,7 @@ VfatOpenFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
string = FileName;
ParentFcb = NULL;
Fcb = ExAllocatePool (NonPagedPool, sizeof (VFATFCB));
Fcb = ExAllocatePoolWithTag (NonPagedPool, sizeof (VFATFCB), TAG_FCB);
memset (Fcb, 0, sizeof (VFATFCB));
Fcb->ObjectName = &Fcb->PathName[1];
Fcb->PathName[0]='\\';
@ -532,7 +540,8 @@ VfatOpenFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
if (ParentFcb == NULL)
{
CHECKPOINT;
Fcb = ExAllocatePool (NonPagedPool, sizeof (VFATFCB));
Fcb = ExAllocatePoolWithTag (NonPagedPool, sizeof (VFATFCB),
TAG_FCB);
memset (Fcb, 0, sizeof (VFATFCB));
Fcb->ObjectName = &Fcb->PathName[1];
Fcb->PathName[0] = '\\';
@ -594,7 +603,7 @@ VfatOpenFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
memset(FileObject->SectionObjectPointers, 0,
sizeof(SECTION_OBJECT_POINTERS));
FileObject->FsContext = (PVOID)&ParentFcb->RFCB;
newCCB = ExAllocatePool (NonPagedPool, sizeof (VFATCCB));
newCCB = ExAllocatePoolWithTag (NonPagedPool, sizeof (VFATCCB), TAG_CCB);
memset (newCCB, 0, sizeof (VFATCCB));
FileObject->FsContext2 = newCCB;
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
* PROJECT: ReactOS system libraries
@ -35,65 +35,50 @@ WaitForInputIdleType lpfnGlobalRegisterWaitForInputIdle;
LPSTARTUPINFO lpLocalStartupInfo = NULL;
VOID
STDCALL
RegisterWaitForInputIdle (
WaitForInputIdleType lpfnRegisterWaitForInputIdle
);
VOID STDCALL
RegisterWaitForInputIdle (WaitForInputIdleType lpfnRegisterWaitForInputIdle);
/* FUNCTIONS ****************************************************************/
WINBOOL
STDCALL
GetProcessId (
HANDLE hProcess,
LPDWORD lpProcessId
);
WINBOOL STDCALL
GetProcessId (HANDLE hProcess, LPDWORD lpProcessId);
WINBOOL
STDCALL
GetProcessTimes (
HANDLE hProcess,
LPFILETIME lpCreationTime,
LPFILETIME lpExitTime,
LPFILETIME lpKernelTime,
LPFILETIME lpUserTime
)
WINBOOL STDCALL
GetProcessTimes (HANDLE hProcess,
LPFILETIME lpCreationTime,
LPFILETIME lpExitTime,
LPFILETIME lpKernelTime,
LPFILETIME lpUserTime)
{
NTSTATUS Status;
KERNEL_USER_TIMES Kut;
Status = NtQueryInformationProcess (
hProcess,
ProcessTimes,
& Kut,
sizeof Kut,
NULL
);
if (!NT_SUCCESS(Status))
{
SetLastErrorByStatus (Status);
return (FALSE);
}
lpCreationTime->dwLowDateTime = Kut.CreateTime.u.LowPart;
lpCreationTime->dwHighDateTime = Kut.CreateTime.u.HighPart;
NTSTATUS Status;
KERNEL_USER_TIMES Kut;
Status = NtQueryInformationProcess (hProcess,
ProcessTimes,
&Kut,
sizeof(Kut),
NULL
);
if (!NT_SUCCESS(Status))
{
SetLastErrorByStatus (Status);
return (FALSE);
}
lpCreationTime->dwLowDateTime = Kut.CreateTime.u.LowPart;
lpCreationTime->dwHighDateTime = Kut.CreateTime.u.HighPart;
lpExitTime->dwLowDateTime = Kut.ExitTime.u.LowPart;
lpExitTime->dwHighDateTime = Kut.ExitTime.u.HighPart;
lpExitTime->dwLowDateTime = Kut.ExitTime.u.LowPart;
lpExitTime->dwHighDateTime = Kut.ExitTime.u.HighPart;
lpKernelTime->dwLowDateTime = Kut.KernelTime.u.LowPart;
lpKernelTime->dwHighDateTime = Kut.KernelTime.u.HighPart;
lpUserTime->dwLowDateTime = Kut.UserTime.u.LowPart;
lpUserTime->dwHighDateTime = Kut.UserTime.u.HighPart;
return (TRUE);
lpKernelTime->dwLowDateTime = Kut.KernelTime.u.LowPart;
lpKernelTime->dwHighDateTime = Kut.KernelTime.u.HighPart;
lpUserTime->dwLowDateTime = Kut.UserTime.u.LowPart;
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
* PROJECT: ReactOS system libraries
@ -24,28 +24,28 @@
/* FUNCTIONS *****************************************************************/
DWORD STDCALL TlsAlloc(VOID)
DWORD STDCALL
TlsAlloc(VOID)
{
ULONG Index;
RtlAcquirePebLock();
Index = RtlFindClearBitsAndSet (NtCurrentPeb()->TlsBitmap,
1,
0);
Index = RtlFindClearBitsAndSet (NtCurrentPeb()->TlsBitmap, 1, 0);
if (Index == (ULONG)-1)
{
SetLastErrorByStatus(STATUS_NO_MEMORY);
SetLastErrorByStatus(STATUS_NO_MEMORY);
}
else
{
NtCurrentTeb()->TlsSlots[Index] = 0;
NtCurrentTeb()->TlsSlots[Index] = 0;
}
RtlReleasePebLock();
return Index;
return(Index);
}
WINBOOL STDCALL TlsFree(DWORD dwTlsIndex)
WINBOOL STDCALL
TlsFree(DWORD dwTlsIndex)
{
if (dwTlsIndex >= TLS_MINIMUM_AVAILABLE)
{
@ -73,7 +73,8 @@ WINBOOL STDCALL TlsFree(DWORD dwTlsIndex)
return(TRUE);
}
LPVOID STDCALL TlsGetValue(DWORD dwTlsIndex)
LPVOID STDCALL
TlsGetValue(DWORD dwTlsIndex)
{
if (dwTlsIndex >= TLS_MINIMUM_AVAILABLE)
{
@ -83,7 +84,8 @@ LPVOID STDCALL TlsGetValue(DWORD dwTlsIndex)
return(NtCurrentTeb()->TlsSlots[dwTlsIndex]);
}
WINBOOL STDCALL TlsSetValue(DWORD dwTlsIndex, LPVOID lpTlsValue)
WINBOOL STDCALL
TlsSetValue(DWORD dwTlsIndex, LPVOID lpTlsValue)
{
if (dwTlsIndex >= TLS_MINIMUM_AVAILABLE)
{

View file

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

View file

@ -1,6 +1,6 @@
/*
* 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
* 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
* 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
* 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
* PROJECT: ReactOS kernel
@ -15,6 +15,7 @@
#include <internal/ob.h>
#include <limits.h>
#include <string.h>
#include <internal/pool.h>
#define NDEBUG
#include <internal/debug.h>
@ -301,7 +302,6 @@ static NTSTATUS
CmiAddFree(PREGISTRY_FILE RegistryFile,
PFREE_SUB_BLOCK FreeBlock,BLOCK_OFFSET FreeOffset);
/* --------------------------------------------- Public Interface */
VOID

View file

@ -34,12 +34,6 @@ typedef ULONG SWAPENTRY;
#define NR_SECTION_PAGE_TABLES (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
*/
@ -398,7 +392,9 @@ typedef struct _MM_PAGEOP
BOOLEAN Abandoned;
/* The memory area to be affected by the operation. */
PMEMORY_AREA MArea;
ULONG Hash;
struct _MM_PAGEOP* Next;
struct _ETHREAD* Thread;
/*
* These fields are used to identify the operation if it is against a
* virtual memory area.
@ -413,6 +409,13 @@ typedef struct _MM_PAGEOP
ULONG Offset;
} 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
MiDebugDumpNonPagedPool(BOOLEAN NewOnly);
VOID
@ -430,4 +433,7 @@ typedef struct _MM_IMAGE_SECTION_OBJECT
MM_SECTION_SEGMENT Segments[0];
} MM_IMAGE_SECTION_OBJECT, *PMM_IMAGE_SECTION_OBJECT;
VOID
MmFreeVirtualMemory(struct _EPROCESS* Process, PMEMORY_AREA MemoryArea);
#endif

View file

@ -16,11 +16,13 @@
/* FUNCTIONS *****************************************************************/
NTSTATUS STDCALL NtSetLdtEntries(HANDLE Thread,
ULONG FirstEntry,
PULONG Entries)
NTSTATUS STDCALL
NtSetLdtEntries(HANDLE Thread, ULONG FirstEntry, PULONG Entries)
{
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
* PROJECT: ReactOS kernel
@ -33,42 +33,41 @@
*
*/
VOID
NiClosePort (PVOID ObjectBody,
ULONG HandleCount)
NiClosePort (PVOID ObjectBody, ULONG HandleCount)
{
PEPORT Port = (PEPORT) ObjectBody;
LPC_MESSAGE Message;
// DPRINT1("NiClosePort(ObjectBody %x, HandleCount %d) RefCount %d\n",
// ObjectBody, HandleCount, ObGetReferenceCount(Port));
if ((HandleCount == 0) &&
(Port->State == EPORT_CONNECTED_CLIENT) &&
(ObGetReferenceCount(Port) == 2))
{
// DPRINT1("All handles closed to client port\n");
Message.MessageSize = sizeof(LPC_MESSAGE);
Message.DataSize = 0;
EiReplyOrRequestPort (Port->OtherPort,
&Message,
LPC_PORT_CLOSED,
Port);
KeSetEvent (&Port->OtherPort->Event,
IO_NO_INCREMENT,
FALSE);
PEPORT Port = (PEPORT)ObjectBody;
LPC_MESSAGE Message;
/*
* 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 &&
ObGetReferenceCount(Port) == 2)
{
Message.MessageSize = sizeof(LPC_MESSAGE);
Message.DataSize = 0;
EiReplyOrRequestPort (Port->OtherPort,
&Message,
LPC_PORT_CLOSED,
Port);
KeSetEvent (&Port->OtherPort->Event,
IO_NO_INCREMENT,
FALSE);
Port->OtherPort->OtherPort = NULL;
Port->OtherPort->State = EPORT_DISCONNECTED;
ObDereferenceObject (Port);
}
Port->OtherPort->OtherPort = NULL;
Port->OtherPort->State = EPORT_DISCONNECTED;
ObDereferenceObject (Port);
}
if ((HandleCount == 0) &&
(Port->State == EPORT_CONNECTED_SERVER) &&
(ObGetReferenceCount(Port) == 2))
{
// DPRINT("All handles closed to server\n");
/*
* If the server has closed all of its handles then disconnect the port,
* don't actually notify the client until it attempts an operation.
*/
if (HandleCount == 0 && Port->State == EPORT_CONNECTED_SERVER &&
ObGetReferenceCount(Port) == 2)
{
Port->OtherPort->OtherPort = NULL;
Port->OtherPort->State = EPORT_DISCONNECTED;
ObDereferenceObject(Port->OtherPort);

View file

@ -32,7 +32,6 @@ typedef struct _PHYSICAL_PAGE
ULONG Flags;
LIST_ENTRY ListEntry;
ULONG ReferenceCount;
KEVENT Event;
SWAPENTRY SavedSwapEntry;
ULONG LockCount;
ULONG MapCount;
@ -187,9 +186,6 @@ PVOID MmInitializePageList(PVOID FirstPhysKernelAddress,
{
MmPageArray[i].Flags = MM_PHYSICAL_PAGE_FREE;
MmPageArray[i].ReferenceCount = 0;
KeInitializeEvent(&MmPageArray[i].Event,
NotificationEvent,
FALSE);
InsertTailList(&FreePageListHead,
&MmPageArray[i].ListEntry);
}
@ -199,9 +195,6 @@ PVOID MmInitializePageList(PVOID FirstPhysKernelAddress,
{
MmPageArray[i].Flags = MM_PHYSICAL_PAGE_USED;
MmPageArray[i].ReferenceCount = 1;
KeInitializeEvent(&MmPageArray[i].Event,
NotificationEvent,
FALSE);
InsertTailList(&UsedPageListHead,
&MmPageArray[i].ListEntry);
}
@ -210,9 +203,6 @@ PVOID MmInitializePageList(PVOID FirstPhysKernelAddress,
{
MmPageArray[i].Flags = MM_PHYSICAL_PAGE_FREE;
MmPageArray[i].ReferenceCount = 0;
KeInitializeEvent(&MmPageArray[i].Event,
NotificationEvent,
FALSE);
InsertTailList(&FreePageListHead,
&MmPageArray[i].ListEntry);
}
@ -221,9 +211,6 @@ PVOID MmInitializePageList(PVOID FirstPhysKernelAddress,
{
MmPageArray[i].Flags = MM_PHYSICAL_PAGE_BIOS;
MmPageArray[i].ReferenceCount = 1;
KeInitializeEvent(&MmPageArray[i].Event,
NotificationEvent,
FALSE);
InsertTailList(&BiosPageListHead,
&MmPageArray[i].ListEntry);
}
@ -235,9 +222,6 @@ PVOID MmInitializePageList(PVOID FirstPhysKernelAddress,
{
MmPageArray[i].Flags = MM_PHYSICAL_PAGE_FREE;
MmPageArray[i].ReferenceCount = 0;
KeInitializeEvent(&MmPageArray[i].Event,
NotificationEvent,
FALSE);
InsertTailList(&FreePageListHead,
&MmPageArray[i].ListEntry);
}
@ -246,9 +230,6 @@ PVOID MmInitializePageList(PVOID FirstPhysKernelAddress,
{
MmPageArray[i].Flags = MM_PHYSICAL_PAGE_BIOS;
MmPageArray[i].ReferenceCount = 1;
KeInitializeEvent(&MmPageArray[i].Event,
NotificationEvent,
FALSE);
InsertTailList(&BiosPageListHead,
&MmPageArray[i].ListEntry);
}
@ -257,9 +238,6 @@ PVOID MmInitializePageList(PVOID FirstPhysKernelAddress,
{
MmPageArray[i].Flags = MM_PHYSICAL_PAGE_FREE;
MmPageArray[i].ReferenceCount = 0;
KeInitializeEvent(&MmPageArray[i].Event,
NotificationEvent,
FALSE);
InsertTailList(&FreePageListHead,
&MmPageArray[i].ListEntry);
}
@ -269,9 +247,6 @@ PVOID MmInitializePageList(PVOID FirstPhysKernelAddress,
{
MmPageArray[i].Flags = MM_PHYSICAL_PAGE_USED;
MmPageArray[i].ReferenceCount = 1;
KeInitializeEvent(&MmPageArray[i].Event,
NotificationEvent,
FALSE);
InsertTailList(&UsedPageListHead,
&MmPageArray[i].ListEntry);
}
@ -282,9 +257,6 @@ PVOID MmInitializePageList(PVOID FirstPhysKernelAddress,
{
MmPageArray[i].Flags = MM_PHYSICAL_PAGE_FREE;
MmPageArray[i].ReferenceCount = 0;
KeInitializeEvent(&MmPageArray[i].Event,
NotificationEvent,
FALSE);
InsertTailList(&FreePageListHead,
&MmPageArray[i].ListEntry);
}
@ -638,39 +610,3 @@ MmAllocPageMaybeSwap(SWAPENTRY SavedSwapEntry)
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
* PROJECT: ReactOS kernel
@ -15,13 +15,19 @@
#include <internal/mm.h>
#include <internal/mmhal.h>
#include <internal/ps.h>
#include <internal/pool.h>
#define NDEBUG
#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;
@ -318,7 +324,8 @@ PMDL STDCALL MmCreateMdl (PMDL MemoryDescriptorList,
ULONG Size;
Size = MmSizeOfMdl(Base,Length);
MemoryDescriptorList = (PMDL)ExAllocatePool(NonPagedPool,Size);
MemoryDescriptorList =
(PMDL)ExAllocatePoolWithTag(NonPagedPool, Size, TAG_MDL);
if (MemoryDescriptorList == 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
* PROJECT: ReactOS kernel
@ -32,20 +50,6 @@ extern PVOID MmSharedDataPagePhysicalAddress;
/* 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 Status;
@ -64,13 +68,8 @@ NTSTATUS MmReleaseMemoryArea(PEPROCESS Process, PMEMORY_AREA Marea)
assert(Status == STATUS_SUCCESS);
return(STATUS_SUCCESS);
case MEMORY_AREA_VIRTUAL_MEMORY:
Status = MmFreeMemoryArea(&Process->AddressSpace,
Marea->BaseAddress,
0,
MmFreeVirtualMemoryPage,
(PVOID)Process);
assert(Status == STATUS_SUCCESS);
case MEMORY_AREA_VIRTUAL_MEMORY:
MmFreeVirtualMemory(Process, Marea);
break;
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
* PROJECT: ReactOS kernel
@ -14,6 +14,7 @@
#include <internal/ps.h>
#include <internal/mm.h>
#include <internal/mmhal.h>
#include <internal/pool.h>
#define NDEBUG
#include <internal/debug.h>
@ -31,10 +32,12 @@ PMM_PAGEOP MmPageOpHashTable[PAGEOP_HASH_TABLE_SIZE];
VOID
MmReleasePageOp(PMM_PAGEOP PageOp)
/*
* FUNCTION: Release a reference to a page operation descriptor
*/
{
ULONG h;
KIRQL oldIrql;
PMM_PAGEOP PPageOp;
PMM_PAGEOP PrevPageOp;
PageOp->ReferenceCount--;
if (PageOp->ReferenceCount > 0)
@ -42,38 +45,26 @@ MmReleasePageOp(PMM_PAGEOP PageOp)
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);
PPageOp = MmPageOpHashTable[h];
if (PPageOp == PageOp)
PrevPageOp = MmPageOpHashTable[PageOp->Hash];
if (PrevPageOp == PageOp)
{
MmPageOpHashTable[h] = PageOp->Next;
MmPageOpHashTable[PageOp->Hash] = PageOp->Next;
KeReleaseSpinLock(&MmPageOpHashTableLock, oldIrql);
ExFreePool(PageOp);
return;
}
PPageOp = PPageOp->Next;
while (PPageOp != NULL)
PrevPageOp = PrevPageOp->Next;
while (PrevPageOp != NULL)
{
if (PPageOp == PageOp)
if (PrevPageOp == PageOp)
{
PPageOp->Next = PageOp->Next;
PrevPageOp->Next = PageOp->Next;
KeReleaseSpinLock(&MmPageOpHashTableLock, oldIrql);
ExFreePool(PageOp);
return;
}
PPageOp = PPageOp->Next;
PrevPageOp = PrevPageOp->Next;
}
KeReleaseSpinLock(&MmPageOpHashTableLock, oldIrql);
KeBugCheck(0);
@ -82,8 +73,13 @@ MmReleasePageOp(PMM_PAGEOP PageOp)
PMM_PAGEOP
MmGetPageOp(PMEMORY_AREA MArea, ULONG Pid, PVOID Address,
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;
PMM_PAGEOP PageOp;
@ -92,19 +88,20 @@ MmGetPageOp(PMEMORY_AREA MArea, ULONG Pid, PVOID Address,
*/
if (MArea->Type == MEMORY_AREA_SECTION_VIEW_COMMIT)
{
h = (((ULONG)Segment) | Offset) % PAGEOP_HASH_TABLE_SIZE;
Hash = (((ULONG)Segment) | (((ULONG)Offset) / PAGESIZE));
}
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);
/*
* Check for an existing pageop structure
*/
PageOp = MmPageOpHashTable[h];
PageOp = MmPageOpHashTable[Hash];
while (PageOp != NULL)
{
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.
*/
PageOp = ExAllocatePoolWithTag(NonPagedPool, sizeof(MM_PAGEOP),
PageOp = ExAllocatePoolWithTag(NonPagedPool, sizeof(MM_PAGEOP),
TAG_MM_PAGEOP);
if (PageOp == NULL)
{
@ -148,7 +145,7 @@ MmGetPageOp(PMEMORY_AREA MArea, ULONG Pid, PVOID Address,
return(NULL);
}
if (MArea->Type == MEMORY_AREA_SECTION_VIEW_COMMIT)
if (MArea->Type != MEMORY_AREA_SECTION_VIEW_COMMIT)
{
PageOp->Pid = Pid;
PageOp->Address = Address;
@ -159,9 +156,22 @@ MmGetPageOp(PMEMORY_AREA MArea, ULONG Pid, PVOID Address,
PageOp->Offset = Offset;
}
PageOp->ReferenceCount = 1;
PageOp->Next = MmPageOpHashTable[h];
MmPageOpHashTable[h] = PageOp;
PageOp->Next = MmPageOpHashTable[Hash];
PageOp->Hash = Hash;
PageOp->Thread = PsGetCurrentThread();
PageOp->Abandoned = FALSE;
PageOp->Status = STATUS_PENDING;
KeInitializeEvent(&PageOp->CompletionEvent, NotificationEvent, FALSE);
MmPageOpHashTable[Hash] = PageOp;
KeReleaseSpinLock(&MmPageOpHashTableLock, oldIrql);
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
* PROJECT: ReactOS kernel
@ -184,123 +184,6 @@ MmGetPageEntrySectionSegment(PMM_SECTION_SEGMENT Segment,
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
MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
MEMORY_AREA* MemoryArea,
@ -318,10 +201,7 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
ULONG Entry;
ULONG Entry1;
ULONG Attributes;
DPRINT("MmSectionHandleFault(MemoryArea %x, Address %x)\n",
MemoryArea,Address);
PMM_PAGEOP PageOp;
/*
* There is a window between taking the page fault and locking the
@ -330,7 +210,6 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
*/
if (MmIsPagePresent(NULL, Address))
{
DbgPrint("Page is already present\n");
if (Locked)
{
MmLockPage((PVOID)MmGetPhysicalAddressForProcess(NULL, Address));
@ -350,6 +229,84 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
MmLockSection(Section);
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
*/
@ -366,6 +323,13 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
{
MmLockPage((PVOID)MmGetPhysicalAddressForProcess(NULL, Address));
}
/*
* Cleanup and release locks
*/
PageOp->Status = STATUS_SUCCESS;
KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
MmReleasePageOp(PageOp);
MmUnlockSectionSegment(Segment);
MmUnlockSection(Section);
return(STATUS_SUCCESS);
@ -384,11 +348,6 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
MmUnlockAddressSpace(AddressSpace);
MmWaitForFreePages();
MmLockAddressSpace(AddressSpace);
if (MmIsPagePresent(NULL, Address))
{
MmUnlockAddressSpace(AddressSpace);
return(STATUS_SUCCESS);
}
MmLockSection(Section);
MmLockSectionSegment(Segment);
Page = MmAllocPage(0);
@ -401,10 +360,21 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
{
MmLockPage((PVOID)MmGetPhysicalAddressForProcess(NULL, Address));
}
/*
* Cleanup and release locks
*/
PageOp->Status = STATUS_SUCCESS;
KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
MmReleasePageOp(PageOp);
MmUnlockSectionSegment(Segment);
MmUnlockSection(Section);
return(STATUS_SUCCESS);
}
/*
* Check if this page needs to be mapped COW
*/
if (Segment->Characteristics & IMAGE_SECTION_CHAR_DATA)
{
Attributes = PAGE_READONLY;
@ -419,8 +389,6 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
*/
Entry = MmGetPageEntrySectionSegment(Segment, Offset.u.LowPart);
DPRINT("Entry %x\n", Entry);
if (Entry == 0)
{
/*
@ -440,55 +408,8 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
MmUnlockAddressSpace(AddressSpace);
MmWaitForFreePages();
MmLockAddressSpace(AddressSpace);
if (MmIsPagePresent(NULL, Address))
{
MmUnlockAddressSpace(AddressSpace);
return(STATUS_SUCCESS);
}
MmLockSection(Section);
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);
}
@ -498,26 +419,12 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
Mdl = MmCreateMdl(NULL, NULL, PAGESIZE);
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
*/
MmUnlockSectionSegment(Segment);
MmUnlockSection(Section);
MmUnlockAddressSpace(AddressSpace);
DPRINT("Reading file offset %x\n", Offset.QuadPart);
Status = IoPageRead(MemoryArea->Data.SectionData.Section->FileObject,
Mdl,
&Offset,
@ -529,6 +436,13 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
* FIXME: What do we know in this case?
*/
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);
return(Status);
}
@ -558,12 +472,6 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
Entry = (ULONG)Page;
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(),
Address,
Attributes,
@ -577,23 +485,13 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
{
MmLockPage((PVOID)MmGetPhysicalAddressForProcess(NULL, Address));
}
MmUnlockSectionSegment(Segment);
MmUnlockSection(Section);
DPRINT("MmNotPresentFaultSectionView succeeded\n");
return(STATUS_SUCCESS);
}
else if (Entry & SPE_PAGEIN_PENDING)
{
return(MmWaitForPendingOperationSection(AddressSpace,
MemoryArea,
Address,
Section,
Segment,
Offset,
Entry,
Attributes,
Locked));
PageOp->Status = STATUS_SUCCESS;
KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
MmReleasePageOp(PageOp);
MmUnlockSectionSegment(Segment);
MmUnlockSection(Section);
DPRINT("MmNotPresentFaultSectionView succeeded\n");
return(STATUS_SUCCESS);
}
else
{
@ -618,10 +516,12 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
{
MmLockPage((PVOID)MmGetPhysicalAddressForProcess(NULL, Address));
}
MmUnlockSectionSegment(Segment);
MmUnlockSection(Section);
return(STATUS_SUCCESS);
PageOp->Status = STATUS_SUCCESS;
KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
MmReleasePageOp(PageOp);
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
* PROJECT: ReactOS kernel
@ -222,7 +222,22 @@ MmNotPresentFaultVirtualMemory(PMADDRESS_SPACE AddressSpace,
NTSTATUS Status;
PMM_SEGMENT Segment;
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
*/
@ -235,13 +250,56 @@ MmNotPresentFaultVirtualMemory(PMADDRESS_SPACE AddressSpace,
{
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)
{
MmLockPage((PVOID)MmGetPhysicalAddressForProcess(NULL, Address));
}
MmReleasePageOp(PageOp);
return(STATUS_SUCCESS);
}
@ -254,18 +312,9 @@ MmNotPresentFaultVirtualMemory(PMADDRESS_SPACE AddressSpace,
MmUnlockAddressSpace(AddressSpace);
MmWaitForFreePages();
MmLockAddressSpace(AddressSpace);
if (MmIsPagePresent(NULL, Address))
{
if (Locked)
{
MmLockPage((PVOID)MmGetPhysicalAddressForProcess(NULL,
Address));
}
return(STATUS_SUCCESS);
}
Page = MmAllocPage(0);
}
/*
* Add the page to the process's working set
*/
@ -285,16 +334,6 @@ MmNotPresentFaultVirtualMemory(PMADDRESS_SPACE AddressSpace,
MmUnlockAddressSpace(AddressSpace);
MmWaitForFreePages();
MmLockAddressSpace(AddressSpace);
if (MmIsPagePresent(NULL, Address))
{
if (Locked)
{
MmLockPage((PVOID)MmGetPhysicalAddressForProcess(NULL,
Address));
}
MmDereferencePage(Page);
return(STATUS_SUCCESS);
}
Status = MmCreateVirtualMapping(PsGetCurrentProcess(),
Address,
MemoryArea->Attributes,
@ -302,16 +341,22 @@ MmNotPresentFaultVirtualMemory(PMADDRESS_SPACE AddressSpace,
}
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));
}
return(STATUS_SUCCESS);
}
MmLockPage((PVOID)MmGetPhysicalAddressForProcess(NULL, Address));
}
PageOp->Status = STATUS_SUCCESS;
KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
MmReleasePageOp(PageOp);
return(STATUS_SUCCESS);
}
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
NtFreeVirtualMemory(IN HANDLE ProcessHandle,
IN PVOID* PBaseAddress,
@ -1033,12 +1099,8 @@ NtFreeVirtualMemory(IN HANDLE ProcessHandle,
MmDereserveSwapPages(PAGE_ROUND_UP(MemoryArea->Length));
}
#endif
MmFreeMemoryArea(&Process->AddressSpace,
BaseAddress,
0,
MmFreeVirtualMemoryPage,
(PVOID)Process);
MmFreeVirtualMemory(Process, MemoryArea);
MmUnlockAddressSpace(AddressSpace);
ObDereferenceObject(Process);
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
* PROJECT: ReactOS kernel
@ -16,6 +16,7 @@
#include <internal/ob.h>
#include <ntos/synch.h>
#include <internal/pool.h>
#include <internal/ps.h>
#define NDEBUG
#include <internal/debug.h>
@ -87,7 +88,6 @@ NtCreateSemaphore(OUT PHANDLE SemaphoreHandle,
{
PKSEMAPHORE Semaphore;
DPRINT("NtCreateSemaphore()\n");
Semaphore = ObCreateObject(SemaphoreHandle,
DesiredAccess,
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
* PROJECT: ReactOS kernel
@ -13,15 +13,20 @@
//#include <internal/nls.h>
#include <ctype.h>
#include <ntos/minmax.h>
#include <internal/pool.h>
#define NDEBUG
#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 *****************************************************************/
WCHAR
STDCALL
WCHAR STDCALL
RtlAnsiCharToUnicodeChar(CHAR AnsiChar)
{
ULONG Size;
@ -79,8 +84,9 @@ RtlAnsiStringToUnicodeString (
{
DestinationString->MaximumLength = Length + sizeof(WCHAR);
DestinationString->Buffer =
ExAllocatePool (NonPagedPool,
DestinationString->MaximumLength);
ExAllocatePoolWithTag (NonPagedPool,
DestinationString->MaximumLength,
TAG_USTR);
if (DestinationString->Buffer == NULL)
return STATUS_NO_MEMORY;
}
@ -444,8 +450,9 @@ RtlCreateUnicodeString (
Length = (wcslen (Source) + 1) * sizeof(WCHAR);
Destination->Buffer = ExAllocatePool (NonPagedPool,
Length);
Destination->Buffer = ExAllocatePoolWithTag (NonPagedPool,
Length,
TAG_USTR);
if (Destination->Buffer == NULL)
return FALSE;
@ -481,56 +488,55 @@ RtlCreateUnicodeStringFromAsciiz (
}
NTSTATUS
STDCALL
RtlDowncaseUnicodeString (
IN OUT PUNICODE_STRING DestinationString,
IN PUNICODE_STRING SourceString,
IN BOOLEAN AllocateDestinationString
)
NTSTATUS STDCALL
RtlDowncaseUnicodeString (IN OUT PUNICODE_STRING DestinationString,
IN PUNICODE_STRING SourceString,
IN BOOLEAN AllocateDestinationString)
{
ULONG i;
PWCHAR Src, Dest;
if (AllocateDestinationString == TRUE)
ULONG i;
PWCHAR Src, Dest;
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);
DestinationString->Buffer = ExAllocatePool (NonPagedPool,
SourceString->Length + sizeof(WCHAR));
if (DestinationString->Buffer == NULL)
return STATUS_NO_MEMORY;
*Dest = *Src;
}
else
else if (*Src <= L'Z')
{
if (SourceString->Length >= DestinationString->MaximumLength)
return STATUS_BUFFER_TOO_SMALL;
*Dest = (*Src + (L'a' - L'A'));
}
DestinationString->Length = SourceString->Length;
Src = SourceString->Buffer;
Dest = DestinationString->Buffer;
for (i=0; i < SourceString->Length / sizeof(WCHAR); i++)
else
{
if (*Src < L'A')
{
*Dest = *Src;
}
else if (*Src <= L'Z')
{
*Dest = (*Src + (L'a' - L'A'));
}
else
{
/* FIXME: characters above 'Z' */
*Dest = *Src;
}
Dest++;
Src++;
/* FIXME: characters above 'Z' */
*Dest = *Src;
}
*Dest = 0;
return STATUS_SUCCESS;
Dest++;
Src++;
}
*Dest = 0;
return STATUS_SUCCESS;
}
@ -829,60 +835,58 @@ RtlIntegerToUnicodeString (
}
NTSTATUS
STDCALL
RtlOemStringToCountedUnicodeString (
IN OUT PUNICODE_STRING DestinationString,
IN POEM_STRING SourceString,
IN BOOLEAN AllocateDestinationString
)
NTSTATUS STDCALL
RtlOemStringToCountedUnicodeString (IN OUT PUNICODE_STRING DestinationString,
IN POEM_STRING SourceString,
IN BOOLEAN AllocateDestinationString)
{
NTSTATUS Status;
ULONG Length;
NTSTATUS Status;
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)
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 =
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;
DestinationString->Buffer[Length / sizeof(WCHAR)] = 0;
return STATUS_SUCCESS;
}
@ -902,59 +906,57 @@ RtlOemStringToUnicodeSize (
}
NTSTATUS
STDCALL
RtlOemStringToUnicodeString (
IN OUT PUNICODE_STRING DestinationString,
IN POEM_STRING SourceString,
IN BOOLEAN AllocateDestinationString
)
NTSTATUS STDCALL
RtlOemStringToUnicodeString (IN OUT PUNICODE_STRING DestinationString,
IN POEM_STRING SourceString,
IN BOOLEAN AllocateDestinationString)
{
NTSTATUS Status;
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 =
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,
NTSTATUS Status;
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 (!NT_SUCCESS(Status))
{
if (AllocateDestinationString)
ExFreePool (DestinationString->Buffer);
return Status;
}
DestinationString->Buffer[Length / sizeof(WCHAR)] = 0;
return STATUS_SUCCESS;
DestinationString->Buffer[Length / sizeof(WCHAR)] = 0;
return STATUS_SUCCESS;
}
@ -1061,118 +1063,116 @@ RtlUnicodeStringToAnsiSize(IN PUNICODE_STRING UnicodeString)
NTSTATUS
STDCALL
RtlUnicodeStringToAnsiString (
IN OUT PANSI_STRING DestinationString,
IN PUNICODE_STRING SourceString,
IN BOOLEAN AllocateDestinationString
)
RtlUnicodeStringToAnsiString (IN OUT PANSI_STRING DestinationString,
IN PUNICODE_STRING SourceString,
IN BOOLEAN AllocateDestinationString)
{
NTSTATUS Status;
ULONG Length;
if (NlsMbCodePageTag == TRUE)
Length = RtlUnicodeStringToAnsiSize (SourceString);
else
Length = SourceString->Length / sizeof(WCHAR);
if (AllocateDestinationString == TRUE)
{
DestinationString->MaximumLength = Length + sizeof(CHAR);
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 = RtlUnicodeToMultiByteN (DestinationString->Buffer,
DestinationString->Length,
NULL,
SourceString->Buffer,
SourceString->Length);
if (!NT_SUCCESS(Status))
{
if (AllocateDestinationString)
ExFreePool (DestinationString->Buffer);
NTSTATUS Status;
ULONG Length;
if (NlsMbCodePageTag == TRUE)
Length = RtlUnicodeStringToAnsiSize (SourceString);
else
Length = SourceString->Length / sizeof(WCHAR);
if (AllocateDestinationString == TRUE)
{
DestinationString->MaximumLength = Length + sizeof(CHAR);
DestinationString->Buffer =
ExAllocatePoolWithTag (NonPagedPool,
DestinationString->MaximumLength,
TAG_ASTR);
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 = RtlUnicodeToMultiByteN (DestinationString->Buffer,
DestinationString->Length,
NULL,
SourceString->Buffer,
SourceString->Length);
if (!NT_SUCCESS(Status))
{
if (AllocateDestinationString)
ExFreePool (DestinationString->Buffer);
return Status;
}
DestinationString->Buffer[Length] = 0;
return STATUS_SUCCESS;
}
DestinationString->Buffer[Length] = 0;
return STATUS_SUCCESS;
}
NTSTATUS
STDCALL
RtlUnicodeStringToCountedOemString (
IN OUT POEM_STRING DestinationString,
IN PUNICODE_STRING SourceString,
IN BOOLEAN AllocateDestinationString
)
RtlUnicodeStringToCountedOemString (IN OUT POEM_STRING DestinationString,
IN PUNICODE_STRING SourceString,
IN BOOLEAN AllocateDestinationString)
{
NTSTATUS Status;
ULONG Length;
ULONG Size;
if (NlsMbOemCodePageTag == 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 (AllocateDestinationString)
{
DestinationString->Buffer = ExAllocatePool (NonPagedPool,
Length);
if (DestinationString->Buffer == NULL)
return STATUS_NO_MEMORY;
RtlZeroMemory (DestinationString->Buffer,
Length);
DestinationString->MaximumLength = (WORD)Length;
NTSTATUS Status;
ULONG Length;
ULONG Size;
if (NlsMbOemCodePageTag == 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 (AllocateDestinationString)
{
DestinationString->Buffer = ExAllocatePoolWithTag (NonPagedPool,
Length,
TAG_ASTR);
if (DestinationString->Buffer == NULL)
return STATUS_NO_MEMORY;
RtlZeroMemory (DestinationString->Buffer,
Length);
DestinationString->MaximumLength = (WORD)Length;
}
else
else
{
if (Length > DestinationString->MaximumLength)
{
if (Length > DestinationString->MaximumLength)
{
if (DestinationString->MaximumLength == 0)
return STATUS_BUFFER_OVERFLOW;
DestinationString->Length =
DestinationString->MaximumLength - 1;
}
if (DestinationString->MaximumLength == 0)
return STATUS_BUFFER_OVERFLOW;
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,
DestinationString->Length,
&Size,
SourceString->Buffer,
SourceString->Length);
if (!NT_SUCCESS(Status))
{
if (AllocateDestinationString)
ExFreePool (DestinationString->Buffer);
return Status;
}
DestinationString->Buffer[Size] = 0;
return STATUS_SUCCESS;
return Status;
}
DestinationString->Buffer[Size] = 0;
return STATUS_SUCCESS;
}
@ -1282,56 +1282,54 @@ RtlUnicodeStringToOemSize (
}
NTSTATUS
STDCALL
RtlUnicodeStringToOemString (
IN OUT POEM_STRING DestinationString,
IN PUNICODE_STRING SourceString,
IN BOOLEAN AllocateDestinationString
)
NTSTATUS STDCALL
RtlUnicodeStringToOemString (IN OUT POEM_STRING DestinationString,
IN PUNICODE_STRING SourceString,
IN BOOLEAN AllocateDestinationString)
{
NTSTATUS Status;
ULONG Length;
if (NlsMbOemCodePageTag == TRUE)
Length = RtlUnicodeStringToAnsiSize (SourceString);
else
Length = SourceString->Length / sizeof(WCHAR);
if (AllocateDestinationString == TRUE)
{
DestinationString->MaximumLength = Length + sizeof(CHAR);
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 = RtlUnicodeToOemN (DestinationString->Buffer,
DestinationString->Length,
NULL,
SourceString->Buffer,
SourceString->Length);
if (!NT_SUCCESS(Status))
{
if (AllocateDestinationString)
ExFreePool (DestinationString->Buffer);
return Status;
}
DestinationString->Buffer[Length] = 0;
return STATUS_SUCCESS;
NTSTATUS Status;
ULONG Length;
if (NlsMbOemCodePageTag == TRUE)
Length = RtlUnicodeStringToAnsiSize (SourceString);
else
Length = SourceString->Length / sizeof(WCHAR);
if (AllocateDestinationString == TRUE)
{
DestinationString->MaximumLength = Length + sizeof(CHAR);
DestinationString->Buffer =
ExAllocatePoolWithTag (NonPagedPool,
DestinationString->MaximumLength,
TAG_OSTR);
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 = RtlUnicodeToOemN (DestinationString->Buffer,
DestinationString->Length,
NULL,
SourceString->Buffer,
SourceString->Length);
if (!NT_SUCCESS(Status))
{
if (AllocateDestinationString)
ExFreePool (DestinationString->Buffer);
return Status;
}
DestinationString->Buffer[Length] = 0;
return STATUS_SUCCESS;
}
@ -1353,43 +1351,42 @@ RtlUpcaseUnicodeChar (
}
NTSTATUS
STDCALL
RtlUpcaseUnicodeString (
IN OUT PUNICODE_STRING DestinationString,
IN PUNICODE_STRING SourceString,
IN BOOLEAN AllocateDestinationString
)
NTSTATUS STDCALL
RtlUpcaseUnicodeString (IN OUT PUNICODE_STRING DestinationString,
IN PUNICODE_STRING SourceString,
IN BOOLEAN AllocateDestinationString)
{
ULONG i;
PWCHAR Src, Dest;
if (AllocateDestinationString == TRUE)
{
DestinationString->MaximumLength = SourceString->Length + sizeof(WCHAR);
DestinationString->Buffer = ExAllocatePool (NonPagedPool,
SourceString->Length + sizeof(WCHAR));
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++)
{
*Dest = RtlUpcaseUnicodeChar (*Src);
Dest++;
Src++;
}
*Dest = 0;
return STATUS_SUCCESS;
ULONG i;
PWCHAR Src, Dest;
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++)
{
*Dest = RtlUpcaseUnicodeChar (*Src);
Dest++;
Src++;
}
*Dest = 0;
return STATUS_SUCCESS;
}
@ -1401,111 +1398,111 @@ RtlUpcaseUnicodeStringToAnsiString (
IN BOOLEAN AllocateDestinationString
)
{
NTSTATUS Status;
ULONG Length;
if (NlsMbCodePageTag == TRUE)
Length = RtlUnicodeStringToAnsiSize (SourceString);
else
Length = SourceString->Length / sizeof(WCHAR);
if (AllocateDestinationString == TRUE)
{
DestinationString->MaximumLength = Length + sizeof(CHAR);
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 = RtlUpcaseUnicodeToMultiByteN (DestinationString->Buffer,
DestinationString->Length,
NULL,
SourceString->Buffer,
SourceString->Length);
if (!NT_SUCCESS(Status))
{
if (AllocateDestinationString)
ExFreePool (DestinationString->Buffer);
return Status;
}
DestinationString->Buffer[Length] = 0;
return STATUS_SUCCESS;
NTSTATUS Status;
ULONG Length;
if (NlsMbCodePageTag == TRUE)
Length = RtlUnicodeStringToAnsiSize (SourceString);
else
Length = SourceString->Length / sizeof(WCHAR);
if (AllocateDestinationString == TRUE)
{
DestinationString->MaximumLength = Length + sizeof(CHAR);
DestinationString->Buffer =
ExAllocatePoolWithTag (NonPagedPool,
DestinationString->MaximumLength,
TAG_ASTR);
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 = RtlUpcaseUnicodeToMultiByteN (DestinationString->Buffer,
DestinationString->Length,
NULL,
SourceString->Buffer,
SourceString->Length);
if (!NT_SUCCESS(Status))
{
if (AllocateDestinationString)
ExFreePool (DestinationString->Buffer);
return Status;
}
DestinationString->Buffer[Length] = 0;
return STATUS_SUCCESS;
}
NTSTATUS
STDCALL
RtlUpcaseUnicodeStringToCountedOemString (
IN OUT POEM_STRING DestinationString,
IN PUNICODE_STRING SourceString,
IN BOOLEAN AllocateDestinationString
)
NTSTATUS STDCALL
RtlUpcaseUnicodeStringToCountedOemString (IN OUT POEM_STRING DestinationString,
IN PUNICODE_STRING SourceString,
IN BOOLEAN AllocateDestinationString)
{
NTSTATUS Status;
ULONG Length;
ULONG Size;
NTSTATUS Status;
ULONG Length;
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)
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 (AllocateDestinationString == TRUE)
if (AllocateDestinationString == TRUE)
{
DestinationString->Buffer = ExAllocatePoolWithTag (NonPagedPool,
Length,
TAG_OSTR);
if (DestinationString->Buffer == NULL)
return STATUS_NO_MEMORY;
RtlZeroMemory (DestinationString->Buffer,
Length);
DestinationString->MaximumLength = (WORD)Length;
}
else
{
if (Length > DestinationString->MaximumLength)
{
DestinationString->Buffer = ExAllocatePool (NonPagedPool,
Length);
if (DestinationString->Buffer == NULL)
return STATUS_NO_MEMORY;
RtlZeroMemory (DestinationString->Buffer,
Length);
DestinationString->MaximumLength = (WORD)Length;
if (DestinationString->MaximumLength == 0)
return STATUS_BUFFER_OVERFLOW;
DestinationString->Length =
DestinationString->MaximumLength - 1;
}
else
{
if (Length > DestinationString->MaximumLength)
{
if (DestinationString->MaximumLength == 0)
return STATUS_BUFFER_OVERFLOW;
DestinationString->Length =
DestinationString->MaximumLength - 1;
}
}
Status = RtlUpcaseUnicodeToOemN (DestinationString->Buffer,
DestinationString->Length,
&Size,
SourceString->Buffer,
SourceString->Length);
if (!NT_SUCCESS(Status))
{
if (AllocateDestinationString)
ExFreePool (DestinationString->Buffer);
return Status;
}
DestinationString->Buffer[Size] = 0;
return STATUS_SUCCESS;
}
Status = RtlUpcaseUnicodeToOemN (DestinationString->Buffer,
DestinationString->Length,
&Size,
SourceString->Buffer,
SourceString->Length);
if (!NT_SUCCESS(Status))
{
if (AllocateDestinationString)
ExFreePool (DestinationString->Buffer);
return Status;
}
DestinationString->Buffer[Size] = 0;
return STATUS_SUCCESS;
}
@ -1528,8 +1525,8 @@ RtlUpcaseUnicodeStringToOemString (
if (AllocateDestinationString == TRUE)
{
DestinationString->MaximumLength = Length + sizeof(CHAR);
DestinationString->Buffer = ExAllocatePool (NonPagedPool,
DestinationString->MaximumLength);
DestinationString->Buffer = ExAllocatePoolWithTag (NonPagedPool,
DestinationString->MaximumLength, TAG_OSTR);
if (DestinationString->Buffer == NULL)
return STATUS_NO_MEMORY;
}