[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:
Aleksey Bragin 2009-09-28 10:43:27 +00:00
parent eaf6203af2
commit dfe3bd48b3
5 changed files with 207 additions and 10 deletions

View file

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

View file

@ -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 */

View file

@ -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 */

View file

@ -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,

View file

@ -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