/*
* Service.xs
*/
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#include "../ppport.h"
#define RETURNRESULT(x) if ((x)){ XST_mYES(0); }\
else { XST_mNO(0); }\
XSRETURN(1)
#define SETIV(index,value) sv_setiv(ST(index), value)
#define SETPV(index,string) sv_setpv(ST(index), string)
/* constant function for exporting NT definitions. */
static long
constant(char *name)
{
errno = 0;
switch (*name) {
case 'A':
break;
case 'B':
break;
case 'C':
break;
case 'D':
break;
case 'E':
break;
case 'F':
break;
case 'G':
break;
case 'H':
break;
case 'I':
break;
case 'J':
break;
case 'K':
break;
case 'L':
break;
case 'M':
break;
case 'N':
break;
case 'O':
break;
case 'P':
break;
case 'Q':
break;
case 'R':
break;
case 'S':
if (strEQ(name, "SERVICE_WIN32_OWN_PROCESS"))
#ifdef SERVICE_WIN32_OWN_PROCESS
return SERVICE_WIN32_OWN_PROCESS;
#else
goto not_there;
#endif
if (strEQ(name, "SERVICE_WIN32_SHARE_PROCESS"))
#ifdef SERVICE_WIN32_SHARE_PROCESS
return SERVICE_WIN32_SHARE_PROCESS;
#else
goto not_there;
#endif
if (strEQ(name, "SERVICE_KERNEL_DRIVER"))
#ifdef SERVICE_KERNEL_DRIVER
return SERVICE_KERNEL_DRIVER;
#else
goto not_there;
#endif
if (strEQ(name, "SERVICE_FILE_SYSTEM_DRIVER"))
#ifdef SERVICE_FILE_SYSTEM_DRIVER
return SERVICE_FILE_SYSTEM_DRIVER;
#else
goto not_there;
#endif
if (strEQ(name, "SERVICE_INTERACTIVE_PROCESS"))
#ifdef SERVICE_INTERACTIVE_PROCESS
return SERVICE_INTERACTIVE_PROCESS;
#else
goto not_there;
#endif
if (strEQ(name, "SERVICE_STOPPED"))
#ifdef SERVICE_STOPPED
return SERVICE_STOPPED;
#else
goto not_there;
#endif
if (strEQ(name, "SERVICE_START_PENDING"))
#ifdef SERVICE_START_PENDING
return SERVICE_START_PENDING;
#else
goto not_there;
#endif
if (strEQ(name, "SERVICE_STOP_PENDING"))
#ifdef SERVICE_STOP_PENDING
return SERVICE_STOP_PENDING;
#else
goto not_there;
#endif
if (strEQ(name, "SERVICE_RUNNING"))
#ifdef SERVICE_RUNNING
return SERVICE_RUNNING;
#else
goto not_there;
#endif
if (strEQ(name, "SERVICE_CONTINUE_PENDING"))
#ifdef SERVICE_CONTINUE_PENDING
return SERVICE_CONTINUE_PENDING;
#else
goto not_there;
#endif
if (strEQ(name, "SERVICE_PAUSE_PENDING"))
#ifdef SERVICE_PAUSE_PENDING
return SERVICE_PAUSE_PENDING;
#else
goto not_there;
#endif
if (strEQ(name, "SERVICE_PAUSED"))
#ifdef SERVICE_PAUSED
return SERVICE_PAUSED;
#else
goto not_there;
#endif
if (strEQ(name, "SERVICE_ACCEPT_STOP"))
#ifdef SERVICE_ACCEPT_STOP
return SERVICE_ACCEPT_STOP;
#else
goto not_there;
#endif
if (strEQ(name, "SERVICE_ACCEPT_PAUSE_CONTINUE"))
#ifdef SERVICE_ACCEPT_PAUSE_CONTINUE
return SERVICE_ACCEPT_PAUSE_CONTINUE;
#else
goto not_there;
#endif
if (strEQ(name, "SERVICE_ACCEPT_SHUTDOWN"))
#ifdef SERVICE_ACCEPT_SHUTDOWN
return SERVICE_ACCEPT_SHUTDOWN;
#else
goto not_there;
#endif
break;
case 'T':
break;
case 'U':
break;
case 'V':
break;
case 'W':
break;
case 'X':
break;
case 'Y':
break;
case 'Z':
break;
}
errno = EINVAL;
return 0;
not_there:
errno = ENOENT;
return 0;
}
MODULE = Win32::Service PACKAGE = Win32::Service
PROTOTYPES: DISABLE
long
constant(name)
char *name
CODE:
RETVAL = constant(name);
OUTPUT:
RETVAL
bool
StartService(lpHostName, lpServiceName)
char *lpHostName
char *lpServiceName
CODE:
{
SC_HANDLE hSCManager, hSCService;
WCHAR wbuffer[MAX_PATH+1];
RETVAL = FALSE;
if (lpHostName && *lpHostName == '\0')
lpHostName = NULL;
if (lpServiceName && *lpServiceName != '\0') {
if(lpHostName && USING_WIDE()) {
A2WHELPER(lpHostName, wbuffer, sizeof(wbuffer));
hSCManager = OpenSCManagerW(wbuffer, NULL, SC_MANAGER_CONNECT);
}
else
hSCManager = OpenSCManagerA(lpHostName, NULL, SC_MANAGER_CONNECT);
if (hSCManager != NULL) {
if(USING_WIDE()) {
A2WHELPER(lpServiceName, wbuffer, sizeof(wbuffer));
hSCService = OpenServiceW(hSCManager, wbuffer, SERVICE_START);
}
else
hSCService = OpenServiceA(hSCManager, lpServiceName, SERVICE_START);
if (hSCService != NULL) {
RETVAL = StartService(hSCService, 0, NULL);
CloseServiceHandle(hSCService);
}
CloseServiceHandle(hSCManager);
}
}
}
OUTPUT:
RETVAL
bool
StopService(lpHostName, lpServiceName)
char *lpHostName
char *lpServiceName
CODE:
{
SERVICE_STATUS serviceStatus;
WCHAR wbuffer[MAX_PATH+1];
SC_HANDLE hSCManager, hSCService;
RETVAL = FALSE;
if (lpHostName && *lpHostName == '\0')
lpHostName = NULL;
if (lpServiceName && *lpServiceName != '\0') {
if(lpHostName && USING_WIDE()) {
A2WHELPER(lpHostName, wbuffer, sizeof(wbuffer));
hSCManager = OpenSCManagerW(wbuffer, NULL, SC_MANAGER_CONNECT);
}
else
hSCManager = OpenSCManagerA(lpHostName, NULL, SC_MANAGER_CONNECT);
if (hSCManager != NULL) {
if(USING_WIDE()) {
A2WHELPER(lpServiceName, wbuffer, sizeof(wbuffer));
hSCService = OpenServiceW(hSCManager, wbuffer, SERVICE_STOP);
}
else
hSCService = OpenServiceA(hSCManager, lpServiceName, SERVICE_STOP);
if (hSCService != NULL) {
RETVAL = ControlService(hSCService, SERVICE_CONTROL_STOP,
&serviceStatus);
CloseServiceHandle(hSCService);
}
CloseServiceHandle(hSCManager);
}
}
}
OUTPUT:
RETVAL
bool
GetStatus(lpHostName,lpServiceName,status)
char *lpHostName
char *lpServiceName
SV *status
CODE:
{
SERVICE_STATUS serviceStatus;
WCHAR wbuffer[MAX_PATH+1];
SC_HANDLE hSCManager, hSCService;
RETVAL = FALSE;
if (!(status && SvROK(status) &&
(status = SvRV(status)) && SvTYPE(status) == SVt_PVHV))
croak("third arg must be a HASHREF");
if (lpHostName && *lpHostName == '\0')
lpHostName = NULL;
if (lpServiceName && *lpServiceName != '\0') {
if(lpHostName && USING_WIDE()) {
A2WHELPER(lpHostName, wbuffer, sizeof(wbuffer));
hSCManager = OpenSCManagerW(wbuffer, NULL, SC_MANAGER_CONNECT);
}
else
hSCManager = OpenSCManagerA(lpHostName, NULL, SC_MANAGER_CONNECT);
if (hSCManager != NULL) {
if(USING_WIDE()) {
A2WHELPER(lpServiceName, wbuffer, sizeof(wbuffer));
hSCService = OpenServiceW(hSCManager, wbuffer, SERVICE_INTERROGATE);
}
else
hSCService = OpenServiceA(hSCManager, lpServiceName, SERVICE_INTERROGATE);
if (hSCService != NULL) {
RETVAL = ControlService(hSCService, SERVICE_CONTROL_INTERROGATE,
&serviceStatus);
if (!RETVAL && GetLastError() == ERROR_SERVICE_NOT_ACTIVE) {
Zero(&serviceStatus, 1, SERVICE_STATUS);
serviceStatus.dwCurrentState = SERVICE_STOPPED;
RETVAL = TRUE;
}
CloseServiceHandle(hSCService);
}
CloseServiceHandle(hSCManager);
if (RETVAL) {
SV *sv;
sv = newSViv(serviceStatus.dwServiceType);
hv_store((HV*)status, "ServiceType", strlen("ServiceType"), sv, 0);
sv = newSViv(serviceStatus.dwCurrentState);
hv_store((HV*)status, "CurrentState", strlen("CurrentState"), sv, 0);
sv = newSViv(serviceStatus.dwControlsAccepted);
hv_store((HV*)status, "ControlsAccepted", strlen("ControlsAccepted"), sv, 0);
sv = newSViv(serviceStatus.dwWin32ExitCode);
hv_store((HV*)status, "Win32ExitCode", strlen("Win32ExitCode"), sv, 0);
sv = newSViv(serviceStatus.dwServiceSpecificExitCode);
hv_store((HV*)status, "ServiceSpecificExitCode", strlen("ServiceSpecificExitCode"), sv, 0);
sv = newSViv(serviceStatus.dwCheckPoint);
hv_store((HV*)status, "CheckPoint", strlen("CheckPoint"), sv, 0);
sv = newSViv(serviceStatus.dwWaitHint);
hv_store((HV*)status, "WaitHint", strlen("WaitHint"), sv, 0);
}
}
}
}
OUTPUT:
RETVAL
bool
PauseService(lpHostName,lpServiceName)
char *lpHostName
char *lpServiceName
CODE:
{
SERVICE_STATUS serviceStatus;
WCHAR wbuffer[MAX_PATH+1];
SC_HANDLE hSCManager, hSCService;
RETVAL = FALSE;
if (lpHostName && *lpHostName == '\0')
lpHostName = NULL;
if (lpServiceName && *lpServiceName != '\0') {
if(lpHostName && USING_WIDE()) {
A2WHELPER(lpHostName, wbuffer, sizeof(wbuffer));
hSCManager = OpenSCManagerW(wbuffer, NULL, SC_MANAGER_CONNECT);
}
else
hSCManager = OpenSCManagerA(lpHostName, NULL, SC_MANAGER_CONNECT);
if (hSCManager != NULL) {
if(USING_WIDE()) {
A2WHELPER(lpServiceName, wbuffer, sizeof(wbuffer));
hSCService = OpenServiceW(hSCManager, wbuffer, SERVICE_PAUSE_CONTINUE);
}
else
hSCService = OpenServiceA(hSCManager, lpServiceName, SERVICE_PAUSE_CONTINUE);
if (hSCService != NULL) {
RETVAL = ControlService(hSCService, SERVICE_CONTROL_PAUSE, &serviceStatus);
CloseServiceHandle(hSCService);
}
CloseServiceHandle(hSCManager);
}
}
}
OUTPUT:
RETVAL
bool
ResumeService(lpHostName,lpServiceName)
char *lpHostName
char *lpServiceName
CODE:
{
SERVICE_STATUS serviceStatus;
WCHAR wbuffer[MAX_PATH+1];
SC_HANDLE hSCManager, hSCService;
RETVAL = FALSE;
if (lpHostName && *lpHostName == '\0')
lpHostName = NULL;
if (lpServiceName && *lpServiceName != '\0') {
if(lpHostName && USING_WIDE()) {
A2WHELPER(lpHostName, wbuffer, sizeof(wbuffer));
hSCManager = OpenSCManagerW(wbuffer, NULL, SC_MANAGER_CONNECT);
}
else
hSCManager = OpenSCManagerA(lpHostName, NULL, SC_MANAGER_CONNECT);
if (hSCManager != NULL) {
if(USING_WIDE()) {
A2WHELPER(lpServiceName, wbuffer, sizeof(wbuffer));
hSCService = OpenServiceW(hSCManager, wbuffer, SERVICE_PAUSE_CONTINUE);
}
else
hSCService = OpenServiceA(hSCManager, lpServiceName, SERVICE_PAUSE_CONTINUE);
if (hSCService != NULL) {
RETVAL = ControlService(hSCService, SERVICE_CONTROL_CONTINUE,
&serviceStatus);
CloseServiceHandle(hSCService);
}
CloseServiceHandle(hSCManager);
}
}
}
OUTPUT:
RETVAL
bool
GetServices(lpHostName, hv)
char *lpHostName
SV *hv
CODE:
{
DWORD dwBytesNeeded, dwServicesReturned, dwResumeHandle, dwIndex;
ENUM_SERVICE_STATUSA essA[1000];
ENUM_SERVICE_STATUSW essW[1000];
WCHAR wbuffer[MAX_PATH+1];
char szService[MAX_PATH+1];
char szDisplay[MAX_PATH+1];
LPSTR lpDisplayName, lpServiceName;
BOOL bUsingWide = USING_WIDE();
SC_HANDLE hSCManager;
SV *sv;
RETVAL = FALSE;
if (!(hv && SvROK(hv) &&
(hv = SvRV(hv)) && SvTYPE(hv) == SVt_PVHV))
croak("second argument must be a HASHREF");
if (lpHostName && *lpHostName == '\0')
lpHostName = NULL;
if(lpHostName && bUsingWide) {
A2WHELPER(lpHostName, wbuffer, sizeof(wbuffer));
hSCManager = OpenSCManagerW(wbuffer, NULL, SC_MANAGER_CONNECT|SC_MANAGER_ENUMERATE_SERVICE);
}
else
hSCManager = OpenSCManagerA(lpHostName, NULL, SC_MANAGER_CONNECT|SC_MANAGER_ENUMERATE_SERVICE);
if (hSCManager != NULL) {
dwResumeHandle = 0;
dwBytesNeeded = 0;
dwServicesReturned = 0;
while ((bUsingWide
? EnumServicesStatusW(hSCManager, SERVICE_WIN32,
SERVICE_ACTIVE | SERVICE_INACTIVE,
essW, sizeof(essW), &dwBytesNeeded,
&dwServicesReturned,
&dwResumeHandle)
: EnumServicesStatusA(hSCManager, SERVICE_WIN32,
SERVICE_ACTIVE | SERVICE_INACTIVE,
essA, sizeof(essA), &dwBytesNeeded,
&dwServicesReturned,
&dwResumeHandle)) == TRUE
|| GetLastError() == ERROR_MORE_DATA)
{
lpServiceName = szService;
lpDisplayName = szDisplay;
for (dwIndex = 0; dwIndex < dwServicesReturned; ++dwIndex) {
if (bUsingWide) {
W2AHELPER(essW[dwIndex].lpServiceName, szService, sizeof(szService));
W2AHELPER(essW[dwIndex].lpDisplayName, szDisplay, sizeof(szDisplay));
}
else {
lpServiceName = essA[dwIndex].lpServiceName;
lpDisplayName = essA[dwIndex].lpDisplayName;
}
sv = newSVpv(lpServiceName, 0);
hv_store((HV*)hv, lpDisplayName,
strlen(lpDisplayName), sv, 0);
}
if (dwResumeHandle == 0) {
RETVAL = TRUE;
break;
}
}
CloseServiceHandle(hSCManager);
}
}
OUTPUT:
RETVAL