icecastService.cpp 5.41 KB
Newer Older
1
#define _WIN32_WINNT 0x0400
2 3 4 5
#include <windows.h>
#include <stdio.h>
#include <direct.h>
extern "C" {
6 7 8
#include "thread/thread.h"
#include "avl/avl.h"
#include "log/log.h"
9
#include "global.h"
10 11
#include "httpp/httpp.h"
#include "net/sock.h"
12 13 14 15 16 17
#include "connection.h"
#include "refbuf.h"
#include "client.h"
#include "stats.h"
}

18 19 20 21
// Issues to be wary of. Careful of the runtime you use, I've had printf and similar routines
// crash because of this on apparently valid strings. some weird thing related to checking for
// multiple byte characters.  DeleteService only marks a service for deletion, and the docs
// are unclear on the cases that lead to purging however a reboot should do it.
22 23 24 25 26 27 28 29 30

SERVICE_STATUS          ServiceStatus; 
SERVICE_STATUS_HANDLE   hStatus; 
 
void  ServiceMain(int argc, char** argv); 
void  ControlHandler(DWORD request); 
extern "C" int mainService(int argc, char **argv);


31
void installService (const char *path)
32
{
33 34 35
    if (path) {
        char	fullPath[8096*2] = "\"";
        int len = GetModuleFileName (NULL, fullPath+1, sizeof (fullPath)-1);
36

37 38 39 40
         _snprintf(fullPath+len+1, sizeof (fullPath)-len, "\" \"%s\"", path);

        SC_HANDLE manager = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS );
        if (manager == NULL)
41
		{
42
            MessageBox (NULL, "OpenSCManager failed", NULL, MB_SERVICE_NOTIFICATION);
43 44 45
			return;
		}

46
		SC_HANDLE service = CreateService(
47 48 49
				manager,
                PACKAGE_STRING,
                PACKAGE_STRING " Streaming Media Server",
50 51 52 53 54 55 56 57 58 59 60
			GENERIC_READ | GENERIC_EXECUTE,
			SERVICE_WIN32_OWN_PROCESS,
			SERVICE_AUTO_START,
			SERVICE_ERROR_IGNORE,
			fullPath,
			NULL,
			NULL,
			NULL,
			NULL,
			NULL
		);
61
		if (service == NULL)
62
		{
63
            MessageBox (NULL, "CreateService failed", NULL, MB_SERVICE_NOTIFICATION);
64
			CloseServiceHandle (manager);
65 66 67
			return;
		}

68
		printf("Service Installed\n");
69
		CloseServiceHandle (service);
70
		CloseServiceHandle (manager);
71 72 73 74
	}
}
void removeService()
{
75 76
	SC_HANDLE manager = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS );
	if (manager == NULL)
77
	{
78
        MessageBox (NULL, "OpenSCManager failed", NULL, MB_SERVICE_NOTIFICATION);
79 80 81
		return;
	}

82
	SC_HANDLE service = OpenService (manager, PACKAGE_STRING, DELETE);
83 84
	if (service) {
		DeleteService(service);
85
        CloseServiceHandle (service);
86
        printf ("Service deleted, may require reboot to complete removal\n");
87
	}
88 89
	else
		printf("Service not found\n");
90
    CloseServiceHandle (manager);
91
    Sleep (1500);
92 93 94 95 96
}
void ControlHandler(DWORD request) 
{ 
   switch(request) { 
      case SERVICE_CONTROL_STOP: 
97 98 99 100 101 102 103
          if (ServiceStatus.dwCurrentState != SERVICE_STOP)
          {
              ServiceStatus.dwCurrentState = SERVICE_STOP_PENDING; 
              SetServiceStatus (hStatus, &ServiceStatus);
              global.running = ICE_HALTING;
              return; 
          }
104 105 106 107 108 109 110 111 112 113 114
 
      default:
		break;
    } 
 
    // Report current status
    SetServiceStatus (hStatus, &ServiceStatus);
}

void ServiceMain(int argc, char** argv) 
{ 
115
   ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
116 117 118 119 120
   ServiceStatus.dwWin32ExitCode = 0; 
   ServiceStatus.dwServiceSpecificExitCode = 0; 
   ServiceStatus.dwCheckPoint = 0; 
   ServiceStatus.dwWaitHint = 0; 
 
121
   hStatus = RegisterServiceCtrlHandler(PACKAGE_STRING, (LPHANDLER_FUNCTION)ControlHandler); 
122 123
   if (hStatus == (SERVICE_STATUS_HANDLE)0) { 
      // Registering Control Handler failed
124
      MessageBox (NULL, "RegisterServiceCtrlHandler failed", NULL, MB_SERVICE_NOTIFICATION);
125 126 127 128
      return; 
   }  
   // We report the running status to SCM. 
   ServiceStatus.dwCurrentState = SERVICE_RUNNING; 
129
   ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
130 131 132 133 134
   SetServiceStatus (hStatus, &ServiceStatus);
 
   /* Here we do the work */

   	int		argc2 = 3;
135
	char*	argv2 [4];
136

137 138 139 140 141 142 143
    argv2 [0] = argv[0];
    argv2 [1] = "-c";
    if (argc < 2)
        argv2 [2] = "icecast.xml";
    else
        argv2 [2] = argv[1];
    argv2[3] = NULL;
144

145
	ServiceStatus.dwWin32ExitCode = mainService(argc2, (char **)argv2);
146 147 148 149 150 151

	ServiceStatus.dwCurrentState = SERVICE_STOPPED;
	SetServiceStatus(hStatus, &ServiceStatus);
}


152
int main(int argc, char **argv) 
153
{
154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172
    if (argc < 2)
    {
        printf ("Usage:\n %s  remove\n %s  install path\n", argv[0], argv[0]);
        return 0;
    }
    if (!strcmp(argv[1], "install"))
    {
        if (argc > 2)
            installService(argv[2]);
        else
            printf ("install requires a path arg as well\n");
        Sleep (2000);
        return 0;
    }
    if (!strcmp(argv[1], "remove") || !strcmp(argv[1], "uninstall"))
    {
        removeService();
        return 0;
    }
173

174 175
    if (_chdir(argv[1]) < 0)
    {
176 177 178
        char buffer [256];
        _snprintf (buffer, sizeof(buffer), "Unable to change to directory %s", argv[1]);
        MessageBox (NULL, buffer, NULL, MB_SERVICE_NOTIFICATION);
179 180
        return 0;
    }
181 182

	SERVICE_TABLE_ENTRY ServiceTable[2];
183
	ServiceTable[0].lpServiceName = PACKAGE_STRING;
184 185 186 187 188
	ServiceTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceMain;

	ServiceTable[1].lpServiceName = NULL;
	ServiceTable[1].lpServiceProc = NULL;
	// Start the control dispatcher thread for our service
189 190
    if (StartServiceCtrlDispatcher(ServiceTable) == 0)
        MessageBox (NULL, "StartServiceCtrlDispatcher failed", NULL, MB_SERVICE_NOTIFICATION);
191 192

    return 0;
193
}