2017-03-15 89 views
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 

回答

1

gSvcStatusHandle = RegisterServiceCtrlHandler(SVCNAME,SvcCtrlHandler,NULL);

應該是: gSvcStatusHandle = RegisterServiceCtrlHandlerEx(SVCNAME,SvcCtrlHandler,NULL);