mirror of
https://github.com/reactos/reactos.git
synced 2025-02-24 01:15:09 +00:00
Represent page-in operations by descriptors
svn path=/trunk/; revision=1682
This commit is contained in:
parent
c20f2479b6
commit
47ea39add9
18 changed files with 854 additions and 943 deletions
|
@ -51,3 +51,4 @@ int main()
|
|||
printf("VirtualAlloc failed 5\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -16,11 +16,13 @@
|
|||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
|
||||
|
||||
NTSTATUS STDCALL NtSetLdtEntries(HANDLE Thread,
|
||||
ULONG FirstEntry,
|
||||
PULONG Entries)
|
||||
NTSTATUS STDCALL
|
||||
NtSetLdtEntries(HANDLE Thread, ULONG FirstEntry, PULONG Entries)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue