Пример #1
0
BOOL
CNdasUnitDeviceCreator::ReadDIBv1AndConvert(PNDAS_DIB_V2 pDIBv2)
{
    BOOL fSuccess = FALSE;
    NDAS_DIB DIBv1 = {0};
    PNDAS_DIB pDIBv1 = &DIBv1;

    fSuccess = m_devComm.ReadDiskBlock(
                   reinterpret_cast<PBYTE>(pDIBv1),
                   NDAS_BLOCK_LOCATION_DIB_V1);

    if (!fSuccess)
    {
        XTLTRACE2(NDASSVC_NDASUNITDEVICE, TRACE_LEVEL_ERROR,
                  "ReadDiskBlock(DIBv1) failed, error=0x%X\n",
                  GetLastError());
        return FALSE;
    }

    //
    // If there is no DIB in the disk,
    // create a pseudo DIBv2
    //
    if (NDAS_DIB_SIGNATURE != pDIBv1->Signature ||
            IS_NDAS_DIBV1_WRONG_VERSION(*pDIBv1))
    {
        //
        // Create a pseudo DIBv2
        //
        InitializeDIBv2AsSingle(pDIBv2);
        return TRUE;
    }

    //
    // Convert V1 to V2
    //
    fSuccess = ConvertDIBv1toDIBv2(
                   pDIBv1,
                   pDIBv2,
                   m_udinfo.SectorCount.QuadPart);

    if (!fSuccess) {
        //
        // Create a pseudo DIBv2 again!
        //
        InitializeDIBv2AsSingle(pDIBv2);
        return TRUE;
    }

    return TRUE;
}
Пример #2
0
BOOL 
CNdasUnitDeviceCreator::ReadDIBv1AndConvert(PNDAS_DIB_V2 pDIBv2)
{
	BOOL fSuccess = FALSE;
	NDAS_DIB DIBv1 = {0};
	PNDAS_DIB pDIBv1 = &DIBv1;

	fSuccess = m_devComm.ReadDiskBlock(
		reinterpret_cast<PBYTE>(pDIBv1), 
		NDAS_BLOCK_LOCATION_DIB_V1);

	if (!fSuccess) {
		DBGPRT_ERR_EX(_FT("Reading DIBv1 block failed: "));
		return FALSE;
	}

	//
	// If there is no DIB in the disk,
	// create a pseudo DIBv2
	//
	if (NDAS_DIB_SIGNATURE != pDIBv1->Signature ||
		IS_NDAS_DIBV1_WRONG_VERSION(*pDIBv1)) 
	{
		//
		// Create a pseudo DIBv2
		//
		InitializeDIBv2AsSingle(pDIBv2);		
		return TRUE;
	}

	//
	// Convert V1 to V2
	//
	fSuccess = ConvertDIBv1toDIBv2(
		pDIBv1, 
		pDIBv2, 
		m_udinfo.SectorCount.QuadPart);

	if (!fSuccess) {
		//
		// Create a pseudo DIBv2 again!
		//
		InitializeDIBv2AsSingle(pDIBv2);		
		return TRUE;
	}

	return TRUE;
}
Пример #3
0
BOOL
CNdasUnitDeviceCreator::ConvertDIBv1toDIBv2(
    CONST NDAS_DIB* pDIBv1,
    NDAS_DIB_V2* pDIBv2,
    UINT64 nDiskSectorCount)
{
    XTLASSERT(!IsBadReadPtr(pDIBv1, sizeof(NDAS_DIB)));
    XTLASSERT(!IsBadWritePtr(pDIBv2, sizeof(NDAS_DIB_V2)));

    InitializeDIBv2(pDIBv2, nDiskSectorCount);
    // fit to old system
    pDIBv2->sizeUserSpace = nDiskSectorCount - pDIBv2->sizeXArea;
    pDIBv2->iSectorsPerBit = 0; // no backup information

    // single disk
    if(IS_NDAS_DIBV1_WRONG_VERSION(*pDIBv1) || // no DIB information
            NDAS_DIB_DISK_TYPE_SINGLE == pDIBv1->DiskType)
    {
        InitializeDIBv2AsSingle(pDIBv2);
    }
    else
    {
        // pair(2) disks (mirror, aggregation)
        UNIT_DISK_LOCATION *pUnitDiskLocation0, *pUnitDiskLocation1;
        if(NDAS_DIB_DISK_TYPE_MIRROR_MASTER == pDIBv1->DiskType ||
                NDAS_DIB_DISK_TYPE_AGGREGATION_FIRST == pDIBv1->DiskType)
        {
            pUnitDiskLocation0 = &pDIBv2->UnitDisks[0];
            pUnitDiskLocation1 = &pDIBv2->UnitDisks[1];
        }
        else
        {
            pUnitDiskLocation0 = &pDIBv2->UnitDisks[1];
            pUnitDiskLocation1 = &pDIBv2->UnitDisks[0];
        }

        //
        // EtherAddress Conversion
        //
        if(
            0x00 == pDIBv1->EtherAddress[0] &&
            0x00 == pDIBv1->EtherAddress[1] &&
            0x00 == pDIBv1->EtherAddress[2] &&
            0x00 == pDIBv1->EtherAddress[3] &&
            0x00 == pDIBv1->EtherAddress[4] &&
            0x00 == pDIBv1->EtherAddress[5])
        {
            // usually, there is no ether address information
            C_ASSERT(
                sizeof(pUnitDiskLocation0->MACAddr) ==
                sizeof(m_pDevice->GetDeviceId().Node));

            CopyMemory(
                pUnitDiskLocation0->MACAddr,
                m_pDevice->GetDeviceId().Node,
                sizeof(pUnitDiskLocation0->MACAddr));

            pUnitDiskLocation0->UnitNumber = static_cast<UCHAR>(m_dwUnitNo);
        }
        else
        {
            C_ASSERT(
                sizeof(pUnitDiskLocation0->MACAddr) ==
                sizeof(pDIBv1->EtherAddress));

            CopyMemory(
                pUnitDiskLocation0->MACAddr,
                pDIBv1->EtherAddress,
                sizeof(pUnitDiskLocation0->MACAddr));

            pUnitDiskLocation0->UnitNumber = pDIBv1->UnitNumber;
        }

        //
        // Peer Address Conversion
        //
        {
            C_ASSERT(
                sizeof(pUnitDiskLocation1->MACAddr) ==
                sizeof(pDIBv1->PeerAddress));

            CopyMemory(
                pUnitDiskLocation1->MACAddr,
                pDIBv1->PeerAddress,
                sizeof(pUnitDiskLocation1->MACAddr));

            pUnitDiskLocation1->UnitNumber = pDIBv1->UnitNumber;
        }

        pDIBv2->nDiskCount = 2;
        pDIBv2->nSpareCount = 0;

        switch(pDIBv1->DiskType)
        {
        case NDAS_DIB_DISK_TYPE_MIRROR_MASTER:
            pDIBv2->iMediaType = NMT_MIRROR;
            pDIBv2->iSequence = 0;
            break;
        case NDAS_DIB_DISK_TYPE_MIRROR_SLAVE:
            pDIBv2->iMediaType = NMT_MIRROR;
            pDIBv2->iSequence = 1;
            break;
        case NDAS_DIB_DISK_TYPE_AGGREGATION_FIRST:
            pDIBv2->iMediaType = NMT_AGGREGATE;
            pDIBv2->iSequence = 0;
            break;
        case NDAS_DIB_DISK_TYPE_AGGREGATION_SECOND:
            pDIBv2->iMediaType = NMT_AGGREGATE;
            pDIBv2->iSequence = 1;
            break;
        default:
            return FALSE;
        }
    }

    // write crc
    pDIBv2->crc32 = crc32_calc(
                        (unsigned char *)pDIBv2,
                        sizeof(pDIBv2->bytes_248));

    pDIBv2->crc32_unitdisks = crc32_calc(
                                  (unsigned char *)pDIBv2->UnitDisks,
                                  sizeof(pDIBv2->UnitDisks));

    return TRUE;
}
Пример #4
0
BOOL
CNdasUnitDeviceCreator::ReadDIB(NDAS_DIB_V2** ppDIBv2)
{
    //
    // ppDIBv2 will be set only if this function succeed.
    //

    PNDAS_DIB_V2 pDIBv2 = reinterpret_cast<PNDAS_DIB_V2>(
                              HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 512));

    if (NULL == pDIBv2)
    {
        XTLTRACE2(NDASSVC_NDASUNITDEVICE, TRACE_LEVEL_ERROR,
                  "ReadDiskBlock failed, error=0x%X\n",
                  GetLastError());

        return FALSE;
    }

    BOOL fSuccess = m_devComm.ReadDiskBlock(
                        reinterpret_cast<PBYTE>(pDIBv2),
                        NDAS_BLOCK_LOCATION_DIB_V2);

    //
    // Regardless of the existence,
    // Disk Block should be read.
    // Failure means communication error or disk error
    //
    if (!fSuccess)
    {
        XTLTRACE2(NDASSVC_NDASUNITDEVICE, TRACE_LEVEL_ERROR,
                  "ReadDiskBlock failed, error=0x%X\n",
                  GetLastError());

        XTLVERIFY( HeapFree(GetProcessHeap(), 0, pDIBv2) );

        return FALSE;
    }

    //
    // check signature
    //

    if(NDAS_DIB_V2_SIGNATURE != pDIBv2->Signature ||
            pDIBv2->crc32 != crc32_calc((unsigned char *)pDIBv2,
                                        sizeof(pDIBv2->bytes_248)) ||
            pDIBv2->crc32_unitdisks != crc32_calc((unsigned char *)pDIBv2->UnitDisks,
                    sizeof(pDIBv2->UnitDisks)))
    {
        //
        // Read DIBv1
        //

        fSuccess = ReadDIBv1AndConvert(pDIBv2);

        if (!fSuccess)
        {
            XTLVERIFY( HeapFree(GetProcessHeap(), 0, pDIBv2) );
            return FALSE;
        }

        if ( ! IsConsistentDIB(pDIBv2) )
        {
            // Inconsistent DIB will be reported as single
            InitializeDIBv2AsSingle(pDIBv2);
        }

        *ppDIBv2 = pDIBv2;
        return TRUE;
    }

    //
    // check version
    //
    if(IS_HIGHER_VERSION_V2(*pDIBv2))
    {
        XTLTRACE2(NDASSVC_NDASUNITDEVICE, TRACE_LEVEL_ERROR,
                  "Unsupported version V2.\n");

        XTLVERIFY( HeapFree(GetProcessHeap(), 0, pDIBv2) );
        return FALSE;
    }

    //
    // TODO: Lower version process (future code) ???
    //
    if(0)
    {
        XTLTRACE2(NDASSVC_NDASUNITDEVICE, TRACE_LEVEL_ERROR,
                  "lower version V2 detected\n");
    }

    //
    // read additional locations if needed
    //
    if (pDIBv2->nDiskCount + pDIBv2->nSpareCount > NDAS_MAX_UNITS_IN_V2)
    {

        UINT32 nTrailSectorCount =
            GET_TRAIL_SECTOR_COUNT_V2(pDIBv2->nDiskCount + pDIBv2->nSpareCount);

        SIZE_T dwBytes = sizeof(NDAS_DIB_V2) + 512 * nTrailSectorCount;

        LPVOID ptr = HeapReAlloc(
                         GetProcessHeap(),
                         HEAP_ZERO_MEMORY,
                         pDIBv2,
                         dwBytes);

        if (NULL == ptr)
        {
            XTLTRACE2(NDASSVC_NDASUNITDEVICE, TRACE_LEVEL_ERROR,
                      "HeapReAlloc failed, bytes=%d\n", dwBytes);

            // When HeapReAlloc fails, pDIBv2 should be freed
            XTLVERIFY( HeapFree(GetProcessHeap(), 0, pDIBv2) );

            return FALSE;
        }

        pDIBv2 = reinterpret_cast<PNDAS_DIB_V2>(ptr);

        for(DWORD i = 0; i < nTrailSectorCount; i++) {

            fSuccess = m_devComm.ReadDiskBlock(
                           reinterpret_cast<PBYTE>(pDIBv2) + sizeof(NDAS_DIB_V2) + 512 * i,
                           NDAS_BLOCK_LOCATION_ADD_BIND + i);

            if(!fSuccess)
            {
                XTLTRACE2(NDASSVC_NDASUNITDEVICE, TRACE_LEVEL_ERROR,
                          "Reading additional block failed, block=%d, error=0x%X\n",
                          NDAS_BLOCK_LOCATION_ADD_BIND + i, GetLastError());

                XTLVERIFY( HeapFree(GetProcessHeap(), 0, pDIBv2) );

                return FALSE;
            }
        }
    }

    // Virtual DVD check. Not supported ATM.

    //
    // DIB Consistency Check
    //
    if ( ! IsConsistentDIB(pDIBv2) )
    {
        // Inconsistent DIB will be reported as single
        InitializeDIBv2AsSingle(pDIBv2);
    }

    *ppDIBv2 = pDIBv2;

    return TRUE;
}