/* $Id$ */
#define FlagOn(x,f) ((x) & (f))
+VOID
+STDCALL
+FsRtlFreeFileLock(
+ IN PFILE_LOCK FileLock
+ );
+
+PFILE_LOCK
+STDCALL
+FsRtlAllocateFileLock (
+ IN PCOMPLETE_LOCK_IRP_ROUTINE CompleteLockIrpRoutine OPTIONAL,
+ IN PUNLOCK_ROUTINE UnlockRoutine OPTIONAL
+ );
+
+#define FsRtlAreThereCurrentFileLocks(FL) (((FL)->FastIoIsQuestionable))
+
BOOLEAN STDCALL
FsRtlAddLargeMcbEntry(IN PLARGE_MCB Mcb,
IN LONGLONG Vbn,
LARGE_INTEGER EndingByte;
} FILE_LOCK_INFO, *PFILE_LOCK_INFO;
+typedef struct _FILE_LOCK_TOC {
+ KSPIN_LOCK SpinLock;
+ LIST_ENTRY GrantedListHead;
+ LIST_ENTRY PendingListHead;
+} FILE_LOCK_TOC, *PFILE_LOCK_TOC;
+
+typedef struct _FILE_LOCK_GRANTED {
+ LIST_ENTRY ListEntry;
+ FILE_LOCK_INFO Lock;
+} FILE_LOCK_GRANTED, *PFILE_LOCK_GRANTED;
+
+typedef struct _FILE_LOCK_PENDING {
+ LIST_ENTRY ListEntry;
+ PIRP Irp;
+ PVOID Context;
+} FILE_LOCK_PENDING, *PFILE_LOCK_PENDING;
+
// raw internal file lock struct returned from FsRtlGetNextFileLock
typedef struct _FILE_SHARED_LOCK_ENTRY {
PVOID Unknown1;
#define IRP_MJ_SCSI IRP_MJ_INTERNAL_DEVICE_CONTROL
/*
+ * Minor function numbers for IRP_MJ_LOCK_CONTROL
+ */
+#define IRP_MN_LOCK 0x01
+#define IRP_MN_UNLOCK_SINGLE 0x02
+#define IRP_MN_UNLOCK_ALL 0x03
+#define IRP_MN_UNLOCK_ALL_BY_KEY 0x04
+
+/*
* Minor function numbers for IRP_MJ_FILE_SYSTEM_CONTROL
*/
#define IRP_MN_USER_FS_REQUEST 0x00
struct _SCSI_REQUEST_BLOCK *Srb;
} Scsi;
+ //byte range file locking
+ struct
+ {
+ PLARGE_INTEGER Length;
+ ULONG Key;
+ LARGE_INTEGER ByteOffset;
+ } LockControl;
+
/* Paramters for other calls */
struct
{
#define HEAP_NO_SERIALIZE (1)
#define HEAP_ZERO_MEMORY (8)
#define HEAP_REALLOC_IN_PLACE_ONLY (16)
-#define HEAP_GROWABLE (32)
+#define HEAP_GROWABLE (2)
#define HEAP_NO_VALLOC (64)
#endif /* __INCLUDE_HEAP_H */
Length = RtlUnicodeStringToAnsiSize (&WindowsDirectory); //len of ansi str incl. nullchar
- printf("windirlen incl term %i\n", Length);
-
if (uSize >= Length){
- printf("ok: enoug space\n");
-
String.Length = 0;
String.MaximumLength = uSize;
String.Buffer = lpBuffer;
if (!NT_SUCCESS(Status))
return 0;
- printf("good: ret chars %i\n",Length-1);
- printf("dir: %s\n",lpBuffer);
return Length-1; //good: ret chars excl. nullchar
}
- printf("bad: ret chars needed %i\n",Length);
return Length; //bad: ret space needed incl. nullchar
}
switch ((ULONG)hFile)
{
case STD_INPUT_HANDLE:
- hFile = NtCurrentPeb()->ProcessParameters->hStdInput;\r
+ hFile = NtCurrentPeb()->ProcessParameters->hStdInput;
+
break;
case STD_OUTPUT_HANDLE:
- hFile = NtCurrentPeb()->ProcessParameters->hStdOutput;\r
+ hFile = NtCurrentPeb()->ProcessParameters->hStdOutput;
+
break;
case STD_ERROR_HANDLE:
- hFile = NtCurrentPeb()->ProcessParameters->hStdError;\r
+ hFile = NtCurrentPeb()->ProcessParameters->hStdError;
+
break;
}
}
+/*
+The caller must have opened the file with the DesiredAccess FILE_WRITE_DATA flag set.
+*/
WINBOOL STDCALL
SetEndOfFile(HANDLE hFile)
{
- int x = -1;
- DWORD Num;
- return WriteFile(hFile,&x,1,&Num,NULL);
+ IO_STATUS_BLOCK IoStatusBlock;
+ FILE_END_OF_FILE_INFORMATION EndOfFileInfo;
+ FILE_ALLOCATION_INFORMATION FileAllocationInfo;
+ FILE_POSITION_INFORMATION FilePosInfo;
+ NTSTATUS Status;
+
+ //get current position
+ Status = NtQueryInformationFile(
+ hFile,
+ &IoStatusBlock,
+ &FilePosInfo,
+ sizeof(FILE_POSITION_INFORMATION),
+ FilePositionInformation
+ );
+
+ if (!NT_SUCCESS(Status)){
+ SetLastErrorByStatus(Status);
+ return FALSE;
+ }
+
+ EndOfFileInfo.EndOfFile.QuadPart = FilePosInfo.CurrentByteOffset.QuadPart;
+
+ /*
+ NOTE:
+ This call is not supposed to free up any space after the eof marker
+ if the file gets truncated. We have to deallocate the space explicitly afterwards.
+ But...most file systems dispatch both FileEndOfFileInformation
+ and FileAllocationInformation as they were the same command.
+
+ */
+ Status = NtSetInformationFile(
+ hFile,
+ &IoStatusBlock, //out
+ &EndOfFileInfo,
+ sizeof(FILE_END_OF_FILE_INFORMATION),
+ FileEndOfFileInformation
+ );
+
+ if (!NT_SUCCESS(Status)){
+ SetLastErrorByStatus(Status);
+ return FALSE;
+ }
+
+ FileAllocationInfo.AllocationSize.QuadPart = FilePosInfo.CurrentByteOffset.QuadPart;
+
+
+ Status = NtSetInformationFile(
+ hFile,
+ &IoStatusBlock, //out
+ &FileAllocationInfo,
+ sizeof(FILE_ALLOCATION_INFORMATION),
+ FileAllocationInformation
+ );
+
+ if (!NT_SUCCESS(Status)){
+ SetLastErrorByStatus(Status);
+ return FALSE;
+ }
+
+ return TRUE;
+
}
/* EOF */
DWORD FileAttributes = 0;
- if ( iAttribute == 1 )
+ if ( iAttribute == 0 )
FileAttributes |= FILE_ATTRIBUTE_NORMAL;
- else if ( iAttribute == 2 )
+ else if ( iAttribute == 1 )
FileAttributes |= FILE_ATTRIBUTE_READONLY;
- else if ( iAttribute == 3 )
+ else if ( iAttribute == 2 )
FileAttributes |= FILE_ATTRIBUTE_HIDDEN;
else if ( iAttribute == 4 )
FileAttributes |= FILE_ATTRIBUTE_SYSTEM;
return Result;
}
+struct _CONTEXT;
+struct __EXCEPTION_RECORD;
+
+static
+EXCEPTION_DISPOSITION
+__cdecl
+_except_handler(
+ struct _EXCEPTION_RECORD *ExceptionRecord,
+ void * EstablisherFrame,
+ struct _CONTEXT *ContextRecord,
+ void * DispatcherContext )
+{
+ DPRINT("Process terminated abnormally...\n");
-static\r
-EXCEPTION_DISPOSITION\r
-__cdecl\r
-_except_handler(\r
- struct _EXCEPTION_RECORD *ExceptionRecord,\r
- void * EstablisherFrame,\r
- struct _CONTEXT *ContextRecord,\r
- void * DispatcherContext )\r
-{\r
- DPRINT("Process terminated abnormally...\n");\r
-\r
- if (/* FIXME: */ TRUE) /* Not a service */\r
- {\r
+ if (/* FIXME: */ TRUE) /* Not a service */
+ {
ExitProcess(0);
}
else
/* We should not get to here */
return ExceptionContinueSearch;
-}\r
+}
VOID STDCALL
BaseProcessStart(LPTHREAD_START_ROUTINE lpStartAddress,
- DWORD lpParameter)
+ DWORD lpParameter)
{
UINT uExitCode = 0;
__try1(_except_handler)
{
- uExitCode = (lpStartAddress)(lpParameter);
+ uExitCode = (lpStartAddress)((PVOID)lpParameter);
} __except1
{
}
/* create the PPB */
PpbBase = NULL;
- PpbSize = Ppb->AllocationSize;\r
+ PpbSize = Ppb->AllocationSize;
Status = NtAllocateVirtualMemory(ProcessHandle,
&PpbBase,
0,
NtWriteVirtualMemory(ProcessHandle,
PpbBase,
Ppb,
- Ppb->AllocationSize,\r
+ Ppb->AllocationSize,
&BytesWritten);
/* write pointer to environment */
{
s = TempApplicationNameW;
}
- s = wcsrchr(TempApplicationNameW, L'.');
+ s = wcsrchr(s, L'.');
if (s == NULL)
wcscat(TempApplicationNameW, L".exe");
}
/*
* Translate some handles for the new process
*/
- if (Ppb->CurrentDirectoryHandle)\r
+ if (Ppb->CurrentDirectoryHandle)
{
Status = NtDuplicateObject (NtCurrentProcess(),
- Ppb->CurrentDirectoryHandle,\r
+ Ppb->CurrentDirectoryHandle,
hProcess,
- &Ppb->CurrentDirectoryHandle,\r
+ &Ppb->CurrentDirectoryHandle,
0,
TRUE,
DUPLICATE_SAME_ACCESS);
}
- if (Ppb->hConsole)\r
+ if (Ppb->hConsole)
{
Status = NtDuplicateObject (NtCurrentProcess(),
- Ppb->hConsole,\r
+ Ppb->hConsole,
hProcess,
- &Ppb->hConsole,\r
+ &Ppb->hConsole,
0,
TRUE,
DUPLICATE_SAME_ACCESS);
}
// Set the child console handles
- Ppb->hStdInput = NtCurrentPeb()->ProcessParameters->hStdInput;\r
- Ppb->hStdOutput = NtCurrentPeb()->ProcessParameters->hStdOutput;\r
- Ppb->hStdError = NtCurrentPeb()->ProcessParameters->hStdError;\r
+ Ppb->hStdInput = NtCurrentPeb()->ProcessParameters->hStdInput;
+ Ppb->hStdOutput = NtCurrentPeb()->ProcessParameters->hStdOutput;
+ Ppb->hStdError = NtCurrentPeb()->ProcessParameters->hStdError;
if (lpStartupInfo && (lpStartupInfo->dwFlags & STARTF_USESTDHANDLES))
{
if (lpStartupInfo->hStdInput)
- Ppb->hStdInput = lpStartupInfo->hStdInput;\r
+ Ppb->hStdInput = lpStartupInfo->hStdInput;
if (lpStartupInfo->hStdOutput)
- Ppb->hStdOutput = lpStartupInfo->hStdOutput;\r
+ Ppb->hStdOutput = lpStartupInfo->hStdOutput;
if (lpStartupInfo->hStdError)
- Ppb->hStdError = lpStartupInfo->hStdError;\r
+ Ppb->hStdError = lpStartupInfo->hStdError;
}
- if (IsConsoleHandle(Ppb->hStdInput))\r
+ if (IsConsoleHandle(Ppb->hStdInput))
{
- Ppb->hStdInput = CsrReply.Data.CreateProcessReply.InputHandle;\r
+ Ppb->hStdInput = CsrReply.Data.CreateProcessReply.InputHandle;
}
else
{
DPRINT("Duplicate input handle\n");
Status = NtDuplicateObject (NtCurrentProcess(),
- Ppb->hStdInput,\r
+ Ppb->hStdInput,
hProcess,
- &Ppb->hStdInput,\r
+ &Ppb->hStdInput,
0,
TRUE,
DUPLICATE_SAME_ACCESS);
}
}
- if (IsConsoleHandle(Ppb->hStdOutput))\r
+ if (IsConsoleHandle(Ppb->hStdOutput))
{
- Ppb->hStdOutput = CsrReply.Data.CreateProcessReply.OutputHandle;\r
+ Ppb->hStdOutput = CsrReply.Data.CreateProcessReply.OutputHandle;
}
else
{
DPRINT("Duplicate output handle\n");
Status = NtDuplicateObject (NtCurrentProcess(),
- Ppb->hStdOutput,\r
+ Ppb->hStdOutput,
hProcess,
- &Ppb->hStdOutput,\r
+ &Ppb->hStdOutput,
0,
TRUE,
DUPLICATE_SAME_ACCESS);
DPRINT("NtDuplicateObject failed, status %x\n", Status);
}
}
- if (IsConsoleHandle(Ppb->hStdError))\r
+ if (IsConsoleHandle(Ppb->hStdError))
{
- Ppb->hStdError = CsrReply.Data.CreateProcessReply.OutputHandle;\r
+ Ppb->hStdError = CsrReply.Data.CreateProcessReply.OutputHandle;
}
else
{
DPRINT("Duplicate error handle\n");
Status = NtDuplicateObject (NtCurrentProcess(),
- Ppb->hStdError,\r
+ Ppb->hStdError,
hProcess,
- &Ppb->hStdError,\r
+ &Ppb->hStdError,
0,
TRUE,
DUPLICATE_SAME_ACCESS);
*/
if (lpStartupInfo)
{
- Ppb->dwFlags = lpStartupInfo->dwFlags;\r
- if (Ppb->dwFlags & STARTF_USESHOWWINDOW)\r
+ Ppb->dwFlags = lpStartupInfo->dwFlags;
+ if (Ppb->dwFlags & STARTF_USESHOWWINDOW)
{
- Ppb->wShowWindow = lpStartupInfo->wShowWindow;\r
+ Ppb->wShowWindow = lpStartupInfo->wShowWindow;
}
else
{
- Ppb->wShowWindow = SW_SHOWDEFAULT;\r
+ Ppb->wShowWindow = SW_SHOWDEFAULT;
}
- Ppb->dwX = lpStartupInfo->dwX;\r
- Ppb->dwY = lpStartupInfo->dwY;\r
- Ppb->dwXSize = lpStartupInfo->dwXSize;\r
- Ppb->dwYSize = lpStartupInfo->dwYSize;\r
- Ppb->dwFillAttribute = lpStartupInfo->dwFillAttribute;\r
+ Ppb->dwX = lpStartupInfo->dwX;
+ Ppb->dwY = lpStartupInfo->dwY;
+ Ppb->dwXSize = lpStartupInfo->dwXSize;
+ Ppb->dwYSize = lpStartupInfo->dwYSize;
+ Ppb->dwFillAttribute = lpStartupInfo->dwFillAttribute;
}
else
{
/* $Id$ */
-#include <windows.h>
#include <msvcrt/process.h>
#include <msvcrt/stdlib.h>
-#include <msvcrt/fcntl.h>
+#include <msvcrt/string.h>
#include <msvcrt/errno.h>
+#include <msvcrt/internal/file.h>
#define NDEBUG
#include <msvcrt/msvcrtdbg.h>
extern int maxfno;
+char const* ext[] =
+{
+ "",
+ ".bat",
+ ".cmd",
+ ".com",
+ ".exe"
+};
+
+const char* find_exec(const char* path, char* rpath)
+{
+ char *rp;
+ const char *rd;
+ int i, found = 0;
+
+ DPRINT("find_exec('%s', %x)\n", path, rpath);
+
+ if (path == NULL)
+ {
+ return NULL;
+ }
+ if (strlen(path) > FILENAME_MAX - 1)
+ {
+ return path;
+ }
+ /* copy path in rpath */
+ for (rd = path, rp = rpath; *rd; *rp++ = *rd++);
+ *rp = 0;
+ /* try first with the name as is */
+ for (i = 0; i < sizeof(ext) / sizeof(*ext); i++)
+ {
+ strcpy(rp, ext[i]);
+
+ DPRINT("trying '%s'\n", rpath);
+
+ if (_access(rpath, F_OK) == 0 && _access(rpath, D_OK) != 0)
+ {
+ found = 1;
+ break;
+ }
+ }
+ if (!found)
+ {
+ char* env = getenv("PATH");
+ if (env)
+ {
+ char* ep = env;
+ while (*ep && !found)
+ {
+ if (*ep == ';') ep++;
+ rp=rpath;
+ for (; *ep && (*ep != ';'); *rp++ = *ep++);
+ if (rp > rpath)
+ {
+ rp--;
+ if (*rp != '/' && *rp != '\\')
+ {
+ *++rp = '\\';
+ }
+ rp++;
+ }
+ for (rd=path; *rd; *rp++ = *rd++);
+ for (i = 0; i < sizeof(ext) / sizeof(*ext); i++)
+ {
+ strcpy(rp, ext[i]);
+
+ DPRINT("trying '%s'\n", rpath);
+
+ if (_access(rpath, F_OK) == 0 && _access(rpath, D_OK) != 0)
+ {
+ found = 1;
+ break;
+ }
+ }
+ }
+ free(env);
+ }
+ }
+
+ return found ? rpath : path;
+}
+
static char*
argvtos(char* const* argv, char delim)
{
DPRINT("_spawnvp('%s')\n", cmdname);
- _searchenv(cmdname, "PATH", pathname);
-
- return _spawnv(mode, pathname[0] ? pathname : cmdname, argv);
+ return _spawnv(mode, find_exec(cmdname, pathname), argv);
}
int _spawnlpe(int mode, const char* cmdname, const char* arg0, .../*, NULL, const char* const* envp*/)
DPRINT("_spawnlpe('%s')\n", cmdname);
- _searchenv(cmdname, "PATH", pathname);
-
va_start(argp, arg0);
args = valisttos(arg0, argp, ' ');
do
envs = argvtos(ptr, 0);
if (args)
{
- ret = do_spawn(mode, pathname[0] ? pathname : cmdname, args, envs);
+ ret = do_spawn(mode, find_exec(cmdname, pathname), args, envs);
free(args);
}
if (envs)
DPRINT("_spawnvpe('%s')\n", cmdname);
- _searchenv(cmdname, "PATH", pathname);
-
- return _spawnve(mode, pathname[0] ? pathname : cmdname, argv, envp);
+ return _spawnve(mode, find_exec(cmdname, pathname), argv, envp);
}
int _execl(const char* cmdname, const char* arg0, ...)
DPRINT("_execlp('%s')\n", cmdname);
- _searchenv(cmdname, "PATH", pathname);
-
va_start(argp, arg0);
args = valisttos(arg0, argp, ' ');
if (args)
{
- ret = do_spawn(P_OVERLAY, pathname[0] ? pathname : cmdname, args, NULL);
+ ret = do_spawn(P_OVERLAY, find_exec(cmdname, pathname), args, NULL);
free(args);
}
return ret;
DPRINT("_execlpe('%s')\n", cmdname);
- _searchenv(cmdname, "PATH", pathname);
-
va_start(argp, arg0);
args = valisttos(arg0, argp, ' ');
do
envs = argvtos(ptr, 0);
if (args)
{
- ret = do_spawn(P_OVERLAY, pathname[0] ? pathname : cmdname, args, envs);
+ ret = do_spawn(P_OVERLAY, find_exec(cmdname, pathname), args, envs);
free(args);
}
if (envs)
}
else
{
- Handle = LoadImageW(hinst, lpszWName, uType, cxDesired,
+ Handle = LoadImageW(hinst, (LPCWSTR)lpszName, uType, cxDesired,
cyDesired, fuLoad);
}
return(Handle);
LRESULT STDCALL
DefWndNCCalcSize(HWND hWnd, RECT* Rect)
{
- LRESULT Result;
+ LRESULT Result = 0;
LONG Style = GetClassLongW(hWnd, GCL_STYLE);
RECT TmpRect = {0, 0, 0, 0};
}
else
{
- Ret = RemovePropW(hWnd, lpWString);
+ Ret = RemovePropW(hWnd, (LPCWSTR)lpString);
}
return(Ret);
}
; $Header$
;
; $Log$
-; Revision 1.2 2002/11/04 22:01:07 short
-; update for HEAD-2002110401
+; Revision 1.3 2002/11/07 12:04:04 short
+; update for HEAD-2002110701
;
; Revision 1.4 2000/06/25 03:59:14 dwelch
;
# $Header$
#
# $Log$
-# Revision 1.2 2002/11/04 22:01:07 short
-# update for HEAD-2002110401
+# Revision 1.3 2002/11/07 12:04:04 short
+# update for HEAD-2002110701
#
# Revision 1.4 2000/06/25 03:59:14 dwelch
#
; $Header$
;
; $Log$
-; Revision 1.2 2002/11/04 22:01:07 short
-; update for HEAD-2002110401
+; Revision 1.3 2002/11/07 12:04:04 short
+; update for HEAD-2002110701
;
; Revision 1.4 2000/06/25 03:59:14 dwelch
;
if (!NT_SUCCESS(Status))
{
DPRINT("Failing create request with status %x\n", Status);
+ FileObject->DeviceObject = NULL;
+ FileObject->Vpb = NULL;
+
ZwClose(*FileHandle);
}
if (IoStatusBlock)
DPRINT("IopCloseFile()\n");
- if (HandleCount > 0)
+ if (HandleCount > 0 || FileObject->DeviceObject == NULL)
{
return;
}
STANDARD_RIGHTS_REQUIRED,
IoFileObjectType,
UserMode);
-
+ KeResetEvent( &FileObject->Event );
+
Irp = IoBuildSynchronousFsdRequest(IRP_MJ_CLEANUP,
FileObject->DeviceObject,
NULL,
StackPtr->FileObject = FileObject;
Status = IoCallDriver(FileObject->DeviceObject, Irp);
+ if (Status == STATUS_PENDING)
+ {
+ KeWaitForSingleObject(&FileObject->Event, Executive, KernelMode, FALSE, NULL);
+ }
}
VOID STDCALL
NTSTATUS Status;
DPRINT("IopDeleteFile()\n");
+
+ if (FileObject->DeviceObject)
+ {
+ ObReferenceObjectByPointer(ObjectBody,
+ STANDARD_RIGHTS_REQUIRED,
+ IoFileObjectType,
+ UserMode);
- ObReferenceObjectByPointer(ObjectBody,
- STANDARD_RIGHTS_REQUIRED,
- IoFileObjectType,
- UserMode);
-
- Irp = IoBuildSynchronousFsdRequest(IRP_MJ_CLOSE,
- FileObject->DeviceObject,
- NULL,
- 0,
- NULL,
- NULL,
- NULL);
- StackPtr = IoGetNextIrpStackLocation(Irp);
- StackPtr->FileObject = FileObject;
+ KeResetEvent( &FileObject->Event );
+ Irp = IoBuildSynchronousFsdRequest(IRP_MJ_CLOSE,
+ FileObject->DeviceObject,
+ NULL,
+ 0,
+ NULL,
+ NULL,
+ NULL);
+ StackPtr = IoGetNextIrpStackLocation(Irp);
+ StackPtr->FileObject = FileObject;
- Status = IoCallDriver(FileObject->DeviceObject, Irp);
+ Status = IoCallDriver(FileObject->DeviceObject, Irp);
+ if (Status == STATUS_PENDING)
+ {
+ KeWaitForSingleObject(&FileObject->Event, Executive, KernelMode, FALSE, NULL);
+ }
+ }
if (FileObject->FileName.Buffer != NULL)
{
Characteristics & IMAGE_SECTION_CHAR_DATA ||
Characteristics & IMAGE_SECTION_CHAR_BSS))
{
- for (i = 0; i < PAGE_ROUND_DOWN(Length) / PAGE_SIZE; i++)
+ for (i = 0; i < PAGE_ROUND_UP(Length) / PAGE_SIZE; i++)
{
MmSetPageProtect(NULL, BaseAddress + (i * PAGE_SIZE),
PAGE_READONLY);
KIRQL oldIrql;
PEPORT_CONNECT_REQUEST_MESSAGE CRequest;
PEPORT_CONNECT_REPLY_MESSAGE CReply;
+ ULONG Size;
- CReply = ExAllocatePool(NonPagedPool,
- sizeof(EPORT_CONNECT_REPLY_MESSAGE) + LpcMessage->DataSize);
+ Size = sizeof(EPORT_CONNECT_REPLY_MESSAGE);
+ if (LpcMessage)
+ {
+ Size += LpcMessage->DataSize;
+ }
+
+ CReply = ExAllocatePool(NonPagedPool, Size);
if (CReply == NULL)
{
return(STATUS_NO_MEMORY);
/*
* Create a port object for our side of the connection
*/
- if (AcceptIt == 1)
+ if (AcceptIt)
{
Status = ObCreateObject(ServerPortHandle,
PORT_ALL_ACCESS,
(PVOID*)&OurPort);
if (!NT_SUCCESS(Status))
{
+ ExFreePool(CReply);
ObDereferenceObject(NamedPort);
return(Status);
}
sizeof(LPC_MESSAGE);
CReply->ConnectDataLength = 0;
}
- if (AcceptIt != 1)
+ if (!AcceptIt)
{
EiReplyOrRequestPort(ConnectionRequest->Sender,
&CReply->MessageHeader,
LPC_REPLY,
OurPort);
ExFreePool(ConnectionRequest);
+ ExFreePool(CReply);
ObDereferenceObject(OurPort);
ObDereferenceObject(NamedPort);
*/
MmDisableVirtualMapping(MemoryArea->Process, Address,
&WasDirty, &PhysicalAddress);
+
if (PhysicalAddress.QuadPart == 0)
{
KeBugCheck(0);
* Write the page to the pagefile
*/
Mdl = MmCreateMdl(NULL, NULL, PAGE_SIZE);
- MmBuildMdlFromPages(Mdl, (PULONG)&PhysicalAddress);
+ MmBuildMdlFromPages(Mdl, &PhysicalAddress.u.LowPart);
Status = MmWriteToSwapPage(SwapEntry, Mdl);
if (!NT_SUCCESS(Status))
{
{
ULONG i;
- for (i=0; i <= (RegionSize/PAGE_SIZE); i++)
+ for (i=0; i < PAGE_ROUND_UP(RegionSize)/PAGE_SIZE; i++)
{
LARGE_INTEGER PhysicalAddr;
{
ULONG i;
- for (i=0; i <= (RegionSize/PAGE_SIZE); i++)
+ for (i=0; i < PAGE_ROUND_UP(RegionSize)/PAGE_SIZE; i++)
{
if (MmIsPagePresent(AddressSpace->Process,
BaseAddress + (i*PAGE_SIZE)))
if (PBaseAddress != 0)
{
- MemoryArea = MmOpenMemoryAreaByAddress(&Process->AddressSpace,
+ MemoryArea = MmOpenMemoryAreaByAddress(AddressSpace,
BaseAddress);
if (MemoryArea != NULL &&
MemoryArea->Length >= RegionSize)
{
Status =
- MmAlterRegion(&Process->AddressSpace,
+ MmAlterRegion(AddressSpace,
MemoryArea->BaseAddress,
&MemoryArea->Data.VirtualMemoryData.RegionListHead,
PBaseAddress, RegionSize,
*/
if (MemoryArea->PageOpCount > 0)
{
- for (i = 0; i < (PAGE_ROUND_UP(MemoryArea->Length) / PAGE_SIZE); i++)
+ for (i = 0; i < PAGE_ROUND_UP(MemoryArea->Length) / PAGE_SIZE; i++)
{
PMM_PAGEOP PageOp;
Alignment);
if (PBase.QuadPart == 0LL)
{
+ MmLockAddressSpace(MmGetKernelAddressSpace());
MmFreeMemoryArea(MmGetKernelAddressSpace(),
BaseAddress,
0,
NULL,
NULL);
+ MmUnlockAddressSpace(MmGetKernelAddressSpace());
return(NULL);
}
for (i = 0; i < (PAGE_ROUND_UP(NumberOfBytes) / 4096); i++)
VOID STDCALL
MmFreeContiguousMemory(IN PVOID BaseAddress)
{
+ MmLockAddressSpace(MmGetKernelAddressSpace());
MmFreeMemoryArea(MmGetKernelAddressSpace(),
BaseAddress,
0,
MmFreeContinuousPage,
NULL);
+ MmUnlockAddressSpace(MmGetKernelAddressSpace());
}
}
DPRINT("Addr %x\n",PAGETABLE_MAP / (4*1024*1024));
PageDirectory[PAGETABLE_MAP / (4*1024*1024)] =
- (ULONG)PhysPageDirectory.QuadPart | 0x7;
+ PhysPageDirectory.u.LowPart | PA_PRESENT | PA_READWRITE;
ExUnmapPage(PageDirectory);
*(ADDR_TO_PDE(Address)) = 0;
if (Address >= (PVOID)KERNEL_BASE)
{
- MmGlobalKernelPageDirectory[ADDR_TO_PDE_OFFSET(Address)] = 0;
+ KeBugCheck(0);
+// MmGlobalKernelPageDirectory[ADDR_TO_PDE_OFFSET(Address)] = 0;
}
FLUSH_TLB;
if (Process != NULL && Process != CurrentProcess)
ULONG npage;
if (Process != NULL && Process != CurrentProcess)
- {
- KeAttachProcess(Process);
- }
+ {
+ KeAttachProcess(Process);
+ }
+
PageTable = (PULONG)PAGE_ROUND_DOWN((PVOID)ADDR_TO_PTE(Address));
for (i = 0; i < 1024; i++)
- {
- if (PageTable[i] != 0)
- {
- DbgPrint("Page table entry not clear at %x/%x (is %x)\n",
- ((ULONG)Address / 4*1024*1024), i, PageTable[i]);
- KeBugCheck(0);
- }
- }
+ {
+ if (PageTable[i] != 0)
+ {
+ DbgPrint("Page table entry not clear at %x/%x (is %x)\n",
+ ((ULONG)Address / 4*1024*1024), i, PageTable[i]);
+ KeBugCheck(0);
+ }
+ }
npage = *(ADDR_TO_PDE(Address));
*(ADDR_TO_PDE(Address)) = 0;
- if (Address >= (PVOID)KERNEL_BASE)
- {
- MmGlobalKernelPageDirectory[ADDR_TO_PDE_OFFSET(Address)] = 0;
- }
- MmReleasePageMemoryConsumer(MC_NPPOOL, PTE_TO_PAGE(npage));
FLUSH_TLB;
+
+ if (Address >= (PVOID)KERNEL_BASE)
+ {
+// MmGlobalKernelPageDirectory[ADDR_TO_PDE_OFFSET(Address)] = 0;
+ KeBugCheck(0);
+ }
+ else
+ {
+ MmReleasePageMemoryConsumer(MC_NPPOOL, PTE_TO_PAGE(npage));
+ }
if (Process != NULL && Process != CurrentProcess)
- {
- KeDetachProcess();
- }
+ {
+ KeDetachProcess();
+ }
}
NTSTATUS MmGetPageEntry2(PVOID PAddress, PULONG* Pte, BOOLEAN MayWait)
* FUNCTION: Get a pointer to the page table entry for a virtual address
*/
{
- PULONG Pde;
- ULONG Address = (ULONG)PAddress;
+ PULONG Pde, kePde;
PHYSICAL_ADDRESS npage;
+ BOOLEAN Free = FALSE;
+ NTSTATUS Status;
+ KIRQL oldIrql;
- DPRINT("MmGetPageEntry(Address %x)\n", Address);
+ DPRINT("MmGetPageEntry(Address %x)\n", PAddress);
- Pde = ADDR_TO_PDE(Address);
- if ((*Pde) == 0)
- {
- if (Address >= KERNEL_BASE &&
- MmGlobalKernelPageDirectory[ADDR_TO_PDE_OFFSET(Address)] != 0)
+ Pde = ADDR_TO_PDE(PAddress);
+ if (*Pde == 0)
+ {
+ if (PAddress >= (PVOID)KERNEL_BASE)
+ {
+ kePde = MmGlobalKernelPageDirectory + ADDR_TO_PDE_OFFSET(PAddress);
+ oldIrql = KeRaiseIrqlToSynchLevel();
+ if (*kePde != 0)
{
- (*Pde) = MmGlobalKernelPageDirectory[ADDR_TO_PDE_OFFSET(Address)];
- FLUSH_TLB;
+ *Pde = *kePde;
+ FLUSH_TLB;
}
- else
+ else
{
- NTSTATUS Status;
- Status = MmRequestPageMemoryConsumer(MC_NPPOOL, MayWait, &npage);
- if (!NT_SUCCESS(Status))
- {
- return(Status);
- }
- (*Pde) = npage.QuadPart | 0x7;
- if (Address >= KERNEL_BASE)
- {
- MmGlobalKernelPageDirectory[ADDR_TO_PDE_OFFSET(Address)] =
- *Pde;
- }
- memset((PVOID)PAGE_ROUND_DOWN(ADDR_TO_PTE(Address)), 0, PAGE_SIZE);
- FLUSH_TLB;
+ KeLowerIrql(oldIrql);
+ Status = MmRequestPageMemoryConsumer(MC_NPPOOL, MayWait, &npage);
+ if (!NT_SUCCESS(Status))
+ {
+ KeBugCheck(0);
+ }
+ oldIrql = KeRaiseIrqlToSynchLevel();
+ /* An other thread can set this pde entry, we must check again */
+ if (*kePde == 0)
+ {
+ *kePde = npage.u.LowPart | PA_PRESENT | PA_READWRITE;
+ }
+ else
+ {
+ Free = TRUE;
+ }
+ *Pde = *kePde;
+ FLUSH_TLB;
}
- }
- *Pte = ADDR_TO_PTE(Address);
- return(STATUS_SUCCESS);
+ KeLowerIrql(oldIrql);
+ }
+ else
+ {
+ Status = MmRequestPageMemoryConsumer(MC_NPPOOL, MayWait, &npage);
+ if (!NT_SUCCESS(Status))
+ {
+ return(Status);
+ }
+ *Pde = npage.u.LowPart | PA_PRESENT | PA_READWRITE | PA_USER;
+ FLUSH_TLB;
+ }
+ }
+ *Pte = (PULONG)ADDR_TO_PTE(PAddress);
+ if (Free)
+ {
+ MmReleasePageMemoryConsumer(MC_NPPOOL, npage);
+ }
+ return STATUS_SUCCESS;
}
ULONG MmGetPageEntryForProcess(PEPROCESS Process, PVOID Address)
* FUNCTION: Get a pointer to the page table entry for a virtual address
*/
{
- PULONG page_tlb;
- PULONG page_dir;
- ULONG Address = (ULONG)PAddress;
+ PULONG Pde, kePde;
+ ULONG Entry = 0;
- DPRINT("MmGetPageEntry(Address %x)\n", Address);
+ DPRINT("MmGetPageEntry(Address %x)\n", PAddress);
- page_dir = ADDR_TO_PDE(Address);
- if ((*page_dir) == 0 &&
- MmGlobalKernelPageDirectory[ADDR_TO_PDE_OFFSET(Address)] != 0)
- {
- (*page_dir) = MmGlobalKernelPageDirectory[ADDR_TO_PDE_OFFSET(Address)];
- FLUSH_TLB;
- }
- DPRINT("page_dir %x *page_dir %x\n",page_dir,*page_dir);
- if ((*page_dir) == 0)
- {
- return(0);
- }
- page_tlb = ADDR_TO_PTE(Address);
- DPRINT("page_tlb %x\n",page_tlb);
- return(*page_tlb);
+ Pde = ADDR_TO_PDE(PAddress);
+ if (*Pde == 0)
+ {
+ if (PAddress >= (PVOID)KERNEL_BASE)
+ {
+ kePde = MmGlobalKernelPageDirectory + ADDR_TO_PDE_OFFSET(PAddress);
+ if (*kePde != 0)
+ {
+ *Pde = *kePde;
+ FLUSH_TLB;
+ Entry = *(PULONG)ADDR_TO_PTE(PAddress);
+ }
+ }
+ }
+ else
+ {
+ Entry = *(PULONG)ADDR_TO_PTE(PAddress);
+ }
+ return Entry;
}
ULONG MmGetPageEntryForProcess1(PEPROCESS Process, PVOID Address)
*/
{
ULONG Pte;
- PULONG Pde;
+ PULONG Pde, kePde;
PEPROCESS CurrentProcess = PsGetCurrentProcess();
BOOLEAN WasValid;
* the global page directory.
*/
Pde = ADDR_TO_PDE(Address);
- if ((*Pde) == 0 &&
- MmGlobalKernelPageDirectory[ADDR_TO_PDE_OFFSET(Address)] != 0)
- {
- (*Pde) = MmGlobalKernelPageDirectory[ADDR_TO_PDE_OFFSET(Address)];
- FLUSH_TLB;
- }
- if ((*Pde) == 0)
+ if (*Pde == 0 && Address >= (PVOID)KERNEL_BASE)
+ {
+ kePde = MmGlobalKernelPageDirectory + ADDR_TO_PDE_OFFSET(Address);
+ if (*kePde != 0)
+ {
+ *Pde = *kePde;
+ FLUSH_TLB;
+ }
+ }
+
+ if (*Pde == 0)
{
if (Process != NULL && Process != CurrentProcess)
{
}
if (FreePage && WasValid)
{
- MmReleasePageMemoryConsumer(MC_NPPOOL, PTE_TO_PAGE(Pte));
+ MmReleasePageMemoryConsumer(MC_NPPOOL, PTE_TO_PAGE(Pte));
}
/*
*/
if (Process != NULL && WasValid &&
Process->AddressSpace.PageTableRefCountTable != NULL &&
- ADDR_TO_PAGE_TABLE(Address) < 768)
+ Address < (PVOID)KERNEL_BASE)
{
PUSHORT Ptrc;
*/
{
ULONG Pte;
- PULONG Pde;
+ PULONG Pde, kePde;
PEPROCESS CurrentProcess = PsGetCurrentProcess();
BOOLEAN WasValid = FALSE;
* the global page directory.
*/
Pde = ADDR_TO_PDE(Address);
- if ((*Pde) == 0 &&
- MmGlobalKernelPageDirectory[ADDR_TO_PDE_OFFSET(Address)] != 0)
- {
- (*Pde) = MmGlobalKernelPageDirectory[ADDR_TO_PDE_OFFSET(Address)];
- FLUSH_TLB;
- }
- if ((*Pde) == 0)
+ if (*Pde == 0)
+ {
+ if (Address >= (PVOID)KERNEL_BASE)
+ {
+ kePde = MmGlobalKernelPageDirectory + ADDR_TO_PDE_OFFSET(Address);
+ if (*kePde != 0)
+ {
+ *Pde = *kePde;
+ FLUSH_TLB;
+ }
+ }
+ }
+ if (*Pde == 0)
{
if (Process != NULL && Process != CurrentProcess)
{
Pte = (ULONG)InterlockedExchange((PLONG)ADDR_TO_PTE(Address), 0);
FLUSH_TLB;
+ WasValid = PAGE_MASK(Pte) == 0 ? FALSE : TRUE;
+
/*
* Decrement the reference count for this page table.
*/
if (Process != NULL && WasValid &&
Process->AddressSpace.PageTableRefCountTable != NULL &&
- ADDR_TO_PAGE_TABLE(Address) < 768)
+ Address < (PVOID)KERNEL_BASE)
{
PUSHORT Ptrc;
BOOLEAN
Mmi386MakeKernelPageTableGlobal(PVOID PAddress)
{
- PULONG page_dir;
- ULONG Address = (ULONG)PAddress;
+ PULONG kePde, Pde;
- page_dir = ADDR_TO_PDE(Address);
- if ((*page_dir) == 0 &&
- MmGlobalKernelPageDirectory[ADDR_TO_PDE_OFFSET(Address)] != 0)
- {
- (*page_dir) = MmGlobalKernelPageDirectory[ADDR_TO_PDE_OFFSET(Address)];
- FLUSH_TLB;
- return(TRUE);
- }
+ Pde = ADDR_TO_PDE(PAddress);
+ if (*Pde == 0)
+ {
+ kePde = MmGlobalKernelPageDirectory + ADDR_TO_PDE_OFFSET(PAddress);
+ if (*kePde != 0)
+ {
+ *Pde = *kePde;
+ FLUSH_TLB;
+ return(TRUE);
+ }
+ }
return(FALSE);
}
BOOLEAN MmIsPageTablePresent(PVOID PAddress)
{
- PULONG page_dir;
- ULONG Address = (ULONG)PAddress;
+ PULONG Pde, kePde;
- page_dir = ADDR_TO_PDE(Address);
- if ((*page_dir) == 0 &&
- MmGlobalKernelPageDirectory[ADDR_TO_PDE_OFFSET(Address)] != 0)
- {
- (*page_dir) = MmGlobalKernelPageDirectory[ADDR_TO_PDE_OFFSET(Address)];
- FLUSH_TLB;
- }
- return((*page_dir) == 0);
+ Pde = ADDR_TO_PDE(PAddress);
+ if (*Pde == 0)
+ {
+ kePde = MmGlobalKernelPageDirectory + ADDR_TO_PDE_OFFSET(PAddress);
+ if (*kePde != 0)
+ {
+ *Pde = *kePde;
+ FLUSH_TLB;
+ return TRUE;
+ }
+ }
+ return FALSE;
}
NTSTATUS MmCreatePageTable(PVOID PAddress)
{
- PULONG page_dir;
- ULONG Address = (ULONG)PAddress;
+ PULONG Pde, kePde;
PHYSICAL_ADDRESS npage;
+ NTSTATUS Status;
- DPRINT("MmGetPageEntry(Address %x)\n", Address);
+ DPRINT("MmGetPageEntry(Address %x)\n", PAddress);
- page_dir = ADDR_TO_PDE(Address);
- DPRINT("page_dir %x *page_dir %x\n",page_dir,*page_dir);
- if ((*page_dir) == 0 &&
- MmGlobalKernelPageDirectory[ADDR_TO_PDE_OFFSET(Address)] != 0)
- {
- (*page_dir) = MmGlobalKernelPageDirectory[ADDR_TO_PDE_OFFSET(Address)];
- FLUSH_TLB;
- }
- if ((*page_dir) == 0)
- {
- NTSTATUS Status;
- Status = MmRequestPageMemoryConsumer(MC_NPPOOL, FALSE, &npage);
- if (!NT_SUCCESS(Status))
- {
- return(Status);
- }
- (*page_dir) = npage.QuadPart | 0x7;
- memset((PVOID)PAGE_ROUND_DOWN(ADDR_TO_PTE(Address)), 0, PAGE_SIZE);
- FLUSH_TLB;
- }
+ Pde = ADDR_TO_PDE(PAddress);
+ DPRINT("page_dir %x *page_dir %x\n", Pde, *Pde);
+ if (*Pde == 0 && PAddress >= (PVOID)KERNEL_BASE)
+ {
+ kePde = MmGlobalKernelPageDirectory + ADDR_TO_PDE_OFFSET(PAddress);
+ if (*kePde != 0)
+ {
+ *Pde = *kePde;
+ FLUSH_TLB;
+ return STATUS_SUCCESS;
+ }
+ /* Should we create a kernel page table? */
+ DPRINT1("!!!!!!!!!!!!!!!!!!\n");
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ if (*Pde == 0)
+ {
+ Status = MmRequestPageMemoryConsumer(MC_NPPOOL, FALSE, &npage);
+ if (!NT_SUCCESS(Status))
+ {
+ return(Status);
+ }
+ MiZeroPage(npage);
+ *Pde = npage.u.LowPart | PA_PRESENT | PA_READWRITE | PA_USER;
+ FLUSH_TLB;
+ }
return(STATUS_SUCCESS);
}
* FUNCTION: Get a pointer to the page table entry for a virtual address
*/
{
- PULONG page_tlb;
- PULONG page_dir;
- ULONG Address = (ULONG)PAddress;
+ PULONG Pde, kePde;
PHYSICAL_ADDRESS npage;
+ KIRQL oldIrql;
+ BOOLEAN Free = FALSE;
+ NTSTATUS Status;
- DPRINT("MmGetPageEntry(Address %x)\n", Address);
+ DPRINT("MmGetPageEntry(Address %x)\n", PAddress);
- page_dir = ADDR_TO_PDE(Address);
- DPRINT("page_dir %x *page_dir %x\n",page_dir,*page_dir);
- if ((*page_dir) == 0 &&
- MmGlobalKernelPageDirectory[ADDR_TO_PDE_OFFSET(Address)] != 0)
- {
- (*page_dir) = MmGlobalKernelPageDirectory[ADDR_TO_PDE_OFFSET(Address)];
- FLUSH_TLB;
- }
- if ((*page_dir) == 0)
- {
- NTSTATUS Status;
- Status = MmRequestPageMemoryConsumer(MC_NPPOOL, FALSE, &npage);
- if (!NT_SUCCESS(Status))
+ Pde = ADDR_TO_PDE(PAddress);
+ DPRINT("page_dir %x *page_dir %x\n",Pde,*Pde);
+ if (*Pde == 0)
+ {
+ if (PAddress >= (PVOID)KERNEL_BASE)
+ {
+ oldIrql = KeRaiseIrqlToSynchLevel();
+ kePde = MmGlobalKernelPageDirectory + ADDR_TO_PDE_OFFSET(PAddress);
+ if (*kePde != 0)
{
- KeBugCheck(0);
+ *Pde = *kePde;
+ FLUSH_TLB;
}
- (*page_dir) = npage.QuadPart | 0x7;
- memset((PVOID)PAGE_ROUND_DOWN(ADDR_TO_PTE(Address)), 0, PAGE_SIZE);
- FLUSH_TLB;
- }
- page_tlb = ADDR_TO_PTE(Address);
- DPRINT("page_tlb %x\n",page_tlb);
- return(page_tlb);
+ else
+ {
+ KeLowerIrql(oldIrql);
+ Status = MmRequestPageMemoryConsumer(MC_NPPOOL, FALSE, &npage);
+ if (!NT_SUCCESS(Status))
+ {
+ KeBugCheck(0);
+ }
+ MiZeroPage(npage);
+ oldIrql = KeRaiseIrqlToSynchLevel();
+ if (*kePde != 0)
+ {
+ *Pde = *kePde;
+ FLUSH_TLB;
+ Free = TRUE;
+ }
+ else
+ {
+ *Pde = *kePde = npage.u.LowPart | PA_PRESENT | PA_READWRITE;
+ FLUSH_TLB;
+ }
+ }
+ KeLowerIrql(oldIrql);
+ }
+ else
+ {
+ Status = MmRequestPageMemoryConsumer(MC_NPPOOL, FALSE, &npage);
+ if (!NT_SUCCESS(Status))
+ {
+ KeBugCheck(0);
+ }
+ MiZeroPage(npage);
+ *Pde = npage.u.LowPart | PA_PRESENT | PA_READWRITE | PA_USER;
+ FLUSH_TLB;
+ }
+ if (Free)
+ {
+ MmReleasePageMemoryConsumer(MC_NPPOOL, npage);
+ }
+ }
+
+ return ADDR_TO_PTE(PAddress);
}
BOOLEAN MmIsDirtyPage(PEPROCESS Process, PVOID Address)
{
Attributes |= (PAGE_NOCACHE | PAGE_WRITETHROUGH);
}
- for (i = 0; (i < ((NumberOfBytes + PAGE_SIZE - 1) / PAGE_SIZE)); i++)
+ for (i = 0; (i < (PAGE_ROUND_UP(NumberOfBytes) / PAGE_SIZE)); i++)
{
Status =
MmCreateVirtualMappingForKernel(Result + (i * PAGE_SIZE),
MmUnmapIoSpace (IN PVOID BaseAddress,
IN ULONG NumberOfBytes)
{
- (VOID)MmFreeMemoryArea(&PsGetCurrentProcess()->AddressSpace,
- (PVOID)(((ULONG)BaseAddress / PAGE_SIZE) * PAGE_SIZE),
- NumberOfBytes,
- NULL,
- NULL);
+ MmLockAddressSpace(MmGetKernelAddressSpace());
+ MmFreeMemoryArea(MmGetKernelAddressSpace(),
+ (PVOID)(((ULONG)BaseAddress / PAGE_SIZE) * PAGE_SIZE),
+ NumberOfBytes,
+ NULL,
+ NULL);
+ MmUnlockAddressSpace(MmGetKernelAddressSpace());
}
* One bit for each page in the kmalloc region
* If set then the page is used by a kmalloc block
*/
-static ULONG AllocMap[ALLOC_MAP_SIZE/32]={0,};
+static UCHAR AllocMapBuffer[ROUND_UP(ALLOC_MAP_SIZE, 8) / 8];
+static RTL_BITMAP AllocMap;
static KSPIN_LOCK AllocMapLock;
-static ULONG AllocMapHint = 1;
+static ULONG AllocMapHint = 0;
static PVOID NonPagedPoolBase;
ExUnmapPage(PVOID Addr)
{
KIRQL oldIrql;
- ULONG i = (Addr - NonPagedPoolBase) / PAGE_SIZE;
+ ULONG Base = (Addr - NonPagedPoolBase) / PAGE_SIZE;
DPRINT("ExUnmapPage(Addr %x)\n",Addr);
- DPRINT("i %x\n",i);
MmDeleteVirtualMapping(NULL, (PVOID)Addr, FALSE, NULL, NULL);
KeAcquireSpinLock(&AllocMapLock, &oldIrql);
- AllocMap[i / 32] &= (~(1 << (i % 32)));
- AllocMapHint = min(AllocMapHint, i);
+ RtlClearBits(&AllocMap, Base, 1);
+ AllocMapHint = min(AllocMapHint, Base);
KeReleaseSpinLock(&AllocMapLock, oldIrql);
}
ExAllocatePageWithPhysPage(PHYSICAL_ADDRESS PhysPage)
{
KIRQL oldlvl;
- ULONG addr;
- ULONG i;
+ PVOID Addr;
+ ULONG Base;
NTSTATUS Status;
KeAcquireSpinLock(&AllocMapLock, &oldlvl);
- for (i = AllocMapHint; i < ALLOC_MAP_SIZE; i++)
- {
- if (!(AllocMap[i / 32] & (1 << (i % 32))))
- {
- DPRINT("i %x\n",i);
- AllocMap[i / 32] |= (1 << (i % 32));
- AllocMapHint = i + 1;
- addr = (ULONG)(NonPagedPoolBase + (i*PAGE_SIZE));
- Status = MmCreateVirtualMapping(NULL,
- (PVOID)addr,
- PAGE_READWRITE | PAGE_SYSTEM,
- PhysPage,
- FALSE);
- if (!NT_SUCCESS(Status))
- {
- DbgPrint("Unable to create virtual mapping\n");
- KeBugCheck(0);
- }
- KeReleaseSpinLock(&AllocMapLock, oldlvl);
- return((PVOID)addr);
- }
- }
+ Base = RtlFindClearBitsAndSet(&AllocMap, 1, AllocMapHint);
+ if (Base != 0xFFFFFFFF)
+ {
+ AllocMapHint = Base + 1;
+ KeReleaseSpinLock(&AllocMapLock, oldlvl);
+ Addr = NonPagedPoolBase + Base * PAGE_SIZE;
+ Status = MmCreateVirtualMapping(NULL,
+ Addr,
+ PAGE_READWRITE | PAGE_SYSTEM,
+ PhysPage,
+ FALSE);
+ if (!NT_SUCCESS(Status))
+ {
+ DbgPrint("Unable to create virtual mapping\n");
+ KeBugCheck(0);
+ }
+ return Addr;
+ }
KeReleaseSpinLock(&AllocMapLock, oldlvl);
- return(NULL);
+ return NULL;
}
VOID
{
NonPagedPoolBase = BaseAddress;
KeInitializeSpinLock(&AllocMapLock);
+ RtlInitializeBitMap(&AllocMap, (PVOID)&AllocMapBuffer, ALLOC_MAP_SIZE);
+ RtlClearAllBits(&AllocMap);
}
VOID
{
ULONG i;
ULONG Base = (Addr - NonPagedPoolBase) / PAGE_SIZE;
- ULONG Offset;
KIRQL oldlvl;
- KeAcquireSpinLock(&AllocMapLock, &oldlvl);
- AllocMapHint = min(AllocMapHint, Base);
for (i = 0; i < Count; i++)
- {
- Offset = Base + i;
- AllocMap[Offset / 32] &= (~(1 << (Offset % 32)));
+ {
MmDeleteVirtualMapping(NULL,
Addr + (i * PAGE_SIZE),
Free,
NULL,
NULL);
- }
+ }
+ KeAcquireSpinLock(&AllocMapLock, &oldlvl);
+ RtlClearBits(&AllocMap, Base, Count);
+ AllocMapHint = min(AllocMapHint, Base);
KeReleaseSpinLock(&AllocMapLock, oldlvl);
}
* FUNCTION: Allocates a region of pages within the nonpaged pool area
*/
{
- unsigned int start = 0;
- unsigned int length = 0;
- unsigned int i,j;
+ ULONG Base;
KIRQL oldlvl;
KeAcquireSpinLock(&AllocMapLock, &oldlvl);
- for (i=AllocMapHint; i<ALLOC_MAP_SIZE;i++)
- {
- if (!(AllocMap[i/32] & (1 << (i % 32))))
- {
- if (length == 0)
- {
- start=i;
- length = 1;
- }
- else
- {
- length++;
- }
- if (length==nr_pages)
- {
- AllocMapHint = start + length;
- for (j=start;j<(start+length);j++)
- {
- AllocMap[j / 32] |= (1 << (j % 32));
- }
- DPRINT("returning %x\n",((start*PAGE_SIZE)+NonPagedPoolBase));
- KeReleaseSpinLock(&AllocMapLock, oldlvl);
- return(((start*PAGE_SIZE)+NonPagedPoolBase));
- }
- }
- else
- {
- start=0;
- length=0;
- }
- }
- DbgPrint("CRITICAL: Out of non-paged pool space\n");
- KeBugCheck(0);
- return(0);
+ Base = RtlFindClearBitsAndSet(&AllocMap, nr_pages, AllocMapHint);
+ if (Base == 0xFFFFFFFF)
+ {
+ DbgPrint("CRITICAL: Out of non-paged pool space\n");
+ KeBugCheck(0);
+ }
+ if (AllocMapHint == Base)
+ {
+ AllocMapHint += nr_pages;
+ }
+ KeReleaseSpinLock(&AllocMapLock, oldlvl);
+ DPRINT("returning %x\n",NonPagedPoolBase + Base * PAGE_SIZE);
+ return NonPagedPoolBase + Base * PAGE_SIZE;
}
{
current = CONTAINING_RECORD(current_entry,MEMORY_AREA,Entry);
next = CONTAINING_RECORD(current_entry->Flink,MEMORY_AREA,Entry);
- Gap = (next->BaseAddress ) -(current->BaseAddress + current->Length);
+ Gap = next->BaseAddress - (current->BaseAddress + PAGE_ROUND_UP(current->Length));
if (Gap >= Length)
{
return(current->BaseAddress + PAGE_ROUND_UP(current->Length));
for (i=0; i<(PAGE_ROUND_UP(MemoryArea->Length)/PAGE_SIZE); i++)
{
PHYSICAL_ADDRESS PhysAddr = (PHYSICAL_ADDRESS)0LL;
- BOOL Dirty;
+ BOOL Dirty = FALSE;
SWAPENTRY SwapEntry = 0;
if (MmIsPageSwapEntry(AddressSpace->Process,
* NOTES: Lock the address space before calling this function
*/
{
+ ULONG tmpLength;
DPRINT("MmCreateMemoryArea(Type %d, BaseAddress %x,"
"*BaseAddress %x, Length %x, Attributes %x, Result %x)\n",
Type,BaseAddress,*BaseAddress,Length,Attributes,Result);
if ((*BaseAddress)==0 && !FixedAddress)
{
+ tmpLength = PAGE_ROUND_UP(Length);
*BaseAddress = MmFindGap(AddressSpace,
PAGE_ROUND_UP(Length) +(PAGE_SIZE*2));
if ((*BaseAddress)==0)
(*BaseAddress)=(*BaseAddress)+PAGE_SIZE;
}
else
- {
- (*BaseAddress) = (PVOID)PAGE_ROUND_DOWN((*BaseAddress));
+ {
+ tmpLength = (ULONG)*BaseAddress + Length - PAGE_ROUND_DOWN((*BaseAddress));
+ (*BaseAddress) = (PVOID)PAGE_ROUND_DOWN((*BaseAddress));
if (MmOpenMemoryAreaByRegion(AddressSpace,
*BaseAddress,
- Length)!=NULL)
+ tmpLength)!=NULL)
{
DPRINT("Memory area already occupied\n");
return(STATUS_CONFLICTING_ADDRESSES);
RtlZeroMemory(*Result,sizeof(MEMORY_AREA));
(*Result)->Type = Type;
(*Result)->BaseAddress = *BaseAddress;
- (*Result)->Length = Length;
+ (*Result)->Length = tmpLength;
(*Result)->Attributes = Attributes;
(*Result)->LockCount = 0;
(*Result)->Process = Process;
#include <internal/mm.h>
#include <internal/ps.h>
#include <internal/pool.h>
+#include <ntos/minmax.h>
#define NDEBUG
#include <internal/debug.h>
#define MI_MDL_MAPPING_REGION_SIZE (256*1024*1024)
static PVOID MiMdlMappingRegionBase = NULL;
-static PULONG MiMdlMappingRegionAllocMap = NULL;
-static ULONG MiMdlMappingRegionHighWaterMark = 0;
+static RTL_BITMAP MiMdlMappingRegionAllocMap;
+static ULONG MiMdlMappingRegionHint;
static KSPIN_LOCK MiMdlMappingRegionLock;
/* FUNCTIONS *****************************************************************/
{
MEMORY_AREA* Result;
NTSTATUS Status;
+ PVOID Buffer;
+ MiMdlMappingRegionHint = 0;
MiMdlMappingRegionBase = NULL;
MmLockAddressSpace(MmGetKernelAddressSpace());
}
MmUnlockAddressSpace(MmGetKernelAddressSpace());
- MiMdlMappingRegionAllocMap =
- ExAllocatePool(NonPagedPool,
- MI_MDL_MAPPING_REGION_SIZE / (PAGE_SIZE * 32));
- MiMdlMappingRegionHighWaterMark = 0;
+ Buffer = ExAllocatePool(NonPagedPool, MI_MDL_MAPPING_REGION_SIZE / (PAGE_SIZE * 8));
+
+ RtlInitializeBitMap(&MiMdlMappingRegionAllocMap, Buffer, MI_MDL_MAPPING_REGION_SIZE / PAGE_SIZE);
+ RtlClearAllBits(&MiMdlMappingRegionAllocMap);
+
KeInitializeSpinLock(&MiMdlMappingRegionLock);
}
PULONG MdlPages;
KIRQL oldIrql;
ULONG RegionSize;
+ ULONG StartingOffset;
DPRINT("MmMapLockedPages(Mdl %x, AccessMode %x)\n", Mdl, AccessMode);
/* Allocate that number of pages from the mdl mapping region. */
KeAcquireSpinLock(&MiMdlMappingRegionLock, &oldIrql);
- Base = MiMdlMappingRegionBase + MiMdlMappingRegionHighWaterMark * PAGE_SIZE;
- for (i = 0; i < RegionSize; i++)
- {
- ULONG Offset = MiMdlMappingRegionHighWaterMark + i;
- MiMdlMappingRegionAllocMap[Offset / 32] |= (1 << (Offset % 32));
- }
- MiMdlMappingRegionHighWaterMark += RegionSize;
+
+ StartingOffset = RtlFindClearBitsAndSet(&MiMdlMappingRegionAllocMap, RegionSize, MiMdlMappingRegionHint);
+
+ if (StartingOffset == 0xffffffff)
+ {
+ DPRINT1("Out of MDL mapping space\n");
+ KeBugCheck(0);
+ }
+
+ Base = MiMdlMappingRegionBase + StartingOffset * PAGE_SIZE;
+
+ if (MiMdlMappingRegionHint == StartingOffset)
+ {
+ MiMdlMappingRegionHint +=RegionSize;
+ }
+
KeReleaseSpinLock(&MiMdlMappingRegionLock, oldIrql);
/* Set the virtual mappings for the MDL pages. */
ULONG RegionSize;
ULONG Base;
- DPRINT("MmUnmapLockedPages(BaseAddress %x, Mdl %x)\n", Mdl, BaseAddress);
+ DPRINT("MmUnmapLockedPages(BaseAddress %x, Mdl %x)\n", BaseAddress, Mdl);
/*
* In this case, the MDL has the same system address as the base address
/* Calculate the number of pages we mapped. */
RegionSize = PAGE_ROUND_UP(Mdl->ByteCount + Mdl->ByteOffset) / PAGE_SIZE;
+ BaseAddress -= Mdl->ByteOffset;
/* Unmap all the pages. */
for (i = 0; i < RegionSize; i++)
KeAcquireSpinLock(&MiMdlMappingRegionLock, &oldIrql);
/* Deallocate all the pages used. */
- Base = (ULONG)(BaseAddress - MiMdlMappingRegionBase - Mdl->ByteOffset);
- Base = Base / PAGE_SIZE;
- for (i = 0; i < RegionSize; i++)
- {
- ULONG Offset = Base + i;
- MiMdlMappingRegionAllocMap[Offset / 32] &= ~(1 << (Offset % 32));
- }
- /* If all the pages below the high-water mark are free then move it down. */
- if ((Base + RegionSize) == MiMdlMappingRegionHighWaterMark)
- {
- MiMdlMappingRegionHighWaterMark = Base;
- }
+ Base = (ULONG)(BaseAddress - MiMdlMappingRegionBase) / PAGE_SIZE;
+
+ RtlClearBits(&MiMdlMappingRegionAllocMap, Base, RegionSize);
+
+ MiMdlMappingRegionHint = min (MiMdlMappingRegionHint, Base);
+
KeReleaseSpinLock(&MiMdlMappingRegionLock, oldIrql);
/* Reset the MDL state. */
}
Attributes = PAGE_READWRITE | PAGE_SYSTEM | PAGE_NOCACHE |
PAGE_WRITETHROUGH;
- for (i = 0; i <= (NumberOfBytes / PAGE_SIZE); i++)
+ for (i = 0; i < (PAGE_ROUND_UP(NumberOfBytes) / PAGE_SIZE); i++)
{
PHYSICAL_ADDRESS NPage;
VOID STDCALL MmFreeNonCachedMemory (IN PVOID BaseAddress,
IN ULONG NumberOfBytes)
{
+ MmLockAddressSpace(MmGetKernelAddressSpace());
MmFreeMemoryArea (MmGetKernelAddressSpace(),
BaseAddress,
NumberOfBytes,
MmFreeNonCachedPage,
NULL);
+ MmUnlockAddressSpace(MmGetKernelAddressSpace());
}
return;
}
previous = current;
- if ((PVOID)current->tag_next >= (PVOID)0xc1123160)
+ if (current->tag_next &&((PVOID)current->tag_next >= (PVOID)kernel_pool_base + NONPAGED_POOL_SIZE || (PVOID)current->tag_next < (PVOID)kernel_pool_base))
{
DbgPrint("previous %x\n", previous);
}
(unsigned int)next)
{
RemoveEntryList(&next->ListEntry);
- blk->Size = blk->Size + sizeof(BLOCK_HDR) + next->Size;
+ blk->Size = blk->Size + next->Size;
+ memset(next, 0xcc, sizeof(BLOCK_HDR));
+ EiFreeNonPagedPool += sizeof(BLOCK_HDR);
EiNrFreeBlocks--;
}
}
{
RemoveEntryList(&blk->ListEntry);
previous->Size = previous->Size + sizeof(BLOCK_HDR) + blk->Size;
+ memset(blk, 0xcc, sizeof(BLOCK_HDR));
+ EiFreeNonPagedPool += sizeof(BLOCK_HDR);
EiNrFreeBlocks--;
}
}
blk->ListEntry.Blink = current_entry->Blink;
current_entry->Blink->Flink = &blk->ListEntry;
current_entry->Blink = &blk->ListEntry;
+ EiFreeNonPagedPool += blk->Size;
EiNrFreeBlocks++;
return;
}
current_entry = current_entry->Flink;
}
InsertTailList(&FreeBlockListHead, &blk->ListEntry);
+ EiFreeNonPagedPool += blk->Size;
EiNrFreeBlocks++;
}
*/
{
InsertHeadList(&UsedBlockListHead, &blk->ListEntry);
+ EiUsedNonPagedPool += blk->Size;
EiNrUsedBlocks++;
}
static void remove_from_free_list(BLOCK_HDR* current)
{
RemoveEntryList(¤t->ListEntry);
+ EiFreeNonPagedPool -= current->Size;
EiNrFreeBlocks--;
}
static void remove_from_used_list(BLOCK_HDR* current)
{
RemoveEntryList(¤t->ListEntry);
+ EiUsedNonPagedPool -= current->Size;
EiNrUsedBlocks--;
}
( ((int)addr) - sizeof(BLOCK_HDR) );
}
-static BLOCK_HDR* grow_kernel_pool(unsigned int size, ULONG Tag, PVOID Caller)
-/*
- * FUNCTION: Grow the executive heap to accomodate a block of at least 'size'
- * bytes
- */
+static BLOCK_HDR* lookup_block(unsigned int size)
{
- unsigned int total_size = size + sizeof(BLOCK_HDR);
- unsigned int nr_pages = PAGE_ROUND_UP(total_size) / PAGE_SIZE;
- unsigned int start;
- BLOCK_HDR* used_blk=NULL;
- BLOCK_HDR* free_blk=NULL;
- int i;
- NTSTATUS Status;
- KIRQL oldIrql;
-
- start = (ULONG)MiAllocNonPagedPoolRegion(nr_pages);
-
- DPRINT("growing heap for block size %d, ",size);
- DPRINT("start %x\n",start);
-
- for (i=0;i<nr_pages;i++)
- {
- PHYSICAL_ADDRESS Page;
- /* FIXME: Check whether we can really wait here. */
- Status = MmRequestPageMemoryConsumer(MC_NPPOOL, TRUE, &Page);
- if (!NT_SUCCESS(Status))
+ PLIST_ENTRY current_entry;
+ BLOCK_HDR* current;
+ BLOCK_HDR* best = NULL;
+ ULONG new_size;
+ PVOID block, block_boundary;
+
+ current_entry = FreeBlockListHead.Flink;
+ if (size < PAGE_SIZE)
+ {
+ while (current_entry != &FreeBlockListHead)
+ {
+ DPRINT("current %x size %x tag_next %x\n",
+ current, current->Size, current->tag_next);
+ current = CONTAINING_RECORD(current_entry, BLOCK_HDR, ListEntry);
+ if (current->Size >= size &&
+ (best == NULL || current->Size < best->Size))
{
- KeBugCheck(0);
- return(NULL);
+ best = current;
}
- Status = MmCreateVirtualMapping(NULL,
- (PVOID)(start + (i*PAGE_SIZE)),
- PAGE_READWRITE,
- Page,
- FALSE);
- if (!NT_SUCCESS(Status))
- {
- DbgPrint("Unable to create virtual mapping\n");
- KeBugCheck(0);
- }
- }
-
- KeAcquireSpinLock(&MmNpoolLock, &oldIrql);
- if ((PAGE_SIZE-(total_size%PAGE_SIZE))>(2*sizeof(BLOCK_HDR)))
- {
- used_blk = (struct _BLOCK_HDR *)start;
- DPRINT("Creating block at %x\n",start);
- used_blk->Magic = BLOCK_HDR_USED_MAGIC;
- used_blk->Size = size;
- add_to_used_list(used_blk);
-
- free_blk = (BLOCK_HDR *)(start + sizeof(BLOCK_HDR) + size);
- DPRINT("Creating block at %x\n",free_blk);
- free_blk->Magic = BLOCK_HDR_FREE_MAGIC;
- free_blk->Size = (nr_pages * PAGE_SIZE) -((sizeof(BLOCK_HDR)*2) + size);
- add_to_free_list(free_blk);
-
- EiFreeNonPagedPool = EiFreeNonPagedPool + free_blk->Size;
- EiUsedNonPagedPool = EiUsedNonPagedPool + used_blk->Size;
- }
+ current_entry = current_entry->Flink;
+ }
+ }
else
- {
- used_blk = (struct _BLOCK_HDR *)start;
- used_blk->Magic = BLOCK_HDR_USED_MAGIC;
- used_blk->Size = (nr_pages * PAGE_SIZE) - sizeof(BLOCK_HDR);
- add_to_used_list(used_blk);
-
- EiUsedNonPagedPool = EiUsedNonPagedPool + used_blk->Size;
- }
-
- used_blk->Tag = Tag;
- used_blk->Caller = Caller;
- used_blk->Dumped = FALSE;
-#ifdef TAG_STATISTICS_TRACKING
- MiAddToTagHashTable(used_blk);
-#endif /* TAG_STATISTICS_TRACKING */
-
- VALIDATE_POOL;
- KeReleaseSpinLock(&MmNpoolLock, oldIrql);
- return(used_blk);
+ {
+ while (current_entry != &FreeBlockListHead)
+ {
+ DPRINT("current %x size %x tag_next %x\n",
+ current, current->Size, current->tag_next);
+ current = CONTAINING_RECORD(current_entry, BLOCK_HDR, ListEntry);
+
+ block = block_to_address(current);
+ block_boundary = (PVOID)PAGE_ROUND_UP((ULONG)block);
+ new_size = (ULONG)block_boundary - (ULONG)block + size;
+ if (new_size != size && (ULONG)block_boundary - (ULONG)block < sizeof(BLOCK_HDR))
+ {
+ new_size += PAGE_SIZE;
+ }
+ if (current->Size >= new_size &&
+ (best == NULL || current->Size < best->Size))
+ {
+ best = current;
+ }
+ current_entry = current_entry->Flink;
+ }
+ }
+ return best;
}
static void* take_block(BLOCK_HDR* current, unsigned int size,
* RETURNS: The address of the created memory block
*/
{
+
+ BLOCK_HDR* blk;
+ if (size >= PAGE_SIZE)
+ {
+ blk = address_to_block((PVOID)PAGE_ROUND_UP(block_to_address (current)));
+ if (blk != current)
+ {
+ if ((ULONG)blk - (ULONG)current < sizeof(BLOCK_HDR))
+ {
+ (ULONG)blk += PAGE_SIZE;
+ }
+ assert((ULONG)blk - (ULONG)current + size <= current->Size && (ULONG)blk - (ULONG)current >= sizeof(BLOCK_HDR));
+
+ memset(blk, 0, sizeof(BLOCK_HDR));
+ blk->Magic = BLOCK_HDR_FREE_MAGIC;
+ blk->Size = current->Size - ((ULONG)blk - (ULONG)current);
+ current->Size -= (blk->Size + sizeof(BLOCK_HDR));
+ InsertHeadList(¤t->ListEntry, &blk->ListEntry);
+ EiFreeNonPagedPool -= sizeof(BLOCK_HDR);
+ EiNrFreeBlocks++;
+ current = blk;
+ }
+ }
/*
* If the block is much bigger than required then split it and
* return a pointer to the allocated section. If the difference
* between the sizes is marginal it makes no sense to have the
* extra overhead
*/
- if (current->Size > (1 + size + sizeof(BLOCK_HDR)))
+ if (current->Size > size + sizeof(BLOCK_HDR))
{
BLOCK_HDR* free_blk;
- EiFreeNonPagedPool = EiFreeNonPagedPool - current->Size;
+ EiFreeNonPagedPool -= current->Size;
/*
* Replace the bigger block with a smaller block in the
current->Size=size;
RemoveEntryList(¤t->ListEntry);
- InsertHeadList(&UsedBlockListHead, ¤t->ListEntry);
- EiNrUsedBlocks++;
+ add_to_used_list(current);
current->Magic = BLOCK_HDR_USED_MAGIC;
current->Tag = Tag;
current->Caller = Caller;
MiAddToTagHashTable(current);
#endif /* TAG_STATISTICS_TRACKING */
- EiUsedNonPagedPool = EiUsedNonPagedPool + current->Size;
- EiFreeNonPagedPool = EiFreeNonPagedPool + free_blk->Size;
+ EiFreeNonPagedPool += free_blk->Size;
VALIDATE_POOL;
return(block_to_address(current));
remove_from_free_list(current);
add_to_used_list(current);
- EiFreeNonPagedPool = EiFreeNonPagedPool - current->Size;
- EiUsedNonPagedPool = EiUsedNonPagedPool + current->Size;
-
current->Magic = BLOCK_HDR_USED_MAGIC;
current->Tag = Tag;
current->Caller = Caller;
return(block_to_address(current));
}
+static void* grow_kernel_pool(unsigned int size, ULONG Tag, PVOID Caller)
+/*
+ * FUNCTION: Grow the executive heap to accomodate a block of at least 'size'
+ * bytes
+ */
+{
+ ULONG nr_pages = PAGE_ROUND_UP(size + sizeof(BLOCK_HDR)) / PAGE_SIZE;
+ ULONG start;
+ BLOCK_HDR* blk=NULL;
+ int i;
+ KIRQL oldIrql;
+ NTSTATUS Status;
+ PVOID block = NULL;
+
+ if (size >= PAGE_SIZE)
+ {
+ nr_pages++;
+ }
+
+ start = (ULONG)MiAllocNonPagedPoolRegion(nr_pages);
+
+ DPRINT("growing heap for block size %d, ",size);
+ DPRINT("start %x\n",start);
+
+ for (i=0;i<nr_pages;i++)
+ {
+ PHYSICAL_ADDRESS Page;
+ /* FIXME: Check whether we can really wait here. */
+ Status = MmRequestPageMemoryConsumer(MC_NPPOOL, TRUE, &Page);
+ if (!NT_SUCCESS(Status))
+ {
+ KeBugCheck(0);
+ return(NULL);
+ }
+ Status = MmCreateVirtualMapping(NULL,
+ (PVOID)(start + (i*PAGE_SIZE)),
+ PAGE_READWRITE|PAGE_SYSTEM,
+ Page,
+ FALSE);
+ if (!NT_SUCCESS(Status))
+ {
+ DbgPrint("Unable to create virtual mapping\n");
+ KeBugCheck(0);
+ }
+ }
+
+ blk = (struct _BLOCK_HDR *)start;
+ memset(blk, 0, sizeof(BLOCK_HDR));
+ blk->Size = (nr_pages * PAGE_SIZE) - sizeof(BLOCK_HDR);
+ blk->Magic = BLOCK_HDR_FREE_MAGIC;
+ memset(block_to_address(blk), 0xcc, blk->Size);
+
+ KeAcquireSpinLock(&MmNpoolLock, &oldIrql);
+ add_to_free_list(blk);
+ merge_free_block(blk);
+
+ blk = lookup_block(size);
+ if (blk)
+ {
+ block = take_block(blk, size, Tag, Caller);
+ VALIDATE_POOL;
+ }
+ KeReleaseSpinLock(&MmNpoolLock, oldIrql);
+ if (block == NULL)
+ {
+ CHECKPOINT1;
+ }
+ return block;
+}
+
#endif /* not WHOLE_PAGE_ALLOCATIONS */
VOID STDCALL ExFreeNonPagedPool (PVOID block)
#endif /* TAG_STATISTICS_TRACKING */
remove_from_used_list(blk);
blk->Magic = BLOCK_HDR_FREE_MAGIC;
+ blk->Tag = 0;
+ blk->Caller = NULL;
+ blk->tag_next = NULL;
add_to_free_list(blk);
merge_free_block(blk);
- EiUsedNonPagedPool = EiUsedNonPagedPool - blk->Size;
- EiFreeNonPagedPool = EiFreeNonPagedPool + blk->Size;
VALIDATE_POOL;
KeReleaseSpinLock(&MmNpoolLock, oldIrql);
return(block);
#else /* not WHOLE_PAGE_ALLOCATIONS */
- BLOCK_HDR* current = NULL;
- PLIST_ENTRY current_entry;
PVOID block;
BLOCK_HDR* best = NULL;
KIRQL oldIrql;
Size,Caller);
KeAcquireSpinLock(&MmNpoolLock, &oldIrql);
-
+
VALIDATE_POOL;
-
+
+#if 0
+ /* after some allocations print the npaged pool stats */
+#ifdef TAG_STATISTICS_TRACKING
+ {
+ static ULONG counter = 0;
+ if (counter++ % 100000 == 0)
+ {
+ MiDebugDumpNonPagedPoolStats(FALSE);
+ }
+ }
+#endif
+#endif
/*
* accomodate this useful idiom
*/
KeReleaseSpinLock(&MmNpoolLock, oldIrql);
return(NULL);
}
-
+ /* Make the size dword alligned, this makes the block dword alligned */
+ Size = ROUND_UP(Size, 4);
/*
* Look for an already created block of sufficent size
*/
- current_entry = FreeBlockListHead.Flink;
- while (current_entry != &FreeBlockListHead)
- {
- DPRINT("current %x size %x tag_next %x\n",current,current->Size,
- current->tag_next);
- current = CONTAINING_RECORD(current_entry, BLOCK_HDR, ListEntry);
- if (current->Size >= Size &&
- (best == NULL || current->Size < best->Size))
- {
- best = current;
- }
- current_entry = current_entry->Flink;
- }
- if (best != NULL)
- {
- block=take_block(best, Size, Tag, Caller);
- VALIDATE_POOL;
- memset(block,0,Size);
- KeReleaseSpinLock(&MmNpoolLock, oldIrql);
- return(block);
- }
-
-
- /*
- * Otherwise create a new block
- */
- KeReleaseSpinLock(&MmNpoolLock, oldIrql);
- block=block_to_address(grow_kernel_pool(Size, Tag, Caller));
- memset(block, 0, Size);
+ best = lookup_block(Size);
+ if (best == NULL)
+ {
+ KeReleaseSpinLock(&MmNpoolLock, oldIrql);
+ block = grow_kernel_pool(Size, Tag, Caller);
+ assert(block != NULL);
+ memset(block,0,Size);
+ }
+ else
+ {
+ block=take_block(best, Size, Tag, Caller);
+ VALIDATE_POOL;
+ KeReleaseSpinLock(&MmNpoolLock, oldIrql);
+ memset(block,0,Size);
+ }
return(block);
#endif /* WHOLE_PAGE_ALLOCATIONS */
}
PVOID Address;
} MM_RMAP_ENTRY, *PMM_RMAP_ENTRY;
+#define TAG_RMAP TAG('R', 'M', 'A', 'P')
+
/* GLOBALS ******************************************************************/
static FAST_MUTEX RmapListLock;
Address = (PVOID)PAGE_ROUND_DOWN(Address);
- new_entry = ExAllocatePool(NonPagedPool, sizeof(MM_RMAP_ENTRY));
+ new_entry = ExAllocatePoolWithTag(NonPagedPool, sizeof(MM_RMAP_ENTRY), TAG_RMAP);
if (new_entry == NULL)
{
KeBugCheck(0);
* Page - Variable that receives a page contains the read data.
*/
{
- IO_STATUS_BLOCK IoStatus;
+ ULONG BaseOffset;
+ PVOID BaseAddress;
+ BOOLEAN UptoDate;
+ PCACHE_SEGMENT CacheSeg;
PFILE_OBJECT FileObject;
- PMDL Mdl;
NTSTATUS Status;
PREACTOS_COMMON_FCB_HEADER Fcb;
- KEVENT Event;
FileObject = MemoryArea->Data.SectionData.Section->FileObject;
Fcb = (PREACTOS_COMMON_FCB_HEADER)FileObject->FsContext;
if (FileObject->Flags & FO_DIRECT_CACHE_PAGING_READ &&
(Offset->QuadPart % PAGE_SIZE) == 0)
{
- ULONG BaseOffset;
- PVOID BaseAddress;
- BOOLEAN UptoDate;
- PCACHE_SEGMENT CacheSeg;
PHYSICAL_ADDRESS Addr;
/*
* alignment less than the file system block size.
*/
Status = CcRosGetCacheSegment(Fcb->Bcb,
- (ULONG)Offset->QuadPart,
+ Offset->u.LowPart,
&BaseOffset,
&BaseAddress,
&UptoDate,
Status = ReadCacheSegment(CacheSeg);
if (!NT_SUCCESS(Status))
{
+ CcRosReleaseCacheSegment(Fcb->Bcb, CacheSeg, FALSE, FALSE, FALSE);
return Status;
}
}
* Retrieve the page from the cache segment that we actually want.
*/
Addr = MmGetPhysicalAddress(BaseAddress +
- Offset->QuadPart - BaseOffset);
+ Offset->u.LowPart - BaseOffset);
(*Page) = Addr;
MmReferencePage((*Page));
CcRosReleaseCacheSegment(Fcb->Bcb, CacheSeg, TRUE, FALSE, TRUE);
- return(STATUS_SUCCESS);
}
else
{
+ PVOID PageAddr;
+ ULONG OffsetInPage;
/*
* Allocate a page, this is rather complicated by the possibility
* we might have to move other things out of memory
return(Status);
}
- /*
- * Create an mdl to hold the page we are going to read data into.
- */
- Mdl = MmCreateMdl(NULL, NULL, PAGE_SIZE);
- MmBuildMdlFromPages(Mdl, &Page->u.LowPart);
- /*
- * Call the FSD to read the page
- */
-
- KeInitializeEvent(&Event, NotificationEvent, FALSE);
- Status = IoPageRead(FileObject,
- Mdl,
- Offset,
- &Event,
- &IoStatus);
- if (Status == STATUS_PENDING)
+ Status = CcRosGetCacheSegment(Fcb->Bcb,
+ Offset->u.LowPart,
+ &BaseOffset,
+ &BaseAddress,
+ &UptoDate,
+ &CacheSeg);
+ if (!NT_SUCCESS(Status))
+ {
+ return(Status);
+ }
+ if (!UptoDate)
+ {
+ /*
+ * If the cache segment isn't up to date then call the file
+ * system to read in the data.
+ */
+ Status = ReadCacheSegment(CacheSeg);
+ if (!NT_SUCCESS(Status))
+ {
+ CcRosReleaseCacheSegment(Fcb->Bcb, CacheSeg, FALSE, FALSE, FALSE);
+ return Status;
+ }
+ }
+ PageAddr = ExAllocatePageWithPhysPage(*Page);
+ OffsetInPage = BaseOffset + CacheSeg->Bcb->CacheSegmentSize - Offset->u.LowPart;
+ if (OffsetInPage >= PAGE_SIZE)
{
- KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
- return(IoStatus.Status);
+ memcpy(PageAddr, BaseAddress + Offset->u.LowPart - BaseOffset, PAGE_SIZE);
}
- return(Status);
+ else
+ {
+ memcpy(PageAddr, BaseAddress + Offset->u.LowPart - BaseOffset, OffsetInPage);
+ CcRosReleaseCacheSegment(Fcb->Bcb, CacheSeg, TRUE, FALSE, FALSE);
+ Status = CcRosGetCacheSegment(Fcb->Bcb,
+ Offset->u.LowPart + OffsetInPage,
+ &BaseOffset,
+ &BaseAddress,
+ &UptoDate,
+ &CacheSeg);
+ if (!NT_SUCCESS(Status))
+ {
+ ExUnmapPage(PageAddr);
+ return(Status);
+ }
+ if (!UptoDate)
+ {
+ /*
+ * If the cache segment isn't up to date then call the file
+ * system to read in the data.
+ */
+ Status = ReadCacheSegment(CacheSeg);
+ if (!NT_SUCCESS(Status))
+ {
+ CcRosReleaseCacheSegment(Fcb->Bcb, CacheSeg, FALSE, FALSE, FALSE);
+ ExUnmapPage(PageAddr);
+ return Status;
+ }
+ }
+ memcpy(PageAddr + OffsetInPage, BaseAddress, PAGE_SIZE - OffsetInPage);
+ }
+ CcRosReleaseCacheSegment(Fcb->Bcb, CacheSeg, TRUE, FALSE, FALSE);
+ ExUnmapPage(PageAddr);
}
+ return(STATUS_SUCCESS);
}
NTSTATUS
Status = MmCreateVirtualMapping(PsGetCurrentProcess(),
Address,
- Attributes,
+ MemoryArea->Attributes,
Page,
FALSE);
if (!NT_SUCCESS(Status))
/*
* Take an additional reference to the page.
*/
- MmReferencePage(PhysicalAddress);
+// MmReferencePage(PhysicalAddress);
/*
* Paging out data mapped read-only is easy.
if (OldProtect != NewProtect)
{
- for (i = 0; i < (RegionSize / PAGE_SIZE); i++)
+ for (i = 0; i < PAGE_ROUND_UP(RegionSize) / PAGE_SIZE; i++)
{
PVOID Address = BaseAddress + (i * PAGE_SIZE);
ULONG Protect = NewProtect;
PageOp = MmCheckForPageOp(MArea, 0, NULL, MArea->Data.SectionData.Segment,
Offset);
+
+ if (PageOp)
+ {
+ KeWaitForSingleObject(&PageOp->CompletionEvent,
+ 0,
+ KernelMode,
+ FALSE,
+ NULL);
+ MmReleasePageOp(PageOp);
+ PageOp = MmCheckForPageOp(MArea, 0, NULL, MArea->Data.SectionData.Segment,
+ Offset);
+ }
+
assert(PageOp == NULL);
/*
}
MmUnlockAddressSpace(AddressSpace);
DPRINT("Result %p\n",Result);
- for (i = 0; (i <= (Length / PAGE_SIZE)); i++)
+ for (i = 0; i < PAGE_ROUND_UP(Length) / PAGE_SIZE; i++)
{
PHYSICAL_ADDRESS Page;
/* Check there is enough space to map the section at that point. */
if (MmOpenMemoryAreaByRegion(AddressSpace, ImageBase,
- ImageSize) != NULL)
+ PAGE_ROUND_UP(ImageSize)) != NULL)
{
/* Fail if the user requested a fixed base address. */
if ((*BaseAddress) != NULL)
{
MmUnlockSection(Section);
MmUnlockAddressSpace(AddressSpace);
- return(Status);
+ return(STATUS_UNSUCCESSFUL);
}
/* Otherwise find a gap to map the image. */
- ImageBase = MmFindGap(AddressSpace, ImageSize);
+ ImageBase = MmFindGap(AddressSpace, PAGE_ROUND_UP(ImageSize));
if (ImageBase == NULL)
{
MmUnlockSection(Section);
MmUnlockAddressSpace(AddressSpace);
- return(Status);
+ return(STATUS_UNSUCCESSFUL);
}
}
#include <internal/ps.h>
#include <internal/id.h>
#include <internal/ke.h>
+#include <internal/io.h>
#define NDEBUG
#include <internal/debug.h>
PWSTR Path;
PWSTR current;
UNICODE_STRING PathString;
+ ULONG Attributes;
DPRINT("ObFindObject(ObjectAttributes %x, ReturnedObject %x, "
"RemainingPath %x)\n",ObjectAttributes,ReturnedObject,RemainingPath);
}
RootObject = CurrentObject;
+ Attributes = ObjectAttributes->Attributes;
+ if (ObjectType == IoSymbolicLinkType)
+ Attributes |= OBJ_OPENLINK;
while (TRUE)
{
&NextObject,
&PathString,
¤t,
- ObjectAttributes->Attributes);
+ Attributes);
if (Status == STATUS_REPARSE)
{
/* reparse the object path */
if (StartingIndex + NumberToClear > Size)
NumberToClear = Size - StartingIndex;
- Ptr = (PCHAR)(BitMapHeader->Buffer + (StartingIndex / 8));
+ Ptr = (PCHAR)BitMapHeader->Buffer + (StartingIndex / 8);
while (NumberToClear)
{
/* bit shift in current byte */