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; }
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; }
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; }
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; }