예제 #1
0
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;
}
예제 #2
0
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;
}
예제 #3
0
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;
}
예제 #4
0
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;
}
예제 #5
0
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;
}
예제 #6
0
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;
}
예제 #7
0
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;
}