⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 create.c

📁 FSD file system driver
💻 C
📖 第 1 页 / 共 3 页
字号:
							&InodeFileName,
							TRUE))
				{
					bFound = TRUE;
					*Index = dwBytes;
					RtlCopyMemory(ffs_dir, pDir, pDir->d_reclen > sizeof(FFS_DIR_ENTRY)
							? sizeof(FFS_DIR_ENTRY) : pDir->d_reclen);
					Status = STATUS_SUCCESS;

					FFSPrint((DBG_VITAL, "FFSv2ScanDir: Found: Name=%S Inode=%xh\n", InodeFileName.Buffer, pDir->d_ino));
				}

				dwBytes +=pDir->d_reclen;
				Offset = (LONGLONG)dwBytes;
			}
			else
			{
				if (pDir->d_ino == 0)
				{
					if (pDir->d_reclen == 0)
					{
						FFSBreakPoint();
						break;
					}
					else
					{
						dwBytes +=pDir->d_reclen;
						Offset = (LONGLONG)dwBytes;
					}
				}
				else
				{
					break;
				}
			}
		}

		if (!bFound)
		{
			Status = STATUS_NO_SUCH_FILE;
		}
	}

	__finally
	{
		if (InodeFileName.Buffer != NULL)
		{
			ExFreePool(InodeFileName.Buffer);
		}

		if (pDir)
			ExFreePool(pDir);
	}

	return Status;
}


/*
PFFS_FCB
FFSSearchFcbList(
	IN PFFS_VCB     Vcb,
	IN ULONG        inode)
{
	BOOLEAN             bFound = FALSE;
	PLIST_ENTRY         Link;
	PFFS_FCB            TmpFcb;

	Link = Vcb->FcbList.Flink;

	while (!bFound && Link != &Vcb->FcbList)
	{
		TmpFcb = CONTAINING_RECORD(Link, FFS_FCB, Next);

		if (TmpFcb && TmpFcb->Identifier.Type == FCB)
		{
#if DBG
			FFSPrint((DBG_INFO, "FFSSearchFcbList: [%s,%xh]\n", 
				TmpFcb->AnsiFileName.Buffer, TmpFcb->Inode));
#endif          
			if (TmpFcb->Inode == inode)
			{
				FFSPrint((DBG_INFO, "FFSSearchMcb: Found FCB for %xh.\n", inode));
				bFound = TRUE;
			}
		}
		Link = Link->Flink;
	}

	if (bFound)
		return TmpFcb;
	else
		return NULL;

}
*/

NTSTATUS
FFSCreateFile(
	PFFS_IRP_CONTEXT IrpContext,
	PFFS_VCB         Vcb)
{
	NTSTATUS            Status = STATUS_UNSUCCESSFUL;
	PIO_STACK_LOCATION  IrpSp;
	PFFS_FCB            Fcb = NULL;
	PFFS_MCB            FFSMcb = NULL;

	PFFS_FCB            ParentFcb = NULL;
	PFFS_MCB            ParentMcb = NULL;

	BOOLEAN             bParentFcbCreated = FALSE;

	PFFS_CCB            Ccb = NULL;
	PFFSv1_INODE        dinode1;
	PFFSv2_INODE        dinode2;
	BOOLEAN             VcbResourceAcquired = FALSE;
	BOOLEAN             bDir = FALSE;
	BOOLEAN             bFcbAllocated = FALSE;
	BOOLEAN             bCreated = FALSE;
	UNICODE_STRING      FileName;
	PIRP                Irp;

	ULONG               Options;
	ULONG               CreateDisposition;

	BOOLEAN             OpenDirectory;
	BOOLEAN             OpenTargetDirectory;
	BOOLEAN             CreateDirectory;
	BOOLEAN             SequentialOnly;
	BOOLEAN             NoIntermediateBuffering;
	BOOLEAN             IsPagingFile;
	BOOLEAN             DirectoryFile;
	BOOLEAN             NonDirectoryFile;
	BOOLEAN             NoEaKnowledge;
	BOOLEAN             DeleteOnClose;
	BOOLEAN             TemporaryFile;
	BOOLEAN             CaseSensitive;

	ACCESS_MASK         DesiredAccess;
	ULONG               ShareAccess;


	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);

	NonDirectoryFile = IsFlagOn(Options, FILE_NON_DIRECTORY_FILE);
	SequentialOnly = IsFlagOn(Options, FILE_SEQUENTIAL_ONLY);
	NoIntermediateBuffering = IsFlagOn(Options, FILE_NO_INTERMEDIATE_BUFFERING);
	NoEaKnowledge = IsFlagOn(Options, FILE_NO_EA_KNOWLEDGE);
	DeleteOnClose = IsFlagOn(Options, FILE_DELETE_ON_CLOSE);

	CaseSensitive = IsFlagOn(IrpSp->Flags, SL_CASE_SENSITIVE);

	TemporaryFile = IsFlagOn(IrpSp->Parameters.Create.FileAttributes,
			FILE_ATTRIBUTE_TEMPORARY);

	CreateDisposition = (Options >> 24) & 0x000000ff;

	IsPagingFile = IsFlagOn(IrpSp->Flags, SL_OPEN_PAGING_FILE);

	CreateDirectory = (BOOLEAN)(DirectoryFile &&
			((CreateDisposition == FILE_CREATE) ||
			 (CreateDisposition == FILE_OPEN_IF)));

	OpenDirectory   = (BOOLEAN)(DirectoryFile &&
			((CreateDisposition == FILE_OPEN) ||
			 (CreateDisposition == FILE_OPEN_IF)));

	DesiredAccess = IrpSp->Parameters.Create.SecurityContext->DesiredAccess;
	ShareAccess   = IrpSp->Parameters.Create.ShareAccess;

	FileName.Buffer = NULL;

	__try
	{
		ExAcquireResourceExclusiveLite(
				&Vcb->MainResource, TRUE);

		VcbResourceAcquired = TRUE;

		if (Irp->Overlay.AllocationSize.HighPart) 
		{
			Status = STATUS_INVALID_PARAMETER;
			__leave;
		}

		if (FS_VERSION == 1)
		{
			if (!(dinode1 = ExAllocatePoolWithTag(
							PagedPool, DINODE1_SIZE, 'EInd')))
			{
				__leave;
			}

			RtlZeroMemory(dinode1, sizeof(DINODE1_SIZE));
		}
		else
		{
			if (!(dinode2 = ExAllocatePoolWithTag(
							PagedPool, DINODE2_SIZE, 'EInd')))
			{
				__leave;
			}

			RtlZeroMemory(dinode2, sizeof(DINODE2_SIZE));
		}


		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 = (PFFS_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;
		}

		FFSPrint((DBG_INFO, "FFSCreateFile: %S (NameLen=%xh) Paging=%xh Option: %xh.\n",
					FileName.Buffer, FileName.Length, IsPagingFile, IrpSp->Parameters.Create.Options));

		if (ParentFcb)
		{
			ParentMcb = ParentFcb->FFSMcb;
		}

		if (FS_VERSION == 1)
		{
			Status = FFSv1LookupFileName(
						Vcb,
						&FileName,
						ParentMcb,
						&FFSMcb,
						dinode1);
		}
		else
		{
			Status = FFSv2LookupFileName(
						Vcb,
						&FileName,
						ParentMcb,
						&FFSMcb,
						dinode2);
		}

		if (!NT_SUCCESS(Status))
		{
			UNICODE_STRING  PathName;
			UNICODE_STRING  RealName;
			UNICODE_STRING  RemainName;

			LONG            i = 0;


			PathName = FileName;

			FFSPrint((DBG_INFO, "FFSCreateFile: File %S will be created.\n", PathName.Buffer));

			FFSMcb = 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)
			{
				PFFS_MCB   RetMcb;

				if (FS_VERSION == 1)
				{
					Status = FFSv1LookupFileName(
								Vcb,
								&RealName,
								ParentMcb,
								&RetMcb,
								dinode1);
				}
				else
				{
					Status = FFSv2LookupFileName(
								Vcb,
								&RealName,
								ParentMcb,
								&RetMcb,
								dinode2);
				}

				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->FFSFcb;

			if (!ParentFcb)
			{
				if (FS_VERSION == 1)
				{
					PFFSv1_INODE pTmpInode = ExAllocatePool(PagedPool, 
							DINODE1_SIZE);
					if (!pTmpInode)
					{
						Status = STATUS_INSUFFICIENT_RESOURCES;
						__leave;
					}

					if(!FFSv1LoadInode(Vcb, ParentMcb->Inode, pTmpInode))
					{
						Status = STATUS_OBJECT_PATH_NOT_FOUND;
						__leave;
					}

					ParentFcb = FFSv1AllocateFcb(Vcb, ParentMcb, pTmpInode);

					if (!ParentFcb)
					{
						ExFreePool(pTmpInode);
						Status = STATUS_INSUFFICIENT_RESOURCES;
						__leave;
					}
				}
				else
				{
					PFFSv2_INODE pTmpInode = ExAllocatePool(PagedPool, 
							DINODE2_SIZE);
					if (!pTmpInode)
					{
						Status = STATUS_INSUFFICIENT_RESOURCES;
						__leave;
					}

					if(!FFSv2LoadInode(Vcb, ParentMcb->Inode, pTmpInode))
					{
						Status = STATUS_OBJECT_PATH_NOT_FOUND;
						__leave;
					}

					ParentFcb = FFSv2AllocateFcb(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);

					FFSRaiseStatus(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 (ParentFcb->FFSMcb->Inode == FFS_ROOT_INO) 
					{
						if ((RealName.Length == 0x10) && 
								memcmp(RealName.Buffer, L"Recycled\0", 0x10) == 0)
						{
							SetFlag(IrpSp->Parameters.Create.FileAttributes,
									FILE_ATTRIBUTE_READONLY);
						}
					}

					Status = FFSCreateInode(
								IrpContext,
								Vcb, 
								ParentFcb,
								DT_DIR,
								IrpSp->Parameters.Create.FileAttributes,
								&RealName);
				}
				else
				{
					Status = FFSCreateInode(
								IrpContext,
								Vcb,
								ParentFcb,
								DT_REG,
								IrpSp->Parameters.Create.FileAttributes,
								&RealName);
				}

				if (NT_SUCCESS(Status))
				{
					bCreated = TRUE;

					Irp->IoStatus.Information = FILE_CREATED;

					if (FS_VERSION == 1)
					{
						Status = FFSv1LookupFileName(
									Vcb,
									&RealName,
									ParentMcb,
									&FFSMcb,
									dinode1);
					}
					else
					{
						Status = FFSv2LookupFileName(
									Vcb,
									&RealName,
									ParentMcb,
									&FFSMcb,
									dinode2);
					}

					if (NT_SUCCESS(Status))
					{
						if (DirectoryFile)
						{
							FFSNotifyReportChange(
								IrpContext,
								Vcb,
								ParentFcb,
								FILE_NOTIFY_CHANGE_DIR_NAME,
								FILE_ACTION_ADDED);
						}
						else
						{
							FFSNotifyReportChange(
								IrpContext,
								Vcb,
								ParentFcb,
								FILE_NOTIFY_CHANGE_FILE_NAME,
								FILE_ACTION_ADDED);
						}
					}
					else
					{
						FFSBreakPoint();
					}
				}
				else
				{
					FFSBreakPoint();
				}
			}
			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 = FFSMcb->ShortName.Length;

				RtlCopyMemory(IrpSp->FileObject->FileName.Buffer,
						FFSMcb->ShortName.Buffer,
						FFSMcb->ShortName.Length);

				//Let Mcb pointer to it's parent
				FFSMcb = FFSMcb->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(FFSMcb->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 (FFSMcb->Inode == FFS_ROOT_INO)
				{
					if (DeleteOnClose)
					{
						Status = STATUS_CANNOT_DELETE;
						__leave;
					}

					if (OpenTargetDirectory)
					{
						Status = STATUS_INVALID_PARAMETER;
						__leave;
					}
				}
			}

			Irp->IoStatus.Information = FILE_OPENED;
		}

Openit:

		if (FFSMcb)
		{
			Fcb = FFSMcb->FFSFcb;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -