Exemplo n.º 1
0
NTSTATUS
LsuGetDiskInfoBlockV2(
	PLANSCSI_SESSION			LSS,
	PNDAS_DIB_V2				DiskInformationBlock,
	UINT64						LogicalBlockAddress,
	ULONG						PduFlags
) {
	NTSTATUS	status;

	status = LsuReadBlocks(LSS, (PBYTE)DiskInformationBlock, LogicalBlockAddress, 1, PduFlags);
	if(!NT_SUCCESS(status)) {
		return status;
	}


	//
	//	Revision check
	//

	if( DiskInformationBlock->Signature != NDAS_DIB_V2_SIGNATURE ||
		IS_HIGHER_VERSION_V2(*DiskInformationBlock) ) {

		status = STATUS_REVISION_MISMATCH;
		KDPrintM(DBG_PROTO_ERROR, 
			("Error: Revision mismatch. Signature:0x%08lx, Revision:%u.%u\n",
							DiskInformationBlock->Signature,
							DiskInformationBlock->MajorVersion,
							DiskInformationBlock->MinorVersion
				));
	}

	return status;
}
Exemplo n.º 2
0
NTSTATUS
LsuGetDiskInfoBlockV2(
	IN PLANSCSI_SESSION		LSS,
	OUT PNDAS_DIB_V2		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;
	}


	//
	//	Revision check
	//

	if( DiskInformationBlock->Signature != NDAS_DIB_V2_SIGNATURE ||
		IS_HIGHER_VERSION_V2(*DiskInformationBlock) ) {

		status = STATUS_REVISION_MISMATCH;
		KDPrintM(DBG_OTHER_ERROR, 
			("Error: Revision mismatch. Signature:0x%08lx, Revision:%u.%u\n",
							DiskInformationBlock->Signature,
							DiskInformationBlock->MajorVersion,
							DiskInformationBlock->MinorVersion
				));
	}


	//
	//	CRC check.
	//

	if(NT_SUCCESS(status)) {
		if(IS_DIB_CRC_VALID(crc32_calc, *DiskInformationBlock) != TRUE) {
			KDPrintM(DBG_OTHER_ERROR, ("DIBv2's crc is invalid.\n"));
			status = STATUS_REVISION_MISMATCH;
		}
	}

	return status;
}
Exemplo n.º 3
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;
}
Exemplo n.º 4
0
BOOL
NDAS_Unbind(UNIT_DISK_LOCATION *pUnitDisk)
{
	// AING_TO_DO : complex check routine

	BOOL bReturn = FALSE;
	IDE_COMMAND_IO cmd, *cmd_chk = NULL;
	DISK_INFORMATION_BLOCK	*pDiskInfoV1;
	DISK_INFORMATION_BLOCK_V2 *pDiskInfoV2;
	UINT i, j;
	UINT nDIB;

	DebugPrint(1, ("[NDASOpLib] NDAS_Unbind : Start\n"));

	// Check V2
	cmd.command = WIN_READ;
	cmd.iSector = -2;

	DebugPrint(1, ("[NDASOpLib] NDAS_Unbind : Reading V2\n"));
	if(!NDAS_IdeIO(pUnitDisk, 1, &cmd, NULL))
		goto out;
	
	pDiskInfoV2 = (PDISK_INFORMATION_BLOCK_V2)cmd.data;

	if(DISK_INFORMATION_SIGNATURE_V2 != pDiskInfoV2->Signature) // V2 information exists
		goto chk_v1;
	
	DebugPrint(1, ("[NDASOpLib] NDAS_Unbind : V2\n"));

	if(IS_HIGHER_VERSION_V2(*pDiskInfoV2))
		goto out;

	// AING_TO_DO :version check routine needed here

	if(pDiskInfoV2->nDiskCount <= 1)
	{
		// nothing to do
		bReturn = TRUE;
		goto out;
	}

	DebugPrint(1, ("[NDASOpLib] NDAS_Unbind : Disk count >= 2\n"));

	if(NMT_VDVD == pDiskInfoV2->iMediaType)
		goto out;

	DebugPrint(1, ("[NDASOpLib] NDAS_Unbind : not VDVD\n"));
	// AING_TO_DO : if nr of disks is more than NDAS_MAX_UNITS_IN_V2, read more sectors...
	nDIB = 1 + /* DISK_INFORMATION_BLOCK */ + 1 /* DISK_INFORMATION_BLOCK_V2 */ + GET_TRAIL_SECTOR_COUNT_V2(pDiskInfoV2->nDiskCount);
	cmd_chk = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDE_COMMAND_IO) * nDIB);

	DebugPrint(1, ("[NDASOpLib] NDAS_Unbind : nDIB = %d\n", nDIB));
	for(i = 0; i < nDIB; i++)
	{
		cmd_chk[i].command = WIN_READ;
		cmd_chk[i].iSector = -1 * ((signed _int64)i);
	}
	
	DebugPrint(1, ("[NDASOpLib] NDAS_Unbind : nDiskCount = %d\n", pDiskInfoV2->nDiskCount));
	for(i = 0; i < pDiskInfoV2->nDiskCount; i++) // for each netdisks
	{
		DISK_INFORMATION_BLOCK	*pDIV1;
		DISK_INFORMATION_BLOCK_V2 *pDIV2;

		// verify that the disk is bound correctly
		if(!NDAS_IdeIO(&pUnitDisk[i], nDIB, cmd_chk, NULL))
			continue;

		pDIV1 = (PDISK_INFORMATION_BLOCK)cmd_chk[0].data;
		pDIV2 = (PDISK_INFORMATION_BLOCK_V2)cmd_chk[1].data;

		// check V1 data
		if(DISK_INFORMATION_SIGNATURE != pDIV1->Signature ||
			IS_WRONG_VERSION(*pDIV1))
			continue;

		// check V2 data
		if(DISK_INFORMATION_SIGNATURE_V2 != pDIV2->Signature)
			continue;

		// higher version check code
		if(IS_HIGHER_VERSION_V2(*pDIV2))
			continue;

		if(pDIV2->nDiskCount != pDiskInfoV2->nDiskCount ||
			pDIV2->iSequence != i ||
			pDIV2->iMediaType != pDiskInfoV2->iMediaType)
			continue;

		// compare unit disk informations
		if(memcmp(pDIV2->UnitDisks, pDiskInfoV2->UnitDisks, min(pDiskInfoV2->nDiskCount, NDAS_MAX_UNITS_IN_V2) * sizeof(UNIT_DISK_LOCATION)))
			continue;

		if(pDiskInfoV2->nDiskCount > NDAS_MAX_UNITS_IN_V2)
		{
			for(j = NDAS_MAX_UNITS_IN_V2; j < pDiskInfoV2->nDiskCount; j++)
			{
				if(memcmp(&cmd_chk[2 + (j - NDAS_MAX_UNITS_IN_V2) / NDAS_MAX_UNITS_IN_SECTOR].data[(j - NDAS_MAX_UNITS_IN_V2) % NDAS_MAX_UNITS_IN_SECTOR], &pUnitDisk[j], sizeof(UNIT_DISK_LOCATION)))
					continue;
			}
		}

		DebugPrint(1, ("[NDASOpLib] NDAS_Unbind : Clear %d\n", i));

		// ok it is safe to clear
		if(!NDAS_ClearInfo(&(pDiskInfoV2->UnitDisks[i])))
			continue;
	}

//	if(!NDAS_Unbind(pAddress, iTargetID);

	bReturn = TRUE;
	goto out;

chk_v1:
	// Check V1
	cmd.command = WIN_READ;
	cmd.iSector = -1;

	if(!NDAS_IdeIO(pUnitDisk, 1, &cmd, NULL))
		goto out;
	
	pDiskInfoV1 = (PDISK_INFORMATION_BLOCK)cmd.data;

	if(DISK_INFORMATION_SIGNATURE != pDiskInfoV1->Signature)
	{
		// already single
		bReturn = TRUE;
		goto out;
	}

	// only 2 disks bound
	if(
		UNITDISK_TYPE_DVD == pDiskInfoV1->DiskType ||
		UNITDISK_TYPE_VDVD == pDiskInfoV1->DiskType ||
		UNITDISK_TYPE_MO == pDiskInfoV1->DiskType
		)
	{
		goto out;
	}

	if(UNITDISK_TYPE_SINGLE == pDiskInfoV1->DiskType)
	{
		if(!NDAS_ClearInfo(pUnitDisk))
			goto out;
	}
	else
	{
		UNIT_DISK_LOCATION UnitPeer;
		CopyMemory(UnitPeer.MACAddr, pDiskInfoV1->PeerAddress, 6);
		UnitPeer.SlotNumber = pDiskInfoV1->PeerUnitNumber;

		if(!NDAS_ClearInfo(pUnitDisk))
			goto out;

		cmd_chk = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDE_COMMAND_IO));
		cmd_chk->command = WIN_READ;
		cmd_chk->iSector = -1;

		if(
			NDAS_IdeIO(&UnitPeer, 1, cmd_chk, NULL) &&
			0 == memcmp(UnitPeer.MACAddr, ((PDISK_INFORMATION_BLOCK)cmd_chk->data)->PeerAddress, 6) &&
			UnitPeer.SlotNumber == ((PDISK_INFORMATION_BLOCK)cmd_chk->data)->PeerUnitNumber
			)
		{

			if(!NDAS_ClearInfo(&UnitPeer))
				goto out;
		}
	}

	bReturn = TRUE;
out:	

	if(NULL != cmd_chk)
	{
		HeapFree(GetProcessHeap(), 0, cmd_chk);
		cmd_chk = NULL;
	}
	return bReturn;
}
Exemplo n.º 5
0
BOOL NDAS_GetStatus(UNIT_DISK_LOCATION *pUnitDisk, PNDAS_STATUS pStatus)
{
	BOOL bReturn = FALSE;
	IDE_COMMAND_IO cmd[2];
	LONG lResult;

	HKEY hKeyNetDisks;
	HKEY hKey;
	UINT i;
    CHAR     achKey[MAX_KEY_LENGTH];   // buffer for subkey name
    DWORD    cbName;                   // size of name string 
    FILETIME ftLastWriteTime;      // last write time 
	CHAR szAddress[MAX_VALUE_NAME], szAddress2[18];
	UCHAR szSerial[MAX_VALUE_NAME];
	DWORD dwType;
	DWORD dwSize;
	
	LPX_ADDRESS address;
	LANSCSI_PATH path;

	DISK_INFORMATION_BLOCK *pDiskInfoV1;
	DISK_INFORMATION_BLOCK_V2 *pDiskInfoV2;
	
	DebugPrint(1, ("[NDASOpLib] NDAS_GetStatus : %02X:%02X:%02X:%02X:%02X:%02X\n",
		(int)pUnitDisk->MACAddr[0],
		(int)pUnitDisk->MACAddr[1],
		(int)pUnitDisk->MACAddr[2],
		(int)pUnitDisk->MACAddr[3],
		(int)pUnitDisk->MACAddr[4],
		(int)pUnitDisk->MACAddr[5]
		));

	ZeroMemory(&path, sizeof(LANSCSI_PATH));
	CopyMemory(address.Node, pUnitDisk->MACAddr, 6);

	if(NULL == pStatus)
		goto out;

	ZeroMemory(pStatus, sizeof(NDAS_STATUS));

	// Registry check start.
	// AING_TO_DO : use NDAS registry functions
	lResult = RegOpenKeyEx(
		HKEY_LOCAL_MACHINE,
		KEY_NAME_NETDISKS,
		0,
		KEY_READ,
		&hKeyNetDisks
		);

	if(ERROR_SUCCESS != lResult)
		goto out;

	sprintf(szAddress2, "%02x:%02x:%02x:%02x:%02x:%02x",
		pUnitDisk->MACAddr[0],
		pUnitDisk->MACAddr[1],
		pUnitDisk->MACAddr[2],
		pUnitDisk->MACAddr[3],
		pUnitDisk->MACAddr[4],
		pUnitDisk->MACAddr[5]);

	i = 0;

	while(1)
	{
		cbName = MAX_KEY_LENGTH;
		lResult = RegEnumKeyEx(
			hKeyNetDisks,
			i++,
			achKey,
			&cbName,
			NULL,
			NULL,
			NULL,
			&ftLastWriteTime);

		if(ERROR_SUCCESS != lResult)
			goto out;

		lResult = RegOpenKeyEx(
			hKeyNetDisks,
			achKey,
			0,
			KEY_READ,
			&hKey
			);

		if(ERROR_SUCCESS != lResult)
			goto out;

		dwSize = MAX_VALUE_NAME;
		
		lResult = RegQueryValueEx(
			hKey,
			"Address",
			0,
			&dwType,
			szAddress,
			&dwSize);

		if(ERROR_SUCCESS != lResult)
			continue;

		if(stricmp(szAddress, szAddress2))
			continue;

		pStatus->IsRegistered = 1;

		dwSize = MAX_VALUE_NAME;
		
		lResult = RegQueryValueEx(
			hKey,
			"SerialKey",
			0,
			&dwType,
			szSerial,
			&dwSize);

		DebugPrint(1, ("[NDASOpLib] NDAS_GetStatus : lResult  = %d szSerial = %x %x %x %x %x %x %x %x %x, %d\n", 
			lResult,
			(int)szSerial[0],
			(int)szSerial[1],
			(int)szSerial[2],
			(int)szSerial[3],
			(int)szSerial[4],
			(int)szSerial[5],
			(int)szSerial[6],
			(int)szSerial[7],
			(int)szSerial[8],
			(szSerial[8] == 0xff)
			));
		
		if(ERROR_SUCCESS == lResult && szSerial[8] == 0xff)
		{
			pStatus->IsRegisteredWritable = 1;
		}

		break;
	}

	// Registry check end.

	// Connect
	if(!MakeConnection(&address, &path) || (unsigned int)NULL == path.connsock)
	{
		DebugPrint(1, ("[NDASOpLib] NDAS_GetStatus : MakeConnection Failed\n"));
		goto out;
	}

	pStatus->IsAlive = 1;

	// Login
	// if we don't write, login read only
	path.iUserID = (pUnitDisk->SlotNumber +1);

	path.iCommandTag = 0;
	path.HPID = 0;
	path.iHeaderEncryptAlgo = 0;
	path.iDataEncryptAlgo = 0;
	NDAS_SetPassword(address.Node, &path.iPassword);
	path.iSessionPhase = LOGOUT_PHASE;

	if(Login(&path, LOGIN_TYPE_NORMAL))
	{
		DebugPrint(1, ("[NDASOpLib] NDAS_GetStatus : Login Failed\n"));
		goto out;
	}
	
	if(GetDiskInfo(&path, pUnitDisk->SlotNumber))
	{
		DebugPrint(1, ("[NDASOpLib] NDAS_GetStatus : GetDiskInfo Failed\n"));
		goto out;
	}

	if(Logout(&path))
	{
		DebugPrint(1, ("[NDASOpLib] NDAS_GetStatus : Logout Failed\n"));
		goto out;
	}

	if(0 != Discovery(&path))
	{
		DebugPrint(1, ("[NDASOpLib] NDAS_GetStatus : Discovery Failed\n"));
		goto out;
	}

	closesocket(path.connsock);

	pStatus->IsDiscovered = 1;
	pStatus->HWVersion = path.HWVersion;
	pStatus->HWProtoVersion = path.HWProtoVersion;
	pStatus->NrUserReadWrite = path.PerTarget[pUnitDisk->SlotNumber].NRRWHost;
	pStatus->NrUserReadOnly = path.PerTarget[pUnitDisk->SlotNumber].NRROHost;

	if(MEDIA_TYPE_BLOCK_DEVICE != path.PerTarget[pUnitDisk->SlotNumber].MediaType)
	{
		switch(path.PerTarget[pUnitDisk->SlotNumber].MediaType)
		{
		case MEDIA_TYPE_CDROM_DEVICE:
			pStatus->DiskType = NDASSCSI_TYPE_DVD;
			pStatus->IsSupported = 1;
			break;

		case MEDIA_TYPE_OPMEM_DEVICE:
			pStatus->DiskType = NDASSCSI_TYPE_MO;
			pStatus->IsSupported = 1;
			break;
		default:
			pStatus->IsSupported = 0;
		}

		DebugPrint(1, ("[NDASOpLib] NDAS_GetStatus : Packet type %d\n", path.PerTarget[pUnitDisk->SlotNumber].MediaType));
		bReturn = TRUE;
		goto out;
	}

	cmd[0].command = WIN_READ;
	cmd[0].iSector = -1;
	pDiskInfoV1 = (PDISK_INFORMATION_BLOCK)cmd[0].data;
	cmd[1].command = WIN_READ;
	cmd[1].iSector = -2;
	pDiskInfoV2 = (PDISK_INFORMATION_BLOCK_V2)cmd[1].data;

	NDAS_IdeIO(pUnitDisk, 2, cmd, NULL);

	if(DISK_INFORMATION_SIGNATURE_V2 == pDiskInfoV2->Signature)
	{
		pStatus->MajorVersion = pDiskInfoV2->MajorVersion;
		pStatus->MinorVersion = pDiskInfoV2->MinorVersion;

		if(IS_HIGHER_VERSION_V2(*pDiskInfoV2))
			goto out;

		pStatus->IsSupported = 1;

		pStatus->DiskType = 
			(1 == pDiskInfoV2->nDiskCount) ? NDASSCSI_TYPE_DISK_NORMAL :
			(NMT_RAID1 == pDiskInfoV2->iMediaType) ? NDASSCSI_TYPE_DISK_RAID1 :
			(NMT_VDVD == pDiskInfoV2->iMediaType) ? NDASSCSI_TYPE_VDVD :
			NDASSCSI_TYPE_DISK_AGGREGATION;
	}
	else if(DISK_INFORMATION_SIGNATURE == pDiskInfoV1->Signature)
	{
		pStatus->MajorVersion = pDiskInfoV1->MajorVersion;
		pStatus->MinorVersion = pDiskInfoV1->MinorVersion;
		
		if(IS_WRONG_VERSION(*pDiskInfoV1))
			goto out;
	
		pStatus->IsSupported = 1;

		pStatus->DiskType = 
			(UNITDISK_TYPE_SINGLE == pDiskInfoV1->DiskType) ? NDASSCSI_TYPE_DISK_NORMAL :
			(UNITDISK_TYPE_AGGREGATION_FIRST == pDiskInfoV1->DiskType) ? NDASSCSI_TYPE_DISK_AGGREGATION :
			(UNITDISK_TYPE_AGGREGATION_SECOND == pDiskInfoV1->DiskType) ? NDASSCSI_TYPE_DISK_AGGREGATION :
			(UNITDISK_TYPE_AGGREGATION_THIRD == pDiskInfoV1->DiskType) ? NDASSCSI_TYPE_DISK_AGGREGATION :
			(UNITDISK_TYPE_AGGREGATION_FOURTH == pDiskInfoV1->DiskType) ? NDASSCSI_TYPE_DISK_AGGREGATION :
			(UNITDISK_TYPE_MIRROR_MASTER == pDiskInfoV1->DiskType) ? NDASSCSI_TYPE_DISK_RAID1 :
			(UNITDISK_TYPE_MIRROR_SLAVE == pDiskInfoV1->DiskType) ? NDASSCSI_TYPE_DISK_RAID1 :
			(UNITDISK_TYPE_VDVD == pDiskInfoV1->DiskType) ? NDASSCSI_TYPE_VDVD : 0;
	}
	else
	{
		pStatus->MajorVersion = 0;
		pStatus->MinorVersion = 0;
		pStatus->DiskType = NDASSCSI_TYPE_DISK_NORMAL;
		pStatus->IsSupported = 1;
	}

	bReturn = TRUE;
out:
	if(path.connsock)
		closesocket(path.connsock);

	return bReturn;
}