update for HEAD-2002110701 HEAD-2002110701
authorshort <>
Thu, 7 Nov 2002 12:04:04 +0000 (12:04 +0000)
committershort <>
Thu, 7 Nov 2002 12:04:04 +0000 (12:04 +0000)
33 files changed:
include/ddk/fsfuncs.h
include/ddk/fstypes.h
include/ddk/iodef.h
include/ddk/iotypes.h
include/ntos/heap.h
lib/kernel32/file/curdir.c
lib/kernel32/file/file.c
lib/kernel32/file/lfile.c
lib/kernel32/process/create.c
lib/msvcrt/process/process.c
lib/user32/windows/bitmap.c
lib/user32/windows/defwnd.c
lib/user32/windows/prop.c
loaders/boot/boot.asm
loaders/boot/boot.mak
loaders/boot/bootbk.asm
ntoskrnl/io/create.c
ntoskrnl/io/iomgr.c
ntoskrnl/ldr/loader.c
ntoskrnl/lpc/connect.c
ntoskrnl/mm/anonmem.c
ntoskrnl/mm/cont.c
ntoskrnl/mm/i386/page.c
ntoskrnl/mm/iospace.c
ntoskrnl/mm/kmap.c
ntoskrnl/mm/marea.c
ntoskrnl/mm/mdl.c
ntoskrnl/mm/ncache.c
ntoskrnl/mm/npool.c
ntoskrnl/mm/rmap.c
ntoskrnl/mm/section.c
ntoskrnl/ob/object.c
ntoskrnl/rtl/bitmap.c

index 6f03dd3..06ce05f 100644 (file)
@@ -3,6 +3,21 @@
 /* $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,
index 03a6401..8b77390 100644 (file)
@@ -14,6 +14,23 @@ typedef struct _FILE_LOCK_INFO {
     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;
index 4d199cd..4d0b4e9 100644 (file)
@@ -249,6 +249,14 @@ enum
 #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
index d04fd7f..3d6b27a 100644 (file)
@@ -432,6 +432,14 @@ typedef struct __attribute__((packed)) _IO_STACK_LOCATION
          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
        {
index 5efac19..391d638 100644 (file)
@@ -18,7 +18,7 @@
 #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 */
index 85caf3f..31b64a2 100644 (file)
@@ -324,12 +324,8 @@ GetWindowsDirectoryA (
 
        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;
@@ -347,12 +343,9 @@ GetWindowsDirectoryA (
                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
 }
 
index e4c7163..7d0e41d 100644 (file)
@@ -259,15 +259,18 @@ GetFileType(HANDLE hFile)
    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;
      }
 
@@ -800,12 +803,73 @@ SetFileTime(HANDLE hFile,
 }
 
 
+/*
+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 */
index 6bbec15..4dd4acd 100644 (file)
@@ -156,11 +156,11 @@ _lcreat (
 
        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;
index 9abb98f..34748ee 100644 (file)
@@ -167,20 +167,22 @@ CreateProcessA (LPCSTR                    lpApplicationName,
        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
@@ -190,17 +192,17 @@ _except_handler(
 
        /* 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
        {
        }
@@ -520,7 +522,7 @@ KlInitPeb (HANDLE ProcessHandle,
 
    /* create the PPB */
    PpbBase = NULL;
-   PpbSize = Ppb->AllocationSize;\r
+   PpbSize = Ppb->AllocationSize;
    Status = NtAllocateVirtualMemory(ProcessHandle,
                                    &PpbBase,
                                    0,
@@ -536,7 +538,7 @@ KlInitPeb (HANDLE ProcessHandle,
    NtWriteVirtualMemory(ProcessHandle,
                        PpbBase,
                        Ppb,
-                       Ppb->AllocationSize,\r
+                       Ppb->AllocationSize,
                        &BytesWritten);
 
    /* write pointer to environment */
@@ -658,7 +660,7 @@ CreateProcessW(LPCWSTR lpApplicationName,
       {
          s = TempApplicationNameW;
       }
-      s = wcsrchr(TempApplicationNameW, L'.');
+      s = wcsrchr(s, L'.');
       if (s == NULL)
         wcscat(TempApplicationNameW, L".exe");
    }
@@ -798,23 +800,23 @@ CreateProcessW(LPCWSTR lpApplicationName,
    /*
     * 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);
@@ -862,31 +864,31 @@ CreateProcessW(LPCWSTR lpApplicationName,
      }
 
    // 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);
@@ -896,17 +898,17 @@ CreateProcessW(LPCWSTR lpApplicationName,
       }
    }
 
-   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);
@@ -915,17 +917,17 @@ CreateProcessW(LPCWSTR lpApplicationName,
         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);
@@ -940,20 +942,20 @@ CreateProcessW(LPCWSTR lpApplicationName,
     */
    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
      {
index d9cdc52..7e4f85f 100644 (file)
@@ -1,15 +1,97 @@
 /* $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)
 {
@@ -300,9 +382,7 @@ int _spawnvp(int mode, const char* cmdname, char* const* argv)
   
     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*/)
@@ -316,8 +396,6 @@ int _spawnlpe(int mode, const char* cmdname, const char* arg0, .../*, NULL, cons
 
     DPRINT("_spawnlpe('%s')\n", cmdname);
 
-    _searchenv(cmdname, "PATH", pathname);
-
     va_start(argp, arg0);
     args = valisttos(arg0, argp, ' ');
     do
@@ -328,7 +406,7 @@ int _spawnlpe(int mode, const char* cmdname, const char* arg0, .../*, NULL, cons
     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)
@@ -344,9 +422,7 @@ int _spawnvpe(int mode, const char* cmdname, char* const* argv, char* const* env
   
     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, ...)
@@ -419,14 +495,12 @@ int _execlp(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;
@@ -449,8 +523,6 @@ int _execlpe(const char* cmdname, const char* arg0, ... /*, NULL, char* const* e
 
     DPRINT("_execlpe('%s')\n", cmdname);
 
-    _searchenv(cmdname, "PATH", pathname);
-
     va_start(argp, arg0);
     args = valisttos(arg0, argp, ' ');
     do
@@ -461,7 +533,7 @@ int _execlpe(const char* cmdname, const char* arg0, ... /*, NULL, char* const* e
     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)
index 9b8147b..72a6977 100644 (file)
@@ -57,7 +57,7 @@ LoadImageA(HINSTANCE hinst,
     }
   else
     {
-      Handle = LoadImageW(hinst, lpszWName, uType, cxDesired,
+      Handle = LoadImageW(hinst, (LPCWSTR)lpszName, uType, cxDesired,
                          cyDesired, fuLoad);
     }
   return(Handle);
index 631d63e..de7d91b 100644 (file)
@@ -956,7 +956,7 @@ DefWndAdjustRect(RECT* Rect, ULONG Style, BOOL Menu, ULONG ExStyle)
 LRESULT STDCALL
 DefWndNCCalcSize(HWND hWnd, RECT* Rect)
 {
-  LRESULT Result;
+  LRESULT Result = 0;
   LONG Style = GetClassLongW(hWnd, GCL_STYLE);
   RECT TmpRect = {0, 0, 0, 0};
 
index 9de81de..6ca29d1 100644 (file)
@@ -118,7 +118,7 @@ RemovePropA(HWND hWnd, LPCSTR lpString)
     }
   else
     {
-      Ret = RemovePropW(hWnd, lpWString);
+      Ret = RemovePropW(hWnd, (LPCWSTR)lpString);
     }
   return(Ret);
 }
index 17fe2c7..019ea01 100644 (file)
@@ -30,8 +30,8 @@
 ; $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
 ;
index 43dc66a..99fb0b9 100644 (file)
@@ -4,8 +4,8 @@
 # $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
 #
index 3e8d8f0..aafff8c 100644 (file)
@@ -30,8 +30,8 @@
 ; $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
 ;
index e2a0400..4d02162 100644 (file)
@@ -432,6 +432,9 @@ IoCreateFile(OUT    PHANDLE                 FileHandle,
    if (!NT_SUCCESS(Status))
      {
        DPRINT("Failing create request with status %x\n", Status);
+        FileObject->DeviceObject = NULL;
+        FileObject->Vpb = NULL;
+
        ZwClose(*FileHandle);
      }
    if (IoStatusBlock)
index 4c5a358..46b2631 100644 (file)
@@ -54,7 +54,7 @@ IopCloseFile(PVOID ObjectBody,
    
    DPRINT("IopCloseFile()\n");
    
-   if (HandleCount > 0)
+   if (HandleCount > 0 || FileObject->DeviceObject == NULL)
      {
        return;
      }
@@ -63,7 +63,8 @@ IopCloseFile(PVOID ObjectBody,
                              STANDARD_RIGHTS_REQUIRED,
                              IoFileObjectType,
                              UserMode);
-   
+   KeResetEvent( &FileObject->Event );
+  
    Irp = IoBuildSynchronousFsdRequest(IRP_MJ_CLEANUP,
                                      FileObject->DeviceObject,
                                      NULL,
@@ -75,6 +76,10 @@ IopCloseFile(PVOID ObjectBody,
    StackPtr->FileObject = FileObject;
    
    Status = IoCallDriver(FileObject->DeviceObject, Irp);
+   if (Status == STATUS_PENDING)
+   {
+      KeWaitForSingleObject(&FileObject->Event, Executive, KernelMode, FALSE, NULL);
+   }
 }
 
 VOID STDCALL
@@ -86,23 +91,31 @@ IopDeleteFile(PVOID ObjectBody)
    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)
      {
index eba5f27..f428552 100644 (file)
@@ -1115,7 +1115,7 @@ LdrPEProcessModule(PVOID ModuleLoadBase,
            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);
index 460e36a..78e0f35 100644 (file)
@@ -517,9 +517,15 @@ NtAcceptConnectPort (PHANDLE                       ServerPortHandle,
   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);
@@ -540,7 +546,7 @@ NtAcceptConnectPort (PHANDLE                        ServerPortHandle,
   /*
    * Create a port object for our side of the connection
    */
-  if (AcceptIt == 1)
+  if (AcceptIt)
     {
       Status = ObCreateObject(ServerPortHandle,
                              PORT_ALL_ACCESS,
@@ -549,6 +555,7 @@ NtAcceptConnectPort (PHANDLE                        ServerPortHandle,
                              (PVOID*)&OurPort);
       if (!NT_SUCCESS(Status))
        {
+         ExFreePool(CReply);
          ObDereferenceObject(NamedPort);
          return(Status);
        }
@@ -584,7 +591,7 @@ NtAcceptConnectPort (PHANDLE                        ServerPortHandle,
        sizeof(LPC_MESSAGE);
       CReply->ConnectDataLength = 0;
     }
-  if (AcceptIt != 1)
+  if (!AcceptIt)
     {  
       EiReplyOrRequestPort(ConnectionRequest->Sender,
                           &CReply->MessageHeader,
@@ -707,6 +714,7 @@ NtAcceptConnectPort (PHANDLE                        ServerPortHandle,
                       LPC_REPLY,
                       OurPort);
   ExFreePool(ConnectionRequest);
+  ExFreePool(CReply);
    
   ObDereferenceObject(OurPort);
   ObDereferenceObject(NamedPort);
index 0737009..451c5c2 100644 (file)
@@ -154,6 +154,7 @@ MmPageOutVirtualMemory(PMADDRESS_SPACE AddressSpace,
     */
    MmDisableVirtualMapping(MemoryArea->Process, Address,
                           &WasDirty, &PhysicalAddress);
+
    if (PhysicalAddress.QuadPart == 0)
      {
        KeBugCheck(0);
@@ -200,7 +201,7 @@ MmPageOutVirtualMemory(PMADDRESS_SPACE AddressSpace,
     * 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))
      {
@@ -439,7 +440,7 @@ MmModifyAttributes(PMADDRESS_SPACE AddressSpace,
     {
       ULONG i;
       
-      for (i=0; i <= (RegionSize/PAGE_SIZE); i++)
+      for (i=0; i < PAGE_ROUND_UP(RegionSize)/PAGE_SIZE; i++)
        {
          LARGE_INTEGER PhysicalAddr;
 
@@ -485,7 +486,7 @@ MmModifyAttributes(PMADDRESS_SPACE AddressSpace,
     {
       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)))
@@ -581,7 +582,7 @@ NtAllocateVirtualMemory(IN  HANDLE  ProcessHandle,
    
    if (PBaseAddress != 0)
      {
-       MemoryArea = MmOpenMemoryAreaByAddress(&Process->AddressSpace,
+       MemoryArea = MmOpenMemoryAreaByAddress(AddressSpace,
                                               BaseAddress);
        
        if (MemoryArea != NULL &&
@@ -589,7 +590,7 @@ NtAllocateVirtualMemory(IN  HANDLE  ProcessHandle,
            MemoryArea->Length >= RegionSize)
          {
            Status = 
-             MmAlterRegion(&Process->AddressSpace, 
+             MmAlterRegion(AddressSpace, 
                            MemoryArea->BaseAddress, 
                            &MemoryArea->Data.VirtualMemoryData.RegionListHead,
                            PBaseAddress, RegionSize,
@@ -690,7 +691,7 @@ MmFreeVirtualMemory(PEPROCESS Process,
    */
   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;
 
index 37af4a1..8d3bbc6 100644 (file)
@@ -63,11 +63,13 @@ MmAllocateContiguousAlignedMemory(IN ULONG NumberOfBytes,
                                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++)
@@ -142,11 +144,13 @@ MmAllocateContiguousMemory (IN ULONG NumberOfBytes,
 VOID STDCALL 
 MmFreeContiguousMemory(IN PVOID BaseAddress)
 {
+   MmLockAddressSpace(MmGetKernelAddressSpace());
    MmFreeMemoryArea(MmGetKernelAddressSpace(),
                    BaseAddress,
                    0,
                    MmFreeContinuousPage,
                    NULL);
+   MmUnlockAddressSpace(MmGetKernelAddressSpace());
 }
 
 
index 3e19b06..185921c 100644 (file)
@@ -161,7 +161,7 @@ NTSTATUS MmCopyMmInfo(PEPROCESS Src, PEPROCESS Dest)
      }
    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);
    
@@ -180,7 +180,8 @@ VOID MmDeletePageTable(PEPROCESS Process, PVOID Address)
    *(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)
@@ -197,31 +198,37 @@ VOID MmFreePageTable(PEPROCESS Process, PVOID Address)
    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)
@@ -229,41 +236,66 @@ 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)
@@ -288,27 +320,30 @@ ULONG MmGetPageEntry1(PVOID PAddress)
  * 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)
@@ -422,7 +457,7 @@ MmDeleteVirtualMapping(PEPROCESS Process, PVOID Address, BOOL FreePage,
  */
 {
    ULONG Pte;
-   PULONG Pde;
+   PULONG Pde, kePde;
    PEPROCESS CurrentProcess = PsGetCurrentProcess();
    BOOLEAN WasValid;
 
@@ -440,13 +475,17 @@ MmDeleteVirtualMapping(PEPROCESS Process, PVOID Address, BOOL FreePage,
     * 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)
          {
@@ -475,7 +514,7 @@ MmDeleteVirtualMapping(PEPROCESS Process, PVOID Address, BOOL FreePage,
      }
    if (FreePage && WasValid)
      {
-        MmReleasePageMemoryConsumer(MC_NPPOOL, PTE_TO_PAGE(Pte));
+       MmReleasePageMemoryConsumer(MC_NPPOOL, PTE_TO_PAGE(Pte));
      }
 
    /*
@@ -483,7 +522,7 @@ MmDeleteVirtualMapping(PEPROCESS Process, PVOID Address, BOOL FreePage,
     */
    if (Process != NULL && WasValid &&
        Process->AddressSpace.PageTableRefCountTable != NULL &&
-       ADDR_TO_PAGE_TABLE(Address) < 768)
+       Address < (PVOID)KERNEL_BASE)
      {
        PUSHORT Ptrc;
        
@@ -532,7 +571,7 @@ MmDeletePageFileMapping(PEPROCESS Process, PVOID Address,
  */
 {
    ULONG Pte;
-   PULONG Pde;
+   PULONG Pde, kePde;
    PEPROCESS CurrentProcess = PsGetCurrentProcess();
    BOOLEAN WasValid = FALSE;
 
@@ -550,13 +589,19 @@ MmDeletePageFileMapping(PEPROCESS Process, PVOID Address,
     * 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)
          {
@@ -572,12 +617,14 @@ MmDeletePageFileMapping(PEPROCESS Process, PVOID Address,
    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;
        
@@ -607,63 +654,75 @@ MmDeletePageFileMapping(PEPROCESS Process, PVOID Address,
 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);
 }
 
@@ -672,36 +731,69 @@ PULONG MmGetPageEntry(PVOID PAddress)
  * 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)
index a1b55a9..645a778 100644 (file)
@@ -96,7 +96,7 @@ MmMapIoSpace (IN PHYSICAL_ADDRESS PhysicalAddress,
      {
        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),
@@ -141,11 +141,13 @@ VOID STDCALL
 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());
 }
 
 
index 6980931..ab48792 100644 (file)
  * 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;
 
@@ -38,15 +39,14 @@ VOID
 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);
 }
 
@@ -99,35 +99,31 @@ PVOID
 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 
@@ -135,6 +131,8 @@ MmInitKernelMap(PVOID BaseAddress)
 {
    NonPagedPoolBase = BaseAddress;
    KeInitializeSpinLock(&AllocMapLock);
+   RtlInitializeBitMap(&AllocMap, (PVOID)&AllocMapBuffer, ALLOC_MAP_SIZE);
+   RtlClearAllBits(&AllocMap);
 }
 
 VOID
@@ -142,21 +140,19 @@ MiFreeNonPagedPoolRegion(PVOID Addr, ULONG Count, BOOLEAN Free)
 {
   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);
 }
 
@@ -166,44 +162,21 @@ MiAllocNonPagedPoolRegion(ULONG nr_pages)
  * 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;
 }
index 9ff7f1a..dfb5dd5 100644 (file)
@@ -222,7 +222,7 @@ PVOID MmFindGap(PMADDRESS_SPACE AddressSpace, ULONG Length)
      {
        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));
@@ -274,7 +274,7 @@ MmFreeMemoryArea(PMADDRESS_SPACE AddressSpace,
    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,
@@ -376,12 +376,14 @@ NTSTATUS MmCreateMemoryArea(PEPROCESS 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)
@@ -392,11 +394,12 @@ NTSTATUS MmCreateMemoryArea(PEPROCESS Process,
        (*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);
@@ -408,7 +411,7 @@ NTSTATUS MmCreateMemoryArea(PEPROCESS Process,
    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;
index 9ce47a3..4a2f83d 100644 (file)
@@ -15,6 +15,7 @@
 #include <internal/mm.h>
 #include <internal/ps.h>
 #include <internal/pool.h>
+#include <ntos/minmax.h>
 
 #define NDEBUG
 #include <internal/debug.h>
@@ -26,8 +27,8 @@
 #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 *****************************************************************/
@@ -37,7 +38,9 @@ MmInitializeMdlImplementation(VOID)
 {
   MEMORY_AREA* Result;
   NTSTATUS Status;
+  PVOID Buffer;
 
+  MiMdlMappingRegionHint = 0;
   MiMdlMappingRegionBase = NULL;
 
   MmLockAddressSpace(MmGetKernelAddressSpace());
@@ -56,10 +59,11 @@ MmInitializeMdlImplementation(VOID)
     }
   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);
 }
 
@@ -130,6 +134,7 @@ MmMapLockedPages(PMDL Mdl, KPROCESSOR_MODE AccessMode)
    PULONG MdlPages;
    KIRQL oldIrql;
    ULONG RegionSize;
+   ULONG StartingOffset;
    
    DPRINT("MmMapLockedPages(Mdl %x, AccessMode %x)\n", Mdl, AccessMode);
 
@@ -149,13 +154,22 @@ MmMapLockedPages(PMDL Mdl, KPROCESSOR_MODE 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. */
@@ -195,7 +209,7 @@ MmUnmapLockedPages(PVOID BaseAddress, PMDL Mdl)
   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
@@ -208,6 +222,7 @@ MmUnmapLockedPages(PVOID BaseAddress, PMDL Mdl)
 
   /* 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++)
@@ -221,18 +236,12 @@ MmUnmapLockedPages(PVOID BaseAddress, PMDL Mdl)
 
   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. */
index 2ff2129..d013d53 100644 (file)
@@ -71,7 +71,7 @@ MmAllocateNonCachedMemory(IN ULONG NumberOfBytes)
      }
    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;
 
@@ -125,11 +125,13 @@ MmFreeNonCachedPage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address,
 VOID STDCALL MmFreeNonCachedMemory (IN PVOID BaseAddress,
                                    IN ULONG NumberOfBytes)
 {
+  MmLockAddressSpace(MmGetKernelAddressSpace());
   MmFreeMemoryArea (MmGetKernelAddressSpace(),
                    BaseAddress,
                    NumberOfBytes,
                    MmFreeNonCachedPage,
                    NULL);
+  MmUnlockAddressSpace(MmGetKernelAddressSpace());
 }
 
 
index 391c1ae..daef537 100644 (file)
@@ -203,7 +203,7 @@ MiAddToTagHashTable(BLOCK_HDR* block)
          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);
        }
@@ -596,7 +596,9 @@ merge_free_block(BLOCK_HDR* blk)
          (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--;
        }
     }
@@ -610,6 +612,8 @@ merge_free_block(BLOCK_HDR* blk)
        {
          RemoveEntryList(&blk->ListEntry);
          previous->Size = previous->Size + sizeof(BLOCK_HDR) + blk->Size;
+         memset(blk, 0xcc, sizeof(BLOCK_HDR));
+          EiFreeNonPagedPool += sizeof(BLOCK_HDR);
          EiNrFreeBlocks--;
        }
     }
@@ -635,6 +639,7 @@ add_to_free_list(BLOCK_HDR* blk)
          blk->ListEntry.Blink = current_entry->Blink;
          current_entry->Blink->Flink = &blk->ListEntry;
          current_entry->Blink = &blk->ListEntry;
+          EiFreeNonPagedPool += blk->Size;
          EiNrFreeBlocks++;
          return;
        }
@@ -642,6 +647,7 @@ add_to_free_list(BLOCK_HDR* blk)
       current_entry = current_entry->Flink;
     }
   InsertTailList(&FreeBlockListHead, &blk->ListEntry);
+  EiFreeNonPagedPool += blk->Size;
   EiNrFreeBlocks++;
 }
 
@@ -651,6 +657,7 @@ static void add_to_used_list(BLOCK_HDR* blk)
  */
 {
   InsertHeadList(&UsedBlockListHead, &blk->ListEntry);
+  EiUsedNonPagedPool += blk->Size;
   EiNrUsedBlocks++;
 }
 
@@ -658,6 +665,7 @@ static void add_to_used_list(BLOCK_HDR* blk)
 static void remove_from_free_list(BLOCK_HDR* current)
 {
   RemoveEntryList(&current->ListEntry);
+  EiFreeNonPagedPool -= current->Size;
   EiNrFreeBlocks--;
 }
 
@@ -665,6 +673,7 @@ static void remove_from_free_list(BLOCK_HDR* current)
 static void remove_from_used_list(BLOCK_HDR* current)
 {
   RemoveEntryList(&current->ListEntry);
+  EiUsedNonPagedPool -= current->Size;
   EiNrUsedBlocks--;
 }
 
@@ -684,86 +693,54 @@ inline static BLOCK_HDR* address_to_block(void* addr)
                ( ((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,
@@ -774,17 +751,40 @@ 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(&current->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
@@ -798,8 +798,7 @@ static void* take_block(BLOCK_HDR* current, unsigned int size,
        
        current->Size=size;
        RemoveEntryList(&current->ListEntry);
-       InsertHeadList(&UsedBlockListHead, &current->ListEntry);
-       EiNrUsedBlocks++;
+       add_to_used_list(current);
        current->Magic = BLOCK_HDR_USED_MAGIC;
        current->Tag = Tag;
        current->Caller = Caller;
@@ -808,8 +807,7 @@ static void* take_block(BLOCK_HDR* current, unsigned int size,
        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));
@@ -821,9 +819,6 @@ static void* take_block(BLOCK_HDR* current, unsigned int size,
    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;
@@ -836,6 +831,76 @@ static void* take_block(BLOCK_HDR* current, unsigned int size,
    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)
@@ -904,11 +969,12 @@ 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);
 
@@ -942,8 +1008,6 @@ ExAllocateNonPagedPoolWithTag(ULONG Type, ULONG Size, ULONG Tag, PVOID Caller)
    return(block);
 
 #else /* not WHOLE_PAGE_ALLOCATIONS */
-   BLOCK_HDR* current = NULL;
-   PLIST_ENTRY current_entry;
    PVOID block;
    BLOCK_HDR* best = NULL;
    KIRQL oldIrql;
@@ -952,9 +1016,21 @@ ExAllocateNonPagedPoolWithTag(ULONG Type, ULONG Size, ULONG Tag, PVOID Caller)
              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
     */
@@ -964,39 +1040,26 @@ ExAllocateNonPagedPoolWithTag(ULONG Type, ULONG Size, ULONG Tag, PVOID Caller)
        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 */
 }
index 81df3e4..056b906 100644 (file)
@@ -45,6 +45,8 @@ typedef struct _MM_RMAP_ENTRY
   PVOID Address;
 } MM_RMAP_ENTRY, *PMM_RMAP_ENTRY;
 
+#define TAG_RMAP    TAG('R', 'M', 'A', 'P')
+
 /* GLOBALS ******************************************************************/
 
 static FAST_MUTEX RmapListLock;
@@ -353,7 +355,7 @@ MmInsertRmap(PHYSICAL_ADDRESS PhysicalAddress, PEPROCESS Process,
 
   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);
index d4b5f53..5c3af8c 100644 (file)
@@ -318,12 +318,13 @@ MiReadPage(PMEMORY_AREA MemoryArea,
       *       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;
@@ -336,10 +337,6 @@ MiReadPage(PMEMORY_AREA MemoryArea,
   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;
 
       /*
@@ -348,7 +345,7 @@ MiReadPage(PMEMORY_AREA MemoryArea,
        * alignment less than the file system block size.
        */
       Status = CcRosGetCacheSegment(Fcb->Bcb,
-                                (ULONG)Offset->QuadPart,
+                                Offset->u.LowPart,
                                 &BaseOffset,
                                 &BaseAddress,
                                 &UptoDate,
@@ -366,6 +363,7 @@ MiReadPage(PMEMORY_AREA MemoryArea,
           Status = ReadCacheSegment(CacheSeg);
          if (!NT_SUCCESS(Status))
          {
+             CcRosReleaseCacheSegment(Fcb->Bcb, CacheSeg, FALSE, FALSE, FALSE);
              return Status;
          }
        }
@@ -373,15 +371,16 @@ MiReadPage(PMEMORY_AREA MemoryArea,
        * 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
@@ -392,28 +391,70 @@ MiReadPage(PMEMORY_AREA MemoryArea,
          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
@@ -558,7 +599,7 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
 
           Status = MmCreateVirtualMapping(PsGetCurrentProcess(),
                                           Address,
-                                          Attributes,
+                                          MemoryArea->Attributes,
                                           Page,
                                           FALSE);
           if (!NT_SUCCESS(Status))
@@ -1253,7 +1294,7 @@ MmPageOutSectionView(PMADDRESS_SPACE AddressSpace,
   /*
    * Take an additional reference to the page.
    */
-  MmReferencePage(PhysicalAddress);
+//  MmReferencePage(PhysicalAddress);
 
   /*
    * Paging out data mapped read-only is easy.
@@ -1680,7 +1721,7 @@ MmAlterViewAttributes(PMADDRESS_SPACE AddressSpace,
 
   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;
@@ -2873,6 +2914,19 @@ MmFreeSectionPage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address,
 
   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);
 
   /*
@@ -3189,7 +3243,7 @@ MmAllocateSection (IN ULONG Length)
      }
    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;
 
@@ -3310,22 +3364,22 @@ MmMapViewOfSection(IN PVOID SectionObject,
 
        /* 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);
             }
         }
                                    
index 7ac9996..383a25f 100644 (file)
@@ -17,6 +17,7 @@
 #include <internal/ps.h>
 #include <internal/id.h>
 #include <internal/ke.h>
+#include <internal/io.h>
 
 #define NDEBUG
 #include <internal/debug.h>
@@ -111,6 +112,7 @@ NTSTATUS ObFindObject(POBJECT_ATTRIBUTES ObjectAttributes,
    PWSTR Path;
    PWSTR current;
    UNICODE_STRING PathString;
+   ULONG Attributes;
    
    DPRINT("ObFindObject(ObjectAttributes %x, ReturnedObject %x, "
          "RemainingPath %x)\n",ObjectAttributes,ReturnedObject,RemainingPath);
@@ -167,6 +169,9 @@ NTSTATUS ObFindObject(POBJECT_ATTRIBUTES ObjectAttributes,
      }
 
    RootObject = CurrentObject;
+   Attributes = ObjectAttributes->Attributes;
+   if (ObjectType == IoSymbolicLinkType)
+     Attributes |= OBJ_OPENLINK;
 
    while (TRUE)
      {
@@ -185,7 +190,7 @@ NTSTATUS ObFindObject(POBJECT_ATTRIBUTES ObjectAttributes,
                                                  &NextObject,
                                                  &PathString,
                                                  &current,
-                                                 ObjectAttributes->Attributes);
+                                                 Attributes);
        if (Status == STATUS_REPARSE)
          {
             /* reparse the object path */
index 6823b48..3760fa6 100644 (file)
@@ -136,7 +136,7 @@ RtlClearBits (
        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 */