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

📄 rfsd.c

📁 This is a ReiserFs file system driver for Windows NT/2000/XP/Vista.
💻 C
📖 第 1 页 / 共 5 页
字号:
/*
 * COPYRIGHT:        GNU GENERAL PUBLIC LICENSE VERSION 2
 * PROJECT:          ReiserFs file system driver for Windows NT/2000/XP/Vista.
 * FILE:             rfsd.c
 * PURPOSE:          
 * PROGRAMMER:       Mark Piper, Matt Wu, Bo Brant閚.
 * HOMEPAGE:         
 * UPDATE HISTORY: 
 */

/* INCLUDES *****************************************************************/

#include "rfsd.h"
// TODO: turn off (turns off warning about returning without return value, so I could easily disable code sections)
#pragma warning(disable : 4716)

/* GLOBALS ***************************************************************/

extern PRFSD_GLOBAL RfsdGlobal;

/* DEFINITIONS *************************************************************/

#ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE, RfsdLoadSuper)
#pragma alloc_text(PAGE, RfsdSaveSuper)

#pragma alloc_text(PAGE, RfsdLoadGroup)
#pragma alloc_text(PAGE, RfsdSaveGroup)

#pragma alloc_text(PAGE, RfsdLoadInode)
#pragma alloc_text(PAGE, RfsdSaveInode)

#pragma alloc_text(PAGE, RfsdLoadBlock)
#pragma alloc_text(PAGE, RfsdSaveBlock)

#pragma alloc_text(PAGE, RfsdSaveBuffer)

#pragma alloc_text(PAGE, RfsdGetBlock)
#pragma alloc_text(PAGE, RfsdBlockMap)

#pragma alloc_text(PAGE, RfsdBuildBDL)
#pragma alloc_text(PAGE, RfsdBuildBDL2)

#pragma alloc_text(PAGE, RfsdNewBlock)
#pragma alloc_text(PAGE, RfsdFreeBlock)

#pragma alloc_text(PAGE, RfsdExpandBlock)
#pragma alloc_text(PAGE, RfsdExpandInode)

#pragma alloc_text(PAGE, RfsdNewInode)
#pragma alloc_text(PAGE, RfsdFreeInode)

#pragma alloc_text(PAGE, RfsdAddEntry)
#pragma alloc_text(PAGE, RfsdRemoveEntry)

#pragma alloc_text(PAGE, RfsdTruncateBlock)
#pragma alloc_text(PAGE, RfsdTruncateInode)

#pragma alloc_text(PAGE, RfsdAddMcbEntry)
#pragma alloc_text(PAGE, RfsdRemoveMcbEntry)
#pragma alloc_text(PAGE, RfsdLookupMcbEntry)

#pragma alloc_text(PAGE, SuperblockContainsMagicKey)
#pragma alloc_text(PAGE, DetermineOnDiskKeyFormat)
#pragma alloc_text(PAGE, FillInMemoryKey)
#pragma alloc_text(PAGE, CompareShortKeys)
#pragma alloc_text(PAGE, CompareKeysWithoutOffset)
#pragma alloc_text(PAGE, CompareKeys)
#pragma alloc_text(PAGE, NavigateToLeafNode)
#pragma alloc_text(PAGE, _NavigateToLeafNode)
#pragma alloc_text(PAGE, RfsdParseFilesystemTree)

#endif

/* FUNCTIONS ***************************************************************/

PRFSD_SUPER_BLOCK
RfsdLoadSuper(IN PRFSD_VCB      Vcb,
              IN BOOLEAN        bVerify )
{
    NTSTATUS          Status;
    PRFSD_SUPER_BLOCK RfsdSb = NULL;
    
    RfsdSb = (PRFSD_SUPER_BLOCK) ExAllocatePool( PagedPool, 
                                                 SUPER_BLOCK_SIZE);
    if (!RfsdSb) {
        return NULL;
    }

    Status = RfsdReadDisk(
                Vcb,
                (ULONGLONG) SUPER_BLOCK_OFFSET,
                SUPER_BLOCK_SIZE,
                (PVOID) RfsdSb,
                bVerify );

    if (!NT_SUCCESS(Status)) {

        RfsdPrint((DBG_ERROR, "RfsdReadDisk: Read Block Device error.\n"));

        ExFreePool(RfsdSb);
        return NULL;
    }

    return RfsdSb;
}


BOOLEAN
RfsdSaveSuper(  IN PRFSD_IRP_CONTEXT    IrpContext,
                IN PRFSD_VCB            Vcb )
{
DbgBreak();
#if DISABLED
    LONGLONG    Offset;
    BOOLEAN     bRet;

    Offset = (LONGLONG) SUPER_BLOCK_OFFSET;

    bRet = RfsdSaveBuffer( IrpContext,
                           Vcb,
                           Offset,
                           SUPER_BLOCK_SIZE,
                           Vcb->SuperBlock );

    if (IsFlagOn(Vcb->Flags, VCB_FLOPPY_DISK)) {
        RfsdStartFloppyFlushDpc(Vcb, NULL, NULL);
    }

    return bRet;
#endif
}


#if DISABLED
BOOLEAN
RfsdLoadGroup(IN PRFSD_VCB Vcb)
{
    ULONG       Size;
    PVOID       Buffer;
    LONGLONG    Lba;
    NTSTATUS    Status;

    PRFSD_SUPER_BLOCK sb;

    sb = Vcb->SuperBlock;

    Vcb->BlockSize  = RFSD_MIN_BLOCK << sb->s_log_block_size;
    Vcb->SectorBits = RfsdLog2(SECTOR_SIZE);
    ASSERT(BLOCK_BITS == RfsdLog2(BLOCK_SIZE));

    Vcb->NumOfGroups = (sb->s_blocks_count - sb->s_first_data_block +
        sb->s_blocks_per_group - 1) / sb->s_blocks_per_group;

    Size = sizeof(RFSD_GROUP_DESC) * Vcb->NumOfGroups;

    if (Vcb->BlockSize == RFSD_MIN_BLOCK) {
        Lba = (LONGLONG)2 * Vcb->BlockSize;
    }

    if (Vcb->BlockSize > RFSD_MIN_BLOCK) {
        Lba = (LONGLONG) (Vcb->BlockSize);
    }

    if (Lba == 0) {
        return FALSE;
    }

    Buffer = ExAllocatePool(PagedPool, Size);
    if (!Buffer) {
        RfsdPrint((DBG_ERROR, "RfsdLoadSuper: no enough memory.\n"));
        return FALSE;
    }

    RfsdPrint((DBG_USER, "RfsdLoadGroup: Lba=%I64xh Size=%xh\n", Lba, Size));

    Status = RfsdReadDisk(  Vcb,
                            Lba,
                            Size,
                            Buffer,
                            FALSE );

    if (!NT_SUCCESS(Status)) {
        ExFreePool(Buffer);
        Buffer = NULL;

        return FALSE;
    }

/*
    bPinned = CcPinRead(
                Vcb->StreamObj,
                Lba, 
                Size,
                PIN_WAIT,
                &(Vcb->GroupDescBcb),
                &(Buffer));

    if (!bPinned)
    {
        Vcb->GroupDesc = NULL;
        return FALSE;
    }
*/

    Vcb->GroupDesc = (PRFSD_GROUP_DESC) Buffer;

    return TRUE;
}


BOOLEAN
RfsdSaveGroup(  IN PRFSD_IRP_CONTEXT    IrpContext,
                IN PRFSD_VCB            Vcb,
                IN ULONG                Group )
{
    LONGLONG    Offset;
    BOOLEAN     bRet;

    if (Vcb->BlockSize == RFSD_MIN_BLOCK) {

        Offset = (LONGLONG) (2 * Vcb->BlockSize);

    } else {

        Offset = (LONGLONG) (Vcb->BlockSize);
    }

    Offset += ((LONGLONG) sizeof(struct rfsd_group_desc) * Group);

    bRet = RfsdSaveBuffer(
                    IrpContext,
                    Vcb,
                    Offset,
                    sizeof(struct rfsd_group_desc),
                    &(Vcb->GroupDesc[Group]) );

    if (IsFlagOn(Vcb->Flags, VCB_FLOPPY_DISK)) {
        RfsdStartFloppyFlushDpc(Vcb, NULL, NULL);
    }

    return bRet;
}     
#endif


/** Reads an inode structure off disk into the Inode object (which has been allocated, but not filled with any data) */
BOOLEAN
RfsdLoadInode (IN PRFSD_VCB Vcb,
			   IN PRFSD_KEY_IN_MEMORY pKey,
			   IN OUT PRFSD_INODE Inode)
{
	NTSTATUS Status;
	
	PRFSD_ITEM_HEAD pItemHeader = NULL;
	PUCHAR	pItemBuffer  = NULL;
	PUCHAR	pBlockBuffer = NULL;
	
	// Crate the target key for the stat item (stat items always have an offset of 0)
	RFSD_KEY_IN_MEMORY		TargetKey;
	
	TargetKey = *pKey;
	TargetKey.k_offset		= 0x0;
	TargetKey.k_type		= RFSD_KEY_TYPE_v2_STAT_DATA;	

	RfsdPrint((DBG_FUNC, __FUNCTION__ "on %i, %i\n", TargetKey.k_dir_id, TargetKey.k_objectid));

	//Load the stat data
	Status = RfsdLoadItem(Vcb, &TargetKey,
		&(pItemHeader), &(pItemBuffer), &(pBlockBuffer), NULL,  //<
		&CompareKeys
	);
	if (!NT_SUCCESS(Status))
		{ if (pBlockBuffer) {ExFreePool(pBlockBuffer);} return FALSE; }
	
	// Copy the item into the inode / stat data structure
	RtlCopyMemory(Inode, pItemBuffer, sizeof(RFSD_INODE));	

	// Cleanup
	if (pBlockBuffer)
		ExFreePool(pBlockBuffer);

	return TRUE;
}


BOOLEAN
RfsdSaveInode ( IN PRFSD_IRP_CONTEXT IrpContext,
                IN PRFSD_VCB Vcb,
                IN ULONG Inode,
                IN PRFSD_INODE RfsdInode)
{
DbgBreak();
#if DISABLED
    LONGLONG        Offset = 0;
    LARGE_INTEGER   CurrentTime;
    BOOLEAN         bRet;

    KeQuerySystemTime(&CurrentTime);
    RfsdInode->i_mtime = RfsdInode->i_atime = 
                      (ULONG)(RfsdInodeTime(CurrentTime));

    RfsdPrint((DBG_INFO, "RfsdSaveInode: Saving Inode %xh: Mode=%xh Size=%xh\n",
                         Inode, RfsdInode->i_mode, RfsdInode->i_size));

    if (!RfsdGetInodeLba(Vcb, Inode, &Offset))  {
        RfsdPrint((DBG_ERROR, "RfsdSaveInode: error get inode(%xh)'s addr.\n", Inode));
        return FALSE;
    }

    bRet = RfsdSaveBuffer(IrpContext, Vcb, Offset, sizeof(RFSD_INODE), RfsdInode);

    if (IsFlagOn(Vcb->Flags, VCB_FLOPPY_DISK)) {
        RfsdStartFloppyFlushDpc(Vcb, NULL, NULL);
    }

    return bRet;
#endif
}

/** Just reads a block into a buffer */
BOOLEAN
RfsdLoadBlock (
			IN PRFSD_VCB		Vcb,
            IN ULONG			dwBlk,		// A disk block ptr (a disk block number)
            IN OUT PVOID		Buffer )	// A buffer, which must be allocated to contain at least Vcb->BlockSize
{
    IO_STATUS_BLOCK     IoStatus;
    
	LONGLONG            Offset; 
    Offset = (LONGLONG) dwBlk;
    Offset = Offset * Vcb->BlockSize;

    if (!RfsdCopyRead(
            Vcb->StreamObj,
            (PLARGE_INTEGER)&Offset,
            Vcb->BlockSize,
            PIN_WAIT,
            Buffer,
			&IoStatus )) {
		return FALSE;
	}

    if (!NT_SUCCESS(IoStatus.Status)) {
        return FALSE;
    }

    return TRUE;
}


BOOLEAN
RfsdSaveBlock ( IN PRFSD_IRP_CONTEXT    IrpContext,
                IN PRFSD_VCB            Vcb,
                IN ULONG                dwBlk,
                IN PVOID                Buf )
{
DbgBreak();
#if DISABLED
    LONGLONG Offset;
    BOOLEAN  bRet;

    Offset = (LONGLONG) dwBlk;
    Offset = Offset * Vcb->BlockSize;

    bRet = RfsdSaveBuffer(IrpContext, Vcb, Offset, Vcb->BlockSize, Buf);

    if (IsFlagOn(Vcb->Flags, VCB_FLOPPY_DISK)) {
        RfsdStartFloppyFlushDpc(Vcb, NULL, NULL);
    }

    return bRet;
#endif
}

BOOLEAN
RfsdSaveBuffer( IN PRFSD_IRP_CONTEXT    IrpContext,
                IN PRFSD_VCB            Vcb,
                IN LONGLONG             Offset,
                IN ULONG                Size,
                IN PVOID                Buf )
{
    PBCB        Bcb;
    PVOID       Buffer;
    BOOLEAN     bRet;

    if( !CcPinRead( Vcb->StreamObj,
                    (PLARGE_INTEGER) (&Offset),
                    Size,
                    PIN_WAIT,
                    &Bcb,
                    &Buffer )) {

        RfsdPrint((DBG_ERROR, "RfsdSaveBuffer: PinReading error ...\n"));
        return FALSE;
    }

    __try {

        RtlCopyMemory(Buffer, Buf, Size);
        CcSetDirtyPinnedData(Bcb, NULL );
        RfsdRepinBcb(IrpContext, Bcb);

        SetFlag(Vcb->StreamObj->Flags, FO_FILE_MODIFIED);

        RfsdAddMcbEntry(Vcb, Offset, (LONGLONG)Size);

        bRet = TRUE;

    } __finally {

        if (AbnormalTermination()) {

            CcUnpinData(Bcb);
            bRet = FALSE;
        }
    }

    CcUnpinData(Bcb);

    return bRet;
}

NTSTATUS
RfsdGetBlock(
    IN PRFSD_IRP_CONTEXT    IrpContext,
    IN PRFSD_VCB            Vcb,
    IN ULONG                dwContent,			// A ptr to a disk block (disk block number)
    IN ULONG                Index,
    IN ULONG                Layer,
    IN BOOLEAN              bAlloc,
    OUT PULONG              pBlock
    )
{
DbgBreak();
#if DISABLED
    NTSTATUS    Status = STATUS_SUCCESS;
    ULONG       *pData = NULL;
    ULONG       i = 0, j = 0, temp = 1;
    ULONG       dwRet = 0;
    ULONG       dwBlk = 0;

    if (Layer == 0) {

        dwRet = dwContent;

    } else if (Layer <= 3) {

        /* allocate memory for pData to contain the block */
        pData = (ULONG *)ExAllocatePool(NonPagedPool, Vcb->BlockSize);
        if (!pData) {
            RfsdPrint((DBG_ERROR, "RfsdGetBlock: no enough memory.\n"));
            Status = STATUS_INSUFFICIENT_RESOURCES;
            goto errorout;
        }

        /* load the block dwContext into pData buffer */
        if (!RfsdLoadBlock(Vcb, dwContent, pData)) {
            ExFreePool(pData);
            Status = STATUS_INSUFFICIENT_RESOURCES;
            goto errorout;
        }

        temp = 1 << ((BLOCK_BITS - 2) * (Layer - 1));
        
        i = Index / temp;
        j = Index % temp;

        dwBlk = pData[i];

#if DISABLED  // WRITE MODE ONLY
        if (dwBlk ==0 ) {

⌨️ 快捷键说明

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