[fastfat_new]
authorAleksey Bragin <aleksey@reactos.org>
Mon, 28 Sep 2009 09:49:16 +0000 (09:49 +0000)
committerAleksey Bragin <aleksey@reactos.org>
Mon, 28 Sep 2009 09:49:16 +0000 (09:49 +0000)
- Start implementing one of the most massive IFS driver routines - IRP_MJ_CREATE handler. Right now it just does some preliminary work, deciphers all options, prepares all variables, prints out debug stuff.

svn path=/trunk/; revision=43199

reactos/drivers/filesystems/fastfat_new/create.c

index 3c341b2..676a3f3 100644 (file)
 
 /* FUNCTIONS *****************************************************************/
 
+NTSTATUS
+NTAPI
+FatiCreate(IN PFAT_IRP_CONTEXT IrpContext,
+           IN PIRP Irp)
+{
+    /* Boolean options */
+    BOOLEAN CreateDirectory;
+    BOOLEAN SequentialOnly;
+    BOOLEAN NoIntermediateBuffering;
+    BOOLEAN OpenDirectory;
+    BOOLEAN IsPagingFile;
+    BOOLEAN OpenTargetDirectory;
+    BOOLEAN DirectoryFile;
+    BOOLEAN NonDirectoryFile;
+    BOOLEAN NoEaKnowledge;
+    BOOLEAN DeleteOnClose;
+    BOOLEAN TemporaryFile;
+    ULONG CreateDisposition;
+
+    /* Control blocks */
+    PVCB Vcb;
+
+    /* IRP data */
+    PFILE_OBJECT FileObject;
+    PFILE_OBJECT RelatedFO;
+    UNICODE_STRING FileName;
+    ULONG AllocationSize;
+    PFILE_FULL_EA_INFORMATION EaBuffer;
+    PACCESS_MASK DesiredAccess;
+    ULONG Options;
+    UCHAR FileAttributes;
+    USHORT ShareAccess;
+    ULONG EaLength;
+
+    /* Misc */
+    //NTSTATUS Status;
+    IO_STATUS_BLOCK Iosb;
+    PIO_STACK_LOCATION IrpSp;
+
+    /* Get current IRP stack location */
+    IrpSp = IoGetCurrentIrpStackLocation(Irp);
+
+    DPRINT1("FatCommonCreate\n", 0 );
+    DPRINT1("Irp                       = %08lx\n",   Irp );
+    DPRINT1("\t->Flags                   = %08lx\n", Irp->Flags );
+    DPRINT1("\t->FileObject              = %08lx\n", IrpSp->FileObject );
+    DPRINT1("\t->RelatedFileObject       = %08lx\n", IrpSp->FileObject->RelatedFileObject );
+    DPRINT1("\t->FileName                = %wZ\n",   &IrpSp->FileObject->FileName );
+    DPRINT1("\t->AllocationSize.LowPart  = %08lx\n", Irp->Overlay.AllocationSize.LowPart );
+    DPRINT1("\t->AllocationSize.HighPart = %08lx\n", Irp->Overlay.AllocationSize.HighPart );
+    DPRINT1("\t->SystemBuffer            = %08lx\n", Irp->AssociatedIrp.SystemBuffer );
+    DPRINT1("\t->DesiredAccess           = %08lx\n", IrpSp->Parameters.Create.SecurityContext->DesiredAccess );
+    DPRINT1("\t->Options                 = %08lx\n", IrpSp->Parameters.Create.Options );
+    DPRINT1("\t->FileAttributes          = %04x\n",  IrpSp->Parameters.Create.FileAttributes );
+    DPRINT1("\t->ShareAccess             = %04x\n",  IrpSp->Parameters.Create.ShareAccess );
+    DPRINT1("\t->EaLength                = %08lx\n", IrpSp->Parameters.Create.EaLength );
+
+    /* Apply a special hack for Win32, idea taken from FASTFAT reference driver from WDK */
+    if ((IrpSp->FileObject->FileName.Length > sizeof(WCHAR)) &&
+        (IrpSp->FileObject->FileName.Buffer[1] == L'\\') &&
+        (IrpSp->FileObject->FileName.Buffer[0] == L'\\'))
+    {
+        /* Remove two leading slashes */
+        IrpSp->FileObject->FileName.Length -= sizeof(WCHAR);
+
+        RtlMoveMemory(&IrpSp->FileObject->FileName.Buffer[0],
+                      &IrpSp->FileObject->FileName.Buffer[1],
+                      IrpSp->FileObject->FileName.Length );
+
+        /* If there are two leading slashes again, exit */
+        if ((IrpSp->FileObject->FileName.Length > sizeof(WCHAR)) &&
+            (IrpSp->FileObject->FileName.Buffer[1] == L'\\') &&
+            (IrpSp->FileObject->FileName.Buffer[0] == L'\\'))
+        {
+            FatCompleteRequest( IrpContext, Irp, STATUS_OBJECT_NAME_INVALID );
+
+            DPRINT1("FatiCreate: STATUS_OBJECT_NAME_INVALID\n");
+            return STATUS_OBJECT_NAME_INVALID;
+        }
+    }
+
+    /* Make sure we have SecurityContext */
+    ASSERT(IrpSp->Parameters.Create.SecurityContext != NULL);
+
+    /* Get necessary data out of IRP */
+    FileObject     = IrpSp->FileObject;
+    FileName       = FileObject->FileName;
+    RelatedFO      = FileObject->RelatedFileObject;
+    AllocationSize = Irp->Overlay.AllocationSize.LowPart;
+    EaBuffer       = Irp->AssociatedIrp.SystemBuffer;
+    DesiredAccess  = &IrpSp->Parameters.Create.SecurityContext->DesiredAccess;
+    Options        = IrpSp->Parameters.Create.Options;
+    FileAttributes = (UCHAR)(IrpSp->Parameters.Create.FileAttributes & ~FILE_ATTRIBUTE_NORMAL);
+    ShareAccess    = IrpSp->Parameters.Create.ShareAccess;
+    EaLength       = IrpSp->Parameters.Create.EaLength;
+
+    /* Set VPB to related object's VPB if it exists */
+    if (RelatedFO)
+        FileObject->Vpb = RelatedFO->Vpb;
+
+    /* Prepare file attributes mask */
+    FileAttributes &= (FILE_ATTRIBUTE_READONLY |
+                       FILE_ATTRIBUTE_HIDDEN   |
+                       FILE_ATTRIBUTE_SYSTEM   |
+                       FILE_ATTRIBUTE_ARCHIVE);
+
+    /* Get the volume control object */
+    Vcb = &((PVOLUME_DEVICE_OBJECT)IrpSp->DeviceObject)->Vcb;
+
+    /* Get options */
+    DirectoryFile           = BooleanFlagOn(Options, FILE_DIRECTORY_FILE);
+    NonDirectoryFile        = BooleanFlagOn(Options, FILE_NON_DIRECTORY_FILE);
+    SequentialOnly          = BooleanFlagOn(Options, FILE_SEQUENTIAL_ONLY);
+    NoIntermediateBuffering = BooleanFlagOn(Options, FILE_NO_INTERMEDIATE_BUFFERING);
+    NoEaKnowledge           = BooleanFlagOn(Options, FILE_NO_EA_KNOWLEDGE);
+    DeleteOnClose           = BooleanFlagOn(Options, FILE_DELETE_ON_CLOSE);
+    TemporaryFile           = BooleanFlagOn(IrpSp->Parameters.Create.FileAttributes,
+                                            FILE_ATTRIBUTE_TEMPORARY );
+    IsPagingFile            = BooleanFlagOn(IrpSp->Flags, SL_OPEN_PAGING_FILE);
+    OpenTargetDirectory     = BooleanFlagOn(IrpSp->Flags, SL_OPEN_TARGET_DIRECTORY);
+
+    /* Calculate create disposition */
+    CreateDisposition = (Options >> 24) & 0x000000ff;
+
+    /* Get Create/Open directory flags based on it */
+    CreateDirectory = (BOOLEAN)(DirectoryFile &&
+                                ((CreateDisposition == FILE_CREATE) ||
+                                 (CreateDisposition == FILE_OPEN_IF)));
+
+    OpenDirectory   = (BOOLEAN)(DirectoryFile &&
+                                ((CreateDisposition == FILE_OPEN) ||
+                                 (CreateDisposition == FILE_OPEN_IF)));
+
+    //return Iosb.Status;
+    return STATUS_SUCCESS;
+}
+
 NTSTATUS
 NTAPI
 FatCreate(PDEVICE_OBJECT DeviceObject, PIRP Irp)
 {
+    PFAT_IRP_CONTEXT IrpContext;
+    NTSTATUS Status;
+    //PVOLUME_DEVICE_OBJECT VolumeDO = (PVOLUME_DEVICE_OBJECT)DeviceObject;
+
     DPRINT1("FatCreate()\n");
-    return STATUS_NOT_IMPLEMENTED;
+
+    /* If it's called with our Disk FS device object - it's always open */
+    // TODO: Add check for CDROM FS device object
+    if (DeviceObject == FatGlobalData.DiskDeviceObject)
+    {
+        /* Complete the request and return success */
+        Irp->IoStatus.Status = STATUS_SUCCESS;
+        Irp->IoStatus.Information = FILE_OPENED;
+
+        IoCompleteRequest(Irp, IO_DISK_INCREMENT);
+
+        return STATUS_SUCCESS;
+    }
+
+    /* Enter FsRtl critical region */
+    FsRtlEnterFileSystem();
+
+    /* Build an irp context */
+    IrpContext = FatBuildIrpContext(Irp, TRUE);
+
+    /* Call internal function */
+    Status = FatiCreate(IrpContext, Irp);
+
+    /* Leave FsRtl critical region */
+    FsRtlExitFileSystem();
+
+    return Status;
 }
 
 /* EOF */