preliminary comment out the self-modifying code for RtlPrefetchMemoryNonTemporal
[reactos.git] / reactos / ntoskrnl / ob / dirobj.c
index de44ab0..e2558f0 100644 (file)
@@ -4,7 +4,7 @@
  * PROJECT:        ReactOS kernel
  * FILE:           ntoskrnl/ob/dirobj.c
  * PURPOSE:        Interface functions to directory object
- * 
+ *
  * PROGRAMMERS:    David Welch (welch@mcmail.com)
  */
 
  *
  * DESCRIPTION
  *     Opens a namespace directory object.
- *     
+ *
  * ARGUMENTS
  *     DirectoryHandle (OUT)
  *             Variable which receives the directory handle.
- *             
+ *
  *     DesiredAccess
  *             Desired access to the directory.
- *             
+ *
  *     ObjectAttributes
  *             Structure describing the directory.
- *             
+ *
  * RETURN VALUE
  *     Status.
- *     
+ *
  * NOTES
  *     Undocumented.
  */
@@ -49,32 +49,30 @@ NtOpenDirectoryObject (OUT PHANDLE DirectoryHandle,
    HANDLE hDirectory;
    KPROCESSOR_MODE PreviousMode;
    NTSTATUS Status = STATUS_SUCCESS;
-   
+
    PAGED_CODE();
-   
+
    PreviousMode = ExGetPreviousMode();
-   
+
    if(PreviousMode != KernelMode)
    {
      _SEH_TRY
      {
-       ProbeForWrite(DirectoryHandle,
-                     sizeof(HANDLE),
-                     sizeof(ULONG));
+       ProbeForWriteHandle(DirectoryHandle);
      }
      _SEH_HANDLE
      {
        Status = _SEH_GetExceptionCode();
      }
      _SEH_END;
-     
+
      if(!NT_SUCCESS(Status))
      {
        DPRINT1("NtOpenDirectoryObject failed, Status: 0x%x\n", Status);
        return Status;
      }
    }
-   
+
    Status = ObOpenObjectByName(ObjectAttributes,
                                ObDirectoryType,
                                NULL,
@@ -94,7 +92,7 @@ NtOpenDirectoryObject (OUT PHANDLE DirectoryHandle,
      }
      _SEH_END;
    }
-   
+
    return Status;
 }
 
@@ -102,35 +100,35 @@ NtOpenDirectoryObject (OUT PHANDLE DirectoryHandle,
 /**********************************************************************
  * NAME                                                        EXPORTED
  *     NtQueryDirectoryObject
- * 
+ *
  * DESCRIPTION
  *     Reads information from a directory in the system namespace.
- *     
+ *
  * ARGUMENTS
  *     DirectoryHandle
  *             Handle, obtained with NtOpenDirectoryObject(), which
  *             must grant DIRECTORY_QUERY access to the directory
  *             object.
- *             
+ *
  *     Buffer (OUT)
  *             Buffer to hold the data read.
- *             
+ *
  *     BufferLength
  *             Size of the buffer in bytes.
- *             
+ *
  *     ReturnSingleEntry
  *             When TRUE, only 1 entry is written in DirObjInformation;
  *             otherwise as many as will fit in the buffer.
- *             
+ *
  *     RestartScan
  *             If TRUE start reading at index 0.
  *             If FALSE start reading at the index specified
  *             by object index *ObjectIndex.
- *             
+ *
  *     Context
  *             Zero based index into the directory, interpretation
  *             depends on RestartScan.
- *             
+ *
  *     ReturnLength (OUT)
  *             Caller supplied storage for the number of bytes
  *             written (or NULL).
@@ -171,9 +169,9 @@ NtQueryDirectoryObject (IN HANDLE DirectoryHandle,
   ULONG NextEntry = 0;
   ULONG CopyBytes = 0;
   NTSTATUS Status = STATUS_SUCCESS;
-  
+
   PAGED_CODE();
-  
+
   PreviousMode = ExGetPreviousMode();
 
   if(PreviousMode != KernelMode)
@@ -186,18 +184,14 @@ NtQueryDirectoryObject (IN HANDLE DirectoryHandle,
       ProbeForWrite(Buffer,
                     BufferLength,
                     sizeof(WCHAR));
-      ProbeForWrite(Context,
-                    sizeof(ULONG),
-                    sizeof(ULONG));
+      ProbeForWriteUlong(Context);
       if(!RestartScan)
       {
         SkipEntries = *Context;
       }
       if(ReturnLength != NULL)
       {
-        ProbeForWrite(ReturnLength,
-                      sizeof(ULONG),
-                      sizeof(ULONG));
+        ProbeForWriteUlong(ReturnLength);
       }
     }
     _SEH_HANDLE
@@ -216,7 +210,7 @@ NtQueryDirectoryObject (IN HANDLE DirectoryHandle,
   {
     SkipEntries = *Context;
   }
-  
+
   Status = ObReferenceObjectByHandle(DirectoryHandle,
                                      DIRECTORY_QUERY,
                                      ObDirectoryType,
@@ -225,17 +219,17 @@ NtQueryDirectoryObject (IN HANDLE DirectoryHandle,
                                      NULL);
   if(NT_SUCCESS(Status))
   {
-    PVOID TemporaryBuffer = ExAllocatePool(PagedPool,
+    PVOID TemporaryBuffer = ExAllocatePool(NonPagedPool,
                                            BufferLength);
     if(TemporaryBuffer != NULL)
     {
       POBJECT_HEADER EntryHeader;
       PLIST_ENTRY ListEntry;
       KIRQL OldLevel;
-      ULONG RequiredSize = 0;
+      ULONG RequiredSize = sizeof(OBJECT_DIRECTORY_INFORMATION);
       ULONG nDirectories = 0;
       POBJECT_DIRECTORY_INFORMATION DirInfo = (POBJECT_DIRECTORY_INFORMATION)TemporaryBuffer;
-      
+
       Status = STATUS_NO_MORE_ENTRIES;
 
       KeAcquireSpinLock(&Directory->Lock, &OldLevel);
@@ -253,11 +247,11 @@ NtQueryDirectoryObject (IN HANDLE DirectoryHandle,
           EntryHeader = CONTAINING_RECORD(ListEntry, OBJECT_HEADER, Entry);
 
           /* calculate the size of the required buffer space for this entry */
-          Name = (EntryHeader->Name.Length != 0 ? &EntryHeader->Name : NULL);
-          Type = &EntryHeader->ObjectType->TypeName;
+          Name = (HEADER_TO_OBJECT_NAME(EntryHeader)->Name.Length != 0 ? &HEADER_TO_OBJECT_NAME(EntryHeader)->Name : NULL);
+          Type = &EntryHeader->Type->Name;
           EntrySize = sizeof(OBJECT_DIRECTORY_INFORMATION) +
                       ((Name != NULL) ? ((ULONG)Name->Length + sizeof(WCHAR)) : 0) +
-                      (ULONG)EntryHeader->ObjectType->TypeName.Length + sizeof(WCHAR);
+                      (ULONG)EntryHeader->Type->Name.Length + sizeof(WCHAR);
 
           if(RequiredSize + EntrySize <= BufferLength)
           {
@@ -275,7 +269,7 @@ NtQueryDirectoryObject (IN HANDLE DirectoryHandle,
 
             nDirectories++;
             RequiredSize += EntrySize;
-            
+
             Status = STATUS_SUCCESS;
 
             if(ReturnSingleEntry)
@@ -295,12 +289,12 @@ NtQueryDirectoryObject (IN HANDLE DirectoryHandle,
               RequiredSize += EntrySize;
               Status = STATUS_BUFFER_TOO_SMALL;
             }
-            
+
             /* we couldn't query this entry, so leave the index that will be stored
                in Context to this entry so the caller can query it the next time
                he queries (hopefully with a buffer that is large enough then...) */
             NextEntry--;
-            
+
             /* just copy the entries that fit into the buffer */
             break;
           }
@@ -311,7 +305,7 @@ NtQueryDirectoryObject (IN HANDLE DirectoryHandle,
           SkipEntries--;
         }
       }
-      
+
       if(!ReturnSingleEntry && ListEntry != &Directory->head)
       {
         /* there are more entries to enumerate but the buffer is already full.
@@ -321,11 +315,12 @@ NtQueryDirectoryObject (IN HANDLE DirectoryHandle,
 
       if(NT_SUCCESS(Status) && nDirectories > 0)
       {
-        PWSTR strbuf = (PWSTR)((POBJECT_DIRECTORY_INFORMATION)TemporaryBuffer + nDirectories);
-        PWSTR deststrbuf = (PWSTR)((POBJECT_DIRECTORY_INFORMATION)Buffer + nDirectories);
-        
-        CopyBytes = nDirectories * sizeof(OBJECT_DIRECTORY_INFORMATION);
-        
+        PWSTR strbuf = (PWSTR)((POBJECT_DIRECTORY_INFORMATION)TemporaryBuffer + nDirectories + 1);
+        PWSTR deststrbuf = (PWSTR)((POBJECT_DIRECTORY_INFORMATION)Buffer + nDirectories + 1);
+        memset((POBJECT_DIRECTORY_INFORMATION)TemporaryBuffer + nDirectories, 0, sizeof(OBJECT_DIRECTORY_INFORMATION));
+
+        CopyBytes = (nDirectories + 1) * sizeof(OBJECT_DIRECTORY_INFORMATION);
+
         /* copy the names from the objects and append them to the list of the
            objects. copy to the temporary buffer only because the directory
            lock can't be released and the buffer might be pagable memory! */
@@ -334,7 +329,7 @@ NtQueryDirectoryObject (IN HANDLE DirectoryHandle,
             nDirectories--, DirInfo++)
         {
           ULONG NameLength;
-          
+
           if(DirInfo->ObjectName.Length > 0)
           {
             RtlCopyMemory(strbuf,
@@ -350,7 +345,7 @@ NtQueryDirectoryObject (IN HANDLE DirectoryHandle,
 
             CopyBytes += (NameLength + 1) * sizeof(WCHAR);
           }
-          
+
           RtlCopyMemory(strbuf,
                         DirInfo->ObjectTypeName.Buffer,
                         DirInfo->ObjectTypeName.Length);
@@ -361,7 +356,7 @@ NtQueryDirectoryObject (IN HANDLE DirectoryHandle,
           strbuf[NameLength] = L'\0';
           strbuf += NameLength + 1;
           deststrbuf += NameLength + 1;
-          
+
           CopyBytes += (NameLength + 1) * sizeof(WCHAR);
         }
       }
@@ -391,7 +386,7 @@ NtQueryDirectoryObject (IN HANDLE DirectoryHandle,
         }
         _SEH_END;
       }
-      
+
       ExFreePool(TemporaryBuffer);
     }
     else
@@ -399,7 +394,7 @@ NtQueryDirectoryObject (IN HANDLE DirectoryHandle,
       Status = STATUS_INSUFFICIENT_RESOURCES;
     }
   }
-  
+
   return Status;
 }
 
@@ -407,23 +402,23 @@ NtQueryDirectoryObject (IN HANDLE DirectoryHandle,
 /**********************************************************************
  * NAME                                                (EXPORTED as Zw)
  *     NtCreateDirectoryObject
- *     
+ *
  * DESCRIPTION
  *     Creates or opens a directory object (a container for other
  *     objects).
- *     
+ *
  * ARGUMENTS
  *     DirectoryHandle (OUT)
- *             Caller supplied storage for the handle of the 
+ *             Caller supplied storage for the handle of the
  *             directory.
- *             
+ *
  *     DesiredAccess
  *             Access desired to the directory.
- *             
+ *
  *     ObjectAttributes
  *             Object attributes initialized with
  *             InitializeObjectAttributes.
- *             
+ *
  * RETURN VALUE
  *     Status.
  */
@@ -436,12 +431,12 @@ NtCreateDirectoryObject (OUT PHANDLE DirectoryHandle,
   HANDLE hDirectory;
   KPROCESSOR_MODE PreviousMode;
   NTSTATUS Status = STATUS_SUCCESS;
-  
+
   PAGED_CODE();
-  
+
   DPRINT("NtCreateDirectoryObject(DirectoryHandle %x, "
-        "DesiredAccess %x, ObjectAttributes %x\n",
-        DirectoryHandle, DesiredAccess, ObjectAttributes);
+         "DesiredAccess %x, ObjectAttributes %x\n",
+          DirectoryHandle, DesiredAccess, ObjectAttributes);
 
   PreviousMode = ExGetPreviousMode();
 
@@ -449,9 +444,7 @@ NtCreateDirectoryObject (OUT PHANDLE DirectoryHandle,
   {
     _SEH_TRY
     {
-      ProbeForWrite(DirectoryHandle,
-                    sizeof(HANDLE),
-                    sizeof(ULONG));
+      ProbeForWriteHandle(DirectoryHandle);
     }
     _SEH_HANDLE
     {
@@ -475,6 +468,7 @@ NtCreateDirectoryObject (OUT PHANDLE DirectoryHandle,
                           0,
                           0,
                           (PVOID*)&Directory);
+
   if(NT_SUCCESS(Status))
   {
     Status = ObInsertObject((PVOID)Directory,
@@ -483,6 +477,10 @@ NtCreateDirectoryObject (OUT PHANDLE DirectoryHandle,
                             0,
                             NULL,
                             &hDirectory);
+    if (!NT_SUCCESS(Status))
+    {
+       ObMakeTemporaryObject(Directory);
+    }
     ObDereferenceObject(Directory);
 
     if(NT_SUCCESS(Status))