LSBUSCTLAPI BOOL WINAPI LsBusCtlQueryPdoSlotList( PBUSENUM_INFORMATION *BusInfo ) { BOOL bret; BUSENUM_QUERY_INFORMATION query; BUSENUM_INFORMATION tmpInfo; PBUSENUM_INFORMATION info; LONG infoLen; *BusInfo = NULL; query.Size = sizeof(query); query.InfoClass = INFORMATION_PDOSLOTLIST; query.Flags = 0; query.SlotNo = 0; bret = LsBusCtlQueryInformation( &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 = LsBusCtlQueryInformation( &query, sizeof(query), info, infoLen ); if(bret == FALSE) { HeapFree(GetProcessHeap(), 0, info); return FALSE; } *BusInfo = info; return TRUE; }
LSBUSCTLAPI BOOL WINAPI LsBusCtlQueryStatus( ULONG SlotNo, PULONG pStatus) { BOOL fSuccess = FALSE; BUSENUM_QUERY_INFORMATION Query; BUSENUM_INFORMATION Information; // // Query AccessRight to LanscsiBus // Query.InfoClass = INFORMATION_PDO; Query.Size = sizeof(Query) ; Query.SlotNo = SlotNo; fSuccess = LsBusCtlQueryInformation( &Query, sizeof(Query), &Information, sizeof(Information)); if (!fSuccess) { return FALSE; } // lsminiportioctl.h // ADAPTERINFO_STATUS_* // ADAPTERINFO_STATUSFLAG_* *pStatus = Information.PdoInfo.AdapterStatus; return TRUE; }
LSBUSCTLAPI BOOL WINAPI LsBusCtlQueryStatus( ULONG SlotNo, PULONG pStatus) { BOOL fSuccess = FALSE; BUSENUM_QUERY_INFORMATION Query; BUSENUM_INFORMATION Information; // // Query AccessRight to LanscsiBus // Query.InfoClass = INFORMATION_PDO; Query.Size = sizeof(Query) ; Query.SlotNo = SlotNo; fSuccess = LsBusCtlQueryInformation( &Query, sizeof(Query), &Information, sizeof(Information)); if (!fSuccess) { return FALSE; } // if(Information.UnitDisk.StatusFlags & ADAPTERINFO_STATUS_RECONNECTFAILED) { // *pAlarmStatus = ALARM_STATUS_FAIL_RECONNECT; // } else *pStatus = Information.PdoInfo.AdapterStatus; /* if(ADAPTERINFO_ISSTATUSFLAG( Information.PdoInfo.AdapterStatus, ADAPTERINFO_STATUSFLAG_RECONNECT_PENDING)) { *pAlarmStatus = LSBUSCTL_ALARM_STATUS_START_RECONNECT; } else { *pAlarmStatus = LSBUSCTL_ALARM_STATUS_NORMAL; } */ return TRUE; }
LSBUSCTLAPI BOOL WINAPI LsBusCtlQueryPdoEvent( ULONG SlotNo, PHANDLE AlarmEvent, PHANDLE DisconnectEvent ) { BOOL bret; BUSENUM_QUERY_INFORMATION query; BUSENUM_INFORMATION tmpInfo; query.Size = sizeof(query); query.InfoClass = INFORMATION_PDOEVENT; query.Flags = LSBUS_QUERYFLAG_USERHANDLE; query.SlotNo = SlotNo; bret = LsBusCtlQueryInformation( &query, sizeof(query), &tmpInfo, sizeof(tmpInfo) ); if(bret == FALSE) { return FALSE; } if(!(tmpInfo.PdoEvents.Flags & LSBUS_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; }
LSBUSCTLAPI BOOL WINAPI LsBusCtlQueryPdoFileHandle( ULONG SlotNo, PHANDLE PdoFileHandle) { BOOL bret; BUSENUM_QUERY_INFORMATION query; BUSENUM_INFORMATION tmpInfo; query.Size = sizeof(query); query.InfoClass = INFORMATION_PDOFILEHANDLE; query.Flags = LSBUS_QUERYFLAG_USERHANDLE; query.SlotNo = SlotNo; bret = LsBusCtlQueryInformation( &query, sizeof(query), &tmpInfo, sizeof(tmpInfo) ); if(bret == FALSE) { return FALSE; } if(!(tmpInfo.PdoEvents.Flags & LSBUS_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; }
BOOLEAN LsBusCtlQueryAlarmStatus( ULONG SlotNo, PULONG AlarmStatus) { BOOLEAN BRet ; BUSENUM_QUERY_INFORMATION Query; BUSENUM_INFORMATION Information; // // Query AccessRight to LanscsiBus // Query.InfoClass = INFORMATION_PDO; Query.Size = sizeof(Query) ; Query.SlotNo = SlotNo; BRet = LsBusCtlQueryInformation( &Query, sizeof(Query), &Information, sizeof(Information)); if(BRet == FALSE) { return FALSE; } // if(Information.UnitDisk.StatusFlags & ADAPTERINFO_STATUS_RECONNECTFAILED) { // *AlarmStatus = ALARM_STATUS_FAIL_RECONNECT; // } else if(ADAPTERINFO_ISSTATUSFLAG(Information.PdoInfo.AdapterStatus, ADAPTERINFO_STATUSFLAG_RECONNECTPENDING)) { *AlarmStatus = ALARM_STATUS_START_RECONNECT; } else { *AlarmStatus = ALARM_STATUS_NORMAL; } return BRet; }
BOOL CNdasIXBcast::BroadcastStatus() { BUSENUM_QUERY_INFORMATION BusEnumQuery; BUSENUM_INFORMATION BusEnumInformation; CNdasLogicalDeviceManager* pLdm = pGetNdasLogicalDeviceManager(); CNdasLogicalDeviceCollection coll; pLdm->Lock(); pLdm->GetItems(coll); pLdm->Unlock(); for (CNdasLogicalDeviceCollection::const_iterator itr = coll.begin(); itr != coll.end(); ++itr) { CNdasLogicalDevice* pLogDevice = *itr; if (NDAS_LOGICALDEVICE_STATUS_MOUNTED != pLogDevice->GetStatus()) { continue; } CONST NDAS_SCSI_LOCATION& location = pLogDevice->GetNdasScsiLocation(); BusEnumQuery.InfoClass = INFORMATION_PDO; BusEnumQuery.Size = sizeof(BUSENUM_QUERY_INFORMATION); BusEnumQuery.SlotNo = location.SlotNo; BOOL fSuccess = LsBusCtlQueryInformation( &BusEnumQuery, sizeof(BUSENUM_QUERY_INFORMATION), &BusEnumInformation, sizeof(BUSENUM_INFORMATION)); if (!fSuccess) { DPErrorEx(_FT("LanscsiQueryInformation failed at slot %d: "), location.SlotNo); continue; } // // Broadcast a primary write access status // if (ND_ACCESS_ISRW(BusEnumInformation.PdoInfo.GrantedAccess)) { 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); _ASSERTE(sizeof(pixData->Update.NetDiskNode) == sizeof(unitDeviceId.DeviceId)); ::CopyMemory( pixData->Update.NetDiskNode, unitDeviceId.DeviceId.Node, sizeof(pixData->Update.NetDiskNode)); pixData->Update.UnitDiskNo = 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; _ASSERTE(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) { DPWarningEx(_FT("Sending a packet failed: ")); } } // 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; }