mirror of
https://github.com/reactos/reactos.git
synced 2024-07-16 17:36:12 +00:00
[fastfat_new]
- Fix wrong comment in FatiCreate, spotted by Ged Murphy. - Add some parameters validation to FatiCreate, and a check for volume open request. - Add node types and a decoding routine. - Implement VCB locking/unlocking. svn path=/trunk/; revision=43202
This commit is contained in:
parent
eaf6203af2
commit
dfe3bd48b3
|
@ -33,7 +33,9 @@ FatiCreate(IN PFAT_IRP_CONTEXT IrpContext,
|
|||
ULONG CreateDisposition;
|
||||
|
||||
/* Control blocks */
|
||||
PVCB Vcb;
|
||||
PVCB Vcb, DecodedVcb;
|
||||
PFCB Fcb;
|
||||
PCCB Ccb;
|
||||
|
||||
/* IRP data */
|
||||
PFILE_OBJECT FileObject;
|
||||
|
@ -48,8 +50,8 @@ FatiCreate(IN PFAT_IRP_CONTEXT IrpContext,
|
|||
ULONG EaLength;
|
||||
|
||||
/* Misc */
|
||||
//NTSTATUS Status;
|
||||
IO_STATUS_BLOCK Iosb;
|
||||
NTSTATUS Status;
|
||||
//IO_STATUS_BLOCK Iosb;
|
||||
PIO_STACK_LOCATION IrpSp;
|
||||
|
||||
/* Get current IRP stack location */
|
||||
|
@ -75,14 +77,14 @@ FatiCreate(IN PFAT_IRP_CONTEXT IrpContext,
|
|||
(IrpSp->FileObject->FileName.Buffer[1] == L'\\') &&
|
||||
(IrpSp->FileObject->FileName.Buffer[0] == L'\\'))
|
||||
{
|
||||
/* Remove two leading slashes */
|
||||
/* Remove a leading slash */
|
||||
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 */
|
||||
/* Check again: if there are still two leading slashes,
|
||||
exit with an error */
|
||||
if ((IrpSp->FileObject->FileName.Length > sizeof(WCHAR)) &&
|
||||
(IrpSp->FileObject->FileName.Buffer[1] == L'\\') &&
|
||||
(IrpSp->FileObject->FileName.Buffer[0] == L'\\'))
|
||||
|
@ -146,6 +148,55 @@ FatiCreate(IN PFAT_IRP_CONTEXT IrpContext,
|
|||
((CreateDisposition == FILE_OPEN) ||
|
||||
(CreateDisposition == FILE_OPEN_IF)));
|
||||
|
||||
/* Validate parameters: directory/nondirectory mismatch and
|
||||
AllocationSize being more than 4GB */
|
||||
if ((DirectoryFile && NonDirectoryFile) ||
|
||||
Irp->Overlay.AllocationSize.HighPart != 0)
|
||||
{
|
||||
FatCompleteRequest(IrpContext, Irp, STATUS_INVALID_PARAMETER);
|
||||
|
||||
DPRINT1("FatiCreate: STATUS_INVALID_PARAMETER\n", 0);
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
/* Acquire the VCB lock exclusively */
|
||||
if (!FatAcquireExclusiveVcb(IrpContext, Vcb))
|
||||
{
|
||||
// TODO: Postpone the IRP for later processing
|
||||
ASSERT(FALSE);
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
// TODO: Verify the VCB
|
||||
|
||||
/* If VCB is locked, then no file openings are possible */
|
||||
if (Vcb->State & VCB_STATE_FLAG_LOCKED)
|
||||
{
|
||||
DPRINT1("This volume is locked\n");
|
||||
Status = STATUS_ACCESS_DENIED;
|
||||
|
||||
/* Cleanup and return */
|
||||
FatReleaseVcb(IrpContext, Vcb);
|
||||
return Status;
|
||||
}
|
||||
|
||||
// TODO: Check if the volume is write protected and disallow DELETE_ON_CLOSE
|
||||
|
||||
// TODO: Make sure EAs aren't supported on FAT32
|
||||
|
||||
if (FileName.Length == 0)
|
||||
{
|
||||
/* It is a volume open request, check related FO to be sure */
|
||||
|
||||
if (!RelatedFO ||
|
||||
FatDecodeFileObject(RelatedFO, &DecodedVcb, &Fcb, &Ccb) == UserVolumeOpen)
|
||||
{
|
||||
/* It is indeed a volume open request */
|
||||
DPRINT1("Volume open request, not implemented now!\n");
|
||||
UNIMPLEMENTED;
|
||||
}
|
||||
}
|
||||
|
||||
//return Iosb.Status;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -271,4 +271,99 @@ FatQueueRequest(IN PFAT_IRP_CONTEXT IrpContext,
|
|||
ExQueueWorkItem(&IrpContext->WorkQueueItem,
|
||||
DelayedWorkQueue);
|
||||
}
|
||||
|
||||
TYPE_OF_OPEN
|
||||
NTAPI
|
||||
FatDecodeFileObject(IN PFILE_OBJECT FileObject,
|
||||
OUT PVCB *Vcb,
|
||||
OUT PFCB *FcbOrDcb,
|
||||
OUT PCCB *Ccb)
|
||||
{
|
||||
TYPE_OF_OPEN TypeOfOpen = UnopenedFileObject;
|
||||
PVOID FsContext = FileObject->FsContext;
|
||||
PVOID FsContext2 = FileObject->FsContext2;
|
||||
|
||||
/* If FsContext is NULL, then everything is NULL */
|
||||
if (!FsContext)
|
||||
{
|
||||
*Ccb = NULL;
|
||||
*FcbOrDcb = NULL;
|
||||
*Vcb = NULL;
|
||||
|
||||
return TypeOfOpen;
|
||||
}
|
||||
|
||||
/* CCB is always stored in FsContext2 */
|
||||
*Ccb = FsContext2;
|
||||
|
||||
/* Switch according to the NodeType */
|
||||
switch (FatNodeType(FsContext))
|
||||
{
|
||||
/* Volume */
|
||||
case FAT_NTC_VCB:
|
||||
*FcbOrDcb = NULL;
|
||||
*Vcb = FsContext;
|
||||
|
||||
TypeOfOpen = ( *Ccb == NULL ? VirtualVolumeFile : UserVolumeOpen );
|
||||
|
||||
break;
|
||||
|
||||
/* Root or normal directory*/
|
||||
case FAT_NTC_ROOT_DCB:
|
||||
case FAT_NTC_DCB:
|
||||
*FcbOrDcb = FsContext;
|
||||
*Vcb = (*FcbOrDcb)->Vcb;
|
||||
|
||||
TypeOfOpen = (*Ccb == NULL ? DirectoryFile : UserDirectoryOpen);
|
||||
|
||||
DPRINT1("Referencing a directory: %Z\n", &(*FcbOrDcb)->FullFileName);
|
||||
break;
|
||||
|
||||
/* File */
|
||||
case FAT_NTC_FCB:
|
||||
*FcbOrDcb = FsContext;
|
||||
*Vcb = (*FcbOrDcb)->Vcb;
|
||||
|
||||
TypeOfOpen = (*Ccb == NULL ? EaFile : UserFileOpen);
|
||||
|
||||
DPRINT1("Referencing a file: %Z\n", &(*FcbOrDcb)->FullFileName);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
DPRINT1("Unknown node type %x\n", FatNodeType(FsContext));
|
||||
ASSERT(FALSE);
|
||||
}
|
||||
|
||||
return TypeOfOpen;
|
||||
}
|
||||
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
FatAcquireExclusiveVcb(IN PFAT_IRP_CONTEXT IrpContext,
|
||||
IN PVCB Vcb)
|
||||
{
|
||||
/* Acquire VCB's resource if possible */
|
||||
if (ExAcquireResourceExclusiveLite(&Vcb->Resource,
|
||||
BooleanFlagOn(IrpContext->Flags, IRPCONTEXT_CANWAIT)))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
FatReleaseVcb(IN PFAT_IRP_CONTEXT IrpContext,
|
||||
IN PVCB Vcb)
|
||||
{
|
||||
/* Release VCB's resource */
|
||||
ExReleaseResourceLite(&Vcb->Resource);
|
||||
}
|
||||
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -132,6 +132,20 @@ FatCompleteRequest(PFAT_IRP_CONTEXT IrpContext OPTIONAL,
|
|||
PIRP Irp OPTIONAL,
|
||||
NTSTATUS Status);
|
||||
|
||||
BOOLEAN NTAPI
|
||||
FatAcquireExclusiveVcb(IN PFAT_IRP_CONTEXT IrpContext,
|
||||
IN PVCB Vcb);
|
||||
|
||||
VOID NTAPI
|
||||
FatReleaseVcb(IN PFAT_IRP_CONTEXT IrpContext,
|
||||
IN PVCB Vcb);
|
||||
|
||||
TYPE_OF_OPEN
|
||||
NTAPI
|
||||
FatDecodeFileObject(IN PFILE_OBJECT FileObject,
|
||||
OUT PVCB *Vcb,
|
||||
OUT PFCB *FcbOrDcb,
|
||||
OUT PCCB *Ccb);
|
||||
|
||||
/* --------------------------------------------------------- lock.c */
|
||||
|
||||
|
|
|
@ -489,6 +489,12 @@ FatInitializeVcb(IN PFAT_IRP_CONTEXT IrpContext,
|
|||
Vcb->Header.ValidDataLength.HighPart = MAXLONG;
|
||||
Vcb->Header.ValidDataLength.LowPart = MAXULONG;
|
||||
|
||||
/* Set VCB to a good condition */
|
||||
Vcb->Condition = VcbGood;
|
||||
|
||||
/* Initialize VCB's resource */
|
||||
ExInitializeResourceLite(&Vcb->Resource);
|
||||
|
||||
/* Initialize CC */
|
||||
CcInitializeCacheMap(Vcb->StreamFileObject,
|
||||
(PCC_FILE_SIZES)&Vcb->Header.AllocationSize,
|
||||
|
|
|
@ -8,6 +8,18 @@ typedef PVOID PBCB;
|
|||
|
||||
typedef NTSTATUS (*PFAT_OPERATION_HANDLER) (PFAT_IRP_CONTEXT);
|
||||
|
||||
/* Node type stuff */
|
||||
typedef CSHORT FAT_NODE_TYPE;
|
||||
typedef FAT_NODE_TYPE *PFAT_NODE_TYPE;
|
||||
|
||||
#define FatNodeType(Ptr) (*((PFAT_NODE_TYPE)(Ptr)))
|
||||
|
||||
/* Node type codes */
|
||||
#define FAT_NTC_VCB (CSHORT) '00VF'
|
||||
#define FAT_NTC_FCB (CSHORT) 'CF'
|
||||
#define FAT_NTC_DCB (CSHORT) 'DF'
|
||||
#define FAT_NTC_ROOT_DCB (CSHORT) 'RFD'
|
||||
|
||||
typedef struct _FAT_GLOBAL_DATA
|
||||
{
|
||||
ERESOURCE Resource;
|
||||
|
@ -116,7 +128,14 @@ typedef struct _FAT_METHODS {
|
|||
PFAT_SETFAT_VALUE_RUN_ROUTINE SetValueRun;
|
||||
} FAT_METHODS, *PFAT_METHODS;
|
||||
|
||||
#define FAT_NTC_VCB (USHORT) '00VF'
|
||||
#define VCB_STATE_FLAG_LOCKED 0x01
|
||||
|
||||
typedef enum _VCB_CONDITION
|
||||
{
|
||||
VcbGood,
|
||||
VcbNotMounted,
|
||||
VcbBad
|
||||
} VCB_CONDITION;
|
||||
|
||||
/* Volume Control Block */
|
||||
typedef struct _VCB
|
||||
|
@ -129,6 +148,9 @@ typedef struct _VCB
|
|||
PDEVICE_OBJECT TargetDeviceObject;
|
||||
LIST_ENTRY VcbLinks;
|
||||
PVPB Vpb;
|
||||
ULONG State;
|
||||
VCB_CONDITION Condition;
|
||||
ERESOURCE Resource;
|
||||
|
||||
/* Notifications support */
|
||||
PNOTIFY_SYNC NotifySync;
|
||||
|
@ -196,9 +218,6 @@ typedef struct _FCB_NAME_LINK {
|
|||
UCHAR Type;
|
||||
} FCB_NAME_LINK, *PFCB_NAME_LINK;
|
||||
|
||||
#define FAT_NTC_FCB (USHORT) 'CF'
|
||||
#define FAT_NTC_DCB (USHORT) 'DF'
|
||||
|
||||
typedef struct _FCB
|
||||
{
|
||||
FSRTL_ADVANCED_FCB_HEADER Header;
|
||||
|
@ -225,6 +244,8 @@ typedef struct _FCB
|
|||
FCB_NAME_LINK FileName[0x2];
|
||||
/* Buffer for the short name */
|
||||
WCHAR ShortNameBuffer[0xc];
|
||||
/* Full file name */
|
||||
UNICODE_STRING FullFileName;
|
||||
/* File basic info */
|
||||
FILE_BASIC_INFORMATION BasicInfo;
|
||||
union
|
||||
|
@ -285,6 +306,16 @@ typedef struct _CCB
|
|||
UCHAR Flags;
|
||||
} CCB, *PCCB;
|
||||
|
||||
typedef enum _TYPE_OF_OPEN
|
||||
{
|
||||
UnopenedFileObject,
|
||||
UserFileOpen,
|
||||
UserDirectoryOpen,
|
||||
UserVolumeOpen,
|
||||
VirtualVolumeFile,
|
||||
DirectoryFile,
|
||||
EaFile
|
||||
} TYPE_OF_OPEN;
|
||||
|
||||
#define CCB_SEARCH_RETURN_SINGLE_ENTRY 0x01
|
||||
#define CCB_SEARCH_PATTERN_LEGAL_8DOT3 0x02
|
||||
|
|
Loading…
Reference in a new issue