📄 autolaunch.cpp
字号:
// 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 + -