Ejemplo n.º 1
0
/**
 * Write Update Cache Pool with Buffer
 */
VOID
WriteUpdateCachePool (
    PCACHE_POOL CachePool,
    PUCHAR Buf, OFFSET_T Offset, LENGTH_T Length
)
{
    PUCHAR              origBuf;
    OFFSET_T            front_offset;
    LENGTH_T            i, front_skip, end_cut, origLen;
    BOOLEAN             front_broken, end_broken;
    PCACHE_BLOCK        pBlock;
    Cache_Operations   *ops = CachePool->Cache_Ops;

    origBuf = Buf;
    origLen = Length;

    detect_broken (Offset, Length, front_broken, end_broken,
                   front_offset, front_skip, end_cut);
    Offset /= BLOCK_SIZE;
    Length /= BLOCK_SIZE;

    if (front_broken)
    {
        if (ops->QueryPoolByIndex(CachePool, Offset-1, &pBlock) == TRUE)
        {
            _WRITE_TO_CBLOCK(pBlock, front_offset, Buf, front_skip);
        }
        Buf += front_skip;
    }
    for (i = 0; i < Length; i++)
    {
        CACHE_INDEX_T Index = Offset + i;
        if(ops->QueryPoolByIndex(CachePool, Index, &pBlock) == TRUE)
        {
            _WRITE_TO_CBLOCK(pBlock, 0, Buf, BLOCK_SIZE);
        }
        else if (ops->IsFull(CachePool) == FALSE)
        {
            pBlock = ops->AddNewBlockToPool(CachePool, Index, Buf, TRUE);
        }
        else
        {
            pBlock = ops->FindBlockToReplace(CachePool, Index, Buf, TRUE);
        }
        Buf += BLOCK_SIZE;
    }
    if (end_broken)
    {
        if (ops->QueryPoolByIndex(CachePool, Offset+Length, &pBlock) == TRUE)
        {
            _WRITE_TO_CBLOCK(pBlock, 0, Buf, end_cut);
        }
        Buf += end_cut;
    }
    ASSERT (Buf - origBuf == origLen);
}
Ejemplo n.º 2
0
/**
 * Read Update Cache Pool with Buffer
 */
VOID ReadUpdateCachePool(
	PCACHE_POOL CachePool,
	PUCHAR Buf, LONGLONG Offset, ULONG Length
#ifdef READ_VERIFY
	,PDEVICE_OBJECT LowerDeviceObject
	,ULONG DiskNumber
	,ULONG PartitionNumber
#endif
)
{
	PUCHAR origBuf;
	ULONG i, front_offset, front_skip, end_cut, origLen;
	PCACHE_BLOCK pBlock;
	BOOLEAN front_broken, end_broken;

	origBuf = Buf;
	origLen = Length;

	detect_broken(Offset, Length, front_broken, end_broken, front_offset, front_skip, end_cut);
	Offset /= BLOCK_SIZE;
	Length /= BLOCK_SIZE;

	if(front_broken == TRUE)
	{
	#ifdef WRITE_BACK_ENABLE
		if (_QueryPoolByIndex(CachePool, Offset-1, &pBlock) == TRUE &&
			pBlock->Modified == TRUE)
		{
			_read_data(Buf, pBlock, front_offset, front_skip);
		}
	#endif
		Buf += front_skip;
	}
	for (i = 0; i < Length; i++)
	{
		LONGLONG Index = Offset + i;
		if (_QueryPoolByIndex(CachePool, Index, &pBlock) == TRUE)
		{
			DO_READ_VERIFY(CachePool, &CachePool->Storage, pBlock);
		#ifdef WRITE_BACK_ENABLE
			if (pBlock->Modified == TRUE)
			{
				_read_data(Buf, pBlock, 0, BLOCK_SIZE);
			}
		#endif
			_IncreaseBlockReference(CachePool, pBlock);
		}
		else if (_IsFull(CachePool) == FALSE)
		{
			pBlock = _AddNewBlockToPool(CachePool, Index, Buf, FALSE);
		}
		else
		{
			pBlock = _FindBlockToReplace(CachePool, Index, Buf, FALSE);
		}
		Buf += BLOCK_SIZE;
	}
	if (end_broken == TRUE)
	{
	#ifdef WRITE_BACK_ENABLE
		if (_QueryPoolByIndex(CachePool, Offset+Length, &pBlock) == TRUE &&
			pBlock->Modified == TRUE)
		{
			_read_data(Buf, pBlock, 0, end_cut);
		}
	#endif
		Buf += end_cut;
	}
	ASSERT(Buf - origBuf == origLen);
}
Ejemplo n.º 3
0
/**
 * Query Cache Pool (If the _WRITE_ Request is Matched)
 * If it's fully matched, update cache and return TRUE,
 * else return FALSE
 */
BOOLEAN QueryAndWriteToCachePool (
	PCACHE_POOL CachePool, PUCHAR Buf, LONGLONG Offset, ULONG Length
#ifdef READ_VERIFY
	,PDEVICE_OBJECT LowerDeviceObject
	,ULONG DiskNumber
	,ULONG PartitionNumber
#endif
)
{
	PUCHAR origBuf;
	ULONG i, front_offset, front_skip, end_cut, origLen;
	BOOLEAN Ret = FALSE;
	BOOLEAN front_broken, end_broken;
	PCACHE_BLOCK *ppInternalBlocks = NULL;

	origBuf = Buf;
	origLen = Length;

	detect_broken(Offset, Length, front_broken, end_broken, front_offset, front_skip, end_cut);
	Offset /= BLOCK_SIZE;
	Length /= BLOCK_SIZE;

	ppInternalBlocks = (PCACHE_BLOCK*) ExAllocatePoolWithTag (
		NonPagedPool,
		(SIZE_T)((Length+2) * sizeof(PCACHE_BLOCK)),
		CACHE_POOL_TAG
	);
	if (ppInternalBlocks == NULL)
		goto l_error;

	// Query Pool to Check If Fully Matched
	if (front_broken == TRUE && _QueryPoolByIndex(CachePool, Offset-1, ppInternalBlocks+0) == FALSE)
		goto l_error;
	for (i = 0; i < Length; i++)
		if (_QueryPoolByIndex(CachePool, Offset+i, ppInternalBlocks+i+1) == FALSE)
			goto l_error;
	if (end_broken == TRUE && _QueryPoolByIndex(CachePool, Offset+Length, ppInternalBlocks+Length+1) == FALSE)
		goto l_error;

	if (front_broken == TRUE)
	{
		DO_READ_VERIFY(CachePool, &CachePool->Storage, ppInternalBlocks[0]);
		_write_data(ppInternalBlocks[0], front_offset, Buf, front_skip);
		Buf += front_skip;
	}

	for (i = 0; i < Length; i++)
	{
		DO_READ_VERIFY(CachePool, &CachePool->Storage, ppInternalBlocks[i+1]);
		_write_data(ppInternalBlocks[i+1], 0, Buf, BLOCK_SIZE);
		Buf += BLOCK_SIZE;
	}

	if (end_broken == TRUE)
	{
		DO_READ_VERIFY(CachePool, &CachePool->Storage, ppInternalBlocks[Length+1]);
		_write_data(ppInternalBlocks[Length+1], 0, Buf, end_cut);
		Buf += end_cut;
	}

	ASSERT(Buf - origBuf == origLen);
	Ret = TRUE;
l_error:
	if (ppInternalBlocks != NULL)
		ExFreePoolWithTag(ppInternalBlocks, CACHE_POOL_TAG);
	return Ret;
}
Ejemplo n.º 4
0
/**
 * Write Update Cache Pool with Buffer
 */
VOID WriteUpdateCachePool(
	PCACHE_POOL CachePool,
	PUCHAR Buf, LONGLONG Offset, ULONG Length
#ifdef READ_VERIFY
	,PDEVICE_OBJECT LowerDeviceObject
	,ULONG DiskNumber
	,ULONG PartitionNumber
#endif
)
{
	PUCHAR origBuf;
	ULONG i, front_offset, front_skip, end_cut, origLen;
	PCACHE_BLOCK pBlock;
	BOOLEAN front_broken, end_broken;

	origBuf = Buf;
	origLen = Length;

	detect_broken(Offset, Length, front_broken, end_broken, front_offset, front_skip, end_cut);
	Offset /= BLOCK_SIZE;
	Length /= BLOCK_SIZE;

	if (front_broken)
	{
		if (_QueryPoolByIndex(CachePool, Offset-1, &pBlock) == TRUE)
		{
			DO_READ_VERIFY(CachePool, &CachePool->Storage, pBlock);
			_write_data(pBlock, front_offset, Buf, front_skip);
		}
		Buf += front_skip;
	}
	for (i = 0; i < Length; i++)
	{
		LONGLONG Index = Offset + i;
		if(_QueryPoolByIndex(CachePool, Index, &pBlock) == TRUE)
		{
			DO_READ_VERIFY(CachePool, &CachePool->Storage, pBlock);
			_write_data(pBlock, 0, Buf, BLOCK_SIZE);
		}
		else if (_IsFull(CachePool) == FALSE)
		{
			pBlock = _AddNewBlockToPool(CachePool, Index, Buf, FALSE);
			ADD_TO_WBQUEUE_SAFE(pBlock);
		}
		else
		{
			pBlock = _FindBlockToReplace(CachePool, Index, Buf, FALSE);
			ADD_TO_WBQUEUE_SAFE(pBlock);
		}
		Buf += BLOCK_SIZE;
	}
	if (end_broken)
	{
		if (_QueryPoolByIndex(CachePool, Offset+Length, &pBlock) == TRUE)
		{
			DO_READ_VERIFY(CachePool, &CachePool->Storage, pBlock);
			_write_data(pBlock, 0, Buf, end_cut);
		}
		Buf += end_cut;
	}
	ASSERT (Buf - origBuf == origLen);
}
Ejemplo n.º 5
0
/**
 * Query Cache Pool (If the _WRITE_ Request is Matched)
 * If it's fully matched, update cache and return TRUE,
 * else return FALSE
 */
BOOLEAN
QueryAndWriteToCachePool (
    PCACHE_POOL CachePool,
    PUCHAR Buf, OFFSET_T Offset, LENGTH_T Length
)
{
    PUCHAR              origBuf;
    OFFSET_T            front_offset;
    LENGTH_T            i, front_skip, end_cut, origLen;
    BOOLEAN             Ret, front_broken, end_broken;
    PCACHE_BLOCK       *ppInternalBlocks = NULL;
    Cache_Operations   *ops = CachePool->Cache_Ops;

    Ret = FALSE;
    origBuf = Buf;
    origLen = Length;

    detect_broken (Offset, Length, front_broken, end_broken,
                   front_offset, front_skip, end_cut);
    Offset /= BLOCK_SIZE;
    Length /= BLOCK_SIZE;

    ppInternalBlocks = (PCACHE_BLOCK*) MALLOC ((Length+2) * sizeof(PCACHE_BLOCK));
    if (ppInternalBlocks == NULL)
        goto l_error;

    // Query Pool to Check If Fully Matched
    if (front_broken == TRUE && ops->QueryPoolByIndex(CachePool, Offset-1, ppInternalBlocks+0) == FALSE)
        goto l_error;
    for (i = 0; i < Length; i++)
        if (ops->QueryPoolByIndex(CachePool, Offset+i, ppInternalBlocks+i+1) == FALSE)
            goto l_error;
    if (end_broken == TRUE && ops->QueryPoolByIndex(CachePool, Offset+Length, ppInternalBlocks+Length+1) == FALSE)
        goto l_error;

    if (front_broken == TRUE)
    {
        _WRITE_TO_CBLOCK(ppInternalBlocks[0], front_offset, Buf, front_skip);
        Buf += front_skip;
    }

    for (i = 0; i < Length; i++)
    {
        _WRITE_TO_CBLOCK(ppInternalBlocks[i+1], 0, Buf, BLOCK_SIZE);
        Buf += BLOCK_SIZE;
    }

    if (end_broken == TRUE)
    {
        _WRITE_TO_CBLOCK(ppInternalBlocks[Length+1], 0, Buf, end_cut);
        Buf += end_cut;
    }

    ASSERT(Buf - origBuf == origLen);
    Ret = TRUE;

l_error:
    if (ppInternalBlocks != NULL)
        FREE(ppInternalBlocks);
    return Ret;
}
Ejemplo n.º 6
0
/**
 * Query Cache Pool (If the _READ_ Request is Matched)
 * If it's fully matched, copy to the request buffer and return TRUE,
 * else return FALSE
 */
BOOLEAN
QueryAndCopyFromCachePool (
    PCACHE_POOL CachePool,
    PUCHAR Buf, OFFSET_T Offset, LENGTH_T Length
)
{
    PUCHAR              origBuf;
    OFFSET_T            front_offset;
    LENGTH_T            i, front_skip, end_cut, origLen;
    BOOLEAN             Ret, front_broken, end_broken;
    PCACHE_BLOCK       *ppInternalBlocks = NULL;
    Cache_Operations   *ops = CachePool->Cache_Ops;

    Ret = FALSE;
    origBuf = Buf;
    origLen = Length;

    detect_broken (Offset, Length, front_broken, end_broken,
                   front_offset, front_skip, end_cut);
    Offset /= BLOCK_SIZE;
    Length /= BLOCK_SIZE;

    ppInternalBlocks = (PCACHE_BLOCK*) MALLOC ((Length+2) * sizeof(PCACHE_BLOCK));
    if (ppInternalBlocks == NULL)
        goto l_error;

    // Query Pool to Check If Fully Matched
    if (front_broken == TRUE && ops->QueryPoolByIndex(CachePool, Offset-1, ppInternalBlocks+0) == FALSE)
        goto l_error;
    for (i = 0; i < Length; i++)
        if (ops->QueryPoolByIndex(CachePool, Offset+i, ppInternalBlocks+i+1) == FALSE)
            goto l_error;
    if (end_broken == TRUE && ops->QueryPoolByIndex(CachePool, Offset+Length, ppInternalBlocks+Length+1) == FALSE)
        goto l_error;

#define _copy_data(pBlock,off,len)                      \
        StoragePoolRead (                               \
            &CachePool->Storage,                        \
            Buf,                                        \
            pBlock->StorageIndex,                       \
            off,                                        \
            len                                         \
        );                                              \
        Buf += len;                                     \
        ops->IncreaseBlockReference(CachePool, pBlock);

    if (front_broken == TRUE)
    {
        _copy_data(ppInternalBlocks[0], front_offset, front_skip);
    }

    for (i = 0; i < Length; i++)
    {
        _copy_data(ppInternalBlocks[i+1], 0, BLOCK_SIZE);
    }

    if (end_broken == TRUE)
    {
        _copy_data(ppInternalBlocks[Length+1], 0, end_cut);
    }

    ASSERT(Buf - origBuf == origLen);
    Ret = TRUE;

l_error:
    if (ppInternalBlocks != NULL)
        FREE(ppInternalBlocks);
    return Ret;
}