2
我嘗試構建監視用戶會話活動的服務。目前專注於用戶的登錄和鎖定。 我使用http://msdn.microsoft.com/en-us/library/bb540475(v=VS.85).aspx例如監視器會話更改事件c
我的代碼:
#include <windows.h>
#include <tchar.h>
#include <strsafe.h>
#pragma comment(lib, "advapi32.lib")
#define SVCNAME TEXT("SvcName")
#define SVC_ERROR 4
SERVICE_STATUS gSvcStatus;
SERVICE_STATUS_HANDLE gSvcStatusHandle;
HANDLE ghSvcStopEvent = NULL;
VOID SvcInstall(void);
DWORD WINAPI SvcCtrlHandler(DWORD , DWORD , LPVOID , LPVOID);
VOID WINAPI SvcMain(DWORD, LPTSTR *);
VOID ReportSvcStatus(DWORD, DWORD, DWORD);
VOID SvcInit(DWORD, LPTSTR *);
VOID SvcReportEvent(LPTSTR);
void __cdecl _tmain(int argc, TCHAR *argv[])
{
if (lstrcmpi(argv[1], TEXT("install")) == 0)
{
SvcInstall();
return;
}
SERVICE_TABLE_ENTRY DispatchTable[] =
{
{ SVCNAME, (LPSERVICE_MAIN_FUNCTION)SvcMain },
{ NULL, NULL }
};
if (!StartServiceCtrlDispatcher(DispatchTable))
{
SvcReportEvent(TEXT("StartServiceCtrlDispatcher"));
}
}
VOID SvcInstall()
{
SC_HANDLE schSCManager;
SC_HANDLE schService;
TCHAR szPath[MAX_PATH];
if (!GetModuleFileName(NULL, szPath, MAX_PATH))
{
printf("Cannot install service (%d)\n", GetLastError());
return;
}
schSCManager = OpenSCManager(
NULL, // local computer
NULL, // ServicesActive database
SC_MANAGER_ALL_ACCESS); // full access rights
if (NULL == schSCManager)
{
printf("OpenSCManager failed (%d)\n", GetLastError());
return;
}
// Create the service
schService = CreateService(
schSCManager, // SCM database
SVCNAME, // name of service
SVCNAME, // service name to display
SERVICE_ALL_ACCESS, // desired access
SERVICE_WIN32_OWN_PROCESS, // service type
SERVICE_AUTO_START, // start type
SERVICE_ERROR_NORMAL, // error control type
szPath, // path to service's binary
NULL, // no load ordering group
NULL, // no tag identifier
NULL, // no dependencies
NULL, // LocalSystem account
NULL); // no password
if (schService == NULL)
{
printf("CreateService failed (%d)\n", GetLastError());
CloseServiceHandle(schSCManager);
return;
}
else printf("Service installed successfully\n");
CloseServiceHandle(schService);
CloseServiceHandle(schSCManager);
}
VOID WINAPI SvcMain(DWORD dwArgc, LPTSTR *lpszArgv)
{
gSvcStatusHandle = RegisterServiceCtrlHandler(SVCNAME,SvcCtrlHandler,NULL);
OutputDebugString(L"\n***SVCMAIN");
if (!gSvcStatusHandle)
{
SvcReportEvent(TEXT("RegisterServiceCtrlHandler"));
return;
}
gSvcStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
gSvcStatus.dwServiceSpecificExitCode = 0;
ReportSvcStatus(SERVICE_START_PENDING, NO_ERROR, 3000);
SvcInit(dwArgc, lpszArgv);
}
VOID SvcInit(DWORD dwArgc, LPTSTR *lpszArgv)
{
FILE *f = fopen("c:\\test\\file.txt", "a");
OutputDebugString(L"\n***SVCINIT");
fprintf(f, "init\n");
fclose(f);
ghSvcStopEvent = CreateEvent(
NULL, // default security attributes
TRUE, // manual reset event
FALSE, // not signaled
NULL); // no name
if (ghSvcStopEvent == NULL)
{
ReportSvcStatus(SERVICE_STOPPED, NO_ERROR, 0);
return;
}
ReportSvcStatus(SERVICE_RUNNING, NO_ERROR, 0);
while (WaitForSingleObject(ghSvcStopEvent, 3000) != WAIT_OBJECT_0){
OutputDebugString(L"\n***BEEP");
f = fopen("c:\\test\\file.txt", "a");
fprintf(f, "beep\n");
fclose(f);
Beep(1000, 100);
}
ReportSvcStatus(SERVICE_STOPPED, NO_ERROR, 0);
}
VOID ReportSvcStatus(DWORD dwCurrentState,
DWORD dwWin32ExitCode,
DWORD dwWaitHint)
{
static DWORD dwCheckPoint = 1;
DWORD my_error = 0;
// Fill in the SERVICE_STATUS structure.
gSvcStatus.dwCurrentState = dwCurrentState;
gSvcStatus.dwWin32ExitCode = dwWin32ExitCode;
gSvcStatus.dwWaitHint = dwWaitHint;
gSvcStatus.dwControlsAccepted = SERVICE_ACCEPT_SESSIONCHANGE | SERVICE_ACCEPT_STOP;
if ((dwCurrentState == SERVICE_RUNNING) ||
(dwCurrentState == SERVICE_STOPPED)){
gSvcStatus.dwCheckPoint = 0;
}
else gSvcStatus.dwCheckPoint = dwCheckPoint++;
// Report the status of the service to the SCM.
SetServiceStatus(gSvcStatusHandle, &gSvcStatus);
my_error = GetLastError();
FILE *f = fopen("c:\\test\\file.txt", "a");
fprintf(f, "last error %d \n",my_error);
fprintf(f, "\n***controls accepted %d ***\n", gSvcStatus.dwControlsAccepted);
fclose(f);
}
DWORD WINAPI SvcCtrlHandler(DWORD dwControl, DWORD dwEventType, LPVOID lpEventData, LPVOID lpContext)
{
DWORD dwErrorCode = NO_ERROR;
FILE *f = fopen("c:\\test\\file.txt", "a");
// Handle the requested control code.
fprintf(f, "dwCtrl is = %d \n", dwControl);
fclose(f);
switch (dwControl)
{
case SERVICE_CONTROL_TIMECHANGE:
f = fopen("c:\\test\\file.txt", "a");
fprintf(f, "time\n");
fclose(f);
OutputDebugString(L"\n****GOT time!!!\n\n");
SetEvent(ghSvcStopEvent);
ReportSvcStatus(gSvcStatus.dwCurrentState, NO_ERROR, 0);
break;
case SERVICE_CONTROL_SESSIONCHANGE:
f = fopen("c:\\test\\file.txt", "a");
fprintf(f, "session\n");
fclose(f);
OutputDebugString(L"\n****GOT Session!\n\n");
SetEvent(ghSvcStopEvent);
ReportSvcStatus(gSvcStatus.dwCurrentState, NO_ERROR, 0);
break;
case SERVICE_CONTROL_STOP:
OutputDebugString(L"\n****GOT STOP!\n\n");
f = fopen("c:\\test\\file.txt", "a");
fprintf(f, "stop\n");
fclose(f);
ReportSvcStatus(SERVICE_STOP_PENDING, NO_ERROR, 0);
SetEvent(ghSvcStopEvent);
ReportSvcStatus(gSvcStatus.dwCurrentState, NO_ERROR, 0);
return;
case SERVICE_CONTROL_INTERROGATE:
break;
default:
break;
}
}
VOID SvcReportEvent(LPTSTR szFunction)
{
HANDLE hEventSource;
LPCTSTR lpszStrings[2];
TCHAR Buffer[80];
hEventSource = RegisterEventSource(NULL, SVCNAME);
if (NULL != hEventSource)
{
StringCchPrintf(Buffer, 80, TEXT("%s failed with %d"), szFunction, GetLastError());
lpszStrings[0] = SVCNAME;
lpszStrings[1] = Buffer;
ReportEvent(hEventSource, // event log handle
EVENTLOG_ERROR_TYPE, // event type
0, // event category
SVC_ERROR, // event identifier
NULL, // no security identifier
2, // size of lpszStrings array
0, // no binary data
lpszStrings, // array of strings
NULL); // no binary data
DeregisterEventSource(hEventSource);
}
}
爲什麼我沒有得到任何「情況下SERVICE_CONTROL_SESSIONCHANGE」,只有停止任何想法? 在我的日誌文件,我看到接受蜂鳴日誌和控制 - 129(站+會話更改) 這是我的日誌文件的內容:
last error 0
***controls accepted 129 ***
init
last error 0
***controls accepted 129 ***
beep
beep
beep
beep
beep