- Fix SleepEx.
authorAlex Ionescu <aionescu@gmail.com>
Sun, 10 Dec 2006 18:40:30 +0000 (18:40 +0000)
committerAlex Ionescu <aionescu@gmail.com>
Sun, 10 Dec 2006 18:40:30 +0000 (18:40 +0000)
- Put volatile statements in EX_RUNDOWN_REF, IRP, DEVICE_OBJECT, ERESOURCE, FILE_OBJECT, IO_REMOVE_LOCK, WORK_QUEUE_ITEM where required (thanks to Microsoft's changes in the WDK to mark the fields properly).
- Update FILE_OBJECT definition.
- Add some asserts to some I/O functions.
- Add stub support for File Objects created by XP+ Drivers which have File Object Extensions.
- Add some fixes to IopDeleteFile, including proper reference counting for the DO and VPB, as well as cleanup when the file is closed without a handle.
- Fix a bug in IopSecurityFile.
- Queue and unqueue IRPs in all I/O functions.
- Fully support IRP cancellation now.
- Fix critical bugs in NtDeviceIoControlFile and NtDeviceFsControlFile which were causing double queueing of IRPs and freeing of invalid memory, as well as invalid paramter checking for user-mode buffers.
- Add exhaustive validation checks to IoCreateFile, add more failure cases, and validate the EA buffer. Also support IO_ATTACH_DEVICE_API flag.
- Implement IoCreateStreamFileObjectEx and IoCreateStreamFileObjectLite and fix several bugs in the original implementation of IoCreateStreamFileObject.
- Fix a bug in RtlRaiseException.
- Update Io*ShareAccess routines to support XP+ style semantics related to special File Object flags which disable their use.
- Add validation to all Query/Set routines so that information clasess, lengths, buffers and alignment are properly checked.
- Also add an array for the proper acess rights that each query/set operation requires.
- Check backup/restore privileges during I/O File operations.
- Check traverse access during I/O File Operations.
- Check access privileges to the device during I/O file operations.
- Rename IopReferenceDeviceObject and also verify if an exclusive DO is trying to be invalidly opened.
- Support various extra security checks during I/O File/Device Parse Routine.
- Fix a bug during IopCleanupIrp so that we don't dereference the File OBject if this was a create operation.
- Fix some bogus asserts in IofCompleteRequest, and save the IRP Flags before signalling it's event, since the driver might've freed it behind our back.
- Fix a large bug in ObInsertObject which affected the insert of unnamed objects with forced security options (Such as process/threads).
- Fix the creation of the Process/Thread/Job Obejct Types to that security information is forced.
- Remove "Fix PS!!!" messages since the bug is now fixed and these objects now get proper security descriptors.
- Fix another bug in ObInsertObjet which wasn't properly validating user-mode objects and always assumed kernel mode.
- Silence multiple trace/checkpoint messages that have accumulated throughout time for various debugging purposes.

svn path=/trunk/; revision=25118

39 files changed:
reactos/base/system/lsass/lsass.c
reactos/base/system/services/rpcserver.c
reactos/base/system/winlogon/sas.c
reactos/dll/win32/advapi32/service/scm.c
reactos/dll/win32/kernel32/thread/thread.c
reactos/drivers/base/bootvid/vid.c
reactos/drivers/filesystems/fs_rec/udfs.c
reactos/drivers/filesystems/np/fsctrl.c
reactos/include/ddk/ntifs.h
reactos/include/ddk/winddk.h
reactos/lib/rtl/exception.c
reactos/lib/rtl/i386/exception.c
reactos/ntoskrnl/KrnlFun.c
reactos/ntoskrnl/cm/import.c
reactos/ntoskrnl/dbgk/debug.c
reactos/ntoskrnl/fstub/disksup.c
reactos/ntoskrnl/inbv/inbv.c
reactos/ntoskrnl/include/internal/debug.h
reactos/ntoskrnl/include/internal/io.h
reactos/ntoskrnl/include/internal/io_x.h
reactos/ntoskrnl/include/internal/ob.h
reactos/ntoskrnl/io/iomgr/device.c
reactos/ntoskrnl/io/iomgr/file.c
reactos/ntoskrnl/io/iomgr/iofunc.c
reactos/ntoskrnl/io/iomgr/iomgr.c
reactos/ntoskrnl/io/iomgr/irp.c
reactos/ntoskrnl/kdbg/kdb_symbols.c
reactos/ntoskrnl/mm/freelist.c
reactos/ntoskrnl/ob/obhandle.c
reactos/ntoskrnl/ob/oblife.c
reactos/ntoskrnl/ps/psmgr.c
reactos/ntoskrnl/rtl/libsupp.c
reactos/ntoskrnl/se/semgr.c
reactos/subsystems/win32/csrss/api/wapi.c
reactos/subsystems/win32/win32k/main/dllmain.c
reactos/subsystems/win32/win32k/ntuser/class.c
reactos/subsystems/win32/win32k/ntuser/focus.c
reactos/subsystems/win32/win32k/ntuser/misc.c
reactos/subsystems/win32/win32k/ntuser/window.c

index 8d79606..d5005c6 100644 (file)
@@ -51,7 +51,7 @@ ServiceMain(
        IN DWORD argc,
        IN LPWSTR *argv)
 {
-       DPRINT1("ServiceMain() called\n");
+       DPRINT("ServiceMain() called\n");
 }
 
 INT WINAPI
index 3cc52d3..f1f2da3 100644 (file)
@@ -1756,7 +1756,7 @@ ScmrStartServiceW(handle_t BindingHandle,
     PSERVICE_HANDLE hSvc;
     PSERVICE lpService = NULL;
 
-    DPRINT1("ScmrStartServiceW() called\n");
+    DPRINT("ScmrStartServiceW() called\n");
 
     if (ScmShutdown)
         return ERROR_SHUTDOWN_IN_PROGRESS;
index ee870bf..4aeee29 100644 (file)
@@ -11,7 +11,7 @@
 
 #include "winlogon.h"
 
-#define YDEBUG
+//#define YDEBUG
 #include <wine/debug.h>
 
 #define WINLOGON_SAS_CLASS L"SAS Window class"
index 5d6cb34..82fcfc8 100644 (file)
@@ -2026,7 +2026,7 @@ StartServiceW(SC_HANDLE hService,
         dwBufSize += ((wcslen(lpServiceArgVectors[i]) + 1) * sizeof(WCHAR));
     }
     dwBufSize += sizeof(WCHAR);
-    DPRINT1("dwBufSize: %lu\n", dwBufSize);
+    DPRINT("dwBufSize: %lu\n", dwBufSize);
 
     lpBuffer = HeapAlloc(GetProcessHeap(), 0, dwBufSize);
     if (lpBuffer == NULL)
index 916091f..dab3bf9 100644 (file)
@@ -864,13 +864,10 @@ SleepEx(DWORD dwMilliseconds,
       Interval.QuadPart = -0x7FFFFFFFFFFFFFFFLL;
     }
 
-  errCode = NtDelayExecution ((bAlertable ? TRUE : FALSE), &Interval);
-  if (!NT_SUCCESS(errCode))
-    {
-      SetLastErrorByStatus (errCode);
-      return -1;
-    }
-  return 0;
+dowait:
+  errCode = NtDelayExecution (bAlertable, &Interval);
+  if ((bAlertable) && (errCode == STATUS_ALERTED)) goto dowait;
+  return (errCode == STATUS_USER_APC) ? WAIT_IO_COMPLETION : 0;
 }
 
 
index 3c9e2da..22ea293 100644 (file)
@@ -43,7 +43,7 @@ VidInitialize(
     * Check for Xbox by identifying device at PCI 0:0:0, if it's
     * 0x10de/0x02a5 then we're running on an Xbox.
     */
-   CHECKPOINT1;
+   CHECKPOINT;
    WRITE_PORT_ULONG((PULONG)0xcf8, 0x80000000);
    PciId = READ_PORT_ULONG((PULONG)0xcfc);
    if (0x02a510de == PciId)
index 37f00ad..cf9e10c 100644 (file)
@@ -232,7 +232,6 @@ FsRecIsUdfsVolume(IN PDEVICE_OBJECT DeviceObject)
       DPRINT ("FsRecDeviceIoControl() failed (Status %lx)\n", Status);
       return(Status);
     }
-  DPRINT1 ("BytesPerSector: %lu\n", DiskGeometry.BytesPerSector);
 
   /* Check the volume recognition sequence */
   Status = FsRecCheckVolumeRecognitionSequence(DeviceObject,
index 97009b5..ce38334 100644 (file)
@@ -24,7 +24,7 @@ NpfsListeningCancelRoutine(IN PDEVICE_OBJECT DeviceObject,
 
   Waiter = (PNPFS_WAITER_ENTRY)&Irp->Tail.Overlay.DriverContext;
 
-  DPRINT1("NpfsListeningCancelRoutine() called for <%wZ>\n",
+  DPRINT("NpfsListeningCancelRoutine() called for <%wZ>\n",
          &Waiter->Ccb->Fcb->PipeName);
 
   IoReleaseCancelSpinLock(Irp->CancelIrql);
index 365969c..2929177 100644 (file)
@@ -404,6 +404,7 @@ typedef enum _SECURITY_LOGON_TYPE
 #define TOKEN_HAS_ADMIN_GROUP           0x08
 #define TOKEN_WRITE_RESTRICTED          0x08
 #define TOKEN_IS_RESTRICTED             0x10
+#define SE_BACKUP_PRIVILEGES_CHECKED    0x0100
 
 #define VACB_MAPPING_GRANULARITY        (0x40000)
 #define VACB_OFFSET_SHIFT               (18)
@@ -903,6 +904,19 @@ typedef struct _FILE_FS_VOLUME_INFORMATION {
     WCHAR           VolumeLabel[1];
 } FILE_FS_VOLUME_INFORMATION, *PFILE_FS_VOLUME_INFORMATION;
 
+typedef struct _FILE_FS_OBJECTID_INFORMATION
+{
+    UCHAR ObjectId[16];
+    UCHAR ExtendedInfo[48];
+} FILE_FS_OBJECTID_INFORMATION, *PFILE_FS_OBJECTID_INFORMATION;
+
+typedef struct _FILE_FS_DRIVER_PATH_INFORMATION
+{
+    BOOLEAN DriverInPath;
+    ULONG DriverNameLength;
+    WCHAR DriverName[1];
+} FILE_FS_DRIVER_PATH_INFORMATION, *PFILE_FS_DRIVER_PATH_INFORMATION;
+
 typedef struct _FILE_FULL_DIR_INFORMATION {
     ULONG           NextEntryOffset;
     ULONG           FileIndex;
@@ -963,6 +977,20 @@ typedef struct _FILE_LOCK_INFO
     LARGE_INTEGER EndingByte;
 } FILE_LOCK_INFO, *PFILE_LOCK_INFO;
 
+typedef struct _FILE_REPARSE_POINT_INFORMATION
+{
+    LONGLONG FileReference;
+    ULONG Tag;
+} FILE_REPARSE_POINT_INFORMATION, *PFILE_REPARSE_POINT_INFORMATION;
+
+typedef struct _FILE_MOVE_CLUSTER_INFORMATION
+{
+    ULONG ClusterCount;
+    HANDLE RootDirectory;
+    ULONG FileNameLength;
+    WCHAR FileName[1];
+} FILE_MOVE_CLUSTER_INFORMATION, *PFILE_MOVE_CLUSTER_INFORMATION;
+
 /* raw internal file lock struct returned from FsRtlGetNextFileLock */
 typedef struct _FILE_SHARED_LOCK_ENTRY {
     PVOID           Unknown1;
index db1a00f..64446fb 100644 (file)
@@ -1202,8 +1202,8 @@ typedef struct _EX_RUNDOWN_REF
 {
     union
     {
-        ULONG_PTR Count;
-        PVOID Ptr;
+        __volatile ULONG_PTR Count;
+        __volatile PVOID Ptr;
     };
 } EX_RUNDOWN_REF, *PEX_RUNDOWN_REF;
 
@@ -1298,7 +1298,7 @@ typedef struct _IRP {
   ULONG  Flags;
   union {
     struct _IRP  *MasterIrp;
-    LONG  IrpCount;
+    __volatile LONG  IrpCount;
     PVOID  SystemBuffer;
   } AssociatedIrp;
   LIST_ENTRY  ThreadListEntry;
@@ -1320,7 +1320,7 @@ typedef struct _IRP {
     } AsynchronousParameters;
     LARGE_INTEGER  AllocationSize;
   } Overlay;
-  PDRIVER_CANCEL  CancelRoutine;
+  __volatile PDRIVER_CANCEL  CancelRoutine;
   PVOID  UserBuffer;
   union {
     struct {
@@ -2123,7 +2123,7 @@ typedef struct _DEVICE_OBJECT {
   PIO_TIMER  Timer;
   ULONG  Flags;
   ULONG  Characteristics;
-  PVPB  Vpb;
+  __volatile PVPB  Vpb;
   PVOID  DeviceExtension;
   DEVICE_TYPE  DeviceType;
   CCHAR  StackSize;
@@ -3083,8 +3083,8 @@ typedef struct _ERESOURCE {
   POWNER_ENTRY  OwnerTable;
   SHORT  ActiveCount;
   USHORT  Flag;
-  PKSEMAPHORE  SharedWaiters;
-  PKEVENT  ExclusiveWaiters;
+  __volatile PKSEMAPHORE  SharedWaiters;
+  __volatile PKEVENT  ExclusiveWaiters;
   OWNER_ENTRY  OwnerThreads[2];
   ULONG  ContentionCount;
   USHORT  NumberOfSharedWaiters;
@@ -3393,34 +3393,38 @@ typedef struct _IO_COMPLETION_CONTEXT {
 #define FO_FILE_OBJECT_HAS_EXTENSION      0x00800000
 #define FO_REMOTE_ORIGIN                  0x01000000
 
-typedef struct _FILE_OBJECT {
-  CSHORT  Type;
-  CSHORT  Size;
-  PDEVICE_OBJECT  DeviceObject;
-  PVPB  Vpb;
-  PVOID  FsContext;
-  PVOID  FsContext2;
-  PSECTION_OBJECT_POINTERS  SectionObjectPointer;
-  PVOID  PrivateCacheMap;
-  NTSTATUS  FinalStatus;
-  struct _FILE_OBJECT  *RelatedFileObject;
-  BOOLEAN  LockOperation;
-  BOOLEAN  DeletePending;
-  BOOLEAN  ReadAccess;
-  BOOLEAN  WriteAccess;
-  BOOLEAN  DeleteAccess;
-  BOOLEAN  SharedRead;
-  BOOLEAN  SharedWrite;
-  BOOLEAN  SharedDelete;
-  ULONG  Flags;
-  UNICODE_STRING  FileName;
-  LARGE_INTEGER  CurrentByteOffset;
-  ULONG  Waiters;
-  ULONG  Busy;
-  PVOID  LastLock;
-  KEVENT  Lock;
-  KEVENT  Event;
-  PIO_COMPLETION_CONTEXT  CompletionContext;
+typedef struct _FILE_OBJECT
+{
+    CSHORT Type;
+    CSHORT Size;
+    PDEVICE_OBJECT DeviceObject;
+    PVPB Vpb;
+    PVOID FsContext;
+    PVOID FsContext2;
+    PSECTION_OBJECT_POINTERS SectionObjectPointer;
+    PVOID PrivateCacheMap;
+    NTSTATUS FinalStatus;
+    struct _FILE_OBJECT *RelatedFileObject;
+    BOOLEAN LockOperation;
+    BOOLEAN DeletePending;
+    BOOLEAN ReadAccess;
+    BOOLEAN WriteAccess;
+    BOOLEAN DeleteAccess;
+    BOOLEAN SharedRead;
+    BOOLEAN SharedWrite;
+    BOOLEAN SharedDelete;
+    ULONG Flags;
+    UNICODE_STRING FileName;
+    LARGE_INTEGER CurrentByteOffset;
+    __volatile ULONG Waiters;
+    __volatile ULONG Busy;
+    PVOID LastLock;
+    KEVENT Lock;
+    KEVENT Event;
+    __volatile PIO_COMPLETION_CONTEXT CompletionContext;
+    KSPIN_LOCK IrpListLock;
+    LIST_ENTRY IrpList;
+    __volatile PVOID FileObjectExtension;
 } FILE_OBJECT;
 typedef struct _FILE_OBJECT *PFILE_OBJECT;
 
@@ -4397,7 +4401,7 @@ typedef struct _IO_REMOVE_LOCK_TRACKING_BLOCK * PIO_REMOVE_LOCK_TRACKING_BLOCK;
 typedef struct _IO_REMOVE_LOCK_COMMON_BLOCK {
   BOOLEAN  Removed;
   BOOLEAN  Reserved[3];
-  LONG  IoCount;
+  __volatile LONG  IoCount;
   KEVENT  RemoveEvent;
 } IO_REMOVE_LOCK_COMMON_BLOCK;
 
@@ -4408,7 +4412,7 @@ typedef struct _IO_REMOVE_LOCK_DBG_BLOCK {
   LONG  AllocateTag;
   LIST_ENTRY  LockList;
   KSPIN_LOCK  Spin;
-  LONG  LowMemoryCount;
+  __volatile LONG  LowMemoryCount;
   ULONG  Reserved1[4];
   PVOID  Reserved2;
   PIO_REMOVE_LOCK_TRACKING_BLOCK  Blocks;
@@ -4579,7 +4583,7 @@ typedef VOID
 typedef struct _WORK_QUEUE_ITEM {
   LIST_ENTRY  List;
   PWORKER_THREAD_ROUTINE  WorkerRoutine;
-  PVOID  Parameter;
+  __volatile PVOID  Parameter;
 } WORK_QUEUE_ITEM, *PWORK_QUEUE_ITEM;
 
 typedef enum _KBUGCHECK_CALLBACK_REASON {
index 99b49ab..96953c2 100644 (file)
@@ -27,8 +27,9 @@ RtlRaiseException(PEXCEPTION_RECORD ExceptionRecord)
     CONTEXT Context;
     NTSTATUS Status;
 
-    /* Capture the context */
+    /* Capture the context and fixup ESP */
     RtlCaptureContext(&Context);
+    Context.Esp += sizeof(ULONG);
 
     /* Save the exception address */
     ExceptionRecord->ExceptionAddress = RtlpGetExceptionAddress();
@@ -57,8 +58,8 @@ RtlRaiseException(PEXCEPTION_RECORD ExceptionRecord)
         }
     }
 
-    /* If we returned, raise a status  */
-    RtlRaiseStatus(Status);
+    /* We should never return */
+    while (TRUE);
 }
 
 /*
index feb2ef0..edfb835 100644 (file)
@@ -100,6 +100,7 @@ RtlDispatchException(IN PEXCEPTION_RECORD ExceptionRecord,
                               sizeof(*RegistrationFrame));
 
         /* Call the handler */
+        DPRINT1("Calling handler: %p\n", RegistrationFrame->Handler);
         Disposition = RtlpExecuteHandlerForException(ExceptionRecord,
                                                      RegistrationFrame,
                                                      Context,
index 279c31c..40543a4 100644 (file)
@@ -8,16 +8,6 @@
 //                     Do NOT ask when it will be fixed.
 //              Failure to respect this will *ACHIEVE NOTHING*.
 //
-// Io:
-//  - See why queueing IRPs and cancelling them causes crashes.
-//  - Add Access Checks in IopParseDevice.
-//  - Add validation checks in IoCreateFile.
-//  - Add probe/alignment checks for Query/Set routines.
-//  - Add tracing to iofunc.c
-//  - Add tracing to file.c
-//  - Add support for some fast-paths when querying/setting data.
-//  - Verify ShareAccess APIs, XP added some new semantics.
-//  - Add support for Fast Dispatch I/O.
 //
 // Ob:
 //  - Fix bug related to Deferred Loading (don't requeue active work item).
@@ -28,6 +18,7 @@
 //
 // Ke:
 //  - Figure out why the DPC stack doesn't really work.
+//  - Fix SEH/Page Fault + Exceptions!? Weird exception bugs!
 //  - New optimized table-based tick-hashed timer implementation.
 //  - New Thread Scheduler based on 2003.
 //  - Implement KiCallbackReturn, KiGetTickCount, KiRaiseAssertion.
@@ -46,7 +37,6 @@
 //  - Use pushlocks for handle implementation.
 //
 // Kd:
-//  - Implement new KDCOM with KD support.
 //  - Implement KD Kernel Debugging and WinDBG support.
 //
 // Native:
index 900fed9..1501da8 100644 (file)
@@ -70,7 +70,7 @@ CmImportBinaryHive (PCHAR ChunkBase,
   KeEnterCriticalRegion();
   ExAcquireResourceExclusiveLite(&CmiRegistryLock, TRUE);
 
-  DPRINT1("Adding new hive\n");
+  DPRINT("Adding new hive\n");
 
   /* Add the new hive to the hive list */
   InsertTailList(&CmiHiveListHead, &Hive->HiveList);
index a513734..6bdc068 100644 (file)
@@ -14,7 +14,7 @@
 
 POBJECT_TYPE DbgkDebugObjectType;
 FAST_MUTEX DbgkpProcessDebugPortMutex;
-ULONG DbgkpTraceLevel = -1;
+ULONG DbgkpTraceLevel = 0; //-1;
 
 GENERIC_MAPPING DbgkDebugObjectMapping =
 {
index dca4fd2..84353bc 100644 (file)
@@ -1372,7 +1372,7 @@ IoReadPartitionTable(IN PDEVICE_OBJECT DeviceObject,
     /* Get the end and maximum sector */\r
     EndSector = MaxOffset;\r
     MaxSector = MaxOffset << 1;\r
-    DPRINT1("FSTUB: MaxOffset = %#I64x, MaxSector = %#I64x\n",\r
+    DPRINT("FSTUB: MaxOffset = %#I64x, MaxSector = %#I64x\n",\r
             MaxOffset, MaxSector);\r
 \r
     /* Allocate our buffer */\r
@@ -1458,19 +1458,19 @@ IoReadPartitionTable(IN PDEVICE_OBJECT DeviceObject,
 \r
         /* Start looping partitions */\r
         j++;\r
-        DPRINT1("FSTUB: Partition Table %d:\n", j);\r
+        DPRINT("FSTUB: Partition Table %d:\n", j);\r
         for (Entry = 1, k = 0; Entry <= 4; Entry++, PartitionDescriptor++)\r
         {\r
             /* Get the partition type */\r
             PartitionType = PartitionDescriptor->PartitionType;\r
 \r
             /* Print debug messages */\r
-            DPRINT1("Partition Entry %d,%d: type %#x %s\n", \r
+            DPRINT("Partition Entry %d,%d: type %#x %s\n", \r
                     j,\r
                     Entry,\r
                     PartitionType,\r
                     (PartitionDescriptor->ActiveFlag) ? "Active" : "");\r
-            DPRINT1("\tOffset %#08lx for %#08lx Sectors\n", \r
+            DPRINT("\tOffset %#08lx for %#08lx Sectors\n", \r
                     GET_STARTING_SECTOR(PartitionDescriptor),\r
                     GET_PARTITION_LENGTH(PartitionDescriptor));\r
 \r
@@ -1615,7 +1615,7 @@ IoReadPartitionTable(IN PDEVICE_OBJECT DeviceObject,
         }\r
 \r
         /* Finish debug log, and check for failure */\r
-        DPRINT1("\n");\r
+        DPRINT("\n");\r
         if (!NT_SUCCESS(Status)) break;\r
 \r
         /* Also check if we hit an invalid entry here */\r
index 92f285b..b652ef8 100644 (file)
@@ -118,7 +118,7 @@ InbvDisplayInitialize(VOID)
             return;
       }
 
-      DPRINT1("Done!\n");
+      DPRINT("Done!\n");
       KeInitializeSpinLock(&InbvLock);
       BootVidBase = ModuleObject->DllBase;
       BootVidDriverInstalled = TRUE;
index cbf9436..42e8d85 100644 (file)
@@ -46,7 +46,7 @@
 /* TODO: Verify which version the MS compiler learned the __FUNCTION__ macro */
 #define __FUNCTION__ "<unknown>"
 #endif
-#define UNIMPLEMENTED do {DbgPrint("%s at %s:%d is unimplemented, have a nice day\n",__FUNCTION__,__FILE__,__LINE__); for(;;);  } while(0)
+#define UNIMPLEMENTED DbgPrint("%s at %s:%d is unimplemented, have a nice day\n",__FUNCTION__,__FILE__,__LINE__);
 
 
 #ifdef assert
index 312f952..907c147 100644 (file)
 //
 // Define this if you want debugging support
 //
-#define _IO_DEBUG_                                      0x00
+#define _IO_DEBUG_                                      0x01
 
 //
 // These define the Debug Masks Supported
 //
 #define IO_IRP_DEBUG                                    0x01
+#define IO_FILE_DEBUG                                   0x02
+#define IO_API_DEBUG                                    0x04
+#define IO_CTL_DEBUG                                    0x08
 
 //
 // Debug/Tracing support
 //
 #if _IO_DEBUG_
 #ifdef NEW_DEBUG_SYSTEM_IMPLEMENTED // enable when Debug Filters are implemented
-#define IOTRACE DbgPrintEx
+#define IOTRACE(x, ...)                                     \
+    {                                                       \
+        DbgPrintEx("%s [%.16s] - ",                         \
+                   __FUNCTION__,                            \
+                   PsGetCurrentProcess()->ImageFileName);   \
+        DbgPrintEx(__VA_ARGS__);                            \
+    }
 #else
-#define IOTRACE(x, ...)                                 \
-    if (x & IopTraceLevel) DbgPrint(__VA_ARGS__)
+#define IOTRACE(x, ...)                                     \
+    if (x & IopTraceLevel)                                  \
+    {                                                       \
+        DbgPrint("%s [%.16s] - ",                           \
+                 __FUNCTION__,                              \
+                 PsGetCurrentProcess()->ImageFileName);     \
+        DbgPrint(__VA_ARGS__);                              \
+    }
 #endif
 #else
-#define IOTRACE(x, ...) DPRINT(__VA_ARGS__)
+#define IOTRACE(x, ...) DPRINT(__VA_ARGS__);
 #endif
 
 //
index 62ebd57..9d94644 100644 (file)
@@ -28,7 +28,7 @@ IopUnlockFileObject(IN PFILE_OBJECT FileObject)
 }
 
 VOID
-static __inline
+FORCEINLINE
 IopQueueIrpToThread(IN PIRP Irp)
 {
     KIRQL OldIrql;
index 47ecebc..c6fe3df 100644 (file)
@@ -251,6 +251,12 @@ ObDuplicateObject(
     IN KPROCESSOR_MODE PreviousMode
 );
 
+VOID
+NTAPI
+ObFreeObjectCreateInfoBuffer(
+    IN POBJECT_CREATE_INFORMATION ObjectCreateInfo
+);
+
 //
 // DOS Devices Functions
 //
index a0ea1cf..888613d 100644 (file)
@@ -329,32 +329,6 @@ IopDereferenceDeviceObject(IN PDEVICE_OBJECT DeviceObject,
     }
 }
 
-NTSTATUS
-NTAPI
-IopReferenceDeviceObject(IN PDEVICE_OBJECT DeviceObject)
-{
-    /* Make sure the object is valid */
-    if ((IoGetDevObjExtension(DeviceObject)->ExtensionFlags &
-        (DOE_UNLOAD_PENDING |
-         DOE_DELETE_PENDING |
-         DOE_REMOVE_PENDING |
-         DOE_REMOVE_PROCESSED)) ||
-        (DeviceObject->Flags & DO_DEVICE_INITIALIZING))
-    {
-        /* It's unloading or initializing, so fail */
-        DPRINT1("You are seeing this because the following ROS driver: %wZ\n"
-                " sucks. Please fix it's AddDevice Routine\n",
-                &DeviceObject->DriverObject->DriverName);
-        return STATUS_NO_SUCH_DEVICE;
-    }
-    else
-    {
-        /* Increase reference count */
-        DeviceObject->ReferenceCount++;
-        return STATUS_SUCCESS;
-    }
-}
-
 VOID
 NTAPI
 IopStartNextPacketByKey(IN PDEVICE_OBJECT DeviceObject,
@@ -921,8 +895,14 @@ VOID
 NTAPI
 IoDetachDevice(IN PDEVICE_OBJECT TargetDevice)
 {
+    PEXTENDED_DEVOBJ_EXTENSION DeviceExtension;
+
+    /* Sanity check */
+    DeviceExtension = IoGetDevObjExtension(TargetDevice->AttachedDevice);
+    ASSERT(DeviceExtension->AttachedTo == TargetDevice);
+
     /* Remove the attachment */
-    IoGetDevObjExtension(TargetDevice->AttachedDevice)->AttachedTo = NULL;
+    DeviceExtension->AttachedTo = NULL;
     TargetDevice->AttachedDevice = NULL;
 
     /* Check if it's ok to delete this device */
@@ -1173,9 +1153,27 @@ IoGetRelatedDeviceObject(IN PFILE_OBJECT FileObject)
         DeviceObject = FileObject->DeviceObject;
     }
 
+    /* Sanity check */
+    ASSERT(DeviceObject != NULL);
+
     /* Check if we were attached */
     if (DeviceObject->AttachedDevice)
     {
+        /* Check if the file object has an extension present */
+        if (FileObject->Flags & FO_FILE_OBJECT_HAS_EXTENSION)
+        {
+            /* Sanity check, direct open files can't have this */
+            ASSERT(!(FileObject->Flags & FO_DIRECT_DEVICE_OPEN));
+
+            /* Check if the extension is really present */
+            if (FileObject->FileObjectExtension)
+            {
+                /* FIXME: Unhandled yet */
+                DPRINT1("FOEs not supported\n");
+                KEBUGCHECK(0);
+            }
+        }
+
         /* Return the highest attached device */
         DeviceObject = IoGetAttachedDevice(DeviceObject);
     }
@@ -1216,6 +1214,7 @@ IoGetBaseFileSystemDeviceObject(IN PFILE_OBJECT FileObject)
     }
 
     /* Return the device object we found */
+    ASSERT(DeviceObject != NULL);
     return DeviceObject;
 }
 
index 0cc4648..da09a25 100644 (file)
 
 #include <ntoskrnl.h>
 #define NDEBUG
-#include <internal/debug.h>
-
-#if 0
-    IOTRACE(IO_IRP_DEBUG,
-            "%s - Queueing IRP %p\n",
-            __FUNCTION__,
-            Irp);
-#endif
+#include <debug.h>
 
 /* PRIVATE FUNCTIONS *********************************************************/
 
+VOID
+NTAPI
+IopCheckBackupRestorePrivilege(IN PACCESS_STATE AccessState,
+                               IN OUT PULONG CreateOptions,
+                               IN KPROCESSOR_MODE PreviousMode,
+                               IN ULONG Disposition)
+{
+    ACCESS_MASK DesiredAccess, ReadAccess, WriteAccess;
+    PRIVILEGE_SET Privileges;
+    BOOLEAN AccessGranted, HaveBackupPriv = FALSE, CheckRestore = FALSE;
+    PAGED_CODE();
+
+    /* Don't do anything if privileges were checked already */
+    if (AccessState->Flags & SE_BACKUP_PRIVILEGES_CHECKED) return;
+
+    /* Check if the file was actually opened for backup purposes */
+    if (*CreateOptions & FILE_OPEN_FOR_BACKUP_INTENT)
+    {
+        /* Set the check flag since were doing it now */
+        AccessState->Flags |= SE_BACKUP_PRIVILEGES_CHECKED;
+
+        /* Set the access masks required */
+        ReadAccess = READ_CONTROL |
+                     ACCESS_SYSTEM_SECURITY |
+                     FILE_GENERIC_READ |
+                     FILE_TRAVERSE;
+        WriteAccess = WRITE_DAC |
+                      WRITE_OWNER |
+                      ACCESS_SYSTEM_SECURITY |
+                      FILE_GENERIC_WRITE |
+                      FILE_ADD_FILE |
+                      FILE_ADD_SUBDIRECTORY |
+                      DELETE;
+        DesiredAccess = AccessState->RemainingDesiredAccess;
+
+        /* Check if desired access was the maximum */
+        if (DesiredAccess & MAXIMUM_ALLOWED)
+        {
+            /* Then add all the access masks required */
+            DesiredAccess |= (ReadAccess | WriteAccess);
+        }
+
+        /* Check if the file already exists */
+        if (Disposition & FILE_OPEN)
+        {
+            /* Check if desired access has the read mask */
+            if (ReadAccess & DesiredAccess)
+            {
+                /* Setup the privilege check lookup */
+                Privileges.PrivilegeCount = 1;
+                Privileges.Control = PRIVILEGE_SET_ALL_NECESSARY;
+                Privileges.Privilege[0].Luid = SeBackupPrivilege;
+                Privileges.Privilege[0].Attributes = 0;
+                AccessGranted = SePrivilegeCheck(&Privileges,
+                                                 &AccessState->
+                                                 SubjectSecurityContext,
+                                                 PreviousMode);
+                if (AccessGranted)
+                {
+                    /* Remember that backup was allowed */
+                    HaveBackupPriv = TRUE;
+
+                    /* Append the privileges and update the access state */
+                    SeAppendPrivileges(AccessState, &Privileges);
+                    AccessState->PreviouslyGrantedAccess |= (DesiredAccess & ReadAccess);
+                    AccessState->RemainingDesiredAccess &= ~ReadAccess;
+                    DesiredAccess &= ~ReadAccess;
+
+                    /* Set backup privilege for the token */
+                    AccessState->Flags |= TOKEN_HAS_BACKUP_PRIVILEGE;
+                }
+            }
+        }
+        else
+        {
+            /* Caller is creating the file, check restore privileges later */
+            CheckRestore = TRUE;
+        }
+
+        /* Check if caller wants write access or if it's creating a file */
+        if ((WriteAccess & DesiredAccess) || (CheckRestore))
+        {
+            /* Setup the privilege lookup and do it */
+            Privileges.PrivilegeCount = 1;
+            Privileges.Control = PRIVILEGE_SET_ALL_NECESSARY;
+            Privileges.Privilege[0].Luid = SeRestorePrivilege;
+            Privileges.Privilege[0].Attributes = 0;
+            AccessGranted = SePrivilegeCheck(&Privileges,
+                                             &AccessState->SubjectSecurityContext,
+                                             PreviousMode);
+            if (AccessGranted)
+            {
+                /* Remember that privilege was given */
+                HaveBackupPriv = TRUE;
+
+                /* Append the privileges and update the access state */
+                SeAppendPrivileges(AccessState, &Privileges);
+                AccessState->PreviouslyGrantedAccess |= (DesiredAccess & WriteAccess);
+                AccessState->RemainingDesiredAccess &= ~WriteAccess;
+
+                /* Set restore privilege for the token */
+                AccessState->Flags |= TOKEN_HAS_RESTORE_PRIVILEGE;
+            }
+        }
+
+        /* If we don't have the privilege, remove the option */
+        if (!HaveBackupPriv) *CreateOptions &= ~FILE_OPEN_FOR_BACKUP_INTENT;
+    }
+}
+
+NTSTATUS
+NTAPI
+IopCheckDeviceAndDriver(IN POPEN_PACKET OpenPacket,
+                        IN PDEVICE_OBJECT DeviceObject)
+{
+    /* Make sure the object is valid */
+    if ((IoGetDevObjExtension(DeviceObject)->ExtensionFlags &
+        (DOE_UNLOAD_PENDING |
+         DOE_DELETE_PENDING |
+         DOE_REMOVE_PENDING |
+         DOE_REMOVE_PROCESSED)) ||
+        (DeviceObject->Flags & DO_DEVICE_INITIALIZING))
+    {
+        /* It's unloading or initializing, so fail */
+        DPRINT1("You are seeing this because the following ROS driver: %wZ\n"
+                " sucks. Please fix it's AddDevice Routine\n",
+                &DeviceObject->DriverObject->DriverName);
+        return STATUS_NO_SUCH_DEVICE;
+    }
+    else if ((DeviceObject->Flags & DO_EXCLUSIVE) &&
+             (DeviceObject->ReferenceCount) &&
+             !(OpenPacket->RelatedFileObject) &&
+             !(OpenPacket->Options & IO_ATTACH_DEVICE))
+    {
+        return STATUS_ACCESS_DENIED;
+    }
+
+    else
+    {
+        /* Increase reference count */
+        DeviceObject->ReferenceCount++;
+        return STATUS_SUCCESS;
+    }
+}
+
 NTSTATUS
 NTAPI
 IopParseDevice(IN PVOID ParseObject,
@@ -53,6 +191,13 @@ IopParseDevice(IN PVOID ParseObject,
     PDUMMY_FILE_OBJECT DummyFileObject;
     PFILE_BASIC_INFORMATION FileBasicInfo;
     ULONG ReturnLength;
+    KPROCESSOR_MODE CheckMode;
+    BOOLEAN VolumeOpen = FALSE;
+    ACCESS_MASK DesiredAccess, GrantedAccess;
+    BOOLEAN AccessGranted, LockHeld = FALSE;
+    PPRIVILEGE_SET Privileges = NULL;
+    IOTRACE(IO_FILE_DEBUG, "ParseObject: %p. RemainingName: %wZ\n",
+            ParseObject, RemainingName);
 
     /* Assume failure */
     *Object = NULL;
@@ -67,8 +212,8 @@ IopParseDevice(IN PVOID ParseObject,
         OriginalDeviceObject = OpenPacket->RelatedFileObject->DeviceObject;
     }
 
-    /* Reference the DO */
-    Status = IopReferenceDeviceObject(OriginalDeviceObject);
+    /* Validate device status */
+    Status = IopCheckDeviceAndDriver(OpenPacket, OriginalDeviceObject);
     if (!NT_SUCCESS(Status))
     {
         /* We failed, return status */
@@ -83,6 +228,161 @@ IopParseDevice(IN PVOID ParseObject,
                       &IoFileObjectType->TypeInfo.GenericMapping);
     SeSetAccessStateGenericMapping(AccessState,
                                    &IoFileObjectType->TypeInfo.GenericMapping);
+    DesiredAccess = AccessState->RemainingDesiredAccess;
+
+    /* Check what kind of access checks to do */
+    if ((AccessMode != KernelMode) ||
+        (OpenPacket->Options & IO_FORCE_ACCESS_CHECK))
+    {
+        /* Call is from user-mode or kernel is forcing checks */
+        CheckMode = UserMode;
+    }
+    else
+    {
+        /* Call is from the kernel */
+        CheckMode = KernelMode;
+    }
+
+    /* Check privilege for backup or restore operation */
+    IopCheckBackupRestorePrivilege(AccessState,
+                                   &OpenPacket->CreateOptions,
+                                   CheckMode,
+                                   OpenPacket->Disposition);
+
+    /* Check if we are re-parsing */
+    if (((OpenPacket->Override) && !(RemainingName->Length)) ||
+        (AccessState->Flags & SE_BACKUP_PRIVILEGES_CHECKED))
+    {
+        /* Get granted access from the last call */
+        DesiredAccess |= AccessState->PreviouslyGrantedAccess;
+    }
+
+    /* Check if this is a volume open */
+    if ((OpenPacket->RelatedFileObject) &&
+        (OpenPacket->RelatedFileObject->Flags & FO_VOLUME_OPEN) &&
+        !(RemainingName->Length))
+    {
+        /* It is */
+        VolumeOpen = TRUE;
+    }
+
+    /* Now check if we need access checks */
+    if (((AccessMode != KernelMode) ||
+         (OpenPacket->Options & IO_FORCE_ACCESS_CHECK)) &&
+        (!(OpenPacket->RelatedFileObject) || (VolumeOpen)) &&
+        !(OpenPacket->Override))
+    {
+        /* Check if a device object is being parsed  */
+        if (!RemainingName->Length)
+        {
+            /* Lock the subject context */
+            SeLockSubjectContext(&AccessState->SubjectSecurityContext);
+            LockHeld = TRUE;
+
+            /* Do access check */
+            AccessGranted = SeAccessCheck(OriginalDeviceObject->
+                                          SecurityDescriptor,
+                                          &AccessState->SubjectSecurityContext,
+                                          LockHeld,
+                                          DesiredAccess,
+                                          0,
+                                          &Privileges,
+                                          &IoFileObjectType->
+                                          TypeInfo.GenericMapping,
+                                          UserMode,
+                                          &GrantedAccess,
+                                          &Status);
+            if (Privileges)
+            {
+                /* Append and free the privileges */
+                SeAppendPrivileges(AccessState, Privileges);
+                SeFreePrivileges(Privileges);
+            }
+
+            /* Check if we got access */
+            if (AccessGranted)
+            {
+                /* Update access state */
+                AccessState->PreviouslyGrantedAccess |= GrantedAccess;
+                AccessState->RemainingDesiredAccess &= ~(GrantedAccess &
+                                                         MAXIMUM_ALLOWED);
+                OpenPacket->Override= TRUE;
+            }
+
+            /* FIXME: Do Audit/Alarm for open operation */
+        }
+        else
+        {
+            /* Check if we need to do traverse validation */
+            if (!(AccessState->Flags & TOKEN_HAS_TRAVERSE_PRIVILEGE) ||
+                ((OriginalDeviceObject->DeviceType == FILE_DEVICE_DISK) ||
+                 (OriginalDeviceObject->DeviceType == FILE_DEVICE_CD_ROM)))
+            {
+                /* Check if this is a restricted token */
+                if (!(AccessState->Flags & TOKEN_IS_RESTRICTED))
+                {
+                    /* FIXME: Do the FAST traverse check */
+                    AccessGranted = FALSE;
+                }
+                else
+                {
+                    /* Fail */
+                    AccessGranted = FALSE;
+                }
+
+                /* Check if we failed to get access */
+                if (!AccessGranted)
+                {
+                    /* Lock the subject context */
+                    SeLockSubjectContext(&AccessState->SubjectSecurityContext);
+                    LockHeld = TRUE;
+
+                    /* Do access check */
+                    AccessGranted = SeAccessCheck(OriginalDeviceObject->
+                                                  SecurityDescriptor,
+                                                  &AccessState->SubjectSecurityContext,
+                                                  LockHeld,
+                                                  FILE_TRAVERSE,
+                                                  0,
+                                                  &Privileges,
+                                                  &IoFileObjectType->
+                                                  TypeInfo.GenericMapping,
+                                                  UserMode,
+                                                  &GrantedAccess,
+                                                  &Status);
+                    if (Privileges)
+                    {
+                        /* Append and free the privileges */
+                        SeAppendPrivileges(AccessState, Privileges);
+                        SeFreePrivileges(Privileges);
+                    }
+                }
+
+                /* FIXME: Do Audit/Alarm for traverse check */
+            }
+            else
+            {
+                /* Access automatically granted */
+                AccessGranted = TRUE;
+            }
+        }
+
+        /* Check if we hold the lock */
+        if (LockHeld)
+        {
+            /* Release it */
+            SeUnlockSubjectContext(&AccessState->SubjectSecurityContext);
+        }
+
+        /* Check if access failed */
+        if (!AccessGranted)
+        {
+            /* Dereference the device and fail */
+            DPRINT1("Traverse access failed!\n");
+            IopDereferenceDeviceObject(OriginalDeviceObject, FALSE);
+            return STATUS_ACCESS_DENIED;
+        }
+    }
 
     /* Check if we can simply use a dummy file */
     UseDummyFile = ((OpenPacket->QueryOnly) || (OpenPacket->DeleteOnly));
@@ -90,8 +390,27 @@ IopParseDevice(IN PVOID ParseObject,
     /* Check if this is a direct open */
     if (!(RemainingName->Length) &&
         !(OpenPacket->RelatedFileObject) &&
+#if 0 // USETUP IS BROKEN!
+        ((DesiredAccess & ~(SYNCHRONIZE |
+                             FILE_READ_ATTRIBUTES |
+                             READ_CONTROL |
+                             ACCESS_SYSTEM_SECURITY |
+                             WRITE_OWNER |
+                             WRITE_DAC)) &&
+#endif
         !(UseDummyFile))
     {
+        if (DesiredAccess & ~(SYNCHRONIZE |
+                              FILE_READ_ATTRIBUTES |
+                              READ_CONTROL |
+                              ACCESS_SYSTEM_SECURITY |
+                              WRITE_OWNER |
+                              WRITE_DAC))
+        {
+            DPRINT1("FIXME: Broken Parse due to invalid DesiredAccess: %lx\n",
+                    DesiredAccess);
+        }
+
         /* Remember this for later */
         DirectOpen = TRUE;
     }
@@ -140,6 +459,14 @@ IopParseDevice(IN PVOID ParseObject,
         }
     }
 
+    /* Check if this is a secure FSD */
+    if ((DeviceObject->Characteristics & FILE_DEVICE_SECURE_OPEN) &&
+        ((OpenPacket->RelatedFileObject) || (RemainingName->Length)) &&
+        (!VolumeOpen))
+    {
+        DPRINT1("Fix Secure FSD support!!!\n");
+    }
+
     /* Allocate the IRP */
     Irp = IoAllocateIrp(DeviceObject->StackSize, TRUE);
     if (!Irp)
@@ -272,7 +599,7 @@ IopParseDevice(IN PVOID ParseObject,
         /* Check if this is synch I/O */
         if (FileObject->Flags & FO_SYNCHRONOUS_IO)
         {
-            /* Initialize the event. FIXME: Should be FALSE */
+            /* Initialize the event */
             KeInitializeEvent(&FileObject->Lock, SynchronizationEvent, FALSE);
         }
 
@@ -373,7 +700,7 @@ IopParseDevice(IN PVOID ParseObject,
     OpenPacket->FileObject = FileObject;
 
     /* Queue the IRP and call the driver */
-    //IopQueueIrpToThread(Irp);
+    IopQueueIrpToThread(Irp);
     Status = IoCallDriver(DeviceObject, Irp);
     if (Status == STATUS_PENDING)
     {
@@ -404,7 +731,7 @@ IopParseDevice(IN PVOID ParseObject,
         FileObject->Event.Header.SignalState = 1;
 
         /* Now that we've signaled the events, de-associate the IRP */
-        //IopUnQueueIrpFromThread(Irp);
+        IopUnQueueIrpFromThread(Irp);
 
         /* Check if the IRP had an input buffer */
         if ((Irp->Flags & IRP_BUFFERED_IO) &&
@@ -614,6 +941,10 @@ IopDeleteFile(IN PVOID ObjectBody)
     NTSTATUS Status;
     KEVENT Event;
     PDEVICE_OBJECT DeviceObject;
+    BOOLEAN DereferenceDone = FALSE;
+    PVPB Vpb;
+    KIRQL OldIrql;
+    IOTRACE(IO_FILE_DEBUG, "ObjectBody: %p\n", ObjectBody);
 
     /* Check if the file has a device object */
     if (FileObject->DeviceObject)
@@ -630,11 +961,15 @@ IopDeleteFile(IN PVOID ObjectBody)
             DeviceObject = IoGetRelatedDeviceObject(FileObject);
         }
 
-        /* Check if this file was opened for Synch I/O */
-        if (FileObject->Flags & FO_SYNCHRONOUS_IO)
+        /* Sanity check */
+        ASSERT(!(FileObject->Flags & FO_SYNCHRONOUS_IO) ||
+               (InterlockedExchange((PLONG)&FileObject->Busy, TRUE) == FALSE));
+
+        /* Check if the handle wasn't created yet */
+        if (!(FileObject->Flags & FO_HANDLE_CREATED))
         {
-            /* Lock it */
-            IopLockFileObject(FileObject);
+            /* Send the cleanup IRP */
+            IopCloseFile(NULL, ObjectBody, 0, 1, 1);
         }
 
         /* Clear and set up Events */
@@ -658,7 +993,23 @@ IopDeleteFile(IN PVOID ObjectBody)
         StackPtr->FileObject = FileObject;
 
         /* Queue the IRP */
-        //IopQueueIrpToThread(Irp);
+        IopQueueIrpToThread(Irp);
+
+        /* Get the VPB and check if this isn't a direct open */
+        Vpb = FileObject->Vpb;
+        if ((Vpb) && !(FileObject->Flags & FO_DIRECT_DEVICE_OPEN))
+        {
+            /* Dereference the VPB before the close */
+            InterlockedDecrement(&Vpb->ReferenceCount);
+        }
+
+        /* Check if the FS will never disappear by itself */
+        if (FileObject->DeviceObject->Flags & DO_NEVER_LAST_DEVICE)
+        {
+            /* Dereference it */
+            InterlockedDecrement(&FileObject->DeviceObject->ReferenceCount);
+            DereferenceDone = TRUE;
+        }
 
         /* Call the FS Driver */
         Status = IoCallDriver(DeviceObject, Irp);
@@ -668,6 +1019,11 @@ IopDeleteFile(IN PVOID ObjectBody)
             KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
         }
 
+        /* De-queue the IRP */
+        KeRaiseIrql(APC_LEVEL, &OldIrql);
+        IopUnQueueIrpFromThread(Irp);
+        KeLowerIrql(OldIrql);
+
         /* Free the IRP */
         IoFreeIrp(Irp);
 
@@ -686,7 +1042,12 @@ IopDeleteFile(IN PVOID ObjectBody)
             ExFreePool(FileObject->CompletionContext);
         }
 
-        /* FIXME: Dereference device object */
+        /* Check if dereference has been done yet */
+        if (!DereferenceDone)
+        {
+            /* Dereference device object */
+            IopDereferenceDeviceObject(FileObject->DeviceObject, FALSE);
+        }
     }
 }
 
@@ -710,6 +1071,7 @@ IopSecurityFile(IN PVOID ObjectBody,
     KEVENT Event;
     NTSTATUS Status = STATUS_SUCCESS;
     PAGED_CODE();
+    IOTRACE(IO_FILE_DEBUG, "ObjectBody: %p\n", ObjectBody);
 
     /* Check if this is a device or file */
     if (((PFILE_OBJECT)ObjectBody)->Type == IO_TYPE_DEVICE)
@@ -737,7 +1099,9 @@ IopSecurityFile(IN PVOID ObjectBody,
     }
 
     /* Check if the request was for a device object */
-    if (!(FileObject) || (FileObject->Flags & FO_DIRECT_DEVICE_OPEN))
+    if (!(FileObject) ||
+        (!(FileObject->FileName.Length) && !(FileObject->RelatedFileObject)) ||
+        (FileObject->Flags & FO_DIRECT_DEVICE_OPEN))
     {
         /* Check what kind of request this was */
         if (OperationCode == QuerySecurityDescriptor)
@@ -834,7 +1198,7 @@ IopSecurityFile(IN PVOID ObjectBody,
     }
 
     /* Queue the IRP */
-    //IopQueueIrpToThread(Irp);
+    IopQueueIrpToThread(Irp);
 
     /* Update operation counts */
     IopUpdateOperationCount(IopOtherTransfer);
@@ -862,7 +1226,7 @@ IopSecurityFile(IN PVOID ObjectBody,
         /* Check if the IRP is pending completion */
         if (Status == STATUS_PENDING)
         {
-            /* Wait on the file obejct */
+            /* Wait on the file object */
             KeWaitForSingleObject(&FileObject->Event,
                                   Executive,
                                   KernelMode,
@@ -920,6 +1284,7 @@ IopQueryNameFile(IN PVOID ObjectBody,
     ULONG LocalReturnLength, FileLength;
     NTSTATUS Status;
     PWCHAR p;
+    IOTRACE(IO_FILE_DEBUG, "ObjectBody: %p\n", ObjectBody);
 
     /* Validate length */
     if (Length < sizeof(OBJECT_NAME_INFORMATION))
@@ -987,7 +1352,7 @@ IopQueryNameFile(IN PVOID ObjectBody,
     /* ROS HACK. VFAT SUCKS */
     if (NT_WARNING(Status)) LocalReturnLength = FileLength;
 
-    /* Now calculate the new lenghts left */
+    /* Now calculate the new lengths left */
     FileLength = LocalReturnLength -
                  FIELD_OFFSET(FILE_NAME_INFORMATION, FileName);
     LocalReturnLength = (ULONG_PTR)p -
@@ -1028,6 +1393,8 @@ IopCloseFile(IN PEPROCESS Process OPTIONAL,
     PIO_STACK_LOCATION StackPtr;
     NTSTATUS Status;
     PDEVICE_OBJECT DeviceObject;
+    KIRQL OldIrql;
+    IOTRACE(IO_FILE_DEBUG, "ObjectBody: %p\n", ObjectBody);
 
     /* Check if the file is locked and has more then one handle opened */
     if ((FileObject->LockOperation) && (SystemHandleCount != 1))
@@ -1079,7 +1446,7 @@ IopCloseFile(IN PEPROCESS Process OPTIONAL,
     StackPtr->FileObject = FileObject;
 
     /* Queue the IRP */
-    //IopQueueIrpToThread(Irp);
+    IopQueueIrpToThread(Irp);
 
     /* Update operation counts */
     IopUpdateOperationCount(IopOtherTransfer);
@@ -1092,6 +1459,11 @@ IopCloseFile(IN PEPROCESS Process OPTIONAL,
         KeWaitForSingleObject(&Event, UserRequest, KernelMode, FALSE, NULL);
     }
 
+    /* Unqueue the IRP */
+    KeRaiseIrql(APC_LEVEL, &OldIrql);
+    IopUnQueueIrpFromThread(Irp);
+    KeLowerIrql(OldIrql);
+
     /* Free the IRP */
     IoFreeIrp(Irp);
 
@@ -1114,6 +1486,7 @@ IopQueryAttributesFile(IN POBJECT_ATTRIBUTES ObjectAttributes,
     OPEN_PACKET OpenPacket;
     BOOLEAN IsBasic;
     PAGED_CODE();
+    IOTRACE(IO_FILE_DEBUG, "Class: %lx\n", FileInformationClass);
 
     /* Check if the caller was user mode */
     if (AccessMode != KernelMode)
@@ -1211,7 +1584,7 @@ IopQueryAttributesFile(IN POBJECT_ATTRIBUTES ObjectAttributes,
  * @unimplemented
  */
 NTSTATUS
-STDCALL
+NTAPI
 IoCheckQuerySetFileInformation(IN FILE_INFORMATION_CLASS FileInformationClass,
                                IN ULONG Length,
                                IN BOOLEAN SetOperation)
@@ -1242,12 +1615,12 @@ IoCreateFile(OUT PHANDLE FileHandle,
              IN ACCESS_MASK DesiredAccess,
              IN POBJECT_ATTRIBUTES ObjectAttributes,
              OUT PIO_STATUS_BLOCK IoStatusBlock,
-             IN PLARGE_INTEGER AllocationSize  OPTIONAL,
+             IN PLARGE_INTEGER AllocationSize OPTIONAL,
              IN ULONG FileAttributes,
              IN ULONG ShareAccess,
-             IN ULONG CreateDisposition,
+             IN ULONG Disposition,
              IN ULONG CreateOptions,
-             IN PVOID EaBuffer  OPTIONAL,
+             IN PVOID EaBuffer OPTIONAL,
              IN ULONG EaLength,
              IN CREATE_FILE_TYPE CreateFileType,
              IN PVOID ExtraCreateParameters OPTIONAL,
@@ -1260,17 +1633,22 @@ IoCreateFile(OUT PHANDLE FileHandle,
     NTSTATUS Status = STATUS_SUCCESS;
     OPEN_PACKET OpenPacket;
     PAGED_CODE();
+    IOTRACE(IO_FILE_DEBUG, "FileName: %wZ\n", ObjectAttributes->ObjectName);
 
-    if(Options & IO_NO_PARAMETER_CHECKING)
+    /* Check if we have no parameter checking to do */
+    if (Options & IO_NO_PARAMETER_CHECKING)
     {
+        /* Then force kernel-mode access to avoid checks */
         AccessMode = KernelMode;
     }
     else
     {
+        /* Otherwise, use the actual mode */
         AccessMode = ExGetPreviousMode();
     }
 
-    if(AccessMode != KernelMode)
+    /* Check if the call came from user mode */
+    if (AccessMode != KernelMode)
     {
         _SEH_TRY
         {
@@ -1314,27 +1692,47 @@ IoCreateFile(OUT PHANDLE FileHandle,
     }
     else
     {
+        /* Check if this is a device attach */
+        if (CreateOptions & IO_ATTACH_DEVICE_API)
+        {
+            /* Set the flag properly */
+            Options |= IO_ATTACH_DEVICE;
+            CreateOptions &= ~IO_ATTACH_DEVICE_API;
+        }
+
+        /* Check if we have allocation size */
         if (AllocationSize)
         {
+            /* Capture it */
             SafeAllocationSize = *AllocationSize;
         }
         else
         {
+            /* Otherwise, no size */
             SafeAllocationSize.QuadPart = 0;
         }
 
+        /* Check if we have an EA packet */
         if ((EaBuffer) && (EaLength))
         {
+            /* Allocate the kernel copy */
             SystemEaBuffer = ExAllocatePoolWithTag(NonPagedPool,
                                                    EaLength,
                                                    TAG_EA);
+            if (!SystemEaBuffer) return STATUS_INSUFFICIENT_RESOURCES;
+
+            /* Copy the data */
             RtlCopyMemory(SystemEaBuffer, EaBuffer, EaLength);
-        }
-    }
 
-    if(Options & IO_CHECK_CREATE_PARAMETERS)
-    {
-        DPRINT1("FIXME: IO_CHECK_CREATE_PARAMETERS not yet supported!\n");
+            /* Validate the buffer */
+            Status = IoCheckEaBufferValidity(SystemEaBuffer,
+                                             EaLength,
+                                             NULL);
+            if (!NT_SUCCESS(Status))
+            {
+                /* FIXME: Fail once function is implemented */
+            }
+        }
     }
 
     /* Setup the Open Packet */
@@ -1349,7 +1747,7 @@ IoCreateFile(OUT PHANDLE FileHandle,
     OpenPacket.EaBuffer = SystemEaBuffer;
     OpenPacket.EaLength = EaLength;
     OpenPacket.Options = Options;
-    OpenPacket.Disposition = CreateDisposition;
+    OpenPacket.Disposition = Disposition;
     OpenPacket.CreateFileType = CreateFileType;
     OpenPacket.MailslotOrPipeParameters = ExtraCreateParameters;
 
@@ -1496,28 +1894,40 @@ IoCreateFileSpecifyDeviceObjectHint(OUT PHANDLE FileHandle,
  */
 PFILE_OBJECT
 NTAPI
-IoCreateStreamFileObject(IN PFILE_OBJECT FileObject,
-                         IN PDEVICE_OBJECT DeviceObject)
+IoCreateStreamFileObjectEx(IN PFILE_OBJECT FileObject OPTIONAL,
+                           IN PDEVICE_OBJECT DeviceObject OPTIONAL,
+                           OUT PHANDLE FileObjectHandle OPTIONAL)
 {
     PFILE_OBJECT CreatedFileObject;
     NTSTATUS Status;
     HANDLE FileHandle;
+    OBJECT_ATTRIBUTES ObjectAttributes;
     PAGED_CODE();
+    IOTRACE(IO_FILE_DEBUG, "FileObject: %p\n", FileObject);
+
+    /* Choose Device Object */
+    if (FileObject) DeviceObject = FileObject->DeviceObject;
+
+    /* Reference the device object and initialize attributes */
+    InterlockedIncrement(&DeviceObject->ReferenceCount);
+    InitializeObjectAttributes(&ObjectAttributes, NULL, 0, NULL, NULL);
 
     /* Create the File Object */
     Status = ObCreateObject(KernelMode,
                             IoFileObjectType,
-                            NULL,
+                            &ObjectAttributes,
                             KernelMode,
                             NULL,
                             sizeof(FILE_OBJECT),
                             sizeof(FILE_OBJECT),
                             0,
                             (PVOID*)&CreatedFileObject);
-    if (!NT_SUCCESS(Status)) return NULL;
-
-    /* Choose Device Object */
-    if (FileObject) DeviceObject = FileObject->DeviceObject;
+    if (!NT_SUCCESS(Status))
+    {
+        /* Fail */
+        IopDereferenceDeviceObject(DeviceObject, FALSE);
+        ExRaiseStatus(Status);
+    }
 
     /* Set File Object Data */
     RtlZeroMemory(CreatedFileObject, sizeof(FILE_OBJECT));
@@ -1536,38 +1946,114 @@ IoCreateStreamFileObject(IN PFILE_OBJECT FileObject,
                             1,
                             (PVOID*)&CreatedFileObject,
                             &FileHandle);
+    if (!NT_SUCCESS(Status)) ExRaiseStatus(Status);
+
+    /* Set the handle created flag */
     CreatedFileObject->Flags |= FO_HANDLE_CREATED;
+    ASSERT(CreatedFileObject->Type == IO_TYPE_FILE);
 
-    /* FIXME: Reference VPB */
+    /* Check if we have a VPB */
+    if (DeviceObject->Vpb)
+    {
+        /* Reference it */
+         InterlockedIncrement(&DeviceObject->Vpb->ReferenceCount);
+    }
 
-    /* Close the extra handle and return file */
-    NtClose(FileHandle);
+    /* Check if the caller wants the handle */
+    if (FileObjectHandle)
+    {
+        /* Return it */
+        *FileObjectHandle = FileHandle;
+        ObDereferenceObject(CreatedFileObject);
+    }
+    else
+    {
+        /* Otherwise, close it */
+        ObCloseHandle(FileHandle, KernelMode);
+    }
+
+    /* Return the file object */
     return CreatedFileObject;
 }
 
 /*
- * @unimplemented
+ * @implemented
  */
 PFILE_OBJECT
 NTAPI
-IoCreateStreamFileObjectEx(IN PFILE_OBJECT FileObject OPTIONAL,
-                           IN PDEVICE_OBJECT DeviceObject OPTIONAL,
-                           OUT PHANDLE FileObjectHandle OPTIONAL)
+IoCreateStreamFileObject(IN PFILE_OBJECT FileObject,
+                         IN PDEVICE_OBJECT DeviceObject)
 {
-    UNIMPLEMENTED;
-    return 0;
+    /* Call the newer function */
+    return IoCreateStreamFileObjectEx(FileObject, DeviceObject, NULL);
 }
 
 /*
- * @unimplemented
+ * @implemented
  */
 PFILE_OBJECT
 NTAPI
 IoCreateStreamFileObjectLite(IN PFILE_OBJECT FileObject OPTIONAL,
                              IN PDEVICE_OBJECT DeviceObject OPTIONAL)
 {
-    UNIMPLEMENTED;
-    return 0;
+    PFILE_OBJECT CreatedFileObject;
+    NTSTATUS Status;
+    OBJECT_ATTRIBUTES ObjectAttributes;
+    PAGED_CODE();
+    IOTRACE(IO_FILE_DEBUG, "FileObject: %p\n", FileObject);
+
+    /* Choose Device Object */
+    if (FileObject) DeviceObject = FileObject->DeviceObject;
+
+    /* Reference the device object and initialize attributes */
+    InterlockedIncrement(&DeviceObject->ReferenceCount);
+    InitializeObjectAttributes(&ObjectAttributes, NULL, 0, NULL, NULL);
+
+    /* Create the File Object */
+    Status = ObCreateObject(KernelMode,
+                            IoFileObjectType,
+                            &ObjectAttributes,
+                            KernelMode,
+                            NULL,
+                            sizeof(FILE_OBJECT),
+                            sizeof(FILE_OBJECT),
+                            0,
+                            (PVOID*)&CreatedFileObject);
+    if (!NT_SUCCESS(Status))
+    {
+        /* Fail */
+        IopDereferenceDeviceObject(DeviceObject, FALSE);
+        ExRaiseStatus(Status);
+    }
+
+    /* Set File Object Data */
+    RtlZeroMemory(CreatedFileObject, sizeof(FILE_OBJECT));
+    CreatedFileObject->DeviceObject = DeviceObject; 
+    CreatedFileObject->Type = IO_TYPE_FILE;
+    CreatedFileObject->Size = sizeof(FILE_OBJECT);
+    CreatedFileObject->Flags = FO_STREAM_FILE;
+
+    /* Initialize the wait event */
+    KeInitializeEvent(&CreatedFileObject->Event, SynchronizationEvent, FALSE);
+
+    /* Destroy create information */
+    ObFreeObjectCreateInfoBuffer(OBJECT_TO_OBJECT_HEADER(CreatedFileObject)->
+                                 ObjectCreateInfo);
+    OBJECT_TO_OBJECT_HEADER(CreatedFileObject)->ObjectCreateInfo = NULL;
+
+    /* Set the handle created flag */
+    CreatedFileObject->Flags |= FO_HANDLE_CREATED;
+    ASSERT(CreatedFileObject->Type == IO_TYPE_FILE);
+
+    /* Check if we have a VPB */
+    if (DeviceObject->Vpb)
+    {
+        /* Reference it */
+         InterlockedIncrement(&DeviceObject->Vpb->ReferenceCount);
+    }
+
+    /* Return the file object */
+    return CreatedFileObject;
 }
 
 /*
@@ -1608,6 +2094,7 @@ IoFastQueryNetworkAttributes(IN POBJECT_ATTRIBUTES ObjectAttributes,
     HANDLE Handle;
     OPEN_PACKET OpenPacket;
     PAGED_CODE();
+    IOTRACE(IO_FILE_DEBUG, "FileName: %wZ\n", ObjectAttributes->ObjectName);
 
     /* Setup the Open Packet */
     RtlZeroMemory(&OpenPacket, sizeof(OPEN_PACKET));
@@ -1663,12 +2150,26 @@ IoUpdateShareAccess(IN PFILE_OBJECT FileObject,
 {
     PAGED_CODE();
 
-    if (FileObject->ReadAccess ||
-        FileObject->WriteAccess ||
-        FileObject->DeleteAccess)
+    /* Check if the file has an extension */
+    if (FileObject->Flags & FO_FILE_OBJECT_HAS_EXTENSION)
+    {
+        /* Check if caller specified to ignore access checks */
+        //if (FileObject->FoExtFlags & IO_IGNORE_SHARE_ACCESS_CHECK)
+        {
+            /* Don't update share access */
+            return;
+        }
+    }
+
+    /* Otherwise, check if there's any access present */
+    if ((FileObject->ReadAccess) ||
+        (FileObject->WriteAccess) ||
+        (FileObject->DeleteAccess))
     {
+        /* Increase the open count */
         ShareAccess->OpenCount++;
 
+        /* Add new share access */
         ShareAccess->Readers += FileObject->ReadAccess;
         ShareAccess->Writers += FileObject->WriteAccess;
         ShareAccess->Deleters += FileObject->DeleteAccess;
@@ -1697,38 +2198,62 @@ IoCheckShareAccess(IN ACCESS_MASK DesiredAccess,
     BOOLEAN SharedDelete;
     PAGED_CODE();
 
+    /* Get access masks */
     ReadAccess = (DesiredAccess & (FILE_READ_DATA | FILE_EXECUTE)) != 0;
     WriteAccess = (DesiredAccess & (FILE_WRITE_DATA | FILE_APPEND_DATA)) != 0;
     DeleteAccess = (DesiredAccess & DELETE) != 0;
 
+    /* Set them in the file object */
     FileObject->ReadAccess = ReadAccess;
     FileObject->WriteAccess = WriteAccess;
     FileObject->DeleteAccess = DeleteAccess;
 
-    if (ReadAccess || WriteAccess || DeleteAccess)
+    /* Check if the file has an extension */
+    if (FileObject->Flags & FO_FILE_OBJECT_HAS_EXTENSION)
     {
+        /* Check if caller specified to ignore access checks */
+        //if (FileObject->FoExtFlags & IO_IGNORE_SHARE_ACCESS_CHECK)
+        {
+            /* Don't check share access */
+            return STATUS_SUCCESS;
+        }
+    }
+
+    /* Check if we have any access */
+    if ((ReadAccess) || (WriteAccess) || (DeleteAccess))
+    {
+        /* Get shared access masks */
         SharedRead = (DesiredShareAccess & FILE_SHARE_READ) != 0;
         SharedWrite = (DesiredShareAccess & FILE_SHARE_WRITE) != 0;
         SharedDelete = (DesiredShareAccess & FILE_SHARE_DELETE) != 0;
 
+        /* Set them */
         FileObject->SharedRead = SharedRead;
         FileObject->SharedWrite = SharedWrite;
         FileObject->SharedDelete = SharedDelete;
 
-        if ((ReadAccess && (ShareAccess->SharedRead < ShareAccess->OpenCount)) ||
-            (WriteAccess && (ShareAccess->SharedWrite < ShareAccess->OpenCount)) ||
-            (DeleteAccess && (ShareAccess->SharedDelete < ShareAccess->OpenCount)) ||
+        /* Check if the shared access is violated */
+        if ((ReadAccess &&
+             (ShareAccess->SharedRead < ShareAccess->OpenCount)) ||
+            (WriteAccess &&
+             (ShareAccess->SharedWrite < ShareAccess->OpenCount)) ||
+            (DeleteAccess &&
+             (ShareAccess->SharedDelete < ShareAccess->OpenCount)) ||
             ((ShareAccess->Readers != 0) && !SharedRead) ||
             ((ShareAccess->Writers != 0) && !SharedWrite) ||
             ((ShareAccess->Deleters != 0) && !SharedDelete))
         {
-            return(STATUS_SHARING_VIOLATION);
+            /* Sharing violation, fail */
+            return STATUS_SHARING_VIOLATION;
         }
 
+        /* It's not, check if caller wants us to update it */
         if (Update)
         {
+            /* Increase open count */
             ShareAccess->OpenCount++;
 
+            /* Update shared access */
             ShareAccess->Readers += ReadAccess;
             ShareAccess->Writers += WriteAccess;
             ShareAccess->Deleters += DeleteAccess;
@@ -1738,7 +2263,8 @@ IoCheckShareAccess(IN ACCESS_MASK DesiredAccess,
         }
     }
 
-    return(STATUS_SUCCESS);
+    /* Validation successful */
+    return STATUS_SUCCESS;
 }
 
 /*
@@ -1751,12 +2277,26 @@ IoRemoveShareAccess(IN PFILE_OBJECT FileObject,
 {
     PAGED_CODE();
 
-    if (FileObject->ReadAccess ||
-        FileObject->WriteAccess ||
-        FileObject->DeleteAccess)
+    /* Check if the file has an extension */
+    if (FileObject->Flags & FO_FILE_OBJECT_HAS_EXTENSION)
+    {
+        /* Check if caller specified to ignore access checks */
+        //if (FileObject->FoExtFlags & IO_IGNORE_SHARE_ACCESS_CHECK)
+        {
+            /* Don't update share access */
+            return;
+        }
+    }
+
+    /* Otherwise, check if there's any access present */
+    if ((FileObject->ReadAccess) ||
+        (FileObject->WriteAccess) ||
+        (FileObject->DeleteAccess))
     {
+        /* Decrement the open count */
         ShareAccess->OpenCount--;
 
+        /* Remove share access */
         ShareAccess->Readers -= FileObject->ReadAccess;
         ShareAccess->Writers -= FileObject->WriteAccess;
         ShareAccess->Deleters -= FileObject->DeleteAccess;
@@ -1782,42 +2322,64 @@ IoSetShareAccess(IN ACCESS_MASK DesiredAccess,
     BOOLEAN SharedRead;
     BOOLEAN SharedWrite;
     BOOLEAN SharedDelete;
+    BOOLEAN Update = TRUE;
     PAGED_CODE();
 
     ReadAccess = (DesiredAccess & (FILE_READ_DATA | FILE_EXECUTE)) != 0;
     WriteAccess = (DesiredAccess & (FILE_WRITE_DATA | FILE_APPEND_DATA)) != 0;
     DeleteAccess = (DesiredAccess & DELETE) != 0;
 
+    /* Check if the file has an extension */
+    if (FileObject->Flags & FO_FILE_OBJECT_HAS_EXTENSION)
+    {
+        /* Check if caller specified to ignore access checks */
+        //if (FileObject->FoExtFlags & IO_IGNORE_SHARE_ACCESS_CHECK)
+        {
+            /* Don't update share access */
+            Update = FALSE;
+        }
+    }
+
+    /* Update basic access */
     FileObject->ReadAccess = ReadAccess;
     FileObject->WriteAccess = WriteAccess;
     FileObject->DeleteAccess = DeleteAccess;
 
-    if (!ReadAccess && !WriteAccess && !DeleteAccess)
+    /* Check if we have no access as all */
+    if (!(ReadAccess) && !(WriteAccess) && !(DeleteAccess))
     {
+        /* Check if we need to update the structure */
+        if (!Update) return;
+
+        /* Otherwise, clear data */
         ShareAccess->OpenCount = 0;
         ShareAccess->Readers = 0;
         ShareAccess->Writers = 0;
         ShareAccess->Deleters = 0;
-
         ShareAccess->SharedRead = 0;
         ShareAccess->SharedWrite = 0;
         ShareAccess->SharedDelete = 0;
     }
     else
     {
+        /* Calculate shared access */
         SharedRead = (DesiredShareAccess & FILE_SHARE_READ) != 0;
         SharedWrite = (DesiredShareAccess & FILE_SHARE_WRITE) != 0;
         SharedDelete = (DesiredShareAccess & FILE_SHARE_DELETE) != 0;
 
+        /* Set it in the FO */
         FileObject->SharedRead = SharedRead;
         FileObject->SharedWrite = SharedWrite;
         FileObject->SharedDelete = SharedDelete;
 
+        /* Check if we need to update the structure */
+        if (!Update) return;
+
+        /* Otherwise, set data */
         ShareAccess->OpenCount = 1;
         ShareAccess->Readers = ReadAccess;
         ShareAccess->Writers = WriteAccess;
         ShareAccess->Deleters = DeleteAccess;
-
         ShareAccess->SharedRead = SharedRead;
         ShareAccess->SharedWrite = SharedWrite;
         ShareAccess->SharedDelete = SharedDelete;
@@ -1828,7 +2390,7 @@ IoSetShareAccess(IN ACCESS_MASK DesiredAccess,
  * @unimplemented
  */
 VOID
-STDCALL
+NTAPI
 IoCancelFileOpen(IN PDEVICE_OBJECT DeviceObject,
                  IN PFILE_OBJECT FileObject)
 {
@@ -1839,7 +2401,7 @@ IoCancelFileOpen(IN PDEVICE_OBJECT DeviceObject,
  * @unimplemented
  */
 NTSTATUS
-STDCALL
+NTAPI
 IoQueryFileDosDeviceName(IN PFILE_OBJECT FileObject,
                          OUT POBJECT_NAME_INFORMATION *ObjectNameInformation)
 {
@@ -1851,7 +2413,7 @@ IoQueryFileDosDeviceName(IN PFILE_OBJECT FileObject,
  * @unimplemented
  */
 NTSTATUS
-STDCALL
+NTAPI
 IoSetFileOrigin(IN PFILE_OBJECT FileObject,
                 IN BOOLEAN Remote)
 {
@@ -1863,7 +2425,7 @@ IoSetFileOrigin(IN PFILE_OBJECT FileObject,
  * @implemented
  */
 NTSTATUS
-STDCALL
+NTAPI
 NtCreateFile(PHANDLE FileHandle,
              ACCESS_MASK DesiredAccess,
              POBJECT_ATTRIBUTES ObjectAttributes,
@@ -1894,7 +2456,7 @@ NtCreateFile(PHANDLE FileHandle,
 }
 
 NTSTATUS
-STDCALL
+NTAPI
 NtCreateMailslotFile(OUT PHANDLE FileHandle,
                      IN ACCESS_MASK DesiredAccess,
                      IN POBJECT_ATTRIBUTES ObjectAttributes,
@@ -2146,6 +2708,7 @@ NtCancelIoFile(IN HANDLE FileHandle,
     NTSTATUS Status = STATUS_SUCCESS;
     PLIST_ENTRY ListHead, NextEntry;
     PAGED_CODE();
+    IOTRACE(IO_API_DEBUG, "FileHandle: %p\n", FileHandle);
 
     /* Check the previous mode */
     if (PreviousMode != KernelMode)
@@ -2275,6 +2838,7 @@ NtDeleteFile(IN POBJECT_ATTRIBUTES ObjectAttributes)
     KPROCESSOR_MODE AccessMode = KeGetPreviousMode();
     OPEN_PACKET OpenPacket;
     PAGED_CODE();
+    IOTRACE(IO_API_DEBUG, "FileMame: %wZ\n", ObjectAttributes->ObjectName);
 
     /* Setup the Open Packet */
     RtlZeroMemory(&OpenPacket, sizeof(OPEN_PACKET));
index 056788d..63f0ad4 100644 (file)
 
 #include <ntoskrnl.h>
 #define NDEBUG
-#include <internal/debug.h>
-
-#if 0
-    IOTRACE(IO_IRP_DEBUG,
-            "%s - Queueing IRP %p\n",
-            __FUNCTION__,
-            Irp);
-#endif
+#include <debug.h>
+#include "internal\io_i.h"
 
 /* PRIVATE FUNCTIONS *********************************************************/
 
@@ -31,6 +25,7 @@ IopCleanupAfterException(IN PFILE_OBJECT FileObject,
                          IN PKEVENT LocalEvent OPTIONAL)
 {
     PAGED_CODE();
+    IOTRACE(IO_API_DEBUG, "IRP: %p. FO: %p \n", Irp, FileObject);
 
     /* Check if we had a buffer */
     if (Irp->AssociatedIrp.SystemBuffer)
@@ -73,6 +68,7 @@ IopFinalizeAsynchronousIo(IN NTSTATUS SynchStatus,
 {
     NTSTATUS FinalStatus = SynchStatus;
     PAGED_CODE();
+    IOTRACE(IO_API_DEBUG, "IRP: %p. Status: %lx \n", Irp, SynchStatus);
 
     /* Make sure the IRP was completed, but returned pending */
     if (FinalStatus == STATUS_PENDING)
@@ -125,9 +121,11 @@ IopPerformSynchronousRequest(IN PDEVICE_OBJECT DeviceObject,
     PVOID NormalContext;
     KIRQL OldIrql;
     PAGED_CODE();
+    IOTRACE(IO_API_DEBUG, "IRP: %p. DO: %p. FO: %p \n",
+            Irp, DeviceObject, FileObject);
 
     /* Queue the IRP */
-    //IopQueueIrpToThread(Irp);
+    IopQueueIrpToThread(Irp);
 
     /* Update operation counts */
     IopUpdateOperationCount(TransferType);
@@ -163,7 +161,8 @@ IopPerformSynchronousRequest(IN PDEVICE_OBJECT DeviceObject,
             Status = KeWaitForSingleObject(&FileObject->Event,
                                            Executive,
                                            PreviousMode,
-                                           (FileObject->Flags & FO_ALERTABLE_IO),
+                                           (FileObject->Flags &
+                                            FO_ALERTABLE_IO),
                                            NULL);
             if ((Status == STATUS_ALERTED) || (Status == STATUS_USER_APC))
             {
@@ -208,6 +207,9 @@ IopDeviceFsIoControl(IN HANDLE DeviceHandle,
     OBJECT_HANDLE_INFORMATION HandleInformation;
     ACCESS_MASK DesiredAccess;
     KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+    ULONG BufferLength;
+    IOTRACE(IO_CTL_DEBUG, "Handle: %lx. CTL: %lx. Type: %lx \n",
+            DeviceHandle, IoControlCode, IsDevIoCtl);
 
     /* Get the access type */
     AccessType = IO_METHOD_FROM_CTL_CODE(IoControlCode);
@@ -227,7 +229,9 @@ IopDeviceFsIoControl(IN HANDLE DeviceHandle,
                 if (OutputBuffer)
                 {
                     /* Probe the output buffer */
-                    ProbeForWrite(OutputBuffer, OutputBufferLength, 1);
+                    ProbeForWrite(OutputBuffer,
+                                  OutputBufferLength,
+                                  sizeof(CHAR));
                 }
                 else
                 {
@@ -243,7 +247,7 @@ IopDeviceFsIoControl(IN HANDLE DeviceHandle,
                 if (InputBuffer)
                 {
                     /* Probe the input buffer */
-                    ProbeForRead(InputBuffer, InputBufferLength, 1);
+                    ProbeForRead(InputBuffer, InputBufferLength, sizeof(CHAR));
                 }
                 else
                 {
@@ -258,8 +262,6 @@ IopDeviceFsIoControl(IN HANDLE DeviceHandle,
             Status = _SEH_GetExceptionCode();
         }
         _SEH_END;
-
-        /* Fail if we got an access violation */
         if (!NT_SUCCESS(Status)) return Status;
     }
 
@@ -268,10 +270,18 @@ IopDeviceFsIoControl(IN HANDLE DeviceHandle,
                                        0,
                                        IoFileObjectType,
                                        PreviousMode,
-                                       (PVOID *) &FileObject,
+                                       (PVOID*)&FileObject,
                                        &HandleInformation);
     if (!NT_SUCCESS(Status)) return Status;
 
+    /* Can't use an I/O completion port and an APC in the same time */
+    if ((FileObject->CompletionContext) && (UserApcRoutine))
+    {
+        /* Fail */
+        ObDereferenceObject(FileObject);
+        return STATUS_INVALID_PARAMETER;
+    }
+
     /* Check if we from user mode */
     if (PreviousMode != KernelMode)
     {
@@ -334,29 +344,160 @@ IopDeviceFsIoControl(IN HANDLE DeviceHandle,
     /* Clear the event */
     KeClearEvent(&FileObject->Event);
 
-    /* Build the IRP */
-    Irp = IoBuildDeviceIoControlRequest(IoControlCode,
-                                        DeviceObject,
-                                        InputBuffer,
-                                        InputBufferLength,
-                                        OutputBuffer,
-                                        OutputBufferLength,
-                                        FALSE,
-                                        EventObject,
-                                        IoStatusBlock);
+    /* Allocate IRP */
+    Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
     if (!Irp) return IopCleanupFailedIrp(FileObject, Event, NULL);
 
-    /* Set some extra settings */
-    Irp->Tail.Overlay.AuxiliaryBuffer = (PVOID) NULL;
-    Irp->Tail.Overlay.OriginalFileObject = FileObject;
-    Irp->RequestorMode = PreviousMode;
+    /* Setup the IRP */
+    Irp->UserIosb = IoStatusBlock;
+    Irp->UserEvent = EventObject;
     Irp->Overlay.AsynchronousParameters.UserApcRoutine = UserApcRoutine;
     Irp->Overlay.AsynchronousParameters.UserApcContext = UserApcContext;
+    Irp->Cancel = FALSE;
+    Irp->CancelRoutine = NULL;
+    Irp->PendingReturned = FALSE;
+    Irp->RequestorMode = PreviousMode;
+    Irp->MdlAddress = NULL;
+    Irp->AssociatedIrp.SystemBuffer = NULL;
+    Irp->Flags = 0;
+    Irp->Tail.Overlay.AuxiliaryBuffer = NULL;
+    Irp->Tail.Overlay.OriginalFileObject = FileObject;
+    Irp->Tail.Overlay.Thread = PsGetCurrentThread();
+
+    /* Set stack location settings */
     StackPtr = IoGetNextIrpStackLocation(Irp);
     StackPtr->FileObject = FileObject;
     StackPtr->MajorFunction = IsDevIoCtl ?
                               IRP_MJ_DEVICE_CONTROL :
                               IRP_MJ_FILE_SYSTEM_CONTROL;
+    StackPtr->MinorFunction = 0;
+    StackPtr->Control = 0;
+    StackPtr->Flags = 0;
+    StackPtr->Parameters.DeviceIoControl.Type3InputBuffer = NULL;
+
+    /* Set the IOCTL Data */
+    StackPtr->Parameters.DeviceIoControl.IoControlCode = IoControlCode;
+    StackPtr->Parameters.DeviceIoControl.InputBufferLength = InputBufferLength;
+    StackPtr->Parameters.DeviceIoControl.OutputBufferLength =
+        OutputBufferLength;
+
+    /* Handle the Methods */
+    switch (AccessType)
+    {
+        /* Buffered I/O */
+        case METHOD_BUFFERED:
+
+            /* Enter SEH for allocations */
+            _SEH_TRY
+            {
+                /* Select the right Buffer Length */
+                BufferLength = (InputBufferLength > OutputBufferLength) ?
+                                InputBufferLength : OutputBufferLength;
+
+                /* Make sure there is one */
+                if (BufferLength)
+                {
+                    /* Allocate the System Buffer */
+                    Irp->AssociatedIrp.SystemBuffer =
+                        ExAllocatePoolWithTag(NonPagedPool,
+                                              BufferLength,
+                                              TAG_SYS_BUF);
+
+                    /* Check if we got a buffer */
+                    if (InputBuffer)
+                    {
+                        /* Copy into the System Buffer */
+                        RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer,
+                                      InputBuffer,
+                                      InputBufferLength);
+                    }
+
+                    /* Write the flags */
+                    Irp->Flags = IRP_BUFFERED_IO | IRP_DEALLOCATE_BUFFER;
+                    if (OutputBuffer) Irp->Flags |= IRP_INPUT_OPERATION;
+
+                    /* Save the Buffer */
+                    Irp->UserBuffer = OutputBuffer;
+                }
+                else
+                {
+                    /* Clear the Flags and Buffer */
+                    Irp->UserBuffer = NULL;
+                }
+            }
+            _SEH_HANDLE
+            {
+                /* Cleanup after exception */
+                IopCleanupAfterException(FileObject, Irp, Event, NULL);
+                Status = _SEH_GetExceptionCode();
+            }
+            _SEH_END;
+            if (!NT_SUCCESS(Status)) return Status;
+            break;
+
+        /* Direct I/O */
+        case METHOD_IN_DIRECT:
+        case METHOD_OUT_DIRECT:
+
+            /* Enter SEH */
+            _SEH_TRY
+            {
+                /* Check if we got an input buffer */
+                if ((InputBufferLength) && (InputBuffer))
+                {
+                    /* Allocate the System Buffer */
+                    Irp->AssociatedIrp.SystemBuffer =
+                        ExAllocatePoolWithTag(NonPagedPool,
+                                              InputBufferLength,
+                                              TAG_SYS_BUF);
+
+                    /* Copy into the System Buffer */
+                    RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer,
+                                  InputBuffer,
+                                  InputBufferLength);
+
+                    /* Write the flags */
+                    Irp->Flags = IRP_BUFFERED_IO | IRP_DEALLOCATE_BUFFER;
+                }
+
+                /* Check if we got an output buffer */
+                if (OutputBuffer)
+                {
+                    /* Allocate the System Buffer */
+                    Irp->MdlAddress = IoAllocateMdl(OutputBuffer,
+                                                    OutputBufferLength,
+                                                    FALSE,
+                                                    FALSE,
+                                                    Irp);
+                    if (!Irp->MdlAddress)
+                    {
+                        /* Raise exception we'll catch */
+                        ExRaiseStatus(STATUS_INSUFFICIENT_RESOURCES);
+                    }
+
+                    /* Do the probe */
+                    MmProbeAndLockPages(Irp->MdlAddress,
+                                        PreviousMode,
+                                        (AccessType == METHOD_IN_DIRECT) ?
+                                        IoReadAccess : IoWriteAccess);
+                }
+            }
+            _SEH_HANDLE
+            {
+                /* Cleanup after exception */
+                IopCleanupAfterException(FileObject, Irp, Event, NULL);
+                Status = _SEH_GetExceptionCode();
+            }
+            _SEH_END;
+            if (!NT_SUCCESS(Status)) return Status;
+            break;
+
+        case METHOD_NEITHER:
+
+            /* Just save the Buffer */
+            Irp->UserBuffer = OutputBuffer;
+            StackPtr->Parameters.DeviceIoControl.Type3InputBuffer = InputBuffer;
+    }
 
     /* Use deferred completion for FS I/O */
     Irp->Flags |= (!IsDevIoCtl) ? IRP_DEFER_IO_COMPLETION : 0;
@@ -388,6 +529,8 @@ IopQueryDeviceInformation(IN PFILE_OBJECT FileObject,
     KEVENT Event;
     NTSTATUS Status;
     PAGED_CODE();
+    IOTRACE(IO_API_DEBUG, "Handle: %p. CTL: %lx. Type: %lx \n",
+            FileObject, InformationClass, File);
 
     /* Reference the object */
     ObReferenceObject(FileObject);
@@ -447,7 +590,7 @@ IopQueryDeviceInformation(IN PFILE_OBJECT FileObject,
     }
 
     /* Queue the IRP */
-    //IopQueueIrpToThread(Irp);
+    IopQueueIrpToThread(Irp);
 
     /* Call the Driver */
     Status = IoCallDriver(DeviceObject, Irp);
@@ -509,6 +652,8 @@ IoSynchronousPageWrite(IN PFILE_OBJECT FileObject,
     PIRP Irp;
     PIO_STACK_LOCATION StackPtr;
     PDEVICE_OBJECT DeviceObject;
+    IOTRACE(IO_API_DEBUG, "FileObject: %p. Mdl: %p. Offset: %p \n",
+            FileObject, Mdl, Offset);
 
     /* Get the Device Object */
     DeviceObject = IoGetRelatedDeviceObject(FileObject);
@@ -554,6 +699,8 @@ IoPageRead(IN PFILE_OBJECT FileObject,
     PIRP Irp;
     PIO_STACK_LOCATION StackPtr;
     PDEVICE_OBJECT DeviceObject;
+    IOTRACE(IO_API_DEBUG, "FileObject: %p. Mdl: %p. Offset: %p \n",
+            FileObject, Mdl, Offset);
 
     /* Get the Device Object */
     DeviceObject = IoGetRelatedDeviceObject(FileObject);
@@ -646,6 +793,8 @@ IoSetInformation(IN PFILE_OBJECT FileObject,
     KEVENT Event;
     NTSTATUS Status;
     PAGED_CODE();
+    IOTRACE(IO_API_DEBUG, "FileObject: %p. Class: %lx. Length: %lx \n",
+            FileObject, FileInformationClass, Length);
 
     /* Reference the object */
     ObReferenceObject(FileObject);
@@ -694,7 +843,7 @@ IoSetInformation(IN PFILE_OBJECT FileObject,
     StackPtr->Parameters.SetFile.Length = Length;
 
     /* Queue the IRP */
-    //IopQueueIrpToThread(Irp);
+    IopQueueIrpToThread(Irp);
 
     /* Call the Driver */
     Status = IoCallDriver(DeviceObject, Irp);
@@ -817,6 +966,7 @@ NtFlushBuffersFile(IN HANDLE FileHandle,
     KPROCESSOR_MODE PreviousMode = KeGetPreviousMode();
     IO_STATUS_BLOCK KernelIosb;
     PAGED_CODE();
+    IOTRACE(IO_API_DEBUG, "FileHandle: %p\n", FileHandle);
 
     if (PreviousMode != KernelMode)
     {
@@ -948,6 +1098,7 @@ NtNotifyChangeDirectoryFile(IN HANDLE FileHandle,
     NTSTATUS Status = STATUS_SUCCESS;
     BOOLEAN LockedForSync = FALSE;
     PAGED_CODE();
+    IOTRACE(IO_API_DEBUG, "FileHandle: %p\n", FileHandle);
 
     /* Check if we're called from user mode */
     if (PreviousMode != KernelMode)
@@ -1073,6 +1224,7 @@ NtLockFile(IN HANDLE FileHandle,
     PAGED_CODE();
     CapturedByteOffset.QuadPart = 0;
     CapturedLength.QuadPart = 0;
+    IOTRACE(IO_API_DEBUG, "FileHandle: %p\n", FileHandle);
 
     /* Get File Object */
     Status = ObReferenceObjectByHandle(FileHandle,
@@ -1247,9 +1399,10 @@ NtQueryDirectoryFile(IN HANDLE FileHandle,
     UNICODE_STRING CapturedFileName;
     PUNICODE_STRING SearchPattern;
     PAGED_CODE();
+    IOTRACE(IO_API_DEBUG, "FileHandle: %p\n", FileHandle);
 
     /* Check if we came from user mode */
-    if(PreviousMode != KernelMode)
+    if (PreviousMode != KernelMode)
     {
         /* Enter SEH for probing */
         _SEH_TRY
@@ -1484,10 +1637,26 @@ NtQueryInformationFile(IN HANDLE FileHandle,
     PVOID NormalContext;
     KIRQL OldIrql;
     IO_STATUS_BLOCK KernelIosb;
+    IOTRACE(IO_API_DEBUG, "FileHandle: %p\n", FileHandle);
 
     /* Check if we're called from user mode */
     if (PreviousMode != KernelMode)
     {
+        /* Validate the information class */
+        if ((FileInformationClass >= FileMaximumInformation) ||
+            !(IopQueryOperationLength[FileInformationClass]))
+        {
+            /* Invalid class */
+            return STATUS_INVALID_INFO_CLASS;
+        }
+
+        /* Validate the length */
+        if (Length < IopQueryOperationLength[FileInformationClass])
+        {
+            /* Invalid length */
+            return STATUS_INFO_LENGTH_MISMATCH;
+        }
+
         /* Enter SEH for probing */
         _SEH_TRY
         {
@@ -1495,7 +1664,7 @@ NtQueryInformationFile(IN HANDLE FileHandle,
             ProbeForWriteIoStatusBlock(IoStatusBlock);
 
             /* Probe the information */
-            if (Length) ProbeForWrite(FileInformation, Length, 1);
+            ProbeForWrite(FileInformation, Length, sizeof(ULONG));
         }
         _SEH_HANDLE
         {
@@ -1503,14 +1672,30 @@ NtQueryInformationFile(IN HANDLE FileHandle,
             Status = _SEH_GetExceptionCode();
         }
         _SEH_END;
-
-        /* Check if probing failed */
         if (!NT_SUCCESS(Status)) return Status;
     }
+    else
+    {
+        /* Validate the information class */
+        if ((FileInformationClass >= FileMaximumInformation) ||
+            !(IopQueryOperationLength[FileInformationClass]))
+        {
+            /* Invalid class */
+            return STATUS_INVALID_INFO_CLASS;
+        }
+
+        /* Validate the length */
+        if (Length < IopQueryOperationLength[FileInformationClass])
+        {
+            /* Invalid length */
+            return STATUS_INFO_LENGTH_MISMATCH;
+        }
+    }
 
     /* Reference the Handle */
     Status = ObReferenceObjectByHandle(FileHandle,
-                                       0, // FIXME
+                                       IopQueryOperationAccess
+                                       [FileInformationClass],
                                        IoFileObjectType,
                                        PreviousMode,
                                        (PVOID *)&FileObject,
@@ -1623,7 +1808,7 @@ NtQueryInformationFile(IN HANDLE FileHandle,
     StackPtr->Parameters.QueryFile.Length = Length;
 
     /* Queue the IRP */
-    //IopQueueIrpToThread(Irp);
+    IopQueueIrpToThread(Irp);
 
     /* Update operation counts */
     IopUpdateOperationCount(IopOtherTransfer);
@@ -1764,6 +1949,7 @@ NtReadFile(IN HANDLE FileHandle,
     PMDL Mdl;
     PAGED_CODE();
     CapturedByteOffset.QuadPart = 0;
+    IOTRACE(IO_API_DEBUG, "FileHandle: %p\n", FileHandle);
 
     /* Validate User-Mode Buffers */
     if(PreviousMode != KernelMode)
@@ -2024,10 +2210,26 @@ NtSetInformationFile(IN HANDLE FileHandle,
     PVOID Queue;
     PFILE_COMPLETION_INFORMATION CompletionInfo = FileInformation;
     PIO_COMPLETION_CONTEXT Context;
+    IOTRACE(IO_API_DEBUG, "FileHandle: %p\n", FileHandle);
 
     /* Check if we're called from user mode */
     if (PreviousMode != KernelMode)
     {
+        /* Validate the information class */
+        if ((FileInformationClass >= FileMaximumInformation) ||
+            !(IopSetOperationLength[FileInformationClass]))
+        {
+            /* Invalid class */
+            return STATUS_INVALID_INFO_CLASS;
+        }
+
+        /* Validate the length */
+        if (Length < IopSetOperationLength[FileInformationClass])
+        {
+            /* Invalid length */
+            return STATUS_INFO_LENGTH_MISMATCH;
+        }
+
         /* Enter SEH for probing */
         _SEH_TRY
         {
@@ -2035,7 +2237,10 @@ NtSetInformationFile(IN HANDLE FileHandle,
             ProbeForWriteIoStatusBlock(IoStatusBlock);
 
             /* Probe the information */
-            if (Length) ProbeForRead(FileInformation, Length, 1);
+            ProbeForRead(FileInformation,
+                         Length,
+                         (Length == sizeof(BOOLEAN)) ?
+                         sizeof(BOOLEAN) : sizeof(ULONG));
         }
         _SEH_HANDLE
         {
@@ -2047,10 +2252,28 @@ NtSetInformationFile(IN HANDLE FileHandle,
         /* Check if probing failed */
         if (!NT_SUCCESS(Status)) return Status;
     }
+    else
+    {
+        /* Validate the information class */
+        if ((FileInformationClass >= FileMaximumInformation) ||
+            !(IopSetOperationLength[FileInformationClass]))
+        {
+            /* Invalid class */
+            return STATUS_INVALID_INFO_CLASS;
+        }
+
+        /* Validate the length */
+        if (Length < IopSetOperationLength[FileInformationClass])
+        {
+            /* Invalid length */
+            return STATUS_INFO_LENGTH_MISMATCH;
+        }
+    }
 
     /* Reference the Handle */
     Status = ObReferenceObjectByHandle(FileHandle,
-                                       0, // FIXME
+                                       IopSetOperationAccess
+                                       [FileInformationClass],
                                        IoFileObjectType,
                                        PreviousMode,
                                        (PVOID *)&FileObject,
@@ -2168,7 +2391,7 @@ NtSetInformationFile(IN HANDLE FileHandle,
     StackPtr->Parameters.SetFile.Length = Length;
 
     /* Queue the IRP */
-    //IopQueueIrpToThread(Irp);
+    IopQueueIrpToThread(Irp);
 
     /* Update operation counts */
     IopUpdateOperationCount(IopOtherTransfer);
@@ -2366,6 +2589,7 @@ NtUnlockFile(IN HANDLE FileHandle,
     PAGED_CODE();
     CapturedByteOffset.QuadPart = 0;
     CapturedLength.QuadPart = 0;
+    IOTRACE(IO_API_DEBUG, "FileHandle: %p\n", FileHandle);
 
     /* Get File Object */
     Status = ObReferenceObjectByHandle(FileHandle,
@@ -2548,6 +2772,7 @@ NtWriteFile(IN HANDLE FileHandle,
     OBJECT_HANDLE_INFORMATION ObjectHandleInfo;
     PAGED_CODE();
     CapturedByteOffset.QuadPart = 0;
+    IOTRACE(IO_API_DEBUG, "FileHandle: %p\n", FileHandle);
 
     /* Get File Object */
     Status = ObReferenceObjectByHandle(FileHandle,
@@ -2811,10 +3036,26 @@ NtQueryVolumeInformationFile(IN HANDLE FileHandle,
     NTSTATUS Status = STATUS_SUCCESS;
     IO_STATUS_BLOCK KernelIosb;
     PAGED_CODE();
+    IOTRACE(IO_API_DEBUG, "FileHandle: %p\n", FileHandle);
 
     /* Check if we're called from user mode */
     if (PreviousMode != KernelMode)
     {
+        /* Validate the information class */
+        if ((FsInformationClass >= FileFsMaximumInformation) ||
+            !(IopQueryFsOperationLength[FsInformationClass]))
+        {
+            /* Invalid class */
+            return STATUS_INVALID_INFO_CLASS;
+        }
+
+        /* Validate the length */
+        if (Length < IopQueryFsOperationLength[FsInformationClass])
+        {
+            /* Invalid length */
+            return STATUS_INFO_LENGTH_MISMATCH;
+        }
+
         /* Enter SEH for probing */
         _SEH_TRY
         {
@@ -2822,7 +3063,7 @@ NtQueryVolumeInformationFile(IN HANDLE FileHandle,
             ProbeForWriteIoStatusBlock(IoStatusBlock);
 
             /* Probe the information */
-            if (Length) ProbeForWrite(FsInformation, Length, 1);
+            ProbeForWrite(FsInformation, Length, sizeof(ULONG));
         }
         _SEH_HANDLE
         {
@@ -2830,14 +3071,13 @@ NtQueryVolumeInformationFile(IN HANDLE FileHandle,
             Status = _SEH_GetExceptionCode();
         }
         _SEH_END;
-
-        /* Check if probing failed */
         if (!NT_SUCCESS(Status)) return Status;
     }
 
     /* Get File Object */
     Status = ObReferenceObjectByHandle(FileHandle,
-                                       0, // FIXME
+                                       IopQueryFsOperationAccess
+                                       [FsInformationClass],
                                        IoFileObjectType,
                                        PreviousMode,
                                        (PVOID*)&FileObject,
@@ -2959,10 +3199,26 @@ NtSetVolumeInformationFile(IN HANDLE FileHandle,
     NTSTATUS Status = STATUS_SUCCESS;
     IO_STATUS_BLOCK KernelIosb;
     PAGED_CODE();
+    IOTRACE(IO_API_DEBUG, "FileHandle: %p\n", FileHandle);
 
     /* Check if we're called from user mode */
     if (PreviousMode != KernelMode)
     {
+        /* Validate the information class */
+        if ((FsInformationClass >= FileFsMaximumInformation) ||
+            !(IopSetFsOperationLength[FsInformationClass]))
+        {
+            /* Invalid class */
+            return STATUS_INVALID_INFO_CLASS;
+        }
+
+        /* Validate the length */
+        if (Length < IopSetFsOperationLength[FsInformationClass])
+        {
+            /* Invalid length */
+            return STATUS_INFO_LENGTH_MISMATCH;
+        }
+
         /* Enter SEH for probing */
         _SEH_TRY
         {
@@ -2970,7 +3226,7 @@ NtSetVolumeInformationFile(IN HANDLE FileHandle,
             ProbeForWriteIoStatusBlock(IoStatusBlock);
 
             /* Probe the information */
-            if (Length) ProbeForRead(FsInformation, Length, 1);
+            ProbeForRead(FsInformation, Length, sizeof(ULONG));
         }
         _SEH_HANDLE
         {
@@ -2978,14 +3234,13 @@ NtSetVolumeInformationFile(IN HANDLE FileHandle,
             Status = _SEH_GetExceptionCode();
         }
         _SEH_END;
-
-        /* Check if probing failed */
         if (!NT_SUCCESS(Status)) return Status;
     }
 
     /* Get File Object */
     Status = ObReferenceObjectByHandle(FileHandle,
-                                       0, // FIXME
+                                       IopSetFsOperationAccess
+                                       [FsInformationClass],
                                        IoFileObjectType,
                                        PreviousMode,
                                        (PVOID*)&FileObject,
index 70c1139..2ffc7ea 100644 (file)
@@ -13,7 +13,7 @@
 #define NDEBUG
 #include <internal/debug.h>
 
-ULONG IopTraceLevel = IO_IRP_DEBUG;
+ULONG IopTraceLevel = 0; //IO_API_DEBUG | IO_FILE_DEBUG;
 
 // should go into a proper header
 VOID
index 21955c6..b837439 100644 (file)
@@ -214,12 +214,16 @@ IopCleanupIrp(IN PIRP Irp,
         !(Irp->Flags & IRP_SYNCHRONOUS_API) &&
         (FileObject))
     {
-        /* Derefernce the User Event */
+        /* Dereference the User Event */
         ObDereferenceObject(Irp->UserEvent);
     }
 
-    /* Dereference the File Object */
-    if (FileObject) ObDereferenceObject(FileObject);
+    /* Check if we have a file object and this isn't a create operation */
+    if ((FileObject) && !(Irp->Flags & IRP_CREATE_OPERATION))
+    {
+        /* Dereference the file object */
+        ObDereferenceObject(FileObject);
+    }
 
     /* Free the IRP */
     IoFreeIrp(Irp);
@@ -1099,22 +1103,24 @@ IofCompleteRequest(IN PIRP Irp,
     PMDL Mdl;
     ULONG MasterIrpCount;
     PIRP MasterIrp;
+    ULONG Flags;
     IOTRACE(IO_IRP_DEBUG,
             "%s - Completing IRP %p\n",
             __FUNCTION__,
             Irp);
 
-    /* Make sure this IRP isn't getting completed more then once */
-    if ((Irp->CurrentLocation) > (Irp->StackCount + 1))
+    /* Make sure this IRP isn't getting completed twice or is invalid */
+    if (((Irp->CurrentLocation) > (Irp->StackCount + 1)) ||
+        (Irp->Type != IO_TYPE_IRP))
     {
         /* Bugcheck */
         KeBugCheckEx(MULTIPLE_IRP_COMPLETE_REQUESTS, (ULONG_PTR)Irp, 0, 0, 0);
     }
 
     /* Some sanity checks */
-    ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
     ASSERT(!Irp->CancelRoutine);
     ASSERT(Irp->IoStatus.Status != STATUS_PENDING);
+    ASSERT(Irp->IoStatus.Status != 0xFFFFFFFF);
 
     /* Get the Current Stack and skip it */
     StackPtr = IoGetCurrentIrpStackLocation(Irp);
@@ -1172,9 +1178,6 @@ IofCompleteRequest(IN PIRP Irp,
     /* Check if the IRP is an associated IRP */
     if (Irp->Flags & IRP_ASSOCIATED_IRP)
     {
-        /* This should never happen! */
-        ASSERT(IsListEmpty(&Irp->ThreadListEntry));
-
         /* Get the master IRP and count */
         MasterIrp = Irp->AssociatedIrp.MasterIrp;
         MasterIrpCount = InterlockedDecrement(&MasterIrp->
@@ -1199,6 +1202,9 @@ IofCompleteRequest(IN PIRP Irp,
         return;
     }
 
+    /* We don't support this yet */
+    ASSERT(Irp->IoStatus.Status != STATUS_REPARSE);
+
     /* Check if we have an auxiliary buffer */
     if (Irp->Tail.Overlay.AuxiliaryBuffer)
     {
@@ -1210,18 +1216,16 @@ IofCompleteRequest(IN PIRP Irp,
     /* Check if this is a Paging I/O or Close Operation */
     if (Irp->Flags & (IRP_PAGING_IO | IRP_CLOSE_OPERATION))
     {
-        /* This should never happen! */
-        ASSERT(IsListEmpty(&Irp->ThreadListEntry));
-
         /* Handle a Close Operation or Sync Paging I/O (see page 165) */
         if (Irp->Flags & (IRP_SYNCHRONOUS_PAGING_IO | IRP_CLOSE_OPERATION))
         {
             /* Set the I/O Status and Signal the Event */
+            Flags = Irp->Flags & IRP_SYNCHRONOUS_PAGING_IO;
             *Irp->UserIosb = Irp->IoStatus;
             KeSetEvent(Irp->UserEvent, PriorityBoost, FALSE);
 
             /* Free the IRP for a Paging I/O Only, Close is handled by us */
-            if (Irp->Flags & IRP_SYNCHRONOUS_PAGING_IO) IoFreeIrp(Irp);
+            if (Flags) IoFreeIrp(Irp);
         }
         else
         {
@@ -1271,7 +1275,7 @@ IofCompleteRequest(IN PIRP Irp,
     Thread = Irp->Tail.Overlay.Thread;
     FileObject = Irp->Tail.Overlay.OriginalFileObject;
 
-    /* Make sure the IRP isn't cancelled */
+    /* Make sure the IRP isn't canceled */
     if (!Irp->Cancel)
     {
         /* Initialize the APC */
@@ -1292,7 +1296,7 @@ IofCompleteRequest(IN PIRP Irp,
     }
     else
     {
-        /* The IRP just got cancelled... does a thread still own it? */
+        /* The IRP just got canceled... does a thread still own it? */
         Thread = Irp->Tail.Overlay.Thread;
         if (Thread)
         {
@@ -1315,6 +1319,7 @@ IofCompleteRequest(IN PIRP Irp,
         else
         {
             /* Nothing left for us to do, kill it */
+            ASSERT(Irp->Cancel);
             IopCleanupIrp(Irp, FileObject);
         }
     }
@@ -1348,6 +1353,7 @@ IoFreeIrp(IN PIRP Irp)
             Irp);
 
     /* Make sure the Thread IRP list is empty and that it OK to free it */
+    ASSERT(Irp->Type == IO_TYPE_IRP);
     ASSERT(IsListEmpty(&Irp->ThreadListEntry));
     ASSERT(Irp->CurrentLocation >= Irp->StackCount);
 
index f515256..75d4701 100644 (file)
@@ -647,7 +647,7 @@ KdbSymProcessBootSymbols(IN PUNICODE_STRING FileName)
 
         if (IsRaw)
         {
-            DPRINT1("Data: %p %p %wZ\n", LdrEntry->DllBase, LdrEntry->SizeOfImage, &LdrEntry->FullDllName);
+            DPRINT("Data: %p %p %wZ\n", LdrEntry->DllBase, LdrEntry->SizeOfImage, &LdrEntry->FullDllName);
            if (! RosSymCreateFromRaw(LdrEntry->DllBase,
                                      LdrEntry->SizeOfImage,
                                      (PROSSYM_INFO*)&ModuleObject->PatchInformation))
index 0f342b0..ffefedb 100644 (file)
@@ -1206,7 +1206,7 @@ MmZeroPageThreadMain(PVOID Ignored)
          }
 
       }
-      DPRINT1("Zeroed %d pages.\n", Count);
+      DPRINT("Zeroed %d pages.\n", Count);
       KeResetEvent(&ZeroPageThreadEvent);
       KeReleaseSpinLock(&PageListLock, oldIrql);
    }
index 3eac1b8..85b0271 100644 (file)
@@ -1756,7 +1756,7 @@ ObInsertObject(IN PVOID Object,
     POBJECT_CREATE_INFORMATION ObjectCreateInfo;
     POBJECT_HEADER Header;
     POBJECT_TYPE ObjectType;
-    PVOID FoundObject = NULL;
+    PVOID FoundObject = Object;
     POBJECT_HEADER FoundHeader = NULL;
     NTSTATUS Status = STATUS_SUCCESS, RealStatus;
     PSECURITY_DESCRIPTOR DirectorySd = NULL;
@@ -1841,7 +1841,8 @@ ObInsertObject(IN PVOID Object,
         Status = ObFindObject(ObjectCreateInfo->RootDirectory,
                               &ObjectNameInfo->Name,
                               ObjectCreateInfo->Attributes,
-                              KernelMode,
+                              (Header->Flags & OB_FLAG_KERNEL_MODE) ?
+                              KernelMode : UserMode,
                               &FoundObject,
                               ObjectType,
                               &Context,
index 99c2b06..23e0e5e 100644 (file)
@@ -494,6 +494,14 @@ ObpCaptureObjectAttributes(IN POBJECT_ATTRIBUTES ObjectAttributes,
     return Status;
 }
 
+VOID
+NTAPI
+ObFreeObjectCreateInfoBuffer(IN POBJECT_CREATE_INFORMATION ObjectCreateInfo)
+{
+    /* Call the macro. We use this function to isolate Ob internals from Io */
+    ObpFreeCapturedAttributes(ObjectCreateInfo, LookasideCreateInfoList);
+}
+
 NTSTATUS
 NTAPI
 ObpAllocateObject(IN POBJECT_CREATE_INFORMATION ObjectCreateInfo,
index f73ee7f..41a94f6 100644 (file)
@@ -362,13 +362,20 @@ PspInitPhase0(VOID)
     /* Clear kernel time */
     PsIdleProcess->Pcb.KernelTime = 0;
 
-    /* Initialize the Process type */
+    /* Initialize Object Initializer */
     RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer));
-    RtlInitUnicodeString(&Name, L"Process");
     ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer);
+    ObjectTypeInitializer.InvalidAttributes = OBJ_OPENLINK |
+                                              OBJ_PERMANENT |
+                                              OBJ_EXCLUSIVE |
+                                              OBJ_OPENIF;
+    ObjectTypeInitializer.PoolType = NonPagedPool;
+    ObjectTypeInitializer.SecurityRequired = TRUE;
+
+    /* Initialize the Process type */
+    RtlInitUnicodeString(&Name, L"Process");
     ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(EPROCESS);
     ObjectTypeInitializer.GenericMapping = PspProcessMapping;
-    ObjectTypeInitializer.PoolType = NonPagedPool;
     ObjectTypeInitializer.ValidAccessMask = PROCESS_ALL_ACCESS;
     ObjectTypeInitializer.DeleteProcedure = PspDeleteProcess;
     ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &PsProcessType);
@@ -380,25 +387,20 @@ PspInitPhase0(VOID)
     }
 
     /*  Initialize the Thread type  */
-    RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer));
     RtlInitUnicodeString(&Name, L"Thread");
     ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer);
     ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(ETHREAD);
     ObjectTypeInitializer.GenericMapping = PspThreadMapping;
-    ObjectTypeInitializer.PoolType = NonPagedPool;
     ObjectTypeInitializer.ValidAccessMask = THREAD_ALL_ACCESS;
     ObjectTypeInitializer.DeleteProcedure = PspDeleteThread;
     ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &PsThreadType);
 
     /*  Initialize the Job type  */
-    RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer));
     RtlInitUnicodeString(&Name, L"Job");
     ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer);
     ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(EJOB);
     ObjectTypeInitializer.GenericMapping = PspJobMapping;
-    ObjectTypeInitializer.PoolType = NonPagedPool;
     ObjectTypeInitializer.ValidAccessMask = JOB_OBJECT_ALL_ACCESS;
-    ObjectTypeInitializer.UseDefaultObject = TRUE;
     ObjectTypeInitializer.DeleteProcedure = PspDeleteJob;
     ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &PsJobType);
 
index 3e1e9d6..78f3692 100644 (file)
@@ -206,7 +206,8 @@ RtlpCaptureStackLimits(IN ULONG_PTR Ebp,
     if ((*StackBegin > Ebp) || (Ebp > *StackEnd))
     {
         /* FIXME: TODO */
-        ASSERT(FALSE);
+        //ASSERT(FALSE);
+        DPRINT1("Stacks: %p %p %p\n", Ebp, *StackBegin, *StackEnd);
     }
 
     /* Return success */
index ba5d2ef..a7147c5 100644 (file)
@@ -38,6 +38,9 @@ INIT_FUNCTION
 NTAPI
 SeInit(VOID)
 {
+    DPRINT1("FIXME: SeAccessCheck has been HACKED to always grant access!\n");
+    DPRINT1("FIXME: Please fix all the code that doesn't get proper rights!\n");
+
   SepInitLuid();
 
   if (!SepInitSecurityIDs())
@@ -1050,7 +1053,7 @@ SeAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
   else
     {
       *AccessStatus = STATUS_ACCESS_DENIED;
-      DPRINT1("FIX caller rights (granted 0x%lx, desired 0x%lx)!\n",
+      DPRINT("FIX caller rights (granted 0x%lx, desired 0x%lx)!\n",
         *GrantedAccess, DesiredAccess);
       return TRUE; /* FIXME: should be FALSE */
     }
index bfc91d6..e725f16 100644 (file)
@@ -72,9 +72,9 @@ CsrApiCallHandler(PCSRSS_PROCESS_DATA ProcessData,
   unsigned DefIndex;
   ULONG Type;
   
-  DPRINT1("CSR: Calling handler for type: %x.\n", Request->Type);
+  DPRINT("CSR: Calling handler for type: %x.\n", Request->Type);
   Type = Request->Type & 0xFFFF; /* FIXME: USE MACRO */
-  DPRINT1("CSR: API Number: %x ServerID: %x\n",Type, Request->Type >> 16);
+  DPRINT("CSR: API Number: %x ServerID: %x\n",Type, Request->Type >> 16);
 
   /* FIXME: Extract DefIndex instead of looping */
   for (DefIndex = 0; ! Found && DefIndex < ApiDefinitionsCount; DefIndex++)
@@ -129,7 +129,7 @@ CsrpHandleConnectionRequest (PPORT_MESSAGE Request,
     LpcRead.Length = sizeof(LpcRead);
     ServerPort = NULL;
 
-    DPRINT1("CSR: %s: Handling: %p\n", __FUNCTION__, Request);
+    DPRINT("CSR: %s: Handling: %p\n", __FUNCTION__, Request);
 
     Status = NtAcceptConnectPort(&ServerPort,
 #ifdef NTLPC
@@ -189,7 +189,7 @@ CsrpHandleConnectionRequest (PPORT_MESSAGE Request,
 #endif
 
     Status = STATUS_SUCCESS;
-    DPRINT1("CSR: %s done\n", __FUNCTION__);
+    DPRINT("CSR: %s done\n", __FUNCTION__);
     return Status;
 }
 
@@ -300,7 +300,7 @@ ServerApiPortThread (HANDLE hApiListenPort)
     BYTE RawRequest[sizeof(PORT_MESSAGE) + sizeof(CSR_CONNECTION_INFO)];
     PPORT_MESSAGE Request = (PPORT_MESSAGE)RawRequest;
 
-    DPRINT1("CSR: %s called", __FUNCTION__);
+    DPRINT("CSR: %s called", __FUNCTION__);
 
     for (;;)
     {
@@ -346,7 +346,7 @@ ServerSbApiPortThread (HANDLE hSbApiPortListen)
        NTSTATUS        Status = STATUS_SUCCESS;
     PPORT_MESSAGE Reply = NULL;
 
-       DPRINT1("CSR: %s called\n", __FUNCTION__);
+       DPRINT("CSR: %s called\n", __FUNCTION__);
 
     RtlZeroMemory(&Request, sizeof(PORT_MESSAGE));
        Status = NtListenPort (hSbApiPortListen, & Request);
@@ -417,7 +417,7 @@ DPRINT("-- 5\n");
                        }
                }
        }
-       DPRINT1("CSR: %s: terminating!\n", __FUNCTION__);
+       DPRINT("CSR: %s: terminating!\n", __FUNCTION__);
        if(hConnectedPort) NtClose (hConnectedPort);
        NtClose (hSbApiPortListen);
        NtTerminateThread (NtCurrentThread(), Status);
index 158dad2..ff43a2f 100644 (file)
@@ -285,7 +285,7 @@ Win32kThreadCallback(struct _ETHREAD *Thread,
       while (e)
       {
          PUSER_REFERENCE_ENTRY ref = CONTAINING_RECORD(e, USER_REFERENCE_ENTRY, Entry);
-         DPRINT1("thread clean: remove reference obj 0x%x\n",ref->obj);
+         DPRINT("thread clean: remove reference obj 0x%x\n",ref->obj);
          ObmDereferenceObject(ref->obj);
          
          e = PopEntryList(&Win32Thread->ReferencesList);
index 74c613c..1e4be17 100644 (file)
@@ -52,7 +52,12 @@ static VOID
 IntDestroyClass(IN OUT PWINDOWCLASS Class)
 {
     /* there shouldn't be any clones anymore */
-    ASSERT(Class->Windows == 0);
+    //ASSERT(Class->Windows == 0);
+    if (Class->Windows)
+    {
+        DPRINT1("FIXME: W3Seek's Class Patch is broken!\n");
+        Class->Windows = 0;
+    }
     ASSERT(Class->Clone == NULL);
 
     if (Class->Base == Class)
index 95dafd2..f98a428 100644 (file)
@@ -89,7 +89,7 @@ co_IntSendActivateMessages(HWND hWndPrev, HWND hWnd, BOOL MouseActivate)
 
       /* FIXME: IntIsWindow */
 
-      CHECKPOINT1;
+      CHECKPOINT;
       co_IntPostOrSendMessage(hWnd, WM_NCACTIVATE, (WPARAM)(hWnd == UserGetForegroundWindow()), 0);
       /* FIXME: WA_CLICKACTIVE */
       co_IntPostOrSendMessage(hWnd, WM_ACTIVATE,
@@ -174,7 +174,7 @@ co_IntSetForegroundAndFocusWindow(PWINDOW_OBJECT Window, PWINDOW_OBJECT FocusWin
 
    if (hWndPrev == hWnd)
    {
-      DPRINT1("Failed - Same\n");
+      DPRINT("Failed - Same\n");
       return TRUE;
    }
 
@@ -202,7 +202,7 @@ co_IntSetForegroundAndFocusWindow(PWINDOW_OBJECT Window, PWINDOW_OBJECT FocusWin
       /* FIXME: Send WM_ACTIVATEAPP to all thread windows. */
    }
 
-   CHECKPOINT1;
+   CHECKPOINT;
    co_IntSendSetFocusMessages(hWndFocusPrev, hWndFocus);
    co_IntSendActivateMessages(hWndPrev, hWnd, MouseActivate);
 
index f8b868b..20b7b6d 100644 (file)
@@ -1475,7 +1475,7 @@ UserSystemParametersInfo(
          }
       default :
                  {
-                         DPRINT1("UserSystemParametersInfo : uiAction = %x \n",uiAction );
+              DPRINT1("FIXME: UNIMPLEMENTED SPI Code: %lx \n",uiAction );
                          break;
                  }
    }
index cdc1ed9..9ba5d7f 100644 (file)
@@ -645,7 +645,7 @@ co_DestroyThreadWindows(struct _ETHREAD *Thread)
       Current = WThread->WindowListHead.Flink;
       Wnd = CONTAINING_RECORD(Current, WINDOW_OBJECT, ThreadListEntry);
 
-      DPRINT1("thread cleanup: while destroy wnds, wnd=0x%x\n",Wnd);
+      DPRINT("thread cleanup: while destroy wnds, wnd=0x%x\n",Wnd);
 
       /* window removes itself from the list */