示例#1
0
HRESULT 
CNdasUnitImpl::ImplInitialize(
	__in INdasDevice* pNdasDevice, 
	__in DWORD UnitNo,
	__in NDAS_UNITDEVICE_TYPE Type,
	__in NDAS_UNITDEVICE_SUBTYPE SubType,
	__in const NDAS_UNITDEVICE_HARDWARE_INFO& HardwareInfo,
	__in const NDAS_LOGICALUNIT_DEFINITION& NdasLogicalUnitDefinition,
	__in DWORD LuSequence)
{
	m_pParentNdasDevice = pNdasDevice;
	m_unitDeviceId = pCreateUnitDeviceId(pNdasDevice,UnitNo);
	m_type = Type;
	m_subType = SubType;
	m_status = NDAS_UNITDEVICE_STATUS_NOT_MOUNTED;
	m_lastError = NDAS_UNITDEVICE_ERROR_NONE;
	m_udinfo = HardwareInfo;
	m_NdasLogicalUnitDefinition = NdasLogicalUnitDefinition;
	m_NdasLogicalUnitSequence = LuSequence;

	XTLTRACE2(NDASSVC_NDASUNITDEVICE, TRACE_LEVEL_INFORMATION,
		"NdasUnit=%p, %s\n", this, CNdasUnitDeviceId(m_unitDeviceId).ToStringA());

	DWORD slotNo;
	COMVERIFY(pNdasDevice->get_SlotNo(&slotNo));

	COMVERIFY( StringCchPrintf(
		m_szRegContainer,
		30,
		_T("Devices\\%04d\\%04d"),
		slotNo,
		m_unitDeviceId.UnitNo));

	return S_OK;
}
DWORD 
CNdasAutoRegister::ThreadStart(HANDLE hStopEvent)
{
	CCoInitialize coinit(COINIT_MULTITHREADED);

	XTLASSERT(!m_hSemQueue.IsInvalid() && "Don't forget to call initialize().");

	// Queue Semaphore, Terminating Thread, Pipe Instances(MAX...)
	HANDLE hWaitHandles[2] = { hStopEvent, m_hSemQueue };

	CNdasDeviceHeartbeatListener& listener = pGetNdasDeviceHeartbeatListener();

	COMVERIFY(listener.Advise(this));

	do 
	{
		DWORD waitResult = ::WaitForMultipleObjects(
			RTL_NUMBER_OF(hWaitHandles), 
			hWaitHandles, 
			FALSE, INFINITE);

		if (WAIT_OBJECT_0 == waitResult) 
		{
			break;
		} 
		else if (WAIT_OBJECT_0 + 1 == waitResult) 
		{
			while (TRUE) 
			{
				m_queueLock.LockInstance();
				if (m_queue.empty()) 
				{
					m_queueLock.UnlockInstance();
					break;
				}
				QUEUE_ENTRY entry = m_queue.front();
				m_queue.pop();
				m_queueLock.UnlockInstance();
				(VOID) ProcessRegister(entry.deviceID, entry.access);
			}
		} 
		else 
		{
			XTLASSERT(FALSE);
			// ERROR
		}

	} while (TRUE);

	COMVERIFY(listener.Unadvise(this));

	return 0;
}
void
CNdasEventMonitor::OnLogicalDeviceAlarmedByPnP(
	__in INdasLogicalUnit* pNdasLogicalUnit, 
	__in ULONG NewAdapterStatus)
{
	NDAS_LOCATION ndasLocation;
	COMVERIFY(pNdasLogicalUnit->get_Id(&ndasLocation));

	XTLTRACE2(NDASSVC_EVENTMON, TRACE_LEVEL_INFORMATION,
		"Alarm Event, ndasLocation=%08X, logicalUnit=%p\n", 
		ndasLocation, pNdasLogicalUnit);

	if (0 == ndasLocation) 
	{
		XTLTRACE2(NDASSVC_EVENTMON, TRACE_LEVEL_ERROR,
			"Invalid SCSI Location\n");
		XTLASSERT(FALSE);
		return;
	}

	XTLTRACE2(NDASSVC_EVENTMON, TRACE_LEVEL_INFORMATION,
		"Logical device alarmed by PnP, ndasLocation=%08X, adapterStatus=%08X.\n", 
		ndasLocation, NewAdapterStatus);

	// Determine whether an alarm will be issued.
	// Only viable alarm will be published
	ULONG currentAdapterStatus;
	COMVERIFY(pNdasLogicalUnit->get_AdapterStatus(&currentAdapterStatus));

	if (pIsViableAlarmStatus(currentAdapterStatus, NewAdapterStatus))
	{
		CNdasEventPublisher& epub = pGetNdasEventPublisher();

		if (ADAPTERINFO_ISSTATUS(NewAdapterStatus, NDASSCSI_ADAPTER_STATUS_STOPPED) &&
			ADAPTERINFO_ISSTATUSFLAG(NewAdapterStatus, NDAS_DEVICE_ALARM_STATUSFLAG_ABNORMAL_TERMINAT))
		{
			//
			// Notify abnormal removal of the LU device.
			//
			OnLogicalDeviceDisconnected(pNdasLogicalUnit);
		}
		else
		{
			NDAS_LOGICALDEVICE_ID logicalUnitId;
			COMVERIFY(pNdasLogicalUnit->get_Id(&logicalUnitId));
			(void) epub.LogicalDeviceAlarmed(
				logicalUnitId, 
				pGetSignificantAlarm(currentAdapterStatus, NewAdapterStatus));
		}
	}

	COMVERIFY(pNdasLogicalUnit->put_AdapterStatus(NewAdapterStatus));
}
示例#4
0
STDMETHODIMP
CNdasLogicalUnitManager::RegisterNdasLocation(
	NDAS_LOCATION location, 
	INdasLogicalUnit* pNdasLogicalUnit)
{
	CAutoLock autolock(this);

	NDAS_LOGICALDEVICE_ID logicalUnitId;
	COMVERIFY(pNdasLogicalUnit->get_Id(&logicalUnitId));

	XTLTRACE2(NDASSVC_NDASLOGDEVMANAGER, TRACE_LEVEL_INFORMATION, 
		"RegisterNdasLocation, slot=%d, logDevice=%d\n",
		location,
		logicalUnitId);

	bool result = m_NdasLocationMap.insert(
		std::make_pair(location,pNdasLogicalUnit)).second;
	//
	// result can be false if RAID information is conflicting status 
	// i.e. First RAID member is member of multiple RAID set.
	//
//	XTLASSERT(result);

	return result ? S_OK : E_FAIL;
}
示例#5
0
CNdasUnitDevice::CNdasUnitDevice(
	CNdasDevicePtr pParentDevice, 
	DWORD dwUnitNo, 
	NDAS_UNITDEVICE_TYPE type,
	NDAS_UNITDEVICE_SUBTYPE subType,
	const NDAS_UNITDEVICE_HARDWARE_INFO& unitDeviceInfo,
	const NDAS_LOGICALDEVICE_GROUP& ldGroup,
	DWORD ldSequence) :
	CStringizerA<32>("%s.%02d", pParentDevice->ToStringA(), dwUnitNo),
	m_pParentDevice(pParentDevice),
	m_unitDeviceId(pCreateUnitDeviceId(pParentDevice,dwUnitNo)),
	m_type(type),
	m_subType(subType),
	m_status(NDAS_UNITDEVICE_STATUS_NOT_MOUNTED),
	m_lastError(NDAS_UNITDEVICE_ERROR_NONE),
	m_udinfo(unitDeviceInfo),
	m_ldGroup(ldGroup),
	m_ldSequence(ldSequence),
	m_bSupposeFault(FALSE)
{
	XTLTRACE2(NDASSVC_NDASUNITDEVICE, TRACE_LEVEL_INFORMATION,
		__FUNCTION__ " %s\n", ToStringA());

	::ZeroMemory(
		&m_PrimaryHostInfo, 
		sizeof(NDAS_UNITDEVICE_PRIMARY_HOST_INFO));

	COMVERIFY( StringCchPrintf(
		m_szRegContainer,
		30,
		_T("Devices\\%04d\\%04d"),
		pParentDevice->GetSlotNo(),
		m_unitDeviceId.UnitNo));
}
示例#6
0
STDMETHODIMP
CNdasUnitImpl::RegisterToLogicalUnitManager()
{
	HRESULT hr;

	CComPtr<INdasLogicalUnitManager> pManager;
	COMVERIFY(hr = pGetNdasLogicalUnitManager(&pManager));

	CComPtr<INdasLogicalUnit> pNdasLogicalUnit;
	hr = pManager->Register(this, &pNdasLogicalUnit);

	if (FAILED(hr)) 
	{
		XTLTRACE2(NDASSVC_NDASUNITDEVICE, TRACE_LEVEL_ERROR, 
			"NdasLogicalUnitManager::Register failed, NdasUnit=%p, hr=0x%X\n",
			this, hr);
		return hr;
	}

	LockInstance();
	m_pNdasLogicalUnit = pNdasLogicalUnit;
	UnlockInstance();

	return S_OK;
}
HRESULT
CNdasDeviceComm::Connect(BOOL bWriteAccess)
{
	if (m_hNdas) {

		ATLASSERT(FALSE);
		ATLVERIFY( Disconnect() );
	}

	// Binding Address List
	SOCKADDR_LPX localSockAddrLpx;
	SOCKET_ADDRESS localSocketAddress;
	localSocketAddress.iSockaddrLength = sizeof(SOCKADDR_LPX);
	localSocketAddress.lpSockaddr = reinterpret_cast<LPSOCKADDR>(&localSockAddrLpx);

	COMVERIFY(m_pNdasDevice->get_LocalAddress(&localSocketAddress));

	SOCKET_ADDRESS_LIST localAddressList;
	localAddressList.iAddressCount = 1;
	localAddressList.Address[0] = localSocketAddress;

	// Connection Information
	NDASCOMM_CONNECTION_INFO ci = {0};
	ci.Size = sizeof(NDASCOMM_CONNECTION_INFO);
	ci.AddressType = NDASCOMM_CIT_DEVICE_ID;
	COMVERIFY(m_pNdasDevice->get_NdasDeviceId(&ci.Address.DeviceId));
	ci.LoginType = NDASCOMM_LOGIN_TYPE_NORMAL;
	COMVERIFY(m_pNdasDevice->get_HardwarePassword(&ci.OEMCode.UI64Value));
	ci.Protocol = NDASCOMM_TRANSPORT_LPX;
	ci.UnitNo = m_dwUnitNo;
	ci.WriteAccess = bWriteAccess;
	ci.BindingSocketAddressList = &localAddressList;

	m_hNdas = ::NdasCommConnect(&ci);

	if (NULL == m_hNdas)
	{
		HRESULT hr = HRESULT_FROM_WIN32(GetLastError());
		XTLTRACE2(NDASSVC_NDASCOMM, TRACE_LEVEL_ERROR,
			"NdasCommConnect failed, hr=0x%X\n", hr);
		return hr;
	}

	return S_OK;
}
示例#8
0
void CComponentObj::RegisterActiveObject()
{
	ASSERT( registeractiveobjectret == 0 );

	COMVERIFY( ::RegisterActiveObject(GetInterface(), CLSID_MgaComponent,
		ACTIVEOBJECT_STRONG, &registeractiveobjectret) );

	ASSERT( registeractiveobjectret );
}
示例#9
0
 bool operator()(INdasDevice* pNdasDevice) const
 {
     DWORD flags;
     COMVERIFY(pNdasDevice->get_RegisterFlags(&flags));
     if (flags & NDAS_DEVICE_REG_FLAG_HIDDEN)
     {
         return true;
     }
     return false;
 }
示例#10
0
void 
CNdasEventMonitor::OnLogicalDeviceDisconnected(
	INdasLogicalUnit* pNdasLogicalUnit)
{
	NDAS_LOCATION location;
	COMVERIFY(pNdasLogicalUnit->get_Id(&location));

	XTLTRACE2(NDASSVC_EVENTMON, TRACE_LEVEL_ERROR,
		"Disconnect Event, ndasLocation=%d, logicalUnit=%p\n", 
		location, pNdasLogicalUnit);

	NDAS_LOGICALDEVICE_ID logicalDeviceId;
	COMVERIFY(pNdasLogicalUnit->get_Id(&logicalDeviceId));

	CNdasEventPublisher& epub = pGetNdasEventPublisher();
	(void) epub.LogicalDeviceDisconnected(logicalDeviceId);

	CComQIPtr<INdasLogicalUnitPnpSink> pNdasLogicalUnitPnpSink(pNdasLogicalUnit);
	pNdasLogicalUnitPnpSink->OnDisconnected();
}
示例#11
0
HRESULT CNdasUnitImpl::ConnectUnitDevice(
	HNDAS *ndasHandle)
{
	//
	// Binding Address List
	//
	SOCKADDR_LPX localSockAddrLpx;
	SOCKET_ADDRESS localSocketAddress;
	localSocketAddress.iSockaddrLength = sizeof(SOCKADDR_LPX);
	localSocketAddress.lpSockaddr = reinterpret_cast<LPSOCKADDR>(&localSockAddrLpx);

	COMVERIFY(m_pParentNdasDevice->get_LocalAddress(&localSocketAddress));

	SOCKET_ADDRESS_LIST localAddressList;
	localAddressList.iAddressCount = 1;
	localAddressList.Address[0] = localSocketAddress;

	// Connection Information
	NDASCOMM_CONNECTION_INFO ci = {0};
	ci.Size = sizeof(NDASCOMM_CONNECTION_INFO);
	ci.AddressType = NDASCOMM_CIT_DEVICE_ID;
	COMVERIFY(m_pParentNdasDevice->get_NdasDeviceId(&ci.Address.DeviceId));
	ci.LoginType = NDASCOMM_LOGIN_TYPE_NORMAL;
	COMVERIFY(m_pParentNdasDevice->get_HardwarePassword(&ci.OEMCode.UI64Value));
	ci.Protocol = NDASCOMM_TRANSPORT_LPX;
	ci.UnitNo = m_unitDeviceId.UnitNo;
	ci.WriteAccess = FALSE;
	ci.BindingSocketAddressList = &localAddressList;

	*ndasHandle = ::NdasCommConnect(&ci);

	if (NULL == *ndasHandle)
	{
		HRESULT hr = AtlHresultFromLastError();
		XTLTRACE2(NDASSVC_NDASCOMM, TRACE_LEVEL_ERROR,
			"NdasCommConnect failed, hr=0x%X\n", hr);
		return hr;
	}

	return S_OK;
}
示例#12
0
STDMETHODIMP 
CNdasDiskUnit::IsDibUnchanged()
{
	CAutoInstanceLock autolock(this);

	CNdasUnitDeviceFactory ndasUnitFactory(m_pParentNdasDevice, m_unitDeviceId.UnitNo);

	CComPtr<INdasUnit> pCurrentNdasUnit;
	HRESULT hr = ndasUnitFactory.CreateUnitDevice(&pCurrentNdasUnit);
	if (FAILED(hr))
	{
		XTLTRACE2(NDASSVC_NDASUNITDEVICE, TRACE_LEVEL_ERROR,
			"Recreating an NdasUnit failed, hr=0x%X\n", hr);
		return E_FAIL;
	}

	NDAS_UNITDEVICE_TYPE currentType;
	COMVERIFY(pCurrentNdasUnit->get_Type(&currentType));
	if (m_type != currentType)
	{
		return E_FAIL;
	}

	CComQIPtr<INdasDiskUnit> pCurrentNdasDiskUnit = pCurrentNdasUnit;
	ATLASSERT(pCurrentNdasDiskUnit.p);

	NDAS_DIB_V2 currentDibV2;
	COMVERIFY(pCurrentNdasDiskUnit->get_Dib(&currentDibV2));

	ATLASSERT(NULL != m_pDIBv2);

	int cmp = memcmp(m_pDIBv2, &currentDibV2, sizeof(NDAS_DIB_V2));

	if (0 != cmp)
	{
		return E_FAIL;
	}

	return S_OK;
}
示例#13
0
int 
_tWinMain(
	__in HINSTANCE hInstance, 
	__in_opt HINSTANCE hPrevInstance, 
	__in_opt LPTSTR lpCmdLine,
	__in int nShowCmd )
{
	COMVERIFY(CoInitialize(NULL));

	// this resolves ATL window thunking problem when Microsoft Layer for Unicode (MSLU) is used
	(void) DefWindowProc(NULL, 0, 0, 0L);

	// add flags to support other controls
	ATLVERIFY(AtlInitCommonControls(ICC_WIN95_CLASSES | ICC_INTERNET_CLASSES));	

	COMVERIFY(_Module.Init(NULL, hInstance));

	int retCode = -1;

	if (!VerifyNdasComm())
	{
		AtlMessageBox(
			NULL, 
			IDS_NDASCOMM_NOT_AVAILABLE, 
			IDS_APP_ERROR_TITLE, 
			MB_OK | MB_ICONSTOP);
	}
	else
	{
		ATLVERIFY( NdasCommInitialize() );
		retCode = Run(lpCmdLine, nShowCmd);
		ATLVERIFY( NdasCommUninitialize() );
	}

	_Module.Term();

	CoUninitialize();

	return retCode;
}
示例#14
0
STDMETHODIMP 
CNdasDiskUnit::FillBlockAcl(__in PVOID BlockAcl)
{
	PNDAS_BLOCK_ACL pNdasBlockAcl = (NDAS_BLOCK_ACL *)BlockAcl;
	PNDAS_BLOCK_ACE pNdasBlockAce = NULL;
	PBLOCK_ACCESS_CONTROL_LIST_ELEMENT pBACLE = NULL;

	if (!m_pBACL)
	{
		return S_FALSE;
	}

	if (!BlockAcl)
	{
		return S_FALSE;
	}

	UINT nBACLESkipped = 0;
	for (UINT i = 0; i < m_pBACL->ElementCount; i++)
	{
		ATLASSERT(FALSE);

		pBACLE = &m_pBACL->Elements[i];
		if (!(pBACLE->AccessMask & BACL_ACCESS_MASK_PC_SYSTEM))
		{
			nBACLESkipped++;
			continue;
		}
		pNdasBlockAce = &pNdasBlockAcl->BlockACEs[i - nBACLESkipped];
		pNdasBlockAce->AccessMode |= 
			(pBACLE->AccessMask & BACL_ACCESS_MASK_WRITE) ? NBACE_ACCESS_WRITE : 0;
		pNdasBlockAce->AccessMode |= 
			(pBACLE->AccessMask & BACL_ACCESS_MASK_READ) ? NBACE_ACCESS_READ : 0;
		
		pNdasBlockAce->StartingOffset = pBACLE->ui64StartSector * 512;
		pNdasBlockAce->Length = pBACLE->ui64SectorCount * 512;

		XTLTRACE2(NDASSVC_NDASUNITDEVICE, TRACE_LEVEL_INFORMATION,
			"FillBACL() pNdasBlockAce : %x %I64d ~ %I64d\n",
			pNdasBlockAce->AccessMode,
			pNdasBlockAce->StartingOffset,
			pNdasBlockAce->Length);
	}

	DWORD blockAclLength;
	COMVERIFY(get_BlockAclSize(nBACLESkipped, &blockAclLength));

	pNdasBlockAcl->Length = blockAclLength;
	pNdasBlockAcl->BlockACECnt = m_pBACL->ElementCount - nBACLESkipped;

	return S_OK;
}
	bool operator()(INdasLogicalUnit* pNdasLogicalUnit) const 
	{
		NDAS_LOGICALDEVICE_STATUS status;
		COMVERIFY(pNdasLogicalUnit->get_Status(&status));
		switch (status)
		{
		case NDAS_LOGICALDEVICE_STATUS_MOUNTED:
		case NDAS_LOGICALDEVICE_STATUS_MOUNT_PENDING:
		case NDAS_LOGICALDEVICE_STATUS_UNMOUNT_PENDING:
			return true;
		}
		return false;
	}
示例#16
0
void
CNdasEventMonitor::Attach(INdasDevice* pNdasDevice)
{
	DWORD slotNo;
	COMVERIFY(pNdasDevice->get_SlotNo(&slotNo));
	XTLTRACE2(NDASSVC_EVENTMON, TRACE_LEVEL_INFORMATION,
		"Attaching ndas device %d to the monitor\n", slotNo);

	// DEVICE WRITE LOCK REGION
	{
		XTL::CWriterLockHolder holder(m_NdasDeviceDataLock);
		m_NdasDevices.Add(pNdasDevice);
	}
	// DEVICE WRITE LOCK REGION
}
示例#17
0
HRESULT
CNdasLogicalUnitManager::Unregister(INdasUnit* pNdasUnit)
{
	XTLTRACE2(NDASSVC_NDASLOGDEVMANAGER, TRACE_LEVEL_INFORMATION, 
		"Unregistering NdasUnit=%p from LDM\n", pNdasUnit);

	if (NULL == pNdasUnit)
	{
		return E_POINTER;
	}

	CComPtr<INdasLogicalUnit> pNdasLogicalUnit;
	COMVERIFY(pNdasUnit->get_NdasLogicalUnit(&pNdasLogicalUnit));

	DWORD luseq;
	COMVERIFY(pNdasUnit->get_LogicalUnitSequence(&luseq));

	COMVERIFY(pNdasLogicalUnit->RemoveNdasUnitInstance(pNdasUnit));

	DWORD instanceCount;
	COMVERIFY(pNdasLogicalUnit->get_NdasUnitInstanceCount(&instanceCount));

	if (0 == instanceCount) 
	{
		NDAS_LOGICALDEVICE_ID logicalUnitId;
		COMVERIFY(pNdasLogicalUnit->get_Id(&logicalUnitId));

		NDAS_LOGICALDEVICE_GROUP logicalUnitDefinition;
		COMVERIFY(pNdasLogicalUnit->get_LogicalUnitDefinition(&logicalUnitDefinition));

		LockInstance();
		XTLVERIFY(1 == m_LogicalUnitDefinitionMap.erase(logicalUnitDefinition));
		XTLVERIFY(1 == m_LogicalUnitIdMap.erase(logicalUnitId));
		size_t count = m_NdasLogicalUnits.GetCount();
		for (size_t i = 0; i < count; ++i)
		{
			INdasLogicalUnit* p = m_NdasLogicalUnits.GetAt(i);
			if (p == pNdasLogicalUnit)
			{
				m_NdasLogicalUnits.RemoveAt(i);
				break;
			}
		}
		XTLVERIFY(pDeallocateID(logicalUnitId));
		UnlockInstance();
	}

	return S_OK;
}
示例#18
0
void
CNdasEventMonitor::Detach(INdasDevice* pNdasDevice)
{
	DWORD slotNo;
	COMVERIFY(pNdasDevice->get_SlotNo(&slotNo));
	XTLTRACE2(NDASSVC_EVENTMON, TRACE_LEVEL_INFORMATION,
		"Detaching ndas device %d from the monitor\n", slotNo);

	// DEVICE WRITE LOCK REGION
	{
		XTL::CWriterLockHolder holder(m_NdasDeviceDataLock);
		size_t count = m_NdasDevices.GetCount();
		for (size_t index = 0; index < count; ++index)
		{
			INdasDevice* p = m_NdasDevices.GetAt(index);
			if (pNdasDevice == p)
			{
				m_NdasDevices.RemoveAt(index);
				break;
			}
		}
	}
	// DEVICE WRITE LOCK REGION
}
示例#19
0
void CComponentObj::UnregisterActiveObject()
{
	ASSERT( registeractiveobjectret );
	COMVERIFY( ::RevokeActiveObject(registeractiveobjectret, NULL) );
	registeractiveobjectret = 0;
}
示例#20
0
BOOL
CNdasDeviceRegistrar::Bootstrap()
{
	BOOL fSuccess = FALSE;
	BOOL fMigrated = FALSE;

	//
	// Set bootstrapping flag to prevent multiple events 
	// for DeviceSetChange Events
	//

	m_fBootstrapping = TRUE;

	TCHAR szSubcontainer[30] = {0};
	for (DWORD i = 0; i < MAX_SLOT_NUMBER; ++i) 
	{
		COMVERIFY(StringCchPrintf(
			szSubcontainer, 30, _T("%s\\%04d"), CFG_CONTAINER, i));

		BOOL fAutoRegistered = FALSE;
		fSuccess = _NdasSystemCfg.GetValueEx(
			szSubcontainer,
			_T("AutoRegistered"),
			&fAutoRegistered);

		if (fSuccess && fAutoRegistered)
		{
			XTLTRACE2(NDASSVC_NDASDEVICEREGISTRAR, TRACE_LEVEL_INFORMATION,
				"Deleting %ls\n", szSubcontainer);
			// Auto registered devices are not persistent
			// it is an error to show up here.
			// We just ignore those entries
			fSuccess = _NdasSystemCfg.DeleteContainer(szSubcontainer, TRUE);
			if (!fSuccess)
			{
				XTLTRACE2(NDASSVC_NDASDEVICEREGISTRAR, TRACE_LEVEL_INFORMATION,
					"Deleting a RegKey=%ls failed, error=0x%X\n", 
					szSubcontainer, GetLastError());
			}
			continue;
		}

		DWORD cbUsed;

		NDAS_DEVICE_ID_REG_DATA regData = {0};
		const NDASID_EXT_DATA* ndasIdExtension = NULL;

		fSuccess = _NdasSystemCfg.GetSecureValueEx(
			szSubcontainer, 
			_T("DeviceID2"),
			&regData,
			sizeof(NDAS_DEVICE_ID_REG_DATA),
			&cbUsed);

		if (!fSuccess) 
		{
			//
			// Non-extension data
			//
			fSuccess = _NdasSystemCfg.GetSecureValueEx(
				szSubcontainer, 
				_T("DeviceID"),
				&regData.DeviceId,
				sizeof(regData.DeviceId),
				&cbUsed);

			//
			// ignore read fault - tampered or not exists
			//
			if (!fSuccess || cbUsed != sizeof(NDAS_DEVICE_ID))
			{
				continue;
			}
			if (regData.DeviceId.VID == 0) {
				// Assume VID 0 is VID 1 to support registry entry created by older software(~3.11)
				regData.DeviceId.VID = 1;
			}
		}
		else
		{
			if (cbUsed != sizeof(NDAS_DEVICE_ID_REG_DATA))
			{
				//
				// maybe more recent versions, unrecognized, ignore
				//
				continue;
			}
			ndasIdExtension = &regData.NdasIdExtension;
		}

		DWORD regFlags;
		fSuccess = _NdasSystemCfg.GetSecureValueEx(
			szSubcontainer,
			_T("RegFlags"),
			&regFlags,
			sizeof(regFlags));

		if (!fSuccess)
		{
			regFlags = NDAS_DEVICE_REG_FLAG_NONE;
		}

		CNdasDevicePtr pDevice = Register(
			i, 
			regData.DeviceId, 
			regFlags,
			ndasIdExtension);

		// This may happen due to auto-register feature!
		if (CNdasDeviceNullPtr == pDevice) 
		{
			XTLTRACE2(NDASSVC_NDASDEVICEREGISTRAR, TRACE_LEVEL_ERROR,
				"Registration failed for %s, error=0x%X\n",
				CNdasDeviceId(regData.DeviceId).ToStringA(),
				GetLastError());
			//
			// During bootstrapping register may fail for unsupported VID.
			// In that case, we should retain this slot number to avoid
			// overwriting the existing data which may be created by
			// the higher version.
			//
			m_slotbit[i] = true;
			continue;
		}

		NDAS_OEM_CODE oemCode;
		fSuccess = _NdasSystemCfg.GetSecureValueEx(
			szSubcontainer,
			_T("OEMCode"),
			&oemCode,
			sizeof(NDAS_OEM_CODE),
			&cbUsed);

		if (fSuccess && cbUsed == sizeof(NDAS_OEM_CODE))
		{
			pDevice->SetOemCode(oemCode);
		}

		ACCESS_MASK grantedAccess = GENERIC_READ;
		const DWORD cbBuffer = sizeof(ACCESS_MASK) + sizeof(NDAS_DEVICE_ID);
		BYTE pbBuffer[cbBuffer];
		
		fSuccess = _NdasSystemCfg.GetSecureValueEx(
			szSubcontainer,
			_T("GrantedAccess"),
			pbBuffer,
			cbBuffer);

		if (fSuccess) 
		{
			grantedAccess = *((ACCESS_MASK*)(pbBuffer));
		}
		grantedAccess |= GENERIC_READ; // to prevent invalid access mask configuration
		// XTLASSERT(grantedAccess & GENERIC_READ); // invalid configuration?
		pDevice->SetGrantedAccess(grantedAccess);

		TCHAR szDeviceName[MAX_NDAS_DEVICE_NAME_LEN + 1];
		fSuccess = _NdasSystemCfg.GetValueEx(
			szSubcontainer, 
			_T("DeviceName"),
			szDeviceName,
			sizeof(TCHAR)*(MAX_NDAS_DEVICE_NAME_LEN + 1));

		if (fSuccess) 
		{
			pDevice->SetName(szDeviceName);
		}

		BOOL fEnabled = FALSE;
		fSuccess = _NdasSystemCfg.GetValueEx(
			szSubcontainer,
			_T("Enabled"),
			&fEnabled);

		if (fSuccess && fEnabled) 
		{
			pDevice->Enable(fEnabled);
		}
	}

	//
	// Migration will be done only once 
	// if there is no registered devices in the current configurations
	// and if the migration flag (Install\Migrate = 1) is set
	//
	if (m_deviceSlotMap.size() == 0) 
	{
		fSuccess = _NdasSystemCfg.GetValueEx(_T("Install"), _T("Migrated"), &fMigrated);
		if (!fSuccess || !fMigrated) 
		{
			fMigrated = TRUE;
			ImportLegacySettings();
			_NdasSystemCfg.SetValueEx(_T("Install"), _T("Migrated"), fMigrated);
		}
	}

	//
	// Clear bootstrapping state
	//
	m_fBootstrapping = FALSE;

	return TRUE;
}
示例#21
0
BOOL
CNdasDeviceRegistrar::pImportLegacyEntry(DWORD SlotNo, HKEY hEntryKey)
{
    static CONST size_t CB_ADDR = sizeof(TCHAR) * 18;

    HRESULT hr = E_FAIL;
    TCHAR szAddrVal[CB_ADDR + 1];
    DWORD cbAddrVal = sizeof(szAddrVal);
    DWORD dwValueType;

    LONG lResult = ::RegQueryValueEx(
                       hEntryKey,
                       _T("Address"),
                       0,
                       &dwValueType,
                       (LPBYTE)szAddrVal,
                       &cbAddrVal);

    if (ERROR_SUCCESS != lResult)
    {
        // Ignore invalid values
        return FALSE;
    }

    if (cbAddrVal != CB_ADDR)
    {
        XTLTRACE2(NDASSVC_NDASDEVICEREGISTRAR, TRACE_LEVEL_ERROR,
                  "Invalid Entry(A): %ls, ignored\n", szAddrVal);
        return FALSE;
    }

    //
    // 00:0B:D0:00:D4:2F to NDAS_DEVICE_ID
    //

    NDAS_DEVICE_ID deviceId = {0};
    BOOL success = pConvertStringToDeviceId(szAddrVal, &deviceId);
    if (!success)
    {
        XTLTRACE2(NDASSVC_NDASDEVICEREGISTRAR, TRACE_LEVEL_ERROR,
                  "Invalid Entry(D): %ls, ignored\n", szAddrVal);
        return FALSE;
    }

    XTLTRACE2(NDASSVC_NDASDEVICEREGISTRAR, TRACE_LEVEL_INFORMATION,
              "Importing an entry: %s\n",
              CNdasDeviceId(deviceId).ToStringA());

    TCHAR szNameVal[MAX_NDAS_DEVICE_NAME_LEN + 1] = {0};
    DWORD cbNameVal = sizeof(szNameVal);
    lResult = ::RegQueryValueEx(
                  hEntryKey,
                  _T("Name"),
                  0,
                  &dwValueType,
                  (LPBYTE)szNameVal,
                  &cbNameVal);

    if (ERROR_SUCCESS != lResult || _T('\0') == szNameVal[0])
    {
        TCHAR szDefaultName[MAX_NDAS_DEVICE_NAME_LEN + 1] = {0};
        success = _NdasSystemCfg.GetValueEx(
                      _T("Devices"),
                      _T("DefaultPrefix"),
                      szDefaultName,
                      sizeof(szDefaultName));

        if (!success)
        {
            COMVERIFY( StringCchCopy(
                           szDefaultName,
                           MAX_NDAS_DEVICE_NAME_LEN + 1,
                           _T("NDAS Device ")) );
        }

        hr = ::StringCchPrintf(
                 szNameVal,
                 MAX_NDAS_DEVICE_NAME_LEN,
                 _T("%s %d"),
                 szDefaultName,
                 SlotNo);
    }


    BYTE pbSerialKeyVal[9];
    DWORD cbSerialKeyVal = sizeof(pbSerialKeyVal);
    lResult = ::RegQueryValueEx(
                  hEntryKey,
                  _T("SerialKey"),
                  0,
                  &dwValueType,
                  (LPBYTE)pbSerialKeyVal,
                  &cbSerialKeyVal);

    if (ERROR_SUCCESS != lResult)
    {
        return FALSE;
    }

    if (cbSerialKeyVal != sizeof(pbSerialKeyVal))
    {
        return FALSE;
    }

    ACCESS_MASK fAccessMode = GENERIC_READ;
    if (0xFF == pbSerialKeyVal[8])
    {
        // Registered as RW
        fAccessMode |= GENERIC_WRITE;
    }
    else if (0x00 == pbSerialKeyVal[8])
    {
        // Registered as RO
    }
    else
    {
        // Invalid value
        return FALSE;
    }

    //
    // Register function returns the locked pointer
    //

    CComPtr<INdasDevice> pNdasDevice;

    hr = Register(
             SlotNo,
             deviceId,
             0,
             NULL,
             CComBSTR(szNameVal),
             fAccessMode,
             NULL,
             &pNdasDevice);

    if (FAILED(hr))
    {
        XTLTRACE2(NDASSVC_NDASDEVICEREGISTRAR, TRACE_LEVEL_ERROR,
                  "Failed to register %s at %d during import, error=0x%X",
                  CNdasDeviceId(deviceId).ToStringA(), SlotNo, hr);
        return FALSE;
    }

    // Always enable this!
    COMVERIFY(pNdasDevice->put_Enabled(TRUE));

    return TRUE;
}
示例#22
0
STDMETHODIMP
CNdasDeviceRegistrar::Deregister(INdasDevice* pNdasDevice)
{
    NDAS_DEVICE_ID ndasDeviceId;
    HRESULT hr;

    COMVERIFY(hr = pNdasDevice->get_NdasDeviceId(&ndasDeviceId));
    if (FAILED(hr))
    {
        return hr;
    }

    DWORD slotNo;
    COMVERIFY(hr = pNdasDevice->get_SlotNo(&slotNo));
    XTLASSERT(0 != slotNo);

    NDAS_DEVICE_STATUS status;
    COMVERIFY(pNdasDevice->get_Status(&status));
    if (NDAS_DEVICE_STATUS_DISABLED != status)
    {
        return NDASSVC_ERROR_CANNOT_UNREGISTER_ENABLED_DEVICE;
    }

    CAutoLock<CLock> autolock(&m_DataLock);

    XTLTRACE2(NDASSVC_NDASDEVICEREGISTRAR, TRACE_LEVEL_INFORMATION,
              "Unregister device %s\n", CNdasDeviceId(ndasDeviceId).ToStringA());

    bool found = false;
    size_t count = m_NdasDevices.GetCount();
    for (size_t i = 0; i < count; ++i)
    {
        CComPtr<INdasDevice> p = m_NdasDevices.GetAt(i);
        if (p == pNdasDevice)
        {
            m_NdasDevices.RemoveAt(i);
            found = true;
            break;
        }
    }

    if (!found)
    {
        return NDASSVC_ERROR_DEVICE_ENTRY_NOT_FOUND;
    }

    DeviceIdMap::iterator itrId = m_deviceIdMap.find(ndasDeviceId);
    ATLASSERT(m_deviceIdMap.end() != itrId);

    DeviceSlotMap::iterator itrSlot = m_deviceSlotMap.find(slotNo);
    ATLASSERT(m_deviceSlotMap.end() != itrSlot);

    m_deviceIdMap.erase(itrId);
    m_deviceSlotMap.erase(itrSlot);

    m_slotbit[slotNo] = false;

    XTL::CStaticStringBuffer<30> containerName(_T("Devices\\%04d"), slotNo);
    BOOL success = _NdasSystemCfg.DeleteContainer(containerName, TRUE);
    if (!success)
    {
        XTLTRACE2(NDASSVC_NDASDEVICEREGISTRAR, TRACE_LEVEL_WARNING,
                  "Deleting registration entry from the registry failed at %ls, error=0x%X\n",
                  containerName, GetLastError());
    }

    autolock.Release();

    (void) pGetNdasEventPublisher().DeviceEntryChanged();

    return S_OK;
}
示例#23
0
HRESULT
CNdasLogicalUnitManager::Register(INdasUnit* pNdasUnit, INdasLogicalUnit** ppNdasLogicalUnit)
{
	HRESULT hr;

	XTLTRACE2(NDASSVC_NDASLOGDEVMANAGER, TRACE_LEVEL_INFORMATION, 
		"Registering NdasUnit=%p to LDM\n", pNdasUnit);

	*ppNdasLogicalUnit = NULL;

	NDAS_LOGICALDEVICE_GROUP ludef;
	COMVERIFY(pNdasUnit->get_LogicalUnitDefinition(&ludef));

	DWORD luseq;
	COMVERIFY(pNdasUnit->get_LogicalUnitSequence(&luseq));

	CComPtr<INdasLogicalUnit> pNdasLogicalUnit;

	LockInstance();

	LogicalDeviceGroupMap::iterator itr = m_LogicalUnitDefinitionMap.find(ludef);

	if (itr == m_LogicalUnitDefinitionMap.end()) 
	{
		//
		// New Logical Device Instance
		//
		NDAS_LOGICALDEVICE_ID id = pAllocateID();
		if (0 == id) 
		{
			UnlockInstance();
			// SLOT FULL
			hr = NDASSVC_ERROR_LOGICALDEVICE_SLOT_FULL;
			return hr;
		}

		CComObject<CNdasLogicalUnit>* pNdasLogicalUnitInstance;
		hr = CComObject<CNdasLogicalUnit>::CreateInstance(&pNdasLogicalUnitInstance);
		if (FAILED(hr))
		{
			XTLTRACE2(NDASSVC_NDASLOGDEVMANAGER, TRACE_LEVEL_ERROR, 
				"CNdasLogicalUnit::CreateInstance failed, hr=0x%X\n", hr);
			UnlockInstance();
			return hr;
		}

		hr = pNdasLogicalUnitInstance->Initialize(id, ludef);
		if (FAILED(hr))
		{
			XTLTRACE2(NDASSVC_NDASLOGDEVMANAGER, TRACE_LEVEL_ERROR, 
				"CNdasLogicalUnit::Initialize failed, hr=0x%X\n", hr);
			UnlockInstance();
			return hr;
		}

		pNdasLogicalUnit = pNdasLogicalUnitInstance;

		m_NdasLogicalUnits.Add(pNdasLogicalUnit);
		m_LogicalUnitDefinitionMap.insert(std::make_pair(ludef, pNdasLogicalUnit));
		m_LogicalUnitIdMap.insert(std::make_pair(id, pNdasLogicalUnit));

		UnlockInstance();

		CComPtr<INdasDevice> pNdasDevice;
		COMVERIFY(pNdasUnit->get_ParentNdasDevice(&pNdasDevice));
		XTLASSERT(pNdasDevice);

		DWORD regFlags;
		COMVERIFY(pNdasDevice->get_RegisterFlags(&regFlags));

		if (regFlags & NDAS_DEVICE_REG_FLAG_AUTO_REGISTERED) 
		{
			BOOL fMountOnReady = TRUE;
			if (NdasServiceConfig::Get(nscMountOnReadyForEncryptedOnly))
			{
				NDAS_UNITDEVICE_TYPE unitType;
				COMVERIFY(pNdasUnit->get_Type(&unitType));

				if (0 == luseq && NDAS_UNITDEVICE_TYPE_DISK == unitType)
				{
					CComQIPtr<INdasDiskUnit> pNdasDiskUnit(pNdasUnit);
					ATLASSERT(pNdasDiskUnit.p);

					NDAS_CONTENT_ENCRYPT encryption;
					COMVERIFY(pNdasDiskUnit->get_ContentEncryption(&encryption));

					if (NDAS_CONTENT_ENCRYPT_METHOD_NONE != encryption.Method)
					{
						fMountOnReady = TRUE;
					}
					else
					{
						fMountOnReady = FALSE;
					}
				}
			}

			// auto registered devices always ignore RiskyMountFlag
			pNdasLogicalUnit->SetRiskyMountFlag(FALSE);

			if (fMountOnReady)
			{
				ACCESS_MASK granted;
				pNdasDevice->get_GrantedAccess(&granted);
				pNdasLogicalUnit->SetMountOnReady(granted, FALSE);
			}
		}

	}
	else 
	{
		pNdasLogicalUnit = itr->second;
		UnlockInstance();
	}

	COMVERIFY(pNdasLogicalUnit->AddNdasUnitInstance(pNdasUnit));

	*ppNdasLogicalUnit = pNdasLogicalUnit.Detach();

	return S_OK;
}
示例#24
0
STDMETHODIMP
CNdasDeviceRegistrar::Register(
    __in_opt DWORD SlotNo,
    __in const NDAS_DEVICE_ID& DeviceId,
    __in DWORD RegFlags,
    __in_opt const NDASID_EXT_DATA* NdasIdExtension,
    __in BSTR Name,
    __in ACCESS_MASK GrantedAccess,
    __in_opt const NDAS_OEM_CODE* NdasOemCode,
    __deref_out INdasDevice** ppNdasDevice)
{
    HRESULT hr;

    *ppNdasDevice = 0;

    NDAS_DEVICE_ID ndasDeviceId = DeviceId;

    //
    // this will lock this class from here
    // and releases the lock when the function returns;
    //
    CAutoLock<CLock> autolock(&m_DataLock);

    XTLTRACE2(NDASSVC_NDASDEVICEREGISTRAR, TRACE_LEVEL_INFORMATION,
              "Registering device %s at slot %d\n",
              CNdasDeviceId(DeviceId).ToStringA(), SlotNo);

    if (NULL == NdasIdExtension)
    {
        NdasIdExtension = &NDAS_ID_EXTENSION_DEFAULT;
    }

    //
    // Only DEFAULT and SEAGATE are currently implemented
    //
    if (NDAS_VID_SEAGATE != NdasIdExtension->VID	&&
            NDAS_VID_WINDWOS_RO != NdasIdExtension->VID		&&
            NDAS_VID_DEFAULT != NdasIdExtension->VID)
    {
        XTLTRACE2(NDASSVC_NDASDEVICEREGISTRAR, TRACE_LEVEL_ERROR,
                  "Unknown Vendor ID=0x%02X\n",
                  NdasIdExtension->VID);

        hr = NDASSVC_ERROR_UNKNOWN_VENDOR_ID;
        return hr;
    }

    ndasDeviceId.VID = NdasIdExtension->VID;

    // If SlotNo is zero, automatically assign it.
    // check slot number
    if (0 == SlotNo)
    {
        SlotNo = pLookupEmptySlot();
        if (0 == SlotNo)
        {
            return NDASSVC_ERROR_DEVICE_ENTRY_SLOT_FULL;
        }
    }
    else if (SlotNo > MAX_SLOT_NUMBER)
    {
        return NDASSVC_ERROR_INVALID_SLOT_NUMBER;
    }

    // check and see if the slot is occupied
    if (m_slotbit[SlotNo])
    {
        return NDASSVC_ERROR_SLOT_ALREADY_OCCUPIED;
    }

    // find an duplicate address
    {
        CComPtr<INdasDevice> pExistingDevice;
        if (SUCCEEDED(get_NdasDevice(&ndasDeviceId, &pExistingDevice)))
        {
            return NDASSVC_ERROR_DUPLICATE_DEVICE_ENTRY;
        }
    }

    // register
    CComObject<CNdasDevice>* pNdasDeviceInstance;
    hr = CComObject<CNdasDevice>::CreateInstance(&pNdasDeviceInstance);
    if (FAILED(hr))
    {
        return hr;
    }

    hr = pNdasDeviceInstance->Initialize(
             SlotNo, ndasDeviceId, RegFlags, NdasIdExtension);
    if (FAILED(hr))
    {
        XTLTRACE2(NDASSVC_NDASDEVICEREGISTRAR, TRACE_LEVEL_ERROR,
                  "Device initialization failed, error=0x%X\n", GetLastError());
        return hr;
    }

    CComPtr<INdasDevice> pNdasDevice(pNdasDeviceInstance);

    COMVERIFY(pNdasDevice->put_Name(Name));
    COMVERIFY(pNdasDevice->put_GrantedAccess(GrantedAccess));
    if (NdasOemCode)
    {
        COMVERIFY(pNdasDevice->put_OemCode(NdasOemCode));
    }

    m_slotbit[SlotNo] = true;

    bool insertResult;

    m_NdasDevices.Add(pNdasDevice);

    XTLVERIFY( m_deviceSlotMap.insert(std::make_pair(SlotNo, pNdasDevice)).second );
    //DeviceSlotMap::value_type(SlotNo, pNdasDevice)).second;

    XTLVERIFY( m_deviceIdMap.insert(std::make_pair(ndasDeviceId, pNdasDevice)).second );
    //DeviceIdMap::value_type(ndasDeviceId, pNdasDevice)).second;

    XTLASSERT(m_deviceSlotMap.size() == m_deviceIdMap.size());

    //
    // When NdasIdExtension is NULL, NDAS_ID_EXTENSION_DEFAULT is assigned already
    //

    if (RegFlags & NDAS_DEVICE_REG_FLAG_VOLATILE)
    {
    }
    else
    {
        BOOL success;
        XTL::CStaticStringBuffer<30> containerName(_T("Devices\\%04d"), SlotNo);

        if (0 != memcmp(&NDAS_ID_EXTENSION_DEFAULT, NdasIdExtension, sizeof(NDASID_EXT_DATA)))
        {
            NDAS_DEVICE_ID_REG_DATA regData = {0};
            regData.DeviceId = ndasDeviceId;
            regData.NdasIdExtension = *NdasIdExtension;

            success = _NdasSystemCfg.SetSecureValueEx(
                          containerName,
                          _T("DeviceID2"),
                          &regData,
                          sizeof(regData));
        }
        else
        {
            success = _NdasSystemCfg.SetSecureValueEx(
                          containerName,
                          _T("DeviceID"),
                          &ndasDeviceId,
                          sizeof(ndasDeviceId));
        }

        if (!success)
        {
            XTLTRACE2(NDASSVC_NDASDEVICEREGISTRAR, TRACE_LEVEL_WARNING,
                      "Writing registration entry to the registry failed at %ls, error=0x%X\n",
                      containerName.ToString(), GetLastError());
        }

        success = _NdasSystemCfg.SetSecureValueEx(
                      containerName,
                      _T("RegFlags"),
                      &RegFlags,
                      sizeof(RegFlags));

        if (!success)
        {
            XTLTRACE2(NDASSVC_NDASDEVICEREGISTRAR, TRACE_LEVEL_WARNING,
                      "Writing registration entry to the registry failed at %ls, error=0x%X\n",
                      containerName.ToString(), GetLastError());
        }
    }

    BOOL publishEvent = !m_fBootstrapping;

    autolock.Release();

    //
    // During bootstrapping, we do not publish this event
    // Bootstrap process will publish an event later
    //

    if (publishEvent)
    {
        (void) pGetNdasEventPublisher().DeviceEntryChanged();
    }

    *ppNdasDevice = pNdasDevice.Detach();

    return S_OK;
}
示例#25
0
STDMETHODIMP
CNdasDeviceRegistrar::Bootstrap()
{
    HRESULT hr;

    BOOL success = FALSE;
    BOOL fMigrated = FALSE;

    //
    // Set bootstrapping flag to prevent multiple events
    // for DeviceSetChange Events
    //

    m_fBootstrapping = TRUE;

    TCHAR szSubcontainer[30] = {0};
    for (DWORD i = 0; i < MAX_SLOT_NUMBER; ++i)
    {
        COMVERIFY(StringCchPrintf(
                      szSubcontainer, 30, _T("%s\\%04d"), CFG_CONTAINER, i));

        BOOL fAutoRegistered = FALSE;
        success = _NdasSystemCfg.GetValueEx(
                      szSubcontainer,
                      _T("AutoRegistered"),
                      &fAutoRegistered);

        if (success && fAutoRegistered)
        {
            XTLTRACE2(NDASSVC_NDASDEVICEREGISTRAR, TRACE_LEVEL_INFORMATION,
                      "Deleting %ls\n", szSubcontainer);
            // Auto registered devices are not persistent
            // it is an error to show up here.
            // We just ignore those entries
            success = _NdasSystemCfg.DeleteContainer(szSubcontainer, TRUE);
            if (!success)
            {
                XTLTRACE2(NDASSVC_NDASDEVICEREGISTRAR, TRACE_LEVEL_INFORMATION,
                          "Deleting a RegKey=%ls failed, error=0x%X\n",
                          szSubcontainer, GetLastError());
            }
            continue;
        }

        DWORD cbUsed;

        NDAS_DEVICE_ID_REG_DATA regData = {0};
        const NDASID_EXT_DATA* ndasIdExtension = NULL;

        success = _NdasSystemCfg.GetSecureValueEx(
                      szSubcontainer,
                      _T("DeviceID2"),
                      &regData,
                      sizeof(NDAS_DEVICE_ID_REG_DATA),
                      &cbUsed);

        if (!success)
        {
            //
            // Non-extension data
            //
            success = _NdasSystemCfg.GetSecureValueEx(
                          szSubcontainer,
                          _T("DeviceID"),
                          &regData.DeviceId,
                          sizeof(regData.DeviceId),
                          &cbUsed);

            //
            // ignore read fault - tampered or not exists
            //
            if (!success || cbUsed != sizeof(NDAS_DEVICE_ID))
            {
                continue;
            }
            // For VID's other than 1 (or 0), DeviceID2 should be used instead.
            // In this case, VID is 1.
            // (Assume VID 0 is VID 1 to support registry entry created
            // by older software(~3.11))
            regData.DeviceId.VID = 1;
        }
        else
        {
            if (cbUsed != sizeof(NDAS_DEVICE_ID_REG_DATA))
            {
                //
                // maybe more recent versions, unrecognized, ignore
                //
                continue;
            }
            // DeviceId.VID may not be written correctly by some version of SW.
            regData.DeviceId.VID = regData.NdasIdExtension.VID;
            ndasIdExtension = &regData.NdasIdExtension;
        }

        //
        // RegFlags
        //

        DWORD regFlags;
        success = _NdasSystemCfg.GetSecureValueEx(
                      szSubcontainer,
                      _T("RegFlags"),
                      &regFlags,
                      sizeof(regFlags));

        if (!success)
        {
            regFlags = NDAS_DEVICE_REG_FLAG_NONE;
        }

        //
        // NDAS OEM Code
        //

        const NDAS_OEM_CODE* ndasOemCode = NULL;
        NDAS_OEM_CODE ndasOemCodeBuffer;
        success = _NdasSystemCfg.GetSecureValueEx(
                      szSubcontainer,
                      _T("OEMCode"),
                      &ndasOemCodeBuffer,
                      sizeof(NDAS_OEM_CODE),
                      &cbUsed);

        if (success && cbUsed == sizeof(NDAS_OEM_CODE))
        {
            ndasOemCode = &ndasOemCodeBuffer;
        }

        //
        // Granted Access
        //

        ACCESS_MASK grantedAccess = GENERIC_READ;
        const DWORD cbBuffer = sizeof(ACCESS_MASK) + sizeof(NDAS_DEVICE_ID);
        BYTE pbBuffer[cbBuffer];

        success = _NdasSystemCfg.GetSecureValueEx(
                      szSubcontainer,
                      _T("GrantedAccess"),
                      pbBuffer,
                      cbBuffer);

        if (success)
        {
            grantedAccess = *((ACCESS_MASK*)(pbBuffer));
        }
        grantedAccess |= GENERIC_READ; // to prevent invalid access mask configuration

        //
        // NDAS Device Name
        //

        TCHAR szDeviceName[MAX_NDAS_DEVICE_NAME_LEN + 1];
        success = _NdasSystemCfg.GetValueEx(
                      szSubcontainer,
                      _T("DeviceName"),
                      szDeviceName,
                      sizeof(TCHAR)*(MAX_NDAS_DEVICE_NAME_LEN + 1));

        if (!success)
        {
            COMVERIFY(StringCchCopy(
                          szDeviceName, RTL_NUMBER_OF(szDeviceName), _T("NDAS Device")));
        }

        //
        // Register
        //

        CComPtr<INdasDevice> pNdasDevice;
        hr = Register(
                 i,
                 regData.DeviceId,
                 regFlags,
                 ndasIdExtension,
                 CComBSTR(szDeviceName),
                 grantedAccess,
                 ndasOemCode,
                 &pNdasDevice);

        if (FAILED(hr))
        {
            //
            // This may happen due to auto-register feature!
            //
            XTLTRACE2(NDASSVC_NDASDEVICEREGISTRAR, TRACE_LEVEL_ERROR,
                      "Registration failed for %s, hr=0x%X\n",
                      CNdasDeviceId(regData.DeviceId).ToStringA(),
                      hr);
            //
            // During bootstrapping register may fail for unsupported VID.
            // In that case, we should retain this slot number to avoid
            // overwriting the existing data which may be created by
            // the higher version.
            //
            m_slotbit[i] = true;
            continue;
        }

        BOOL fEnabled = FALSE;
        success = _NdasSystemCfg.GetValueEx(
                      szSubcontainer,
                      _T("Enabled"),
                      &fEnabled);

        if (success && fEnabled)
        {
            COMVERIFY(pNdasDevice->put_Enabled(fEnabled));
        }
    }

    //
    // Migration will be done only once
    // if there is no registered devices in the current configurations
    // and if the migration flag (Install\Migrate = 1) is set
    //
    if (m_deviceSlotMap.size() == 0)
    {
        success = _NdasSystemCfg.GetValueEx(_T("Install"), _T("Migrated"), &fMigrated);
        if (!success || !fMigrated)
        {
            fMigrated = TRUE;
            pImportLegacySettings();
            _NdasSystemCfg.SetValueEx(_T("Install"), _T("Migrated"), fMigrated);
        }
    }

    //
    // Clear bootstrapping state
    //
    m_fBootstrapping = FALSE;

    return S_OK;
}
//
// Return TRUE to grant the request to suspend. 
// To deny the request, return BROADCAST_QUERY_DENY.
//
LRESULT 
CNdasServicePowerEventHandler::OnQuerySuspend(DWORD dwFlags)
{
	HRESULT hr;

	XTLTRACE2(NDASSVC_PNP, TRACE_LEVEL_INFORMATION, "OnQuerySuspend.\n");

	// A DWORD value dwFlags specifies action flags. 
	// If bit 0 is 1, the application can prompt the user for directions 
	// on how to prepare for the suspension; otherwise, the application 
	// must prepare without user interaction. All other bit values are reserved. 

	DWORD dwValue = NdasServiceConfig::Get(nscSuspendOptions);

	if (NDASSVC_SUSPEND_ALLOW == dwValue) 
	{
		return TRUE;
	}

	CComPtr<INdasLogicalUnitManager> pManager;
	COMVERIFY(hr = pGetNdasLogicalUnitManager(&pManager));

	CInterfaceArray<INdasLogicalUnit> ndasLogicalUnits;

	pManager->get_NdasLogicalUnits(NDAS_ENUM_DEFAULT, ndasLogicalUnits);

	bool mounted = false;
	size_t count = ndasLogicalUnits.GetCount();
	for (size_t index = 0; index < count; ++index)
	{
		INdasLogicalUnit* pNdasLogicalUnit = ndasLogicalUnits.GetAt(index);
		if (LogicalDeviceIsMounted()(pNdasLogicalUnit))
		{
			mounted = true;
			break;
		}
	}

	//
	// Service won't interact with the user
	// If you want to make this function interactive
	// You should set the NDASSVC_SUSPEND_ALLOW
	// and the UI application should process NDASSVC_SUSPEND by itself
	//
	if (mounted) 
	{
		if (0x01 == (dwFlags & 0x01)) 
		{
			//
			// Possible to interact with the user
			//
			(void) m_service.GetEventPublisher().SuspendRejected();
			return BROADCAST_QUERY_DENY;
		}
		else 
		{
			//
			// No User interface is available
			//
			(void) m_service.GetEventPublisher().SuspendRejected();
			return BROADCAST_QUERY_DENY;
		}
	}

	return TRUE;
}
示例#27
0
BOOL
CNdasAutoRegister::ProcessRegister(
	const NDAS_DEVICE_ID& deviceId, 
	ACCESS_MASK autoRegAccess)
{
	HRESULT hr;

	CComPtr<INdasDeviceRegistrar> pRegistrar;
	COMVERIFY(hr = pGetNdasDeviceRegistrar(&pRegistrar));
	if (FAILED(hr))
	{
		return FALSE;
	}

	CComPtr<INdasDevice> pExistingDevice;
	hr = pRegistrar->get_NdasDevice(&const_cast<NDAS_DEVICE_ID&>(deviceId), &pExistingDevice);
	if (SUCCEEDED(hr)) 
	{
		return TRUE;
	}

	DWORD dwRegFlags = 
		NDAS_DEVICE_REG_FLAG_AUTO_REGISTERED |
		NDAS_DEVICE_REG_FLAG_VOLATILE;
	
	//
	// Register function returns the locked pointer
	//
	CComPtr<INdasDevice> pNdasDevice;
	hr = pRegistrar->Register(
		0, 
		deviceId, 
		dwRegFlags, 
		NULL, 
		CComBSTR(L"NDAS Device"),
		autoRegAccess,
		NULL,
		&pNdasDevice);
	if (FAILED(hr))
	{
		XTLTRACE2(NDASSVC_AUTOREG, TRACE_LEVEL_ERROR,
			"Register failed, hr=0x%X\n", hr);
		return FALSE;
	}

	DWORD slotNo;
	COMVERIFY(pNdasDevice->get_SlotNo(&slotNo));

	CComBSTR ndasDeviceName(MAX_NDAS_DEVICE_NAME_LEN + 1);
	COMVERIFY(StringCchPrintfW(
		ndasDeviceName, MAX_NDAS_DEVICE_NAME_LEN + 1,
		L"NDAS Device A%04d", slotNo));
	COMVERIFY(pNdasDevice->put_Name(ndasDeviceName));

	hr = pNdasDevice->put_Enabled(TRUE);
	if (FAILED(hr)) 
	{
		XTLTRACE2(NDASSVC_AUTOREG, TRACE_LEVEL_ERROR,
			"Enable failed, hr=0x%X\n", hr);
	}

	return TRUE;
}
示例#28
0
void
CNdasEventMonitor::OnLogicalDeviceAlarmed(INdasLogicalUnit* pNdasLogicalUnit)
{
	NDAS_LOCATION ndasLocation;
	COMVERIFY(pNdasLogicalUnit->get_Id(&ndasLocation));

	NDAS_LOGICALUNIT_ADDRESS ndasLogicalUnitAddress;
	COMVERIFY(pNdasLogicalUnit->get_LogicalUnitAddress(&ndasLogicalUnitAddress));

	XTLTRACE2(NDASSVC_EVENTMON, TRACE_LEVEL_INFORMATION,
		"Alarm Event, ndasLocation=%d, logicalUnit=%p\n", 
		ndasLocation, pNdasLogicalUnit);

	if (0 == ndasLocation) 
	{
		XTLTRACE2(NDASSVC_EVENTMON, TRACE_LEVEL_ERROR,
			"Invalid SCSI Location\n");
		XTLASSERT(FALSE);
		return;
	}

	ULONG newAdapterStatus;

	while(TRUE)
	{
		BOOL success = ::NdasBusCtlQueryEvent(
			ndasLocation,
			&newAdapterStatus);

		if (!success) 
		{
			if (::GetLastError() == ERROR_NO_MORE_ITEMS) 
			{
				XTLTRACE2(NDASSVC_EVENTMON, TRACE_LEVEL_INFORMATION,
					"No more events, ignored, ndasLocation=%d\n", 
					ndasLocation);
			} 
			else 
			{
				XTLTRACE2(NDASSVC_EVENTMON, TRACE_LEVEL_ERROR,
					"Query status failed on alarm, ignored, ndasLocation=%d\n", 
					ndasLocation);
			}
			return;
		}

		XTLTRACE2(NDASSVC_EVENTMON, TRACE_LEVEL_INFORMATION,
			"Logical device alarmed, ndasLocation=%d, adapterStatus=%08X.\n", 
			ndasLocation, newAdapterStatus);

		// Determine whether an alarm will be issued.
		// Only viable alarm will be published
		ULONG currentAdapterStatus;
		COMVERIFY(pNdasLogicalUnit->get_AdapterStatus(&currentAdapterStatus));

		if (pIsViableAlarmStatus(currentAdapterStatus, newAdapterStatus))
		{
			CNdasEventPublisher& epub = pGetNdasEventPublisher();
			NDAS_LOGICALDEVICE_ID logicalUnitId;
			COMVERIFY(pNdasLogicalUnit->get_Id(&logicalUnitId));
			(void) epub.LogicalDeviceAlarmed(
				logicalUnitId, 
				pGetSignificantAlarm(currentAdapterStatus, newAdapterStatus));
		}

		COMVERIFY(pNdasLogicalUnit->put_AdapterStatus(newAdapterStatus));

		if (!ADAPTERINFO_ISSTATUSFLAG(
			newAdapterStatus, 
			NDASSCSI_ADAPTER_STATUSFLAG_NEXT_EVENT_EXIST)) 
		{
			break;
		}
	}
}
示例#29
0
	result_type operator()(argument_type pNdasLogicalUnit) const
	{
		HANDLE h;
		COMVERIFY(pNdasLogicalUnit->get_AlarmEvent(&h));
		return h;
	}