📄 create.c
字号:
__try {
ExAcquireResourceExclusiveLite(
&Vcb->MainResource, TRUE );
VcbResourceAcquired = TRUE;
if (Irp->Overlay.AllocationSize.HighPart) {
Status = STATUS_INVALID_PARAMETER;
__leave;
}
if (!(Inode = ExAllocatePoolWithTag (
PagedPool, sizeof(RFSD_INODE), 'EInd' ) )) {
__leave;
}
RtlZeroMemory(Inode, sizeof(RFSD_INODE));
FileName.MaximumLength = IrpSp->FileObject->FileName.MaximumLength;
FileName.Length = IrpSp->FileObject->FileName.Length;
FileName.Buffer = ExAllocatePool(PagedPool, FileName.MaximumLength);
if (!FileName.Buffer) {
Status = STATUS_INSUFFICIENT_RESOURCES;
__leave;
}
RtlZeroMemory(FileName.Buffer, FileName.MaximumLength);
RtlCopyMemory(FileName.Buffer, IrpSp->FileObject->FileName.Buffer, FileName.Length);
if (IrpSp->FileObject->RelatedFileObject) {
ParentFcb = (PRFSD_FCB)(IrpSp->FileObject->RelatedFileObject->FsContext);
}
if ((FileName.Length > sizeof(WCHAR)) &&
(FileName.Buffer[1] == L'\\') &&
(FileName.Buffer[0] == L'\\')) {
FileName.Length -= sizeof(WCHAR);
RtlMoveMemory( &FileName.Buffer[0],
&FileName.Buffer[1],
FileName.Length );
//
// Bad Name if there are still beginning backslashes.
//
if ((FileName.Length > sizeof(WCHAR)) &&
(FileName.Buffer[1] == L'\\') &&
(FileName.Buffer[0] == L'\\')) {
Status = STATUS_OBJECT_NAME_INVALID;
__leave;
}
}
if (IsFlagOn(Options, FILE_OPEN_BY_FILE_ID)) {
Status = STATUS_NOT_IMPLEMENTED;
__leave;
}
RfsdPrint((DBG_INFO, "RfsdCreateFile: %S (NameLen=%xh) Paging=%xh Option: %xh.\n",
FileName.Buffer, FileName.Length, IsPagingFile, IrpSp->Parameters.Create.Options));
if (ParentFcb) {
ParentMcb = ParentFcb->RfsdMcb;
}
Status = RfsdLookupFileName(
Vcb,
&FileName,
ParentMcb,
&RfsdMcb,
Inode );
if (!NT_SUCCESS(Status)) {
UNICODE_STRING PathName;
UNICODE_STRING RealName;
UNICODE_STRING RemainName;
LONG i = 0;
PathName = FileName;
RfsdPrint((DBG_INFO, "RfsdCreateFile: File %S will be created.\n", PathName.Buffer));
RfsdMcb = NULL;
if (PathName.Buffer[PathName.Length/2 - 1] == L'\\') {
if (DirectoryFile) {
PathName.Length -=2;
PathName.Buffer[PathName.Length/2] = 0;
} else {
Status = STATUS_NOT_A_DIRECTORY;
__leave;
}
}
if (!ParentMcb) {
if (PathName.Buffer[0] != L'\\') {
Status = STATUS_OBJECT_PATH_NOT_FOUND;
__leave;
} else {
ParentMcb = Vcb->McbTree;
}
}
Dissecting:
FsRtlDissectName(PathName, &RealName, &RemainName);
if (((RemainName.Length != 0) && (RemainName.Buffer[0] == L'\\')) ||
(RealName.Length >= 256*sizeof(WCHAR))) {
Status = STATUS_OBJECT_NAME_INVALID;
__leave;
}
if (RemainName.Length != 0) {
PRFSD_MCB RetMcb;
Status = RfsdLookupFileName (
Vcb,
&RealName,
ParentMcb,
&RetMcb,
Inode );
if (!NT_SUCCESS(Status)) {
Status = STATUS_OBJECT_PATH_NOT_FOUND;
__leave;
}
ParentMcb = RetMcb;
PathName = RemainName;
goto Dissecting;
}
if (FsRtlDoesNameContainWildCards(&RealName)) {
Status = STATUS_OBJECT_NAME_INVALID;
__leave;
}
ParentFcb = ParentMcb->RfsdFcb;
if (!ParentFcb) {
PRFSD_INODE pTmpInode = ExAllocatePool( PagedPool,
sizeof(RFSD_INODE));
if (!pTmpInode) {
Status = STATUS_INSUFFICIENT_RESOURCES;
__leave;
}
if(!RfsdLoadInode(Vcb, &(ParentMcb->Key), pTmpInode)) {
Status = STATUS_OBJECT_PATH_NOT_FOUND;
__leave;
}
ParentFcb = RfsdAllocateFcb(Vcb, ParentMcb, pTmpInode);
if (!ParentFcb) {
ExFreePool(pTmpInode);
Status = STATUS_INSUFFICIENT_RESOURCES;
__leave;
}
bParentFcbCreated = TRUE;
ParentFcb->ReferenceCount++;
}
// We need to create a new one ?
if ((CreateDisposition == FILE_CREATE ) ||
(CreateDisposition == FILE_OPEN_IF) ||
(CreateDisposition == FILE_OVERWRITE_IF)) {
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);
}
if (DirectoryFile) {
if (TemporaryFile) {
Status = STATUS_INVALID_PARAMETER;
__leave;
}
}
if (!ParentFcb) {
Status = STATUS_OBJECT_PATH_NOT_FOUND;
__leave;
}
if (DirectoryFile) {
if ( RFSD_IS_ROOT_KEY(ParentFcb->RfsdMcb->Key) ) {
if ( (RealName.Length == 0x10) &&
memcmp(RealName.Buffer, L"Recycled\0", 0x10) == 0) {
SetFlag( IrpSp->Parameters.Create.FileAttributes,
FILE_ATTRIBUTE_READONLY );
}
}
Status = STATUS_UNSUCCESSFUL;
#if DISABLED
Status = RfsdCreateInode( IrpContext,
Vcb,
ParentFcb,
RFSD_FT_DIR,
IrpSp->Parameters.Create.FileAttributes,
&RealName);
#endif
} else {
Status = STATUS_UNSUCCESSFUL;
#if DISABLED
Status = RfsdCreateInode( IrpContext,
Vcb,
ParentFcb,
RFSD_FT_REG_FILE,
IrpSp->Parameters.Create.FileAttributes,
&RealName);
#endif
}
if (NT_SUCCESS(Status)) {
bCreated = TRUE;
Irp->IoStatus.Information = FILE_CREATED;
Status = RfsdLookupFileName (
Vcb,
&RealName,
ParentMcb,
&RfsdMcb,
Inode );
if (NT_SUCCESS(Status)) {
if (DirectoryFile) {
DbgBreak();
#if DISABLED // dirctl.c [ see also in cleanup.c ]
RfsdNotifyReportChange(
IrpContext,
Vcb,
ParentFcb,
FILE_NOTIFY_CHANGE_DIR_NAME,
FILE_ACTION_ADDED );
} else {
RfsdNotifyReportChange(
IrpContext,
Vcb,
ParentFcb,
FILE_NOTIFY_CHANGE_FILE_NAME,
FILE_ACTION_ADDED );
#endif
}
} else {
DbgBreak();
}
} else {
DbgBreak();
}
} else if (OpenTargetDirectory) {
if (IsFlagOn(Vcb->Flags, VCB_READ_ONLY)) {
Status = STATUS_MEDIA_WRITE_PROTECTED;
__leave;
}
if (!ParentFcb) {
Status = STATUS_OBJECT_PATH_NOT_FOUND;
__leave;
}
RtlZeroMemory( IrpSp->FileObject->FileName.Buffer,
IrpSp->FileObject->FileName.MaximumLength);
IrpSp->FileObject->FileName.Length = RealName.Length;
RtlCopyMemory( IrpSp->FileObject->FileName.Buffer,
RealName.Buffer,
RealName.Length );
Fcb = ParentFcb;
Irp->IoStatus.Information = FILE_DOES_NOT_EXIST;
Status = STATUS_SUCCESS;
} else {
Status = STATUS_OBJECT_NAME_NOT_FOUND;
__leave;
}
} else { // File / Dir already exists.
if (OpenTargetDirectory) {
if (IsFlagOn(Vcb->Flags, VCB_READ_ONLY)) {
Status = STATUS_MEDIA_WRITE_PROTECTED;
__leave;
}
Irp->IoStatus.Information = FILE_EXISTS;
Status = STATUS_SUCCESS;
RtlZeroMemory( IrpSp->FileObject->FileName.Buffer,
IrpSp->FileObject->FileName.MaximumLength);
IrpSp->FileObject->FileName.Length = RfsdMcb->ShortName.Length;
RtlCopyMemory( IrpSp->FileObject->FileName.Buffer,
RfsdMcb->ShortName.Buffer,
RfsdMcb->ShortName.Length );
//Let Mcb pointer to it's parent
RfsdMcb = RfsdMcb->Parent;
goto Openit;
}
// We can not create if one exists
if (CreateDisposition == FILE_CREATE) {
Irp->IoStatus.Information = FILE_EXISTS;
Status = STATUS_OBJECT_NAME_COLLISION;
__leave;
}
if(IsFlagOn(RfsdMcb->FileAttr, FILE_ATTRIBUTE_DIRECTORY)) {
if ((CreateDisposition != FILE_OPEN) &&
(CreateDisposition != FILE_OPEN_IF)) {
Status = STATUS_OBJECT_NAME_COLLISION;
__leave;
}
if (NonDirectoryFile) {
Status = STATUS_FILE_IS_A_DIRECTORY;
__leave;
}
if (RFSD_IS_ROOT_KEY(RfsdMcb->Key)) {
if (DeleteOnClose) {
Status = STATUS_CANNOT_DELETE;
__leave;
}
if (OpenTargetDirectory) {
Status = STATUS_INVALID_PARAMETER;
__leave;
}
}
}
Irp->IoStatus.Information = FILE_OPENED;
}
Openit:
if (RfsdMcb) {
Fcb = RfsdMcb->RfsdFcb;
if (!Fcb) {
Fcb = RfsdAllocateFcb (Vcb, RfsdMcb, Inode);
bFcbAllocated = TRUE;
}
}
if (Fcb) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -