create.c
来自「This is a ReiserFs file system driver fo」· C语言 代码 · 共 1,522 行 · 第 1/4 页
C
1,522 行
if (IsFlagOn(Fcb->Flags, FCB_FILE_DELETED)) {
Status = STATUS_FILE_DELETED;
__leave;
}
if (FlagOn(Fcb->Flags, FCB_DELETE_PENDING)) {
Status = STATUS_DELETE_PENDING;
__leave;
}
if (bCreated) {
DbgBreak();
#if DISABLED // ONLY FOR WRITE SUPPORT?
//
// This file is just created.
//
if (DirectoryFile) {
UNICODE_STRING EntryName;
USHORT NameBuf[6];
RtlZeroMemory(&NameBuf, 6 * sizeof(USHORT));
EntryName.Length = EntryName.MaximumLength = 2;
EntryName.Buffer = &NameBuf[0];
NameBuf[0] = (USHORT)'.';
RfsdAddEntry( IrpContext, Vcb, Fcb,
RFSD_FT_DIR,
Fcb->RfsdMcb->Key,
&EntryName );
RfsdSaveInode( IrpContext, Vcb,
Fcb->RfsdMcb->Key,
Fcb->Inode );
EntryName.Length = EntryName.MaximumLength = 4;
EntryName.Buffer = &NameBuf[0];
NameBuf[0] = NameBuf[1] = (USHORT)'.';
RfsdAddEntry( IrpContext, Vcb, Fcb,
RFSD_FT_DIR,
Fcb->RfsdMcb->Parent->Inode,
&EntryName );
RfsdSaveInode( IrpContext, Vcb,
Fcb->RfsdMcb->Parent->Inode,
ParentFcb->Inode );
} else {
DbgBreak();
#if DISABLED
Status = RfsdExpandFile(
IrpContext, Vcb, Fcb,
&(Irp->Overlay.AllocationSize));
#endif
if (!NT_SUCCESS(Status)) {
DbgBreak();
__leave;
}
}
#endif
} else {
//
// This file alreayd exists.
//
if (DeleteOnClose) {
if (IsFlagOn(Vcb->Flags, VCB_READ_ONLY)) {
Status = STATUS_MEDIA_WRITE_PROTECTED;
__leave;
}
if (IsFlagOn(Vcb->Flags, VCB_WRITE_PROTECTED)) {
Status = STATUS_MEDIA_WRITE_PROTECTED;
IoSetHardErrorOrVerifyDevice( IrpContext->Irp,
Vcb->Vpb->RealDevice );
SetFlag(Vcb->Vpb->RealDevice->Flags, DO_VERIFY_VOLUME);
RfsdRaiseStatus(IrpContext, STATUS_MEDIA_WRITE_PROTECTED);
}
SetFlag(Fcb->Flags, FCB_DELETE_ON_CLOSE);
} else {
//
// Just to Open file (Open/OverWrite ...)
//
if ((!IsDirectory(Fcb)) && (IsFlagOn(IrpSp->FileObject->Flags,
FO_NO_INTERMEDIATE_BUFFERING))) {
Fcb->Header.IsFastIoPossible = FastIoIsPossible;
if (IsFlagOn(IrpSp->FileObject->Flags, FO_CACHE_SUPPORTED) &&
(Fcb->SectionObject.DataSectionObject != NULL)) {
if (Fcb->NonCachedOpenCount == Fcb->OpenHandleCount) {
/* IsFlagOn(FileObject->Flags, FO_FILE_MODIFIED) */
if(!IsFlagOn(Vcb->Flags, VCB_READ_ONLY)) {
CcFlushCache(&Fcb->SectionObject, NULL, 0, NULL);
ClearFlag(Fcb->Flags, FCB_FILE_MODIFIED);
}
CcPurgeCacheSection(&Fcb->SectionObject,
NULL,
0,
FALSE );
}
}
}
}
}
if (!IsDirectory(Fcb)) {
if (!IsFlagOn(Vcb->Flags, VCB_READ_ONLY)) {
if ((CreateDisposition == FILE_SUPERSEDE) && !IsPagingFile){
DesiredAccess |= DELETE;
} else if (((CreateDisposition == FILE_OVERWRITE) ||
(CreateDisposition == FILE_OVERWRITE_IF)) && !IsPagingFile) {
DesiredAccess |= (FILE_WRITE_DATA | FILE_WRITE_EA |
FILE_WRITE_ATTRIBUTES );
}
}
}
if (Fcb->OpenHandleCount > 0) {
Status = IoCheckShareAccess( DesiredAccess,
ShareAccess,
IrpSp->FileObject,
&(Fcb->ShareAccess),
TRUE );
if (!NT_SUCCESS(Status)) {
__leave;
}
} else {
IoSetShareAccess( DesiredAccess,
ShareAccess,
IrpSp->FileObject,
&(Fcb->ShareAccess) );
}
Ccb = RfsdAllocateCcb();
Fcb->OpenHandleCount++;
Fcb->ReferenceCount++;
if (IsFlagOn(IrpSp->FileObject->Flags, FO_NO_INTERMEDIATE_BUFFERING)) {
Fcb->NonCachedOpenCount++;
}
Vcb->OpenFileHandleCount++;
Vcb->ReferenceCount++;
IrpSp->FileObject->FsContext = (void*)Fcb;
IrpSp->FileObject->FsContext2 = (void*) Ccb;
IrpSp->FileObject->PrivateCacheMap = NULL;
IrpSp->FileObject->SectionObjectPointer = &(Fcb->SectionObject);
IrpSp->FileObject->Vpb = Vcb->Vpb;
Status = STATUS_SUCCESS;
RfsdPrint((DBG_INFO, "RfsdCreateFile: %s OpenCount: %u ReferCount: %u\n",
Fcb->AnsiFileName.Buffer, Fcb->OpenHandleCount, Fcb->ReferenceCount));
if (!IsDirectory(Fcb) && !NoIntermediateBuffering ) {
IrpSp->FileObject->Flags |= FO_CACHE_SUPPORTED;
}
if (!bCreated && !IsDirectory(Fcb)) {
if ( DeleteOnClose ||
IsFlagOn(DesiredAccess, FILE_WRITE_DATA) ||
(CreateDisposition == FILE_OVERWRITE) ||
(CreateDisposition == FILE_OVERWRITE_IF)) {
if (!MmFlushImageSection( &Fcb->SectionObject,
MmFlushForWrite )) {
Status = DeleteOnClose ? STATUS_CANNOT_DELETE :
STATUS_SHARING_VIOLATION;
__leave;
}
}
if ((CreateDisposition == FILE_SUPERSEDE) ||
(CreateDisposition == FILE_OVERWRITE) ||
(CreateDisposition == FILE_OVERWRITE_IF)) {
#if RFSD_READ_ONLY
Status = STATUS_MEDIA_WRITE_PROTECTED;
__leave;
#endif
#if DISABLED
if (IsFlagOn(Vcb->Flags, VCB_READ_ONLY)) {
Status = STATUS_MEDIA_WRITE_PROTECTED;
__leave;
}
if (IsFlagOn(Vcb->Flags, VCB_WRITE_PROTECTED)) {
IoSetHardErrorOrVerifyDevice( IrpContext->Irp,
Vcb->Vpb->RealDevice );
SetFlag(Vcb->Vpb->RealDevice->Flags, DO_VERIFY_VOLUME);
RfsdRaiseStatus(IrpContext, STATUS_MEDIA_WRITE_PROTECTED);
}
Status = RfsdSupersedeOrOverWriteFile( IrpContext,
Vcb,
Fcb,
CreateDisposition );
if (NT_SUCCESS(Status)) {
__leave;
}
DbgBreak();
#if DISABLED
Status = RfsdExpandFile(
IrpContext,
Vcb,
Fcb,
&(Irp->Overlay.AllocationSize));
#endif
if (!(NT_SUCCESS(Status))) {
__leave;
}
DbgBreak();
#if DISABLED // dirctl.c
RfsdNotifyReportChange(
IrpContext,
Vcb,
Fcb,
FILE_NOTIFY_CHANGE_LAST_WRITE |
FILE_NOTIFY_CHANGE_ATTRIBUTES |
FILE_NOTIFY_CHANGE_SIZE,
FILE_ACTION_MODIFIED );
#endif
if (CreateDisposition == FILE_SUPERSEDE) {
Irp->IoStatus.Information = FILE_SUPERSEDED;
} else {
Irp->IoStatus.Information = FILE_OVERWRITTEN;
}
#endif
}
}
}
} __finally {
if (FileName.Buffer)
ExFreePool(FileName.Buffer);
if (bParentFcbCreated) {
ParentFcb->ReferenceCount--;
}
if (VcbResourceAcquired) {
ExReleaseResourceForThreadLite(
&Vcb->MainResource,
ExGetCurrentResourceThread() );
}
if (!bFcbAllocated) {
if (Inode)
ExFreePool(Inode);
} else {
if (!Fcb && Inode)
ExFreePool(Inode);
}
}
return Status;
}
NTSTATUS
RfsdCreateVolume(PRFSD_IRP_CONTEXT IrpContext, PRFSD_VCB Vcb)
{
PIO_STACK_LOCATION IrpSp;
PIRP Irp;
NTSTATUS Status;
ACCESS_MASK DesiredAccess;
ULONG ShareAccess;
ULONG Options;
BOOLEAN DirectoryFile;
BOOLEAN OpenTargetDirectory;
ULONG CreateDisposition;
RfsdPrint((DBG_FUNC, "Entering CreateVolume\n"));
Irp = IrpContext->Irp;
IrpSp = IoGetCurrentIrpStackLocation(Irp);
Options = IrpSp->Parameters.Create.Options;
DirectoryFile = IsFlagOn(Options, FILE_DIRECTORY_FILE);
OpenTargetDirectory = IsFlagOn(IrpSp->Flags, SL_OPEN_TARGET_DIRECTORY);
CreateDisposition = (Options >> 24) & 0x000000ff;
DesiredAccess = IrpSp->Parameters.Create.SecurityContext->DesiredAccess;
ShareAccess = IrpSp->Parameters.Create.ShareAccess;
if (DirectoryFile) {
return STATUS_NOT_A_DIRECTORY;
}
if (OpenTargetDirectory) {
return STATUS_INVALID_PARAMETER;
}
if ( (CreateDisposition != FILE_OPEN) &&
(CreateDisposition != FILE_OPEN_IF) ) {
return STATUS_ACCESS_DENIED;
}
Status = STATUS_SUCCESS;
if (Vcb->OpenHandleCount > 0) {
Status = IoCheckShareAccess( DesiredAccess, ShareAccess,
IrpSp->FileObject,
&(Vcb->ShareAccess), TRUE);
if (!NT_SUCCESS(Status)) {
goto errorout;
}
} else {
IoSetShareAccess( DesiredAccess, ShareAccess,
IrpSp->FileObject,
&(Vcb->ShareAccess) );
}
if (FlagOn(DesiredAccess, FILE_READ_DATA | FILE_WRITE_DATA | FILE_APPEND_DATA)) {
ExAcquireResourceExclusive(&Vcb->MainResource, TRUE);
RfsdFlushFiles(Vcb, FALSE);
RfsdFlushVolume(Vcb, FALSE);
ExReleaseResource(&Vcb->MainResource);
}
{
PRFSD_CCB Ccb = RfsdAllocateCcb();
if (Ccb == NULL) {
Status = STATUS_INSUFFICIENT_RESOURCES;
goto errorout;
}
IrpSp->FileObject->Flags |= FO_NO_INTERMEDIATE_BUFFERING;
IrpSp->FileObject->FsContext = Vcb;
IrpSp->FileObject->FsContext2 = Ccb;
Vcb->ReferenceCount++;
Vcb->OpenHandleCount++;
Irp->IoStatus.Information = FILE_OPENED;
}
errorout:
return Status;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?