NDASBUSCTLAPI BOOL WINAPI NdasBusCtlQueryPdoSlotList( PNDASBUS_INFORMATION *BusInfo ) { BOOL bret; NDASBUS_QUERY_INFORMATION query; NDASBUS_INFORMATION tmpInfo; PNDASBUS_INFORMATION info; LONG infoLen; *BusInfo = NULL; query.Size = sizeof(query); query.InfoClass = INFORMATION_PDOSLOTLIST; query.Flags = 0; query.SlotNo = 0; bret = NdasBusCtlQueryInformation( &query, sizeof(query), &tmpInfo, sizeof(tmpInfo) ); if(bret == FALSE) { if(GetLastError() != ERROR_INSUFFICIENT_BUFFER) { return FALSE; } } infoLen = tmpInfo.Size; info = HeapAlloc(GetProcessHeap(), 0, infoLen); if (NULL == info) { SetLastError(ERROR_OUTOFMEMORY); return FALSE; } bret = NdasBusCtlQueryInformation( &query, sizeof(query), info, infoLen ); if(bret == FALSE) { HeapFree(GetProcessHeap(), 0, info); return FALSE; } *BusInfo = info; return TRUE; }
NDASBUSCTLAPI BOOL WINAPI NdasBusCtlQueryEvent( ULONG SlotNo, PULONG pStatus) { BOOL fSuccess = FALSE; NDASBUS_QUERY_INFORMATION Query; NDASBUS_INFORMATION Information; // // Query AccessRight to LanscsiBus // Query.InfoClass = INFORMATION_PDO; Query.Size = sizeof(Query) ; Query.SlotNo = SlotNo; Query.Flags = NDASBUS_QUERYFLAG_EVENTQUEUE; fSuccess = NdasBusCtlQueryInformation( &Query, sizeof(Query), &Information, sizeof(Information)); if (!fSuccess) { return FALSE; } // ndasscsiioctl.h // ADAPTERINFO_STATUS_* // ADAPTERINFO_STATUSFLAG_* *pStatus = Information.PdoInfo.AdapterStatus; return TRUE; }
NDASBUSCTLAPI BOOL WINAPI NdasBusCtlQueryDeviceMode( ULONG SlotNo, PULONG pDeviceMode) { BOOL fSuccess = FALSE; NDASBUS_QUERY_INFORMATION Query; NDASBUS_INFORMATION Information; // // Query AccessRight to LanscsiBus // Query.InfoClass = INFORMATION_PDO; Query.Size = sizeof(Query); Query.SlotNo = SlotNo; Query.Flags = 0; fSuccess = NdasBusCtlQueryInformation( &Query, sizeof(Query), &Information, sizeof(Information)); if (!fSuccess) { return FALSE; } // lurdesc.h // DEVMODE_* *pDeviceMode = Information.PdoInfo.DeviceMode; return TRUE; }
NDASBUSCTLAPI BOOL WINAPI NdasBusCtlQueryPdoEvent( ULONG SlotNo, PHANDLE AlarmEvent, PHANDLE DisconnectEvent ) { BOOL bret; NDASBUS_QUERY_INFORMATION query; NDASBUS_INFORMATION tmpInfo; query.Size = sizeof(query); query.InfoClass = INFORMATION_PDOEVENT; query.Flags = NDASBUS_QUERYFLAG_USERHANDLE; query.SlotNo = SlotNo; bret = NdasBusCtlQueryInformation( &query, sizeof(query), &tmpInfo, sizeof(tmpInfo) ); if(bret == FALSE) { return FALSE; } if(!(tmpInfo.PdoEvents.Flags & NDASBUS_QUERYFLAG_USERHANDLE)) { SetLastError(ERROR_INVALID_DATA); return FALSE; } if(tmpInfo.PdoEvents.SlotNo != SlotNo) { SetLastError(ERROR_INVALID_DATA); return FALSE; } *AlarmEvent = tmpInfo.PdoEvents.AlarmEvent; *DisconnectEvent = tmpInfo.PdoEvents.DisconEvent; return TRUE; }
NDASBUSCTLAPI BOOL WINAPI NdasBusCtlQueryPdoFileHandle( ULONG SlotNo, PHANDLE PdoFileHandle) { BOOL bret; NDASBUS_QUERY_INFORMATION query; NDASBUS_INFORMATION tmpInfo; query.Size = sizeof(query); query.InfoClass = INFORMATION_PDOFILEHANDLE; query.Flags = NDASBUS_QUERYFLAG_USERHANDLE; query.SlotNo = SlotNo; bret = NdasBusCtlQueryInformation( &query, sizeof(query), &tmpInfo, sizeof(tmpInfo) ); if(bret == FALSE) { return FALSE; } if(!(tmpInfo.PdoEvents.Flags & NDASBUS_QUERYFLAG_USERHANDLE)) { SetLastError(ERROR_INVALID_DATA); return FALSE; } if(tmpInfo.PdoEvents.SlotNo != SlotNo) { SetLastError(ERROR_INVALID_DATA); return FALSE; } *PdoFileHandle = tmpInfo.PdoFile.PdoFileHandle; return TRUE; }
BOOL CNdasIXBcast::BroadcastStatus() { NDASBUS_QUERY_INFORMATION BusEnumQuery; NDASBUS_INFORMATION BusEnumInformation; CNdasLogicalDeviceManager& manager = pGetNdasLogicalDeviceManager(); CNdasLogicalDeviceVector logDevices; manager.Lock(); manager.GetItems(logDevices); manager.Unlock(); for (CNdasLogicalDeviceVector::const_iterator itr = logDevices.begin(); itr != logDevices.end(); ++itr) { CNdasLogicalDevicePtr pLogDevice = *itr; if (NDAS_LOGICALDEVICE_STATUS_MOUNTED != pLogDevice->GetStatus()) { continue; } CONST NDAS_LOCATION& location = pLogDevice->GetNdasLocation(); BusEnumQuery.InfoClass = INFORMATION_PDO; BusEnumQuery.Size = sizeof(NDASBUS_QUERY_INFORMATION); BusEnumQuery.SlotNo = location; BusEnumQuery.Flags = 0; BOOL fSuccess = NdasBusCtlQueryInformation( &BusEnumQuery, sizeof(NDASBUS_QUERY_INFORMATION), &BusEnumInformation, sizeof(NDASBUS_INFORMATION)); if (!fSuccess) { XTLTRACE2(NDASSVC_IX, TRACE_LEVEL_ERROR, "LanscsiQueryInformation failed, slot=%d, error=0x%X\n", location, GetLastError()); continue; } // // Broadcast a primary write access status // if (BusEnumInformation.PdoInfo.DeviceMode == DEVMODE_SHARED_READWRITE && !(BusEnumInformation.PdoInfo.EnabledFeatures & NDASFEATURE_SECONDARY)) { const DWORD cbBuffer = sizeof(LSINFOX_HEADER) + sizeof(LSINFOX_PRIMARY_UPDATE); BYTE lpbBuffer[cbBuffer] = {0}; PLSINFOX_HEADER pixHeader = reinterpret_cast<PLSINFOX_HEADER>(lpbBuffer); PLSINFOX_DATA pixData = reinterpret_cast<PLSINFOX_DATA>(lpbBuffer + sizeof(LSINFOX_HEADER)); // // CAUTION: InfoExchange Protocol uses little-endian (Intel) // // // Header // UCHAR ixProtocolName[4] = INFOX_DATAGRAM_PROTOCOL; ::CopyMemory(pixHeader->Protocol, ixProtocolName, 4); pixHeader->LSInfoXMajorVersion = INFOX_DATAGRAM_MAJVER; pixHeader->LSInfoXMinorVersion = INFOX_DATAGRAM_MINVER; pixHeader->OsMajorType = OSTYPE_WINDOWS; DWORD dwOSMajorVersion, dwOSMinorVersion; pGetOSVersion(&dwOSMajorVersion, &dwOSMinorVersion); USHORT usLfsOsMinorType = pInfoXGetOSType(dwOSMajorVersion, dwOSMinorVersion); pixHeader->OsMinorType = usLfsOsMinorType; pixHeader->Type = LSINFOX_PRIMARY_UPDATE_MESSAGE; pixHeader->MessageSize = cbBuffer; // // Data // // primary node is dependent to each interface pixData->Update.PrimaryNode; pixData->Update.PrimaryPort = LPXRP_LFS_PRIMARY; pixData->Update.SWMajorVersion = NDASIX_VERSION_MAJOR; // TODO: Change these values pixData->Update.SWMinorVersion = NDASIX_VERSION_MINOR; pixData->Update.SWBuildNumber = NDASIX_VERSION_BUILD; pixData->Update.NDFSCompatVersion = m_NDFSVersion.wMajor; pixData->Update.NDFSVersion = m_NDFSVersion.wMinor; // // NetDisk Node is a property of each unit device // pixData->Update.NetDiskNode; // // We have fixed the port // (CNdasDevice does not store Port Number internally) // Do not try to retrieve from GetRemoteLpxAddress() // pixData->Update.NetDiskPort = NDAS_DEVICE_LPX_PORT; // // Unit Disk Number is a property of each unit device // pixData->Update.UnitDiskNo; // // pLogDevice->GetStatus() // for (DWORD n = 0; n < pLogDevice->GetUnitDeviceCount(); ++n) { // // Actually, we should traverse the real entry // from the device registrar. // However, here we do the shortcut for using NDAS device id // and fixed NetDiskPort, etc. // NDAS_UNITDEVICE_ID unitDeviceId = pLogDevice->GetUnitDeviceID(n); C_ASSERT(sizeof(pixData->Update.NetDiskNode) == sizeof(unitDeviceId.DeviceId.Node)); ::CopyMemory( pixData->Update.NetDiskNode, unitDeviceId.DeviceId.Node, sizeof(pixData->Update.NetDiskNode)); pixData->Update.UnitDiskNo = static_cast<USHORT>(unitDeviceId.UnitNo); // // Broadcast the data to every interface // for (DWORD i = 0; i < MAX_SOCKETLPX_INTERFACE; ++i) { if (INVALID_SOCKET != (SOCKET) m_senders[i]) { // // Fill the Primary Node (LPX Address Node) // LPX_ADDRESS localLpxAddress = m_senders[i].GetBoundAddr()->LpxAddress; C_ASSERT(sizeof(pixData->Update.PrimaryNode) == sizeof(localLpxAddress.Node)); ::CopyMemory( pixData->Update.PrimaryNode, localLpxAddress.Node, sizeof(pixData->Update.PrimaryNode)); // // Send the data // DWORD cbSent = 0; BOOL fSuccess = m_senders[i].SendToSync( &NDASIX_BCAST_ADDR, cbBuffer, lpbBuffer, 0, &cbSent); if (!fSuccess) { XTLTRACE2(NDASSVC_IX, TRACE_LEVEL_ERROR, "SendToSync failed, bytes=%d, error=0x%X\n", cbBuffer, GetLastError()); } } // end if } // for each local LPX address } // for each unit device } // if the logical device has a primary write access. } // for each logical device return TRUE; }
int __cdecl _tmain(int argc, LPTSTR* argv) { BOOL fSuccess(FALSE); ULONG SlotNo; BOOL bret; if(argc < 2) { usage(); return 1; } if (lstrcmpi(argv[1],TEXT("version")) == 0) { WORD VersionMajor; WORD VersionMinor; WORD VersionBuild; WORD VersionPrivate; bret = NdasBusCtlGetVersion( &VersionMajor, &VersionMinor, &VersionBuild, &VersionPrivate ); if(bret == FALSE) { _tprintf(TEXT("LanscsiBus control failed. LastError:%lu\n"), GetLastError()); } else { _tprintf(TEXT("- LanscsiBus version\n")); _tprintf( TEXT("Major : %u\n") TEXT("Minor : %u\n") TEXT("Build : %u\n") TEXT("Private : %u\n"), VersionMajor, VersionMinor, VersionBuild, VersionPrivate); } #if 0 } else if(lstrcmpi(argv[1],TEXT("mpversion")) == 0) { WORD VersionMajor; WORD VersionMinor; WORD VersionBuild; WORD VersionPrivate; if(argc < 3) { usage(); return 1; } SlotNo = _tstoi(argv[2]); bret = NdasBusCtlGetMiniportVersion( SlotNo, &VersionMajor, &VersionMinor, &VersionBuild, &VersionPrivate ); if(bret == FALSE) { _tprintf(TEXT("NDASSCSI control failed. LastError:%lu\n"), GetLastError()); } else { _tprintf(TEXT("- NDASSCSI version\n")); _tprintf( TEXT("Major : %u\n") TEXT("Minor : %u\n") TEXT("Build : %u\n") TEXT("Private : %u\n"), VersionMajor, VersionMinor, VersionBuild, VersionPrivate); } #endif } else if(lstrcmpi(argv[1],TEXT("slotlist")) == 0) { PNDASBUS_INFORMATION busInfo; bret = NdasBusCtlQueryPdoSlotList(&busInfo); if(bret == FALSE) { _tprintf(TEXT("Querying slot list failed. LastError:%lu\n"), GetLastError()); } else { ULONG idx_slot; _tprintf(TEXT("Slot list:")); for(idx_slot = 0; idx_slot < busInfo->PdoSlotList.SlotNoCnt; idx_slot++ ) { _tprintf(TEXT(" %lu"), busInfo->PdoSlotList.SlotNo[idx_slot]); } _tprintf(TEXT("\n")); HeapFree(GetProcessHeap(), 0, busInfo); } } else if(lstrcmpi(argv[1],TEXT("pdoinfo")) == 0) { NDASBUS_QUERY_INFORMATION BusEnumQuery = {0}; NDASBUS_INFORMATION BusEnumInformation = {0}; if(argc < 3) { usage(); return 1; } SlotNo = _tstoi(argv[2]); // // Get default priamry/secondary information from the NDAS bus drver. // BusEnumQuery.InfoClass = INFORMATION_PDO; BusEnumQuery.Size = sizeof(NDASBUS_QUERY_INFORMATION); BusEnumQuery.SlotNo = SlotNo; BusEnumQuery.Flags = 0; bret = NdasBusCtlQueryInformation( &BusEnumQuery, sizeof(NDASBUS_QUERY_INFORMATION), &BusEnumInformation, sizeof(NDASBUS_INFORMATION)); if(bret == FALSE) { _tprintf(TEXT("NdasBusCtlQueryInformation failed. LASTERR=%x\n"), GetLastError()); return 1; } _tprintf(TEXT("Ndas logical address: %d\n"), SlotNo); _tprintf(TEXT("Adapter status : %08lx\n"), BusEnumInformation.PdoInfo.AdapterStatus); _tprintf(TEXT("Device mode : %08lx\n"), BusEnumInformation.PdoInfo.DeviceMode); _tprintf(TEXT("Supported features: %08lx\n"), BusEnumInformation.PdoInfo.SupportedFeatures); _tprintf(TEXT("Enabled features : %08lx\n"), BusEnumInformation.PdoInfo.EnabledFeatures); } else if(lstrcmpi(argv[1],TEXT("pdoevent")) == 0) { ULONG ulStatus; if(argc < 3) { usage(); return 1; } SlotNo = _tstoi(argv[2]); bret = NdasBusCtlQueryEvent(SlotNo, &ulStatus); if(bret == FALSE) { DWORD lastError = GetLastError(); if(lastError == ERROR_NO_MORE_ITEMS) { _tprintf(TEXT("No more event exists.\n")); } else if(lastError == ERROR_FILE_NOT_FOUND) { _tprintf(TEXT("No PDO exists.\n")); } else { _tprintf(TEXT("Querying PDO event failed. LastError:%lu\n"), GetLastError()); } } else { PrintStatus(ulStatus); } } else if(lstrcmpi(argv[1],TEXT("pdoeventptr")) == 0) { HANDLE alarm; HANDLE discon; if(argc < 3) { usage(); return 1; } SlotNo = _tstoi(argv[2]); bret = NdasBusCtlQueryPdoEvent(SlotNo, &alarm, &discon); if(bret == FALSE) { _tprintf(TEXT("Querying pdo events failed. LastError:%lu\n"), GetLastError()); } else { _tprintf( TEXT("Alarm event : %p\n") TEXT("Disconnection event: %p\n"), alarm, discon ); bret = CloseHandle(alarm); if(bret == FALSE) { _tprintf(TEXT("Closing alarm event failed. LastError:%lu\n"), GetLastError()); } bret = CloseHandle(discon); if(bret == FALSE) { _tprintf(TEXT("Closing disconnection event failed. LastError:%lu\n"), GetLastError()); } } } else if(lstrcmpi(argv[1],TEXT("status")) == 0) { ULONG ulStatus; if(argc < 3) { usage(); return 1; } SlotNo = _tstoi(argv[2]); bret = NdasBusCtlQueryStatus(SlotNo, &ulStatus); if(bret == FALSE) { _tprintf(TEXT("Querying PDO status failed. LastError:%lu\n"), GetLastError()); } else { PrintStatus(ulStatus); } } else if(lstrcmpi(argv[1],TEXT("fdoinfo")) == 0) { PNDSCIOCTL_LURINFO lurFullInfo; if(argc < 3) { usage(); return 1; } SlotNo = _tstoi(argv[2]); bret = NdasBusCtlQueryMiniportFullInformation(SlotNo, &lurFullInfo); if(bret == FALSE) { _tprintf(TEXT("Querying LUR full information failed. LastError:%lu\n"), GetLastError()); } else { ULONG idx_ud; PNDSC_LURN_FULL unitDisk; _tprintf(TEXT("Structure length :%u\n"), lurFullInfo->Length); _tprintf(TEXT("Lur.Length :%u\n"), lurFullInfo->Lur.Length); _tprintf(TEXT("Lur.DevType :%08lx\n"), lurFullInfo->Lur.DevType); _tprintf(TEXT("Lur.TargetId :%u\n"), lurFullInfo->Lur.TargetId); _tprintf(TEXT("Lur.Lun :%u\n"), lurFullInfo->Lur.Lun); _tprintf(TEXT("Lur.DeviceMode :%08lx\n"), lurFullInfo->Lur.DeviceMode); _tprintf(TEXT("Lur.SupportedFeatures :%08lx\n"), lurFullInfo->Lur.SupportedFeatures); _tprintf(TEXT("Lur.EnabledFeatures :%08lx\n"), lurFullInfo->Lur.EnabledFeatures); _tprintf(TEXT("Lur.LurnCnt :%u\n"), lurFullInfo->Lur.LurnCnt); _tprintf(TEXT("EnableTime :%I64u\n"), lurFullInfo->EnabledTime.QuadPart); _tprintf(TEXT("UnitDiskCnt :%u\n"), lurFullInfo->UnitDiskCnt); for(idx_ud = 0; idx_ud < lurFullInfo->UnitDiskCnt; idx_ud++) { unitDisk = lurFullInfo->UnitDisks + idx_ud; _tprintf(TEXT("- LURN #%u :\n"), idx_ud); _tprintf(TEXT("Length :%u\n"), unitDisk->Length); _tprintf(TEXT("LurnId :%u\n"), unitDisk->LurnId); _tprintf(TEXT("LurnType :%u\n"), unitDisk->LurnType); _tprintf(TEXT("NetDiskAddress.TAAddressCount :%u\n"), unitDisk->NetDiskAddress.TAAddressCount); _tprintf(TEXT("NetDiskAddress.Address[0].AddressType :%x\n"), unitDisk->NetDiskAddress.Address[0].AddressType); _tprintf(TEXT("NetDiskAddress.Address[0].AddressLength :%x\n"), unitDisk->NetDiskAddress.Address[0].AddressLength); _tprintf(TEXT("NetDiskAddress.Address[0].Address :%02X %02X | %02X %02X %02X %02X %02X %02X\n"), (int)unitDisk->NetDiskAddress.Address[0].Address.Address[0], (int)unitDisk->NetDiskAddress.Address[0].Address.Address[1], (int)unitDisk->NetDiskAddress.Address[0].Address.Address[2], (int)unitDisk->NetDiskAddress.Address[0].Address.Address[3], (int)unitDisk->NetDiskAddress.Address[0].Address.Address[4], (int)unitDisk->NetDiskAddress.Address[0].Address.Address[5], (int)unitDisk->NetDiskAddress.Address[0].Address.Address[6], (int)unitDisk->NetDiskAddress.Address[0].Address.Address[7] ); _tprintf(TEXT("BindingAddress.TAAddressCount :%u\n"), unitDisk->BindingAddress.TAAddressCount); _tprintf(TEXT("BindingAddress.Address[0].AddressType :%x\n"), unitDisk->BindingAddress.Address[0].AddressType); _tprintf(TEXT("BindingAddress.Address[0].AddressLength :%x\n"), unitDisk->BindingAddress.Address[0].AddressLength); _tprintf(TEXT("BindingAddress.Address[0].Address :%02X %02X | %02X %02X %02X %02X %02X %02X\n"), (int)unitDisk->BindingAddress.Address[0].Address.Address[0], (int)unitDisk->BindingAddress.Address[0].Address.Address[1], (int)unitDisk->BindingAddress.Address[0].Address.Address[2], (int)unitDisk->BindingAddress.Address[0].Address.Address[3], (int)unitDisk->BindingAddress.Address[0].Address.Address[4], (int)unitDisk->BindingAddress.Address[0].Address.Address[5], (int)unitDisk->BindingAddress.Address[0].Address.Address[6], (int)unitDisk->BindingAddress.Address[0].Address.Address[7] ); _tprintf(TEXT("UnitDiskId :%u\n"), (int)unitDisk->UnitDiskId); _tprintf(TEXT("UserID :%02x %02x %02x %02x\n"), (int)unitDisk->UserID[0], (int)unitDisk->UserID[1], (int)unitDisk->UserID[2], (int)unitDisk->UserID[3] ); _tprintf(TEXT("Password :%02x %02x %02x %02x %02x %02x\n"), (int)unitDisk->Password[0], (int)unitDisk->Password[1], (int)unitDisk->Password[2], (int)unitDisk->Password[3], (int)unitDisk->Password[4], (int)unitDisk->Password[5] ); _tprintf(TEXT("AccessRight :%08lx\n"), unitDisk->AccessRight); _tprintf(TEXT("UnitBlocks :%u\n"), unitDisk->UnitBlocks); _tprintf(TEXT("StatusFlags :%u\n"), unitDisk->StatusFlags); } _tprintf(TEXT("\n")); HeapFree(GetProcessHeap(), 0, lurFullInfo); } } else if(lstrcmpi(argv[1],TEXT("pdofile")) == 0) { HANDLE pdoFileHandle; SlotNo = _tstoi(argv[2]); bret = NdasBusCtlQueryPdoFileHandle(SlotNo, &pdoFileHandle); if(bret == FALSE) { _tprintf(TEXT("Querying PDO file handle failed. LastError:%lu\n"), GetLastError()); } else { _tprintf(TEXT("PDO file handle :%p\n"), pdoFileHandle); CloseHandle(pdoFileHandle); } } else { usage(); } return fSuccess ? 0 : 1; }