balloon: (related to bz#1082999) add device events handling.

A new implementation of the balloon's service which add handling of
device insertion and removal. It also prepare the service to work with
a new method of write request in the driver.
This commit is contained in:
Gal Hammer authored and Vadim Rozenfeld committed 2014-06-14 23:42:41 +10:00
1 parent 0dcf4e6737
commit f542c3f14d
8 files changed
+264 -278

No files matched your search

+165 -36
View File
@@ -1,61 +1,184 @@
#include "device.h"
#include "public.h"
#include "utils.h"
#include "memstat.h"
#include <dbt.h>
#include <setupapi.h>
#include <tchar.h>
CDevice::CDevice()
{
m_hDevice = INVALID_HANDLE_VALUE;
m_pMemStat = NULL;
m_hService = NULL;
m_hThread = NULL;
m_evtTerminate = NULL;
m_evtWrite = NULL;
}
CDevice::~CDevice()
{
BALLOON_STAT stat[VIRTIO_BALLOON_S_NR];
if (m_hDevice != INVALID_HANDLE_VALUE) {
memset(stat, -1, sizeof(BALLOON_STAT) * VIRTIO_BALLOON_S_NR);
Write(stat, VIRTIO_BALLOON_S_NR);
CloseHandle(m_hDevice);
m_hDevice = INVALID_HANDLE_VALUE;
}
Fini();
}
BOOL CDevice::Init()
BOOL CDevice::Init(SERVICE_STATUS_HANDLE hService)
{
PWCHAR DevicePath = NULL;
if ((DevicePath = GetDevicePath((LPGUID)&GUID_DEVINTERFACE_BALLOON)) != NULL) {
m_hDevice = CreateFile(
DevicePath,
GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL
);
m_pMemStat = new CMemStat();
if (!m_pMemStat || !m_pMemStat->Init()) {
return FALSE;
}
if (m_hDevice != INVALID_HANDLE_VALUE) {
PrintMessage("Open balloon device");
return TRUE;
m_evtTerminate = CreateEvent(NULL, FALSE, FALSE, NULL);
if (!m_evtTerminate) {
return FALSE;
}
m_evtWrite = CreateEvent(NULL, FALSE, FALSE, NULL);
if (!m_evtWrite) {
return FALSE;
}
m_hService = hService;
return TRUE;
}
VOID CDevice::Fini()
{
Stop();
if (m_evtWrite) {
CloseHandle(m_evtWrite);
m_evtWrite = NULL;
}
if (m_evtTerminate) {
CloseHandle(m_evtTerminate);
m_evtTerminate = NULL;
}
m_hService = NULL;
delete m_pMemStat;
m_pMemStat = NULL;
}
DWORD CDevice::Run()
{
PWCHAR DevicePath = GetDevicePath((LPGUID)&GUID_DEVINTERFACE_BALLOON);
if (DevicePath == NULL) {
PrintMessage("File not found.");
return ERROR_FILE_NOT_FOUND;
}
HANDLE hDevice = CreateFile(DevicePath, GENERIC_WRITE, 0, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
free(DevicePath);
if (hDevice == INVALID_HANDLE_VALUE) {
PrintMessage("Failed to create file.");
return GetLastError();
}
DEV_BROADCAST_HANDLE filter;
HDEVNOTIFY devnotify;
ZeroMemory(&filter, sizeof(filter));
filter.dbch_size = sizeof(filter);
filter.dbch_devicetype = DBT_DEVTYP_HANDLE;
filter.dbch_handle = hDevice;
devnotify = RegisterDeviceNotification(m_hService, &filter,
DEVICE_NOTIFY_SERVICE_HANDLE);
if (!devnotify) {
DWORD err = GetLastError();
PrintMessage("Failed to register handle notification.");
CloseHandle(hDevice);
return err;
}
WriteLoop(hDevice);
UnregisterDeviceNotification(devnotify);
CloseHandle(hDevice);
return NO_ERROR;
}
VOID CDevice::WriteLoop(HANDLE hDevice)
{
HANDLE waitfor[] = { m_evtTerminate, m_evtWrite };
OVERLAPPED ovlp;
DWORD timeout;
DWORD written;
DWORD waitrc;
BOOL writerc;
ZeroMemory(&ovlp, sizeof(ovlp));
ovlp.hEvent = m_evtWrite;
while (1) {
// The old version of the balloon driver didn't block write requests
// until stats were requested. So in order not to consume too much CPU
// we keep the old 1s delay behavior and switch to infinite wait only
// if write result is pending.
timeout = 1000;
if (m_pMemStat->Update()) {
writerc = WriteFile(hDevice, m_pMemStat->GetBuffer(),
m_pMemStat->GetSize(), NULL, &ovlp);
if (!writerc && (GetLastError() == ERROR_IO_PENDING)) {
timeout = INFINITE;
}
}
waitrc = WaitForMultipleObjects(sizeof(waitfor) / sizeof(waitfor[0]),
waitfor, FALSE, timeout);
if (waitrc == WAIT_OBJECT_0) {
break;
}
else if (waitrc == WAIT_OBJECT_0 + 1) {
if (!GetOverlappedResult(hDevice, &ovlp, &written, FALSE) ||
(written != m_pMemStat->GetSize()))
{
PrintMessage("Failed to write stats.");
}
}
}
PrintMessage("Cannot find balloon device");
return FALSE;
}
BOOL CDevice::Write(PBALLOON_STAT pstat, int nr)
BOOL CDevice::Start()
{
BOOL res = FALSE;
ULONG ret = 0;
res = WriteFile(m_hDevice, pstat, sizeof(BALLOON_STAT) * nr, &ret, NULL);
if (!res) {
PrintMessage("Cannot write balloon device");
} else if ( ret != sizeof(BALLOON_STAT) * nr) {
PrintMessage("Write balloon device error");
ret = FALSE;
DWORD tid;
if (!m_hThread) {
m_hThread = CreateThread(NULL, 0,
(LPTHREAD_START_ROUTINE)DeviceThread, (LPVOID)this, 0, &tid);
}
return res;
return (m_hThread != NULL);
}
VOID CDevice::Stop()
{
if (m_hThread) {
SetEvent(m_evtTerminate);
if (WaitForSingleObject(m_hThread, 1000) == WAIT_TIMEOUT) {
TerminateThread(m_hThread, 0);
}
CloseHandle(m_hThread);
m_hThread = NULL;
}
}
DWORD WINAPI CDevice::DeviceThread(LPDWORD lParam)
{
CDevice* pDev = reinterpret_cast<CDevice*>(lParam);
return pDev->Run();
}
PTCHAR CDevice::GetDevicePath( IN LPGUID InterfaceGuid )
{
@@ -64,6 +187,7 @@ PTCHAR CDevice::GetDevicePath( IN LPGUID InterfaceGuid )
PSP_DEVICE_INTERFACE_DETAIL_DATA DeviceInterfaceDetailData = NULL;
ULONG Length, RequiredLength = 0;
BOOL bResult;
PTCHAR DevicePath;
HardwareDeviceInfo = SetupDiGetClassDevs(
InterfaceGuid,
@@ -130,5 +254,10 @@ PTCHAR CDevice::GetDevicePath( IN LPGUID InterfaceGuid )
return NULL;
}
return DeviceInterfaceDetailData->DevicePath;
DevicePath = _tcsdup(DeviceInterfaceDetailData->DevicePath);
SetupDiDestroyDeviceInfoList(HardwareDeviceInfo);
LocalFree(DeviceInterfaceDetailData);
return DevicePath;
}
+17 -13
View File
@@ -1,26 +1,30 @@
#ifndef DEVICE_H
#define DEVICE_H
#define INITGUID
#include <windows.h>
#include <strsafe.h>
#include <setupapi.h>
#include <stdio.h>
#include <stdlib.h>
#include "public.h"
#include <wtypes.h>
class CMemStat;
class CDevice {
public:
CDevice();
~CDevice();
BOOL Init();
BOOL Write(PBALLOON_STAT pstat, int nr);
BOOL Init(SERVICE_STATUS_HANDLE hService);
VOID Fini();
BOOL Start();
VOID Stop();
protected:
HANDLE m_hDevice;
PTCHAR GetDevicePath( IN LPGUID InterfaceGuid );
PTCHAR GetDevicePath(IN LPGUID InterfaceGuid);
DWORD Run();
private:
static DWORD WINAPI DeviceThread(LPDWORD lParam);
VOID WriteLoop(HANDLE hDevice);
CMemStat* m_pMemStat;
SERVICE_STATUS_HANDLE m_hService;
HANDLE m_hThread;
HANDLE m_evtTerminate;
HANDLE m_evtWrite;
};
#endif
+3 -21
View File
@@ -1,30 +1,16 @@
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <tchar.h>
#include "utils.h"
#include "service.h"
LPWSTR ServiceName = L"BalloonService";
LPWSTR DisplayName = L"Balloon Service";
CService srvc;
void __stdcall Handler(DWORD ctlcode)
{
CService::HandlerThunk(&srvc, ctlcode);
}
void __stdcall ServiceMain(DWORD argc, TCHAR* argv[])
{
srvc.m_StatusHandle = RegisterServiceCtrlHandler(argv[0], (LPHANDLER_FUNCTION) Handler);
CService::ServiceMainThunk(&srvc, argc, argv);
}
SERVICE_TABLE_ENTRY serviceTable[] =
{
{ ServiceName, (LPSERVICE_MAIN_FUNCTION) ServiceMain},
{ NULL, NULL}
};
void __stdcall HandlerEx(DWORD ctlcode, DWORD evtype, PVOID evdata, PVOID context)
{
CService::HandlerExThunk((CService*) context, ctlcode, evtype, evdata);
@@ -59,10 +45,6 @@ wmain(
ServiceRun();
} else if (_tcsicmp(L"-s", argv[1]) == 0) {
ServiceControl(SERVICE_CONTROL_STOP);
} else if (_tcsicmp(L"-p", argv[1]) == 0) {
ServiceControl(SERVICE_CONTROL_PAUSE);
} else if (_tcsicmp(L"-c", argv[1]) == 0) {
ServiceControl(SERVICE_CONTROL_CONTINUE);
} else if (_tcsicmp(L"status", argv[1]) == 0) {
SC_HANDLE scm, service;
scm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
+14 -17
View File
@@ -6,6 +6,7 @@ CMemStat::CMemStat()
initialized = FALSE;
locator = NULL;
service = NULL;
memset(m_Stats, -1, sizeof(m_Stats));
}
CMemStat::~CMemStat()
@@ -90,7 +91,7 @@ BOOL CMemStat::Init()
return TRUE;
}
BOOL CMemStat::GetStatus(PBALLOON_STAT pStat)
BOOL CMemStat::Update()
{
MEMORYSTATUSEX statex = {sizeof(statex)};
CComPtr< IEnumWbemClassObject > enumerator;
@@ -99,10 +100,6 @@ BOOL CMemStat::GetStatus(PBALLOON_STAT pStat)
_variant_t var_val;
HRESULT status = S_OK;
UINT idx = 0;
if(!pStat) {
PrintMessage("Invalid pointer");
return FALSE;
}
status = service->ExecQuery(
L"WQL",
@@ -141,8 +138,8 @@ BOOL CMemStat::GetStatus(PBALLOON_STAT pStat)
PrintMessage("Cannot get PagesInputPerSec");
var_val.vt = -1;
}
pStat[idx].tag = VIRTIO_BALLOON_S_SWAP_IN;
pStat[idx].val = (long)var_val;
m_Stats[idx].tag = VIRTIO_BALLOON_S_SWAP_IN;
m_Stats[idx].val = (long)var_val;
idx++;
status = memory->Get(
@@ -157,8 +154,8 @@ BOOL CMemStat::GetStatus(PBALLOON_STAT pStat)
PrintMessage("Cannot get PagesOutputPerSec");
var_val.vt = -1;
}
pStat[idx].tag = VIRTIO_BALLOON_S_SWAP_OUT;
pStat[idx].val = (long)var_val;
m_Stats[idx].tag = VIRTIO_BALLOON_S_SWAP_OUT;
m_Stats[idx].val = (long)var_val;
idx++;
status = memory->Get(
@@ -173,8 +170,8 @@ BOOL CMemStat::GetStatus(PBALLOON_STAT pStat)
PrintMessage("Cannot get PageReadsPerSec");
var_val.vt = -1;
}
pStat[idx].tag = VIRTIO_BALLOON_S_MAJFLT;
pStat[idx].val = (long)var_val;
m_Stats[idx].tag = VIRTIO_BALLOON_S_MAJFLT;
m_Stats[idx].val = (long)var_val;
idx++;
status = memory->Get(
@@ -189,18 +186,18 @@ BOOL CMemStat::GetStatus(PBALLOON_STAT pStat)
PrintMessage("Cannot get PageFaultsPerSec");
var_val.vt = -1;
}
pStat[idx].tag = VIRTIO_BALLOON_S_MINFLT;
pStat[idx].val = (long)var_val;
m_Stats[idx].tag = VIRTIO_BALLOON_S_MINFLT;
m_Stats[idx].val = (long)var_val;
idx++;
GlobalMemoryStatusEx(&statex);
pStat[idx].tag = VIRTIO_BALLOON_S_MEMFREE;
pStat[idx].val = statex.ullAvailPhys;
m_Stats[idx].tag = VIRTIO_BALLOON_S_MEMFREE;
m_Stats[idx].val = statex.ullAvailPhys;
idx++;
pStat[idx].tag = VIRTIO_BALLOON_S_MEMTOT;
pStat[idx].val = statex.ullTotalPhys;
m_Stats[idx].tag = VIRTIO_BALLOON_S_MEMTOT;
m_Stats[idx].val = statex.ullTotalPhys;
}
return TRUE;
}
+11 -1
View File
@@ -12,11 +12,21 @@ public:
CMemStat();
~CMemStat();
BOOL Init();
BOOL GetStatus(PBALLOON_STAT pstat);
BOOL Update();
PVOID GetBuffer() {
return m_Stats;
}
size_t GetSize() {
return sizeof(m_Stats);
}
private:
BOOL initialized;
CComPtr< IWbemLocator > locator;
CComPtr< IWbemServices > service;
BALLOON_STAT m_Stats[VIRTIO_BALLOON_S_NR];
};
#endif
+49 -168
View File
@@ -1,15 +1,16 @@
#define INITGUID
#include "service.h"
#include "utils.h"
#include "device.h"
#include "public.h"
CService::CService()
{
m_hDevNotify = NULL;
m_evTerminate = NULL;
m_evWakeUp = NULL;
m_thHandle = NULL;
m_bPauseService = FALSE;
m_bRunningService = FALSE;
m_StatusHandle = NULL;
m_pMemStat = NULL;
m_pDev = NULL;
m_Status = SERVICE_STOPPED;
}
@@ -17,21 +18,12 @@ CService::CService()
CService::~CService()
{
m_evTerminate = NULL;
m_evWakeUp = NULL;
m_thHandle = NULL;
m_bPauseService = FALSE;
m_bRunningService = FALSE;
m_StatusHandle = NULL;
m_pMemStat = NULL;
m_pDev = NULL;
m_Status = SERVICE_STOPPED;
}
void __stdcall CService::HandlerThunk(CService* service, DWORD ctlcode)
{
service->ServiceCtrlHandler(ctlcode);
}
DWORD __stdcall CService::HandlerExThunk(CService* service, DWORD ctlcode, DWORD evtype, PVOID evdata)
{
switch (ctlcode) {
@@ -56,54 +48,11 @@ void __stdcall CService::ServiceMainThunk(CService* service, DWORD argc, TCHAR*
BOOL CService::InitService()
{
DWORD id;
m_thHandle = CreateThread(
NULL,
0,
(LPTHREAD_START_ROUTINE) ServiceThread,
(LPVOID)this,
0,
&id
);
if (m_thHandle == NULL) {
PrintMessage("Cannot create thread");
return FALSE;
}
m_bRunningService = TRUE;
m_Status = SERVICE_RUNNING;
return TRUE;
}
DWORD WINAPI CService::ServiceThread(LPDWORD lParam)
{
CService* service = (CService*)lParam;
service->Run();
return 0;
}
void CService::Run()
{
BALLOON_STAT stat[VIRTIO_BALLOON_S_NR];
DWORD mSec;
while (1) {
mSec = 2000;
memset(stat, -1, sizeof(BALLOON_STAT) * VIRTIO_BALLOON_S_NR);
if (m_pMemStat->GetStatus(stat)) {
EnterCriticalSection(&m_scWrite);
if (m_pDev->Write(stat, VIRTIO_BALLOON_S_NR)) {
mSec = 1000;
}
LeaveCriticalSection(&m_scWrite);
}
if (WaitForSingleObject(m_evWakeUp, mSec) == WAIT_OBJECT_0) {
ResetEvent(m_evWakeUp);
break;
}
}
}
BOOL CService::SendStatusToSCM(DWORD dwCurrentState, DWORD dwWin32ExitCode, DWORD dwServiceSpecificExitCode, DWORD dwCheckPoint, DWORD dwWaitHint)
{
BOOL res;
@@ -117,7 +66,6 @@ BOOL CService::SendStatusToSCM(DWORD dwCurrentState, DWORD dwWin32ExitCode, DWOR
} else {
serviceStatus.dwControlsAccepted =
SERVICE_ACCEPT_STOP |
SERVICE_ACCEPT_PAUSE_CONTINUE |
SERVICE_ACCEPT_SHUTDOWN;
}
@@ -139,39 +87,11 @@ BOOL CService::SendStatusToSCM(DWORD dwCurrentState, DWORD dwWin32ExitCode, DWOR
return res;
}
void CService::ResumeService()
{
m_bPauseService = FALSE;
ResumeThread(m_thHandle);
m_Status = SERVICE_RUNNING;
}
void CService::PauseService()
{
BALLOON_STAT stat[VIRTIO_BALLOON_S_NR];
if (m_bRunningService && !m_bPauseService && m_pDev) {
memset(stat, -1, sizeof(BALLOON_STAT) * VIRTIO_BALLOON_S_NR);
EnterCriticalSection(&m_scWrite);
m_pDev->Write(stat, VIRTIO_BALLOON_S_NR);
m_bPauseService = TRUE;
SuspendThread(m_thHandle);
LeaveCriticalSection(&m_scWrite);
m_Status = SERVICE_PAUSED;
}
}
void CService::StopService()
{
if (m_bRunningService && m_pDev) {
if (m_evWakeUp) {
SetEvent(m_evWakeUp);
if (WaitForSingleObject(m_thHandle, 1000) == WAIT_TIMEOUT) {
TerminateThread(m_thHandle, 0);
}
}
EnterCriticalSection(&m_scWrite);
m_pDev->Stop();
m_bRunningService = FALSE;
LeaveCriticalSection(&m_scWrite);
m_Status = SERVICE_STOPPED;
}
SetEvent(m_evTerminate);
@@ -179,29 +99,23 @@ void CService::StopService()
void CService::terminate(DWORD error)
{
if (m_hDevNotify) {
UnregisterDeviceNotification(m_hDevNotify);
m_hDevNotify = NULL;
}
if (m_evTerminate) {
CloseHandle(m_evTerminate);
m_evTerminate = NULL;
}
if (m_evWakeUp) {
CloseHandle(m_evWakeUp);
}
DeleteCriticalSection(&m_scWrite);
if (m_StatusHandle) {
SendStatusToSCM(SERVICE_STOPPED, error, 0, 0, 0);
}
if (m_thHandle) {
CloseHandle(m_thHandle);
}
delete m_pMemStat;
delete m_pDev;
}
void CService::ServiceCtrlHandler(DWORD controlCode)
{
switch(controlCode)
@@ -218,35 +132,6 @@ void CService::ServiceCtrlHandler(DWORD controlCode)
StopService();
return;
case SERVICE_CONTROL_PAUSE:
if (m_bRunningService && !m_bPauseService) {
m_Status = SERVICE_PAUSE_PENDING;
SendStatusToSCM(
m_Status,
NO_ERROR,
0,
1,
1000
);
PauseService();
}
break;
case SERVICE_CONTROL_CONTINUE:
if (m_bRunningService && m_bPauseService) {
m_Status = SERVICE_CONTINUE_PENDING;
SendStatusToSCM(
m_Status,
NO_ERROR,
0,
1,
1000
);
ResumeService();
}
break;
case SERVICE_CONTROL_INTERROGATE:
break;
@@ -261,7 +146,22 @@ void CService::ServiceCtrlHandler(DWORD controlCode)
DWORD CService::ServiceHandleDeviceChange(DWORD evtype, _DEV_BROADCAST_HEADER* dbhdr)
{
PrintMessage("ServiceHandleDeviceChange");
switch (evtype)
{
case DBT_DEVICEARRIVAL:
case DBT_DEVICEQUERYREMOVEFAILED:
m_pDev->Start();
break;
case DBT_DEVICEQUERYREMOVE:
case DBT_DEVICEREMOVECOMPLETE:
m_pDev->Stop();
break;
default:
break;
}
return NO_ERROR;
}
@@ -280,50 +180,39 @@ void CService::ServiceMain(DWORD argc, LPTSTR *argv)
return;
}
m_pMemStat = new CMemStat;
if (!m_pMemStat || !m_pMemStat->Init()) {
terminate(GetLastError());
return;
}
m_pDev = new CDevice;
if (!m_pDev || !m_pDev->Init()) {
terminate(GetLastError());
return;
}
res = SendStatusToSCM(SERVICE_START_PENDING, NO_ERROR, 0 , 1, 5000);
if (!res) {
terminate(GetLastError());
return;
}
m_pDev = new CDevice();
if (!m_pDev || !m_pDev->Init(m_StatusHandle) || !m_pDev->Start()) {
terminate(GetLastError());
return;
}
DEV_BROADCAST_DEVICEINTERFACE filter;
ZeroMemory(&filter, sizeof(filter));
filter.dbcc_size = sizeof(filter);
filter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
filter.dbcc_classguid = GUID_DEVINTERFACE_BALLOON;
m_hDevNotify = RegisterDeviceNotification(m_StatusHandle, &filter,
DEVICE_NOTIFY_SERVICE_HANDLE);
if (!m_hDevNotify) {
terminate(GetLastError());
return;
}
m_evTerminate = CreateEvent(NULL, TRUE, FALSE, NULL);
if (!m_evTerminate) {
terminate(GetLastError());
return;
}
m_evWakeUp = CreateEvent(NULL, TRUE, FALSE, NULL);
if (!m_evWakeUp) {
terminate(GetLastError());
return;
}
InitializeCriticalSection(&m_scWrite);
res = SendStatusToSCM(SERVICE_START_PENDING, NO_ERROR, 0 , 2, 1000);
if (!res) {
terminate(GetLastError());
return;
}
res = SendStatusToSCM(SERVICE_START_PENDING, NO_ERROR, 0 , 3, 5000);
if (!res) {
terminate(GetLastError());
return;
}
res = InitService();
if (!res) {
terminate(GetLastError());
@@ -357,18 +246,10 @@ void CService::GetStatus(SC_HANDLE service)
CurrentState = SERVICE_STOPPED;
printf("Service STOPPED.\n");
break;
case SERVICE_PAUSED:
CurrentState = SERVICE_PAUSED;
printf("Service PAUSED.\n");
break;
case SERVICE_CONTINUE_PENDING:
CurrentState = SERVICE_CONTINUE_PENDING;
printf("Service is resuming...\n");
break;
case SERVICE_PAUSE_PENDING:
CurrentState = SERVICE_PAUSE_PENDING;
printf("Service is pausing...\n");
break;
case SERVICE_START_PENDING:
CurrentState = SERVICE_START_PENDING;
printf("Service is starting...\n");
+2 -13
View File
@@ -4,9 +4,7 @@
#include <windows.h>
#include <dbt.h>
#include "memstat.h"
#include "device.h"
class CDevice;
class CService
{
@@ -15,17 +13,12 @@ public:
~CService();
BOOL InitService();
void GetStatus(SC_HANDLE service);
static void __stdcall HandlerThunk(CService* service, DWORD ctlcode);
static DWORD __stdcall HandlerExThunk(CService* service, DWORD ctlcode, DWORD evtype, PVOID evdata);
static void __stdcall ServiceMainThunk(CService* service, DWORD argc, TCHAR* argv[]);
SERVICE_STATUS_HANDLE m_StatusHandle;
private:
static DWORD WINAPI ServiceThread( LPDWORD lParam);
void Run();
BOOL SendStatusToSCM(DWORD dwCurrentState, DWORD dwWin32ExitCode, DWORD dwServiceSpecificExitCode, DWORD dwCheckPoint, DWORD dwWaitHint);
void ResumeService();
void PauseService();
void StopService();
void terminate(DWORD error);
void ServiceCtrlHandler(DWORD controlCode);
@@ -33,14 +26,10 @@ private:
DWORD ServiceHandleDeviceChange(DWORD evtype, _DEV_BROADCAST_HEADER* dbhdr);
DWORD ServiceHandlePowerEvent(DWORD evtype, DWORD flags);
HDEVNOTIFY m_hDevNotify;
HANDLE m_evTerminate;
HANDLE m_evWakeUp;
HANDLE m_thHandle;
BOOL m_bPauseService;
BOOL m_bRunningService;
DWORD m_Status;
CRITICAL_SECTION m_scWrite;
CMemStat* m_pMemStat;
CDevice* m_pDev;
};
+3 -9
View File
@@ -3,6 +3,8 @@
#include "strsafe.h"
extern LPWSTR ServiceName;
extern LPWSTR DisplayName;
extern CService srvc;
static struct ErrEntry {
@@ -69,8 +71,6 @@ void ShowUsage()
printf("blnsvr -u\tUninstall service\n");
printf("blnsvr -r\tRun service\n");
printf("blnsvr -s\tStop service\n");
printf("blnsvr -p\tPause service\n");
printf("blnsvr -c\tResume service\n");
printf("blnsvr status\tCurrent status\n");
printf("\n");
}
@@ -100,7 +100,7 @@ BOOL InstallService()
newService = CreateService(
scm,
ServiceName,
ServiceName,
DisplayName,
SERVICE_ALL_ACCESS,
SERVICE_WIN32_OWN_PROCESS,
SERVICE_AUTO_START,
@@ -263,12 +263,6 @@ BOOL ServiceControl(int ctrl)
if (ctrl == SERVICE_CONTROL_STOP) {
printf("Service is stopping...\n");
res = ControlService(service, SERVICE_CONTROL_STOP, &status);
} else if (ctrl == SERVICE_CONTROL_PAUSE) {
printf("Service is pausing...\n");
res = ControlService(service, SERVICE_CONTROL_PAUSE, &status);
} else if (ctrl == SERVICE_CONTROL_CONTINUE) {
printf("Service is resuming...\n");
res = ControlService(service, SERVICE_CONTROL_CONTINUE, &status);
}
if (!res) {