⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 autolaunch.cpp

📁 一本在讲述USB驱动程式的书 及其范例原码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// AUTOLAUNCH.CPP -- Main program for AUTOLAUNCH service program
// Copyright (C) 1999 by Walter Oney
// All rights reserved

#include "stdafx.h"
#include "resource.h"

#include <initguid.h>
#include "AutoLaunch.h"

#define arraysize(p) (sizeof(p)/sizeof((p)[0]))
void Log(LPCTSTR info);

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

// Note: The real functionality of this module is embodied in the CAutoLaunch
// member functions that appear at the end of this file. The rest is just plumbing

#define SVCNAME AUTOLAUNCH			// name of service in Win2K systems
#define TSVCNAME _T("AUTOLAUNCH")

///////////////////////////////////////////////////////////////////////////////

void Log(LPCTSTR info)
	{							// Log
	CTime time = CTime::GetCurrentTime();
	static CString timeformat;
	if (timeformat.GetLength() == 0)
		timeformat.LoadString(IDS_TIMEFORMAT);

	CString msg;
	msg.Format(TSVCNAME _T(" - %-10s  %s\n"), time.Format(timeformat), info);
	OutputDebugString(msg);
	}							// Log

//=============================================================================
//=============================================================================
//                        W I N 2 K   S E R V I C E
//=============================================================================
//=============================================================================

#ifdef NTSERVICE

#include "service.h"

void RegisterServices();
void UnregisterServices();

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

class CAutoLaunch : public CService
{								// class CAutoLaunch
public:
	CAutoLaunch();
	virtual ~CAutoLaunch();

protected:
	HDEVNOTIFY m_hNotification;
	CStringArray m_devices;			// list of devices we've seen arrive

	VOID EnumerateExistingDevices(const GUID* guid);
	virtual DWORD HandleDeviceChange(DWORD evtype, _DEV_BROADCAST_HEADER *dbhdr);
	virtual DWORD InitService(DWORD argc, TCHAR* argv[]);
	VOID OnNewDevice(const CString& devname, HDEVINFO info, PSP_DEVINFO_DATA devdata);
	virtual void ShutdownService();
};								// class CAutoLaunch

CAutoLaunch theService;
DEFINE_SERVICE_EX(DS, theService);

BEGIN_SERVICE_TABLE(svctable)
	DEFINE_SERVICE_TABLE_ENTRY(DS, _T("AutoLaunch Service"))
END_SERVICE_TABLE()

///////////////////////////////////////////////////////////////////////////////

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
	{							// _tmain
	HINSTANCE hInstance = (HINSTANCE) GetModuleHandle(NULL);
	AFX_MODULE_STATE* pModuleState = AfxGetModuleState();
	pModuleState->m_hCurrentInstanceHandle = hInstance;
	pModuleState->m_hCurrentResourceHandle = hInstance;

	// Check for registration or unregistration request

	if (argc > 1)
		if (_tcsicmp(argv[1], _T("-register")) == 0)
			{
			RegisterServices();
			return 0;
			}
		else if (_tcsicmp(argv[1], _T("-unregister")) == 0)
			{
			UnregisterServices();
			return 0;
			}
		else
			{
			TRACE(_T("Invalid argument(s) to service main beginning %s\n"), argv[1]);
			return 0;
			}

	StartServiceCtrlDispatcher(svctable);
	return 0;
	}							// _tmain

///////////////////////////////////////////////////////////////////////////////

void RegisterServices()
	{							// RegisterServices
	TCHAR modname[_MAX_PATH];
	if (GetModuleFileName(NULL, modname, arraysize(modname)) == 0)
		{
		TRACE(_T("Error %d in call to GetModuleFileName\n"), GetLastError());
		return;
		}

	TCHAR fname[_MAX_FNAME];
	_tsplitpath(modname, NULL, NULL, fname, NULL);
	
	SC_HANDLE hsc = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
	if (!hsc)
		{
		TRACE(_T("Error %d in call to OpenSCManager\n"), GetLastError());
		return;
		}

	// Create service entry in the registry:

	SC_HANDLE hservice = CreateService(hsc, fname, svctable[0].lpServiceName,
		SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, SERVICE_DEMAND_START,
		SERVICE_ERROR_NORMAL, modname, NULL, NULL, NULL, NULL, NULL);
	ASSERT(hservice);
	CloseServiceHandle(hservice);
	CloseServiceHandle(hsc);
	}							// RegisterServices

///////////////////////////////////////////////////////////////////////////////

void UnregisterServices()
	{							// UnregisterServices
	TCHAR modname[_MAX_PATH];
	if (GetModuleFileName(NULL, modname, arraysize(modname)) == 0)
		{
		TRACE(_T("Error %d in call to GetModuleFileName\n"), GetLastError());
		return;
		}

	TCHAR fname[_MAX_FNAME];
	_tsplitpath(modname, NULL, NULL, fname, NULL);
	
	SC_HANDLE hsc = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
	if (!hsc)
		{
		TRACE(_T("Error %d in call to OpenSCManager\n"), GetLastError());
		return;
		}

	// Delete service entry in the service database

	SC_HANDLE hservice = OpenService(hsc, fname, SERVICE_ALL_ACCESS);
	ASSERT(hservice);
	DeleteService(hservice);
	CloseServiceHandle(hservice);
	CloseServiceHandle(hsc);
	}							// UnregisterServices

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

CAutoLaunch::CAutoLaunch() : CService(SERVICE_WIN32_OWN_PROCESS, SERVICE_ACCEPT_STOP)
	{							// CAutoLaunch::CAutoLaunch
	m_hNotification = NULL;
	}							// CAutoLaunch::CAutoLaunch

CAutoLaunch::~CAutoLaunch()
	{							// CAutoLaunch::~CAutoLaunch
	if (m_hNotification)
		UnregisterDeviceNotification(m_hNotification);
	}							// CAutoLaunch::~CAutoLaunch

///////////////////////////////////////////////////////////////////////////////

DWORD CAutoLaunch::InitService(DWORD argc, TCHAR* argv[])
	{							// CAutoLaunch::InitService
	Log(_T("Starting service"));

	DEV_BROADCAST_DEVICEINTERFACE filter = {0};
	filter.dbcc_size = sizeof(filter);
	filter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
	filter.dbcc_classguid = GUID_AUTOLAUNCH_NOTIFY;
	
	m_hNotification = RegisterDeviceNotification(m_hService, (PVOID) &filter, DEVICE_NOTIFY_SERVICE_HANDLE);
	if (!m_hNotification)
		TRACE(_T("RegisterDeviceNotification failed - %d\n"), GetLastError());

	// Enumerate all existing devices so we honor AutoLaunch requests for devices that started
	// before this service did.

	EnumerateExistingDevices(&GUID_AUTOLAUNCH_NOTIFY);
	
	return 0;
	}							// CAutoLaunch::InitService

///////////////////////////////////////////////////////////////////////////////

void CAutoLaunch::ShutdownService()
	{							// CAutoLaunch::ShutdownService
	Log(_T("Shutting service down"));
	if (m_hNotification)
		UnregisterDeviceNotification(m_hNotification);
	m_hNotification = NULL;
	}							// CAutoLaunch::ShutdownService

#endif // NTSERVICE

//=============================================================================
//=============================================================================
//                         W I N 9 8   A P P L E T
//=============================================================================
//=============================================================================

#ifndef NTSERVICE

#include "ShutdownDlg.h"

class CAutoLaunchApp : public CWinApp
{								// class CAutoLaunchApp
public:
	virtual int ExitInstance();
	virtual BOOL InitInstance();

	HANDLE m_hMutex;			// mutex object for detecting duplicate invocations
};								// class CAutoLaunchApp

CAutoLaunchApp theApp;

///////////////////////////////////////////////////////////////////////////////

class CAutoLaunch : public CWnd
{								// class CAutoLaunch
public:
	CAutoLaunch();
	virtual ~CAutoLaunch();
	VOID EnumerateExistingDevices(const GUID* guid);

protected:
	CShutdownDlg* m_shutdown;		// shutdown dialog
	CStringArray m_devices;			// list of devices we've seen arrive

	void CreateTrayIcon();
	DWORD HandleDeviceChange(DWORD evtype, _DEV_BROADCAST_HEADER *dbhdr);
	VOID OnNewDevice(const CString& devname, HDEVINFO info, PSP_DEVINFO_DATA devdata);

	afx_msg int OnCreate(LPCREATESTRUCT csp);
	afx_msg void OnDestroy();
	afx_msg BOOL OnDeviceChange(UINT evtype, DWORD dwData);
	afx_msg LRESULT OnNotifyIcon(WPARAM wParam, LPARAM lParam);
	afx_msg void OnTimer(UINT id);

	afx_msg void OnMenuClose();
	virtual void PostNcDestroy();

	DECLARE_MESSAGE_MAP()
};								// class CAutoLaunch

#define PWM_NOTIFYICON (WM_USER + 256)

BEGIN_MESSAGE_MAP(CAutoLaunch, CWnd)
	ON_WM_CREATE()
	ON_WM_DESTROY()
	ON_WM_DEVICECHANGE()
	ON_MESSAGE(PWM_NOTIFYICON, OnNotifyIcon)
	ON_COMMAND(ID_TRAYPOPUP_CLOSE, OnMenuClose)
	ON_WM_TIMER()
END_MESSAGE_MAP()

CAutoLaunch::CAutoLaunch()
	{
	m_shutdown = NULL;
	}

CAutoLaunch::~CAutoLaunch()
	{
	if (m_shutdown)
		delete m_shutdown;
	}

///////////////////////////////////////////////////////////////////////////////

void CAutoLaunch::CreateTrayIcon()
	{							// CAutoLaunch::CreateTrayIcon
	NOTIFYICONDATA nid = {sizeof(NOTIFYICONDATA)};

	nid.hWnd = m_hWnd;
	nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
	nid.uCallbackMessage = PWM_NOTIFYICON;
	nid.hIcon = theApp.LoadIcon(IDI_TRAYICON);
	
	CString traytip;
	traytip.LoadString(IDS_TRAYTIP);
	_tcsncpy(nid.szTip, traytip, arraysize(nid.szTip));

	// When we succeed in registering our tray icon, we know the system is up.
	// Enumerate all existing interfaces to their AutoLaunch's happen

	if (Shell_NotifyIcon(NIM_ADD, &nid))
		{						// tray icon visible
		EnumerateExistingDevices(&GUID_AUTOLAUNCH_NOTIFY);
		return;					// geschafft!
		}						// tray icon visible

	// Shell_NotifyIcon will fail if we call it before the user logs in. This shouldn't
	// normally happen because, by the time we reboot after installing a device that
	// uses us, we should be in the Run list in the registry. But just in case it does
	// happen, retry up to 5 times after a 10-second delay each time.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -