STDMETHODIMP
CNdasLogicalUnitManager::get_NdasLogicalUnits(
	DWORD Flags, CInterfaceArray<INdasLogicalUnit>& dest)
{
	CAutoLock autolock(this);
	dest.Copy(m_NdasLogicalUnits);
	autolock.Release();

	if (NDAS_ENUM_EXCLUDE_HIDDEN & Flags)
	{
		//
		// Filter out hidden logical devices
		// A hidden logical device is a logical device, 
		// of which the device of the primary unit device
		// is hidden.
		//
		size_t count = dest.GetCount();
		for (size_t index = 0; index < count; ++index)
		{
			INdasLogicalUnit* p = dest.GetAt(index);
			if (NdasLogicalUnitIsHidden()(p))
			{
				dest.RemoveAt(index);
				--index; --count;
			}
		}
	}

	return S_OK;
}
Beispiel #2
0
STDMETHODIMP CExplorerCommandProvider::GetCommands(IUnknown* punkSite, REFIID riid, LPVOID* ppenumr)
{
   ATLTRACE(L"CExplorerCommandProvider::GetCommands\n");
   typedef CComEnum< IEnumExplorerCommand, &IID_IEnumExplorerCommand, IExplorerCommand*, _CopyInterface<IExplorerCommand> > CEnumCommands;
   HMENU hMenuPopup = ::GetSubMenu(m_hMenu, _T("CommandMenu"));
   CInterfaceArray<IExplorerCommand> aList;
   for( int i = 0; i < ::GetMenuItemCount(hMenuPopup); i++ ) {
      CComPtr<IExplorerCommand> spCommand;
      HR( _GetCommand(hMenuPopup, ::GetMenuItemID(hMenuPopup, i), IID_PPV_ARGS(&spCommand)) );
      aList.Add(spCommand);
   }
   CComObject<CEnumCommands>* pEnumResources;
   HR( CComObject<CEnumCommands>::CreateInstance(&pEnumResources) );
   HR( pEnumResources->Init(&aList.GetData()->p, &aList.GetData()->p + aList.GetCount(), NULL, AtlFlagCopy) );
   return pEnumResources->QueryInterface(riid, ppenumr);
}
Beispiel #3
0
STDMETHODIMP CExplorerCommand::EnumSubCommands(IEnumExplorerCommand** ppEnum)
{
   typedef CComEnum< IEnumExplorerCommand, &IID_IEnumExplorerCommand, IExplorerCommand*, _CopyInterface<IExplorerCommand> > CEnumCommands;
   HMENU hMenuPopup = ::GetSubMenu(m_spProvider->m_hMenu, _T("CommandMenu"));
   hMenuPopup = ::GetSubMenu(hMenuPopup, ::GetMenuPosFromID(hMenuPopup, m_mii.wID));
   CInterfaceArray<IExplorerCommand> aList;
   for( int i = 0; hMenuPopup != NULL && i < ::GetMenuItemCount(hMenuPopup); i++ ) {
      ATLASSERT(::GetSubMenu(hMenuPopup, i)==NULL);  // No sub-sub menus!
      CComPtr<IExplorerCommand> spCommand;
      HR( m_spProvider->_GetCommand(hMenuPopup, ::GetMenuItemID(hMenuPopup, i), IID_PPV_ARGS(&spCommand)) );
      aList.Add(spCommand);
   }
   CComObject<CEnumCommands>* pEnumResources;
   HR( CComObject<CEnumCommands>::CreateInstance(&pEnumResources) );
   HR( pEnumResources->Init(&aList.GetData()->p, &aList.GetData()->p + aList.GetCount(), NULL, AtlFlagCopy) );
   return pEnumResources->QueryInterface(ppEnum);
}
DWORD
CNdasEventMonitor::ThreadStart(HANDLE hStopEvent)
{
	CCoInitialize coinit(COINIT_MULTITHREADED);

	// 15 sec = 10,000,000 nanosec
	// negative value means relative time
	LARGE_INTEGER liDueTime;
	liDueTime.QuadPart = - 10 * 1000 * 1000;

	BOOL success = ::SetWaitableTimer(
		m_HeartbeatMonitorTimer, 
		&liDueTime, 
		HEARTBEAT_MONITOR_INTERVAL, 
		NULL, 
		NULL, 
		FALSE);

	if (!success) 
	{
		XTLTRACE2(NDASSVC_EVENTMON, TRACE_LEVEL_ERROR,
			"Setting waitable timer failed, error=0x%X\n", GetLastError());
	}

	XTLVERIFY( ::ResetEvent(m_NdasLogicalUnitSetChanged) );

	std::vector<HANDLE> waitHandles;
	waitHandles.reserve(20);

	// Lock-free copy of the devices and logDevices
	CInterfaceArray<INdasDevice> ndasDevices;
	CInterfaceArray<INdasLogicalUnit> ndasLogicalUnits;

	while (true)
	{
		//
		// Copy m_NdasDevices and m_NdasLogicalUnits to devices and logDevices
		// for lock free accesses
		//
		// DEVICE READER LOCK REGION
		{
			XTL::CReaderLockHolder holder(m_NdasDeviceDataLock);
			ndasDevices.Copy(m_NdasDevices);
		}
		{
			XTL::CReaderLockHolder holder(m_NdasLogicalUnitDataLock);
			ndasLogicalUnits.Copy(m_NdasLogicalUnits);
		}
		// DEVICE READER LOCK REGION

		//
		// Recreate wait handles
		//
		size_t ndasLogicalUnitCount = ndasLogicalUnits.GetCount();
		waitHandles.resize(3 + ndasLogicalUnitCount * 2);

		waitHandles[0] = hStopEvent;
		waitHandles[1] = m_NdasLogicalUnitSetChanged;
		waitHandles[2] = m_HeartbeatMonitorTimer;

		// Disconnect events i=[3 ...3+nLogDevices)
		// Alarm Events events i=[3+nLogDevices ... 3+2*nLogDevices)
		for (size_t index = 0; index < ndasLogicalUnitCount; ++index)
		{
			INdasLogicalUnit* pNdasLogicalUnit = ndasLogicalUnits.GetAt(index);
			waitHandles[3 + index] = 
				NdasLogicalUnitDisconnectEvent()(pNdasLogicalUnit);
			waitHandles[3 + index + ndasLogicalUnitCount] = 
				NdasLogicalUnitAlarmEvent()(pNdasLogicalUnit);
		}

		DWORD nWaitHandles = waitHandles.size();

		DWORD waitResult = ::WaitForMultipleObjects(
			nWaitHandles, 
			&waitHandles[0], 
			FALSE, 
			INFINITE);

		if (WAIT_OBJECT_0 == waitResult)
		{
			// Terminate Thread Event
			XTLVERIFY( ::CancelWaitableTimer(m_HeartbeatMonitorTimer) );
			return 0;
		}
		else if (WAIT_OBJECT_0 + 1 == waitResult) 
		{
			// Logical device set change event
			XTLVERIFY( ::ResetEvent(m_NdasLogicalUnitSetChanged) );
			continue;
		} 
		else if (WAIT_OBJECT_0 + 2 == waitResult) 
		{
			// Heartbeat Monitor Timer Event
			AtlForEach(ndasDevices, InvokeTimerEventSink<INdasDevice>());
			AtlForEach(ndasLogicalUnits, InvokeTimerEventSink<INdasLogicalUnit>());
		}
		else if (
			waitResult >= WAIT_OBJECT_0 + 3 &&
			waitResult < WAIT_OBJECT_0 + 3 + ndasLogicalUnitCount)
		{
			XTLVERIFY( ::ResetEvent(waitHandles[waitResult - WAIT_OBJECT_0]) );
			// Disconnect Event
			DWORD n = waitResult - (WAIT_OBJECT_0 + 3);
			OnLogicalDeviceDisconnected(ndasLogicalUnits[n]);
		} 
		else if (
			waitResult >= WAIT_OBJECT_0 + 3 + ndasLogicalUnitCount &&
			waitResult < WAIT_OBJECT_0 + 3 + 2 * ndasLogicalUnitCount)
		{
			XTLVERIFY( ::ResetEvent(waitHandles[waitResult - WAIT_OBJECT_0]) );
			// Alarm Event
			DWORD n = waitResult - (WAIT_OBJECT_0 + 3 + ndasLogicalUnitCount);
			OnLogicalDeviceAlarmed(ndasLogicalUnits[n]);
		}
		else 
		{
			XTLASSERT(FALSE);
		}
	}
}
//
// 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;
}