コード例 #1
0
BOOL
CNdasUnitDevice::UnregisterFromLDM()
{
	ximeta::CAutoLock autolock(this);

	CNdasLogicalDeviceManager* pLDM = pGetNdasLogicalDeviceManager();
	BOOL fSuccess = pLDM->Unregister(*this);
	m_pLogicalDevice->Release();
	_ASSERTE(fSuccess);
	return fSuccess;
}
コード例 #2
0
bool 
CNdasUnitDevice::UnregisterFromLogicalDeviceManager()
{
	InstanceAutoLock autolock(this);
	CNdasLogicalDeviceManager& manager = pGetNdasLogicalDeviceManager();
	if (manager.Unregister(shared_from_this()))
	{
		m_pLogicalDevice.reset();
		return true;
	}
	return false;
}
コード例 #3
0
bool
CNdasUnitDevice::RegisterToLogicalDeviceManager()
{
	InstanceAutoLock autolock(this);

	CNdasLogicalDeviceManager& manager = pGetNdasLogicalDeviceManager();
	m_pLogicalDevice = manager.Register(shared_from_this());
	if (CNdasLogicalDeviceNullPtr == m_pLogicalDevice) 
	{
		XTLTRACE2(NDASSVC_NDASUNITDEVICE, TRACE_LEVEL_ERROR, 
			"Failed to register a unit device to the LDM, error=0x%X\n",
			GetLastError());
		return false;
	}

	return true;
}
コード例 #4
0
DWORD
CNdasService::OnServiceShutdown()
{
	DBGPRT_INFO(_FT("System is shutting down...\n"));

	ReportStatusToSCMgr(SERVICE_STOP_PENDING, 1000);

	CNdasLogicalDeviceManager* pLogDevMan = pGetNdasLogicalDeviceManager();
	pLogDevMan->OnShutdown();

	ReportStatusToSCMgr(SERVICE_STOP_PENDING, 1000);

	(VOID) ::LfsFiltCtlShutdown();

	// TODO: Do I have to stop here?
	this->Stop();

	return NO_ERROR;
}
コード例 #5
0
ファイル: ndaslogdev.cpp プロジェクト: yzx65/ndas4windows
BOOL 
CNdasLogicalDevice::cpCheckPlugInCondForDVD(ACCESS_MASK requestingAccess)
{
	CNdasLogicalDeviceManager* pLdm = pGetNdasLogicalDeviceManager();
	CNdasLogicalDeviceCollection coll;
	pLdm->Lock();
	pLdm->GetItems(coll);
	pLdm->Unlock();

	int mounted = std::count_if(
		coll.begin(), 
		coll.end(), 
		IsLogicalDVDMountedAsRW);

	if (mounted > 0) 
	{
		::SetLastError(NDASHLPSVC_ERROR_NO_MORE_DVD_WRITE_ACCESS_INSTANCE_ALLOWED);
		return FALSE;
	}

	return TRUE;
}
コード例 #6
0
BOOL
CNdasUnitDevice::RegisterToLDM()
{
	ximeta::CAutoLock autolock(this);

	CNdasLogicalDeviceManager* pLDM = pGetNdasLogicalDeviceManager();

	//
	// Support auto-registered devices
	//
	ACCESS_MASK acMountOnReady = 0;
	if (m_pParentDevice->GetAutoRegistered()) {
		acMountOnReady = m_pParentDevice->GetGrantedAccess();
	}

	m_pLogicalDevice = 
		pLDM->Register(*this, acMountOnReady, FALSE);
	if (NULL == m_pLogicalDevice) {
		DBGPRT_ERR_EX(_FT("Failed to register a unit device to the LDM: "));
		return FALSE;
	}

	return TRUE;
}
コード例 #7
0
ファイル: ndaslogdev.cpp プロジェクト: yzx65/ndas4windows
//
// Remove the unit device ID from the list
//
BOOL
CNdasLogicalDevice::RemoveUnitDevice(CNdasUnitDevice& unitDevice)
{
	ximeta::CAutoLock autolock(this);
	DWORD ldSequence = unitDevice.GetLDSequence();

	_ASSERTE(ldSequence < m_logicalDeviceGroup.nUnitDevices);
	if (ldSequence >= m_logicalDeviceGroup.nUnitDevices) {
		DBGPRT_ERR(_FT("Invalid sequence (%d) of the unit device.\n"), ldSequence);
		return FALSE;
	}

	_ASSERTE(&unitDevice == m_pUnitDevices[ldSequence]);
	if (&unitDevice != m_pUnitDevices[ldSequence]) {
		DBGPRT_ERR(_FT("Unit device in sequence (%d) is not occupied.\n"), ldSequence);
		return FALSE;
	}

	m_pUnitDevices[ldSequence]->Release();
	m_pUnitDevices[ldSequence] = NULL;

	//
	// Workaround for Fault-tolerant Mode
	// -> Even if the logical device is incomplete,
	//    Mounted Logical Device Location should be intact
	//    if it is mounted
	//
	if (NDAS_LOGICALDEVICE_STATUS_MOUNT_PENDING == GetStatus() ||
		NDAS_LOGICALDEVICE_STATUS_MOUNTED == GetStatus() ||
		NDAS_LOGICALDEVICE_STATUS_UNMOUNT_PENDING == GetStatus()) 
	{
		--m_nUnitDeviceInstances;
		return TRUE;
	}

	if (IsComplete()) {
		CNdasLogicalDeviceManager* pLdm = pGetNdasLogicalDeviceManager();
		pLdm->UnregisterNdasScsiLocation(m_NdasScsiLocation);
	}

	--m_nUnitDeviceInstances;

	//
	// Deallocation NDAS SCSI Location when the fist unit device is removed
	//
	if (0 == ldSequence) {
		cpDeallocateNdasScsiLocation();
	}

	//
	// Publish Event
	//
	CNdasEventPublisher* pEventPublisher = pGetNdasEventPublisher();
	(VOID) pEventPublisher->LogicalDeviceRelationChanged(m_logicalDeviceId);

	//
	// Set Device Error
	//
	SetLastDeviceError(NDAS_LOGICALDEVICE_ERROR_MISSING_MEMBER);

	return TRUE;
}
コード例 #8
0
ファイル: ndaslogdev.cpp プロジェクト: yzx65/ndas4windows
//
// Set the unit device ID at a sequence 
// to a unit device member ID list
//
BOOL 
CNdasLogicalDevice::AddUnitDevice(CNdasUnitDevice& unitDevice)
{
	ximeta::CAutoLock autolock(this);
	BOOL fSuccess;

	DWORD ldSequence = unitDevice.GetLDSequence();

	_ASSERTE(ldSequence < m_logicalDeviceGroup.nUnitDevices);
	if (ldSequence >= m_logicalDeviceGroup.nUnitDevices) {
		DBGPRT_ERR(_FT("Invalid sequence (%d) of the unit device.\n"), ldSequence);
		return FALSE;
	}

	_ASSERTE(NULL == m_pUnitDevices[ldSequence]);
	if (NULL != m_pUnitDevices[ldSequence]) {
		DBGPRT_ERR(_FT("Sequence (%d) is already occupied.\n"), ldSequence);
		return FALSE;
	}

	_ASSERTE(NULL == m_pUnitDevices[ldSequence]);
	m_pUnitDevices[ldSequence] = &unitDevice;
	m_pUnitDevices[ldSequence]->AddRef();
	++m_nUnitDeviceInstances;

	_ASSERTE(
		m_nUnitDeviceInstances >= 0 && 
		m_nUnitDeviceInstances <= GetUnitDeviceCount()
		);

	if (m_nUnitDeviceInstances < GetUnitDeviceCount()) {
		SetLastDeviceError(NDAS_LOGICALDEVICE_ERROR_MISSING_MEMBER);
	} else {
		SetLastDeviceError(NDAS_LOGICALDEVICE_ERROR_NONE);
	}

	//
	// Allocate NDAS SCSI Location when the first unit device is
	// available
	//
	if (0 == ldSequence) {
		cpAllocateNdasScsiLocation();
	}

	if (IsComplete()) {
		CNdasLogicalDeviceManager* pLdm = pGetNdasLogicalDeviceManager();
		pLdm->RegisterNdasScsiLocation(m_NdasScsiLocation, *this);
	}

	if (IsComplete()) 
	{
		//
		// Reconciliation Support
		//
		BOOL bAlive, bAdapterError;
		fSuccess = ::LsBusCtlQueryNodeAlive(
			m_NdasScsiLocation.SlotNo, 
			&bAlive, 
			&bAdapterError);

		//
		// Reconciliation
		//
		if (fSuccess && bAlive)
		{
			ReconcileFromNdasBus();
		}
	}
	else if (IsComplete() && m_fMountOnReady) 
	{
		//
		// Boot-time Plug In Support
		//

		if ((m_mountOnReadyAccess & GetAllowingAccess()) == 
			m_mountOnReadyAccess)
		{

			(VOID) PlugIn(m_mountOnReadyAccess);

		} else if ((GENERIC_READ & GetAllowingAccess()) && 
			m_fReducedMountOnReadyAccess) 
		{

			(VOID) PlugIn(GENERIC_READ);

		}
	}

	DBGPRT_INFO(_FT("Added %s to Logical Device %s\n"), unitDevice.ToString(), this->ToString());

	CNdasEventPublisher* pEventPublisher = pGetNdasEventPublisher();
	(VOID) pEventPublisher->LogicalDeviceRelationChanged(m_logicalDeviceId);

	return TRUE;
}
コード例 #9
0
ファイル: ndasix.cpp プロジェクト: JanD1943/ndas4windows
BOOL
CNdasIXBcast::BroadcastStatus()
{
	NDASSCSI_QUERY_INFO_DATA NdasScsiQuery;
	NDSCIOCTL_PRIMUNITDISKINFO LurInformation;

	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();

		NdasScsiQuery.InfoClass = NdscPrimaryUnitDiskInformation;
		NdasScsiQuery.Length = sizeof(NDASSCSI_QUERY_INFO_DATA);
		NdasScsiQuery.NdasScsiAddress.SlotNo = location;
		NdasScsiQuery.QueryDataLength = 0;

		XTL::AutoFileHandle	handle = pOpenStorageDeviceByNumber(
			pLogDevice->GetDeviceNumberHint(),
			GENERIC_WRITE|GENERIC_READ);

		BOOL fSuccess = NdasPortCtlQueryInformation(
			handle,
			&NdasScsiQuery,
			sizeof(NDASSCSI_QUERY_INFO_DATA),
			&LurInformation,
			sizeof(NDSCIOCTL_PRIMUNITDISKINFO));

		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 (LurInformation.Lur.DeviceMode == DEVMODE_SHARED_READWRITE &&
			!(LurInformation.Lur.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;
}
コード例 #10
0
ファイル: ndasix.cpp プロジェクト: yzx65/ndas4windows
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;
}