void operator=(const SignalContainer& copy) {
			if (_owner) delete _data;
			_sizes = copy._sizes;
			_w = copy._w;
			_lower_point = copy._lower_point;
			_upper_point = copy._upper_point;
			_owner = true;
			_init();
			_copy_data(copy);
		}
Exemplo n.º 2
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, 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;

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

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

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

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

	ASSERT(Buf - origBuf == origLen);
	Ret = TRUE;
l_error:
	if (ppInternalBlocks != NULL)
		ExFreePoolWithTag(ppInternalBlocks, CACHE_POOL_TAG);
	return Ret;
}
Exemplo n.º 3
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;
}