+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;
+}
+