diff --git a/reactos/apps/tests/vmtest/vmtest.c b/reactos/apps/tests/vmtest/vmtest.c index 99dec96276b..d68ebbb34e2 100644 --- a/reactos/apps/tests/vmtest/vmtest.c +++ b/reactos/apps/tests/vmtest/vmtest.c @@ -51,3 +51,4 @@ int main() printf("VirtualAlloc failed 5\n"); } } + diff --git a/reactos/drivers/fs/vfat/create.c b/reactos/drivers/fs/vfat/create.c index f70a081ee84..63aa396d298 100644 --- a/reactos/drivers/fs/vfat/create.c +++ b/reactos/drivers/fs/vfat/create.c @@ -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; diff --git a/reactos/lib/kernel32/process/proc.c b/reactos/lib/kernel32/process/proc.c index e5d0271a23c..1c584b14465 100644 --- a/reactos/lib/kernel32/process/proc.c +++ b/reactos/lib/kernel32/process/proc.c @@ -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); } diff --git a/reactos/lib/kernel32/thread/tls.c b/reactos/lib/kernel32/thread/tls.c index 29bafcdd779..39a965f643b 100644 --- a/reactos/lib/kernel32/thread/tls.c +++ b/reactos/lib/kernel32/thread/tls.c @@ -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) { diff --git a/reactos/lib/ntdll/rtl/thread.c b/reactos/lib/ntdll/rtl/thread.c index e535a4c93e1..0eef3e50477 100644 --- a/reactos/lib/ntdll/rtl/thread.c +++ b/reactos/lib/ntdll/rtl/thread.c @@ -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; diff --git a/reactos/ntoskrnl/cc/view.c b/reactos/ntoskrnl/cc/view.c index be08c80b303..ab4c0d4038a 100644 --- a/reactos/ntoskrnl/cc/view.c +++ b/reactos/ntoskrnl/cc/view.c @@ -1,6 +1,6 @@ /* * ReactOS kernel - * Copyright (C) 1998, 1999, 2000, 2001 David Welch + * 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 diff --git a/reactos/ntoskrnl/cm/registry.c b/reactos/ntoskrnl/cm/registry.c index 3d86e6d4294..2c55ea0cbb8 100644 --- a/reactos/ntoskrnl/cm/registry.c +++ b/reactos/ntoskrnl/cm/registry.c @@ -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 #include #include +#include #define NDEBUG #include @@ -301,7 +302,6 @@ static NTSTATUS CmiAddFree(PREGISTRY_FILE RegistryFile, PFREE_SUB_BLOCK FreeBlock,BLOCK_OFFSET FreeOffset); - /* --------------------------------------------- Public Interface */ VOID diff --git a/reactos/ntoskrnl/include/internal/mm.h b/reactos/ntoskrnl/include/internal/mm.h index 7739791432f..12997576090 100644 --- a/reactos/ntoskrnl/include/internal/mm.h +++ b/reactos/ntoskrnl/include/internal/mm.h @@ -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 diff --git a/reactos/ntoskrnl/ke/ldt.c b/reactos/ntoskrnl/ke/ldt.c index 5d33e115edc..a689760dbdd 100644 --- a/reactos/ntoskrnl/ke/ldt.c +++ b/reactos/ntoskrnl/ke/ldt.c @@ -16,11 +16,13 @@ /* FUNCTIONS *****************************************************************/ - - -NTSTATUS STDCALL NtSetLdtEntries(HANDLE Thread, - ULONG FirstEntry, - PULONG Entries) +NTSTATUS STDCALL +NtSetLdtEntries(HANDLE Thread, ULONG FirstEntry, PULONG Entries) { UNIMPLEMENTED; } + + + + + diff --git a/reactos/ntoskrnl/lpc/close.c b/reactos/ntoskrnl/lpc/close.c index 2715e15ae75..3d289afe30d 100644 --- a/reactos/ntoskrnl/lpc/close.c +++ b/reactos/ntoskrnl/lpc/close.c @@ -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); diff --git a/reactos/ntoskrnl/mm/freelist.c b/reactos/ntoskrnl/mm/freelist.c index 542ab791d71..e97d820af1e 100644 --- a/reactos/ntoskrnl/mm/freelist.c +++ b/reactos/ntoskrnl/mm/freelist.c @@ -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); -} diff --git a/reactos/ntoskrnl/mm/mdl.c b/reactos/ntoskrnl/mm/mdl.c index 87de1bddb65..b42988f1970 100644 --- a/reactos/ntoskrnl/mm/mdl.c +++ b/reactos/ntoskrnl/mm/mdl.c @@ -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 #include #include +#include #define NDEBUG #include -/* 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); diff --git a/reactos/ntoskrnl/mm/mm.c b/reactos/ntoskrnl/mm/mm.c index bf8786e390f..8af07eaf877 100644 --- a/reactos/ntoskrnl/mm/mm.c +++ b/reactos/ntoskrnl/mm/mm.c @@ -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: diff --git a/reactos/ntoskrnl/mm/pageop.c b/reactos/ntoskrnl/mm/pageop.c index f84edef7b1e..6db3af1e7c1 100644 --- a/reactos/ntoskrnl/mm/pageop.c +++ b/reactos/ntoskrnl/mm/pageop.c @@ -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 #include #include +#include #define NDEBUG #include @@ -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); } + + + + + + + + diff --git a/reactos/ntoskrnl/mm/section.c b/reactos/ntoskrnl/mm/section.c index e257d7757c7..1f26f9af20e 100644 --- a/reactos/ntoskrnl/mm/section.c +++ b/reactos/ntoskrnl/mm/section.c @@ -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); } } diff --git a/reactos/ntoskrnl/mm/virtual.c b/reactos/ntoskrnl/mm/virtual.c index cbe11f5e390..acd03f7b708 100644 --- a/reactos/ntoskrnl/mm/virtual.c +++ b/reactos/ntoskrnl/mm/virtual.c @@ -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); diff --git a/reactos/ntoskrnl/nt/ntsem.c b/reactos/ntoskrnl/nt/ntsem.c index 98a3cf24440..8ffaee0a091 100644 --- a/reactos/ntoskrnl/nt/ntsem.c +++ b/reactos/ntoskrnl/nt/ntsem.c @@ -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 #include #include +#include #define NDEBUG #include @@ -87,7 +88,6 @@ NtCreateSemaphore(OUT PHANDLE SemaphoreHandle, { PKSEMAPHORE Semaphore; - DPRINT("NtCreateSemaphore()\n"); Semaphore = ObCreateObject(SemaphoreHandle, DesiredAccess, ObjectAttributes, diff --git a/reactos/ntoskrnl/rtl/unicode.c b/reactos/ntoskrnl/rtl/unicode.c index 8e67813eb04..63f86417ecb 100644 --- a/reactos/ntoskrnl/rtl/unicode.c +++ b/reactos/ntoskrnl/rtl/unicode.c @@ -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 #include #include +#include #define NDEBUG #include +/* 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; }