예제 #1
0
파일: memory.c 프로젝트: layerfsd/ffsfsd
PFFS_FCB
FFSv2AllocateFcb(
	IN PFFS_VCB           Vcb,
	IN PFFS_MCB           FFSMcb,
	IN PFFSv2_INODE       dinode2)
{
	PFFS_FCB Fcb;

	ExAcquireResourceExclusiveLite(
			&FFSGlobal->LAResource,
			TRUE);

	Fcb = (PFFS_FCB)(ExAllocateFromNPagedLookasideList(&(FFSGlobal->FFSFcbLookasideList)));

	ExReleaseResourceForThreadLite(
			&FFSGlobal->LAResource,
			ExGetCurrentResourceThread());

	if (Fcb == NULL)
	{
		Fcb = (PFFS_FCB)ExAllocatePool(NonPagedPool, sizeof(FFS_FCB));

		RtlZeroMemory(Fcb, sizeof(FFS_FCB));

		SetFlag(Fcb->Flags, FCB_FROM_POOL);
	}
	else
	{
		RtlZeroMemory(Fcb, sizeof(FFS_FCB));
	}

	if (!Fcb)
	{
		return NULL;
	}

	Fcb->Identifier.Type = FFSFCB;
	Fcb->Identifier.Size = sizeof(FFS_FCB);

	FsRtlInitializeFileLock(
			&Fcb->FileLockAnchor,
			NULL,
			NULL);

	Fcb->OpenHandleCount = 0;
	Fcb->ReferenceCount = 0;

	Fcb->Vcb = Vcb;

#if DBG    

	Fcb->AnsiFileName.MaximumLength = (USHORT)
		RtlxUnicodeStringToOemSize(&(FFSMcb->ShortName)) + 1;

	Fcb->AnsiFileName.Buffer = (PUCHAR) 
		ExAllocatePool(PagedPool, Fcb->AnsiFileName.MaximumLength);

	if (!Fcb->AnsiFileName.Buffer)
	{
		goto errorout;
	}

	RtlZeroMemory(Fcb->AnsiFileName.Buffer, Fcb->AnsiFileName.MaximumLength);

	FFSUnicodeToOEM(&(Fcb->AnsiFileName),
			&(FFSMcb->ShortName));

#endif

	FFSMcb->FileAttr = FILE_ATTRIBUTE_NORMAL;

	if ((dinode2->di_mode & IFMT) == IFDIR)
	{
		SetFlag(FFSMcb->FileAttr, FILE_ATTRIBUTE_DIRECTORY);
	}

	if (IsFlagOn(Vcb->Flags, VCB_READ_ONLY) || 
			FFSIsReadOnly(dinode2->di_mode))
	{
		SetFlag(FFSMcb->FileAttr, FILE_ATTRIBUTE_READONLY);
	}

	Fcb->dinode2 = dinode2;

	Fcb->FFSMcb = FFSMcb;
	FFSMcb->FFSFcb = Fcb;

	RtlZeroMemory(&Fcb->Header, sizeof(FSRTL_COMMON_FCB_HEADER));

	Fcb->Header.NodeTypeCode = (USHORT)FFSFCB;
	Fcb->Header.NodeByteSize = sizeof(FFS_FCB);
	Fcb->Header.IsFastIoPossible = FastIoIsNotPossible;
	Fcb->Header.Resource = &(Fcb->MainResource);
	Fcb->Header.PagingIoResource = &(Fcb->PagingIoResource);

	{
		ULONG Totalblocks = (ULONG)(Fcb->dinode2->di_blocks);
		Fcb->Header.AllocationSize.QuadPart = 
			(((LONGLONG)FFSDataBlocks(Vcb, Totalblocks)) << BLOCK_BITS);
	}

	Fcb->Header.FileSize.QuadPart = (LONGLONG)(Fcb->dinode2->di_size);
	Fcb->Header.ValidDataLength.QuadPart = (LONGLONG)(0x7fffffffffffffff);

	Fcb->SectionObject.DataSectionObject = NULL;
	Fcb->SectionObject.SharedCacheMap = NULL;
	Fcb->SectionObject.ImageSectionObject = NULL;

	ExInitializeResourceLite(&(Fcb->MainResource));
	ExInitializeResourceLite(&(Fcb->PagingIoResource));

	InsertTailList(&Vcb->FcbList, &Fcb->Next);

#if DBG

	ExAcquireResourceExclusiveLite(
			&FFSGlobal->CountResource,
			TRUE);

	FFSGlobal->FcbAllocated++;

	ExReleaseResourceForThreadLite(
			&FFSGlobal->CountResource,
			ExGetCurrentResourceThread());
#endif

	return Fcb;

#if DBG
errorout:
#endif

	if (Fcb)
	{

#if DBG
		if (Fcb->AnsiFileName.Buffer)
			ExFreePool(Fcb->AnsiFileName.Buffer);
#endif

		if (FlagOn(Fcb->Flags, FCB_FROM_POOL))
		{
			ExFreePool(Fcb);
		}
		else
		{
			ExAcquireResourceExclusiveLite(
					&FFSGlobal->LAResource,
					TRUE);

			ExFreeToNPagedLookasideList(&(FFSGlobal->FFSFcbLookasideList), Fcb);

			ExReleaseResourceForThreadLite(
					&FFSGlobal->LAResource,
					ExGetCurrentResourceThread());
		}

	}

	return NULL;
}
예제 #2
0
파일: dirctl.c 프로젝트: GYGit/reactos
ULONG
FFSProcessDirEntry(
	IN PFFS_VCB                Vcb,
	IN FILE_INFORMATION_CLASS  FileInformationClass,
	IN ULONG                   in,
	IN PVOID                   Buffer,
	IN ULONG                   UsedLength,
	IN ULONG                   Length,
	IN ULONG                   FileIndex,
	IN PUNICODE_STRING         pName,
	IN BOOLEAN                 Single)
{
	FFSv1_INODE dinode1;
	FFSv2_INODE dinode2;
	PFILE_DIRECTORY_INFORMATION FDI;
	PFILE_FULL_DIR_INFORMATION FFI;
	PFILE_BOTH_DIR_INFORMATION FBI;
	PFILE_NAMES_INFORMATION FNI;

	ULONG InfoLength = 0;
	ULONG NameLength = 0;
	ULONG dwBytes = 0;

    PAGED_CODE();

	NameLength = pName->Length;

	if (!in)
	{
		FFSPrint((DBG_ERROR, "FFSPricessDirEntry: ffs_dir_entry is empty.\n"));
		return 0;
	}

	InfoLength = FFSGetInfoLength(FileInformationClass);

	if (!InfoLength || InfoLength + NameLength - sizeof(WCHAR) > Length)
	{
		FFSPrint((DBG_INFO, "FFSPricessDirEntry: Buffer is not enough.\n"));
		return 0;
	}

	if (FS_VERSION == 1)
	{
		if(!FFSv1LoadInode(Vcb, in, &dinode1))
		{
			FFSPrint((DBG_ERROR, "FFSPricessDirEntry: Loading inode %xh error.\n", in));

			FFSBreakPoint();

			return 0;
		}
	}
	else
	{
		if(!FFSv2LoadInode(Vcb, in, &dinode2))
		{
			FFSPrint((DBG_ERROR, "FFSPricessDirEntry: Loading inode %xh error.\n", in));

			FFSBreakPoint();

			return 0;
		}
	}

	switch(FileInformationClass)
	{
		case FileDirectoryInformation:
			FDI = (PFILE_DIRECTORY_INFORMATION) ((PUCHAR)Buffer + UsedLength);
			if (!Single)
				FDI->NextEntryOffset = InfoLength + NameLength - sizeof(WCHAR);
			else
				FDI->NextEntryOffset = 0;
			FDI->FileIndex = FileIndex;

			if (FS_VERSION == 1)
			{
				FDI->CreationTime = FFSSysTime(dinode1.di_ctime);
				FDI->LastAccessTime = FFSSysTime(dinode1.di_atime);
				FDI->LastWriteTime = FFSSysTime(dinode1.di_mtime);
				FDI->ChangeTime = FFSSysTime(dinode1.di_mtime);
				FDI->EndOfFile.QuadPart = dinode1.di_size;
				FDI->AllocationSize.QuadPart = dinode1.di_size;
				FDI->FileAttributes = FILE_ATTRIBUTE_NORMAL;

				if (FlagOn(Vcb->Flags, VCB_READ_ONLY) || FFSIsReadOnly(dinode1.di_mode))
				{
					SetFlag(FDI->FileAttributes, FILE_ATTRIBUTE_READONLY);
				}

				if ((dinode1.di_mode & IFMT) == IFDIR)
					FDI->FileAttributes |= FILE_ATTRIBUTE_DIRECTORY;

				FDI->FileNameLength = NameLength;
				RtlCopyMemory(FDI->FileName, pName->Buffer, NameLength);
				dwBytes = InfoLength + NameLength - sizeof(WCHAR); 
				break;
			}
			else
			{
				FDI->CreationTime = FFSSysTime((ULONG)dinode2.di_ctime);
				FDI->LastAccessTime = FFSSysTime((ULONG)dinode2.di_atime);
				FDI->LastWriteTime = FFSSysTime((ULONG)dinode2.di_mtime);
				FDI->ChangeTime = FFSSysTime((ULONG)dinode2.di_mtime);
				FDI->EndOfFile.QuadPart = dinode2.di_size;
				FDI->AllocationSize.QuadPart = dinode2.di_size;
				FDI->FileAttributes = FILE_ATTRIBUTE_NORMAL;

				if (FlagOn(Vcb->Flags, VCB_READ_ONLY) || FFSIsReadOnly(dinode2.di_mode))
				{
					SetFlag(FDI->FileAttributes, FILE_ATTRIBUTE_READONLY);
				}

				if ((dinode2.di_mode & IFMT) == IFDIR)
					FDI->FileAttributes |= FILE_ATTRIBUTE_DIRECTORY;

				FDI->FileNameLength = NameLength;
				RtlCopyMemory(FDI->FileName, pName->Buffer, NameLength);
				dwBytes = InfoLength + NameLength - sizeof(WCHAR); 
				break;
			}

		case FileFullDirectoryInformation:
			FFI = (PFILE_FULL_DIR_INFORMATION) ((PUCHAR)Buffer + UsedLength);
			if (!Single)
				FFI->NextEntryOffset = InfoLength + NameLength - sizeof(WCHAR);
			else
				FFI->NextEntryOffset = 0;
			FFI->FileIndex = FileIndex;

			if (FS_VERSION == 1)
			{
				FFI->CreationTime = FFSSysTime(dinode1.di_ctime);
				FFI->LastAccessTime = FFSSysTime(dinode1.di_atime);
				FFI->LastWriteTime = FFSSysTime(dinode1.di_mtime);
				FFI->ChangeTime = FFSSysTime(dinode1.di_mtime);
				FFI->EndOfFile.QuadPart = dinode1.di_size;
				FFI->AllocationSize.QuadPart = dinode1.di_size;
				FFI->FileAttributes = FILE_ATTRIBUTE_NORMAL;

				if (IsFlagOn(Vcb->Flags, VCB_READ_ONLY)  || FFSIsReadOnly(dinode1.di_mode))
				{
					SetFlag(FFI->FileAttributes, FILE_ATTRIBUTE_READONLY);
				}

				if ((dinode1.di_mode & IFMT) == IFDIR)
					FFI->FileAttributes |= FILE_ATTRIBUTE_DIRECTORY;

				FFI->FileNameLength = NameLength;
				RtlCopyMemory(FFI->FileName, pName->Buffer, NameLength);
				dwBytes = InfoLength + NameLength - sizeof(WCHAR); 

				break;
			}
			else
			{
				FFI->CreationTime = FFSSysTime((ULONG)dinode2.di_ctime);
				FFI->LastAccessTime = FFSSysTime((ULONG)dinode2.di_atime);
				FFI->LastWriteTime = FFSSysTime((ULONG)dinode2.di_mtime);
				FFI->ChangeTime = FFSSysTime((ULONG)dinode2.di_mtime);
				FFI->EndOfFile.QuadPart = dinode2.di_size;
				FFI->AllocationSize.QuadPart = dinode2.di_size;
				FFI->FileAttributes = FILE_ATTRIBUTE_NORMAL;

				if (IsFlagOn(Vcb->Flags, VCB_READ_ONLY)  || FFSIsReadOnly(dinode2.di_mode))
				{
					SetFlag(FFI->FileAttributes, FILE_ATTRIBUTE_READONLY);
				}

				if ((dinode2.di_mode & IFMT) == IFDIR)
					FFI->FileAttributes |= FILE_ATTRIBUTE_DIRECTORY;

				FFI->FileNameLength = NameLength;
				RtlCopyMemory(FFI->FileName, pName->Buffer, NameLength);
				dwBytes = InfoLength + NameLength - sizeof(WCHAR); 

				break;
			}

		case FileBothDirectoryInformation:
			FBI = (PFILE_BOTH_DIR_INFORMATION) ((PUCHAR)Buffer + UsedLength);
			if (!Single)
				FBI->NextEntryOffset = InfoLength + NameLength - sizeof(WCHAR);
			else
				FBI->NextEntryOffset = 0;

			if (FS_VERSION == 1)
			{
				FBI->CreationTime = FFSSysTime(dinode1.di_ctime);
				FBI->LastAccessTime = FFSSysTime(dinode1.di_atime);
				FBI->LastWriteTime = FFSSysTime(dinode1.di_mtime);
				FBI->ChangeTime = FFSSysTime(dinode1.di_mtime);

				FBI->FileIndex = FileIndex;
				FBI->EndOfFile.QuadPart = dinode1.di_size;
				FBI->AllocationSize.QuadPart = dinode1.di_size;
				FBI->FileAttributes = FILE_ATTRIBUTE_NORMAL;

				if (FlagOn(Vcb->Flags, VCB_READ_ONLY) || FFSIsReadOnly(dinode1.di_mode))
				{
					SetFlag(FBI->FileAttributes, FILE_ATTRIBUTE_READONLY);
				}

				if ((dinode1.di_mode & IFMT) == IFDIR)
					FBI->FileAttributes |= FILE_ATTRIBUTE_DIRECTORY;
				FBI->FileNameLength = NameLength;
				RtlCopyMemory(FBI->FileName, pName->Buffer, NameLength);
				dwBytes = InfoLength + NameLength - sizeof(WCHAR); 

				break;
			}
			else
			{
				FBI->CreationTime = FFSSysTime((ULONG)dinode2.di_ctime);
				FBI->LastAccessTime = FFSSysTime((ULONG)dinode2.di_atime);
				FBI->LastWriteTime = FFSSysTime((ULONG)dinode2.di_mtime);
				FBI->ChangeTime = FFSSysTime((ULONG)dinode2.di_mtime);

				FBI->FileIndex = FileIndex;
				FBI->EndOfFile.QuadPart = dinode2.di_size;
				FBI->AllocationSize.QuadPart = dinode2.di_size;
				FBI->FileAttributes = FILE_ATTRIBUTE_NORMAL;

				if (FlagOn(Vcb->Flags, VCB_READ_ONLY) || FFSIsReadOnly(dinode2.di_mode))
				{
					SetFlag(FBI->FileAttributes, FILE_ATTRIBUTE_READONLY);
				}

				if ((dinode2.di_mode & IFMT) == IFDIR)
					FBI->FileAttributes |= FILE_ATTRIBUTE_DIRECTORY;
				FBI->FileNameLength = NameLength;
				RtlCopyMemory(FBI->FileName, pName->Buffer, NameLength);
				dwBytes = InfoLength + NameLength - sizeof(WCHAR); 

				break;
			}

		case FileNamesInformation:
			FNI = (PFILE_NAMES_INFORMATION) ((PUCHAR)Buffer + UsedLength);
			if (!Single)
				FNI->NextEntryOffset = InfoLength + NameLength - sizeof(WCHAR);
			else
				FNI->NextEntryOffset = 0;
			FNI->FileNameLength = NameLength;
			RtlCopyMemory(FNI->FileName, pName->Buffer, NameLength);
			dwBytes = InfoLength + NameLength - sizeof(WCHAR); 

			break;

		default:
			break;
	}

	return dwBytes;
}