Registering a Super Service Programmatically

It is possible to register a super service programmatically. Upon starting the service through a call to RegisterService, the flag SERVICE_INIT_STOPPED should be set in the dwInfo parameter that is passed to xxx_Init. Services.exe does not use any of the previously mentioned registry information. This requires the program calling RegisterService to have super services bind to the appropriate ports.

Once DeregisterService has been called, all sockets that are associated with a given service will be closed. To add a port, the ServiceAddPort function should be used.

If IOCTL_SERVICE_START is sent to a service, Services.exe will automatically bind any sockets and reread any registry values if xxx_IOControl returns TRUE. If xxx_IOControl returns FALSE, the service ports will not be bound again.

The following code example shows the programmatic registering of a Web server to use super services. This code can be used for a home gateway configuration that has multiple network interfaces. In this example, the Web server is configured to accept connections on port 80 only if they arrive on address 169.254.0.1. If a connection arrives over the Secure Sockets Layer (SSL) port 443, it will be accepted no matter which interface it arrived on.

{
SOCKADDR_IN SockAddr;
int iProtocol = 0;
memset(&SockAddr,0,sizeof(SockAddr));
HANDLE hService = RegisterService("HTP",0,"httpd.dll",0x00000001);
if(!hService)
    goto cleanup;
//hService is the same value that GetServiceHandle would return, so it can
//be used for ServiceIoControl functions.
//A value of 0 indicates that the service does not support super services.
if(!ServiceIoControl(hService, IOCTL_SERVICE_REGISTER_SOCKADDR,0,0,0,0,0,0))
     goto cleanUp; //does not support super services
SockAddr.sin_family = AF_INET;
SockAddr.sin_port=htons(80);
SockAddr.sin_addr=0x0100fea9; //169.254.0.1
ServiceAddPort(hService,(SOCK_ADDR*)&SockAddr, sizeof(SockAddr), iProtocol,0);
if (! ServiceAddPort(hService,(SOCK_ADDR*)&SockAddr, sizeof(SockAddr), iProtocol,0))
     goto cleanup;
memset(&SockAddr,0,sizeof(SockAddr));
SockAddr.sin_family = AF_INET;
SockAddr.sin_port = htons(443);
ServiceAddPort(hService,(SOCK_ADDR*)&SockAddr, sizeof(SockAddr), iProtocol,0);
//When all sockets have been bound, the service must be informed that it
//is ready to start.
if(!ServiceIoControl(hService, IOCTL_SERVICE_STARTED,0,0,0,0,0,0))
     goto cleanUp; //if the service cannot start
}

See Also

Super Services | xxx_Init | RegisterService | DeregisterService | ServiceAddPort | xxx_IOControl

 Last updated on Saturday, April 10, 2004

© 1992-2003 Microsoft Corporation. All rights reserved.