NTSTATUS LsuGetDiskInfoBlockV1( IN PLANSCSI_SESSION LSS, OUT PNDAS_DIB DiskInformationBlock, IN UINT64 LogicalBlockAddress, IN ULONG BlockBytes, IN ULONG PduFlags ) { NTSTATUS status; status = LsuReadBlocks(LSS, (PBYTE)DiskInformationBlock, LogicalBlockAddress, 1, BlockBytes, PduFlags); if(!NT_SUCCESS(status)) { return status; } if( DiskInformationBlock->Signature != NDAS_DIB_SIGNATURE || IS_NDAS_DIBV1_WRONG_VERSION(*DiskInformationBlock) ) { status = STATUS_REVISION_MISMATCH; KDPrintM(DBG_OTHER_ERROR, ("Error: Revision mismatch. Signature:0x%08lx, Revision:%d.%d\n", DiskInformationBlock->Signature, DiskInformationBlock->MajorVersion, DiskInformationBlock->MinorVersion )); } return status; }
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; }