diff --git a/src/sbbs3/ntsvcs.c b/src/sbbs3/ntsvcs.c
index 69aa19ccd15c937cf4022071e950461f74e0f261..74e2b8a641b5edf7c9907773d81143dd1b45057f 100644
--- a/src/sbbs3/ntsvcs.c
+++ b/src/sbbs3/ntsvcs.c
@@ -51,6 +51,9 @@
 	#define NO_WEB_SERVER
 #endif
 
+#define NTSVC_TIMEOUT_STARTUP	30000	/* Milliseconds */
+#define NTSVC_TIMEOUT_TERMINATE	30000	/* Milliseconds */
+
 static void WINAPI bbs_ctrl_handler(DWORD dwCtrlCode);
 static void WINAPI ftp_ctrl_handler(DWORD dwCtrlCode);
 static void WINAPI web_ctrl_handler(DWORD dwCtrlCode);
@@ -129,6 +132,7 @@ sbbs_ntsvc_t services = {
 };
 #endif
 
+/* This list is used for enumerating all services */
 sbbs_ntsvc_t* ntsvc_list[] = {
 	&bbs,
 	&ftp,
@@ -164,18 +168,33 @@ static BOOL winsock_cleanup(void)
 	return(FALSE);
 }
 
+/****************************************/
 /* Service Control Handlers (Callbacks) */
+/****************************************/
 
+/* Common control handler for all services */
+static void svc_ctrl_handler(sbbs_ntsvc_t* svc, DWORD dwCtrlCode)
+{
+	switch(dwCtrlCode) {
+		case SERVICE_CONTROL_STOP:
+		case SERVICE_CONTROL_SHUTDOWN:
+			svc->status.dwWaitHint=NTSVC_TIMEOUT_TERMINATE;
+			svc->status.dwCurrentState=SERVICE_STOP_PENDING;
+			break;
+	}
+	SetServiceStatus(svc->status_handle, &svc->status);
+}
+
+/* Service-specific control handler stub functions */
 static void WINAPI bbs_ctrl_handler(DWORD dwCtrlCode)
 {
 	switch(dwCtrlCode) {
 		case SERVICE_CONTROL_STOP:
 		case SERVICE_CONTROL_SHUTDOWN:
 			bbs_terminate();
-			bbs.status.dwCurrentState=SERVICE_STOP_PENDING;
 			break;
 	}
-	SetServiceStatus(bbs.status_handle, &bbs.status);
+	svc_ctrl_handler(&bbs, dwCtrlCode);
 }
 
 static void WINAPI ftp_ctrl_handler(DWORD dwCtrlCode)
@@ -184,10 +203,9 @@ static void WINAPI ftp_ctrl_handler(DWORD dwCtrlCode)
 		case SERVICE_CONTROL_STOP:
 		case SERVICE_CONTROL_SHUTDOWN:
 			ftp_terminate();
-			ftp.status.dwCurrentState=SERVICE_STOP_PENDING;
 			break;
 	}
-	SetServiceStatus(ftp.status_handle, &ftp.status);
+	svc_ctrl_handler(&ftp, dwCtrlCode);
 }
 
 #if !defined(NO_WEB_SERVER)
@@ -197,10 +215,9 @@ static void WINAPI web_ctrl_handler(DWORD dwCtrlCode)
 		case SERVICE_CONTROL_STOP:
 		case SERVICE_CONTROL_SHUTDOWN:
 			web_terminate();
-			web.status.dwCurrentState=SERVICE_STOP_PENDING;
 			break;
 	}
-	SetServiceStatus(web.status_handle, &web.status);
+	svc_ctrl_handler(&web, dwCtrlCode);
 }
 #endif
 
@@ -210,10 +227,9 @@ static void WINAPI mail_ctrl_handler(DWORD dwCtrlCode)
 		case SERVICE_CONTROL_STOP:
 		case SERVICE_CONTROL_SHUTDOWN:
 			mail_terminate();
-			mail.status.dwCurrentState=SERVICE_STOP_PENDING;
 			break;
 	}
-	SetServiceStatus(mail.status_handle, &mail.status);
+	svc_ctrl_handler(&mail, dwCtrlCode);
 }
 
 #if !defined(NO_SERVICES)
@@ -223,47 +239,43 @@ static void WINAPI services_ctrl_handler(DWORD dwCtrlCode)
 		case SERVICE_CONTROL_STOP:
 		case SERVICE_CONTROL_SHUTDOWN:
 			services_terminate();
-			services.status.dwCurrentState=SERVICE_STOP_PENDING;
 			break;
 	}
-	SetServiceStatus(services.status_handle, &services.status);
+	svc_ctrl_handler(&services, dwCtrlCode);
 }
 #endif
 
 /****************************************************************************/
-/* BBS local/log print routine												*/
+/* Event thread local/log print routine										*/
 /****************************************************************************/
-static int svc_lputs(void* p, char* str)
+static int event_lputs(char *str)
 {
 	char line[1024];
-	sbbs_ntsvc_t* svc = (sbbs_ntsvc_t*)p;
 
-	snprintf(line,sizeof(line),"%s: %s",svc==NULL ? "Synchronet" : svc->name, str);
+	snprintf(line,sizeof(line),"SynchronetEvent: %s",str);
 	OutputDebugString(line);
     return(0);
 }
 
-/****************************************************************************/
-/* Event thread local/log print routine										*/
-/****************************************************************************/
-static int event_lputs(char *str)
+/************************************/
+/* Shared Service Callback Routines */
+/************************************/
+static int svc_lputs(void* p, char* str)
 {
 	char line[1024];
+	sbbs_ntsvc_t* svc = (sbbs_ntsvc_t*)p;
 
-	snprintf(line,sizeof(line),"SynchronetEvent: %s",str);
+	snprintf(line,sizeof(line),"%s: %s",svc==NULL ? "Synchronet" : svc->name, str);
 	OutputDebugString(line);
     return(0);
 }
 
-/************************************/
-/* Shared Service Callback Routines */
-/************************************/
 static void svc_started(void* p)
 {
 	sbbs_ntsvc_t* svc = (sbbs_ntsvc_t*)p;
 
 	svc->status.dwCurrentState=SERVICE_RUNNING;
-	svc->status.dwControlsAccepted=SERVICE_ACCEPT_STOP;
+	svc->status.dwControlsAccepted|=SERVICE_ACCEPT_STOP;
 	SetServiceStatus(svc->status_handle, &svc->status);
 }
 
@@ -278,7 +290,11 @@ static void svc_terminated(void* p, int code)
 	}
 }
 
-/* Generic ServiceMain function */
+/***************/
+/* ServiceMain */
+/***************/
+
+/* Common ServiceMain for all services */
 static void WINAPI svc_start(sbbs_ntsvc_t* svc)
 {
 	svc_lputs(svc,"Starting service");
@@ -290,7 +306,8 @@ static void WINAPI svc_start(sbbs_ntsvc_t* svc)
 
 	memset(&svc->status,0,sizeof(SERVICE_STATUS));
 	svc->status.dwServiceType=SERVICE_WIN32_SHARE_PROCESS;
-	svc->status.dwWaitHint=30000;	/* milliseconds */
+	svc->status.dwControlsAccepted=SERVICE_ACCEPT_SHUTDOWN;
+	svc->status.dwWaitHint=NTSVC_TIMEOUT_STARTUP;
 
 	svc->status.dwCurrentState=SERVICE_START_PENDING;
 	SetServiceStatus(svc->status_handle, &svc->status);
@@ -301,7 +318,7 @@ static void WINAPI svc_start(sbbs_ntsvc_t* svc)
 	SetServiceStatus(svc->status_handle, &svc->status);
 }
 
-/* These are the actual ServiceMain stub functions */
+/* Service-specific ServiceMain stub functions */
 
 static void WINAPI bbs_start(DWORD dwArgc, LPTSTR *lpszArgv)
 {
@@ -353,6 +370,9 @@ static void describe_service(HANDLE hSCMlib, SC_HANDLE hService, char* descripti
 		changeServiceConfig2(hService, SERVICE_CONFIG_DESCRIPTION, &service_desc);
 }
 
+/****************************************************************************/
+/* Utility function to create a service with description (on Win2K+)		*/
+/****************************************************************************/
 static SC_HANDLE create_service(HANDLE hSCMlib, SC_HANDLE hSCManager
 								,char* name, char* display_name, char* description, char* path)
 {
@@ -386,7 +406,9 @@ static SC_HANDLE create_service(HANDLE hSCMlib, SC_HANDLE hSCManager
 	return(hService);
 }
 
-
+/****************************************************************************/
+/* Install one or all services												*/
+/****************************************************************************/
 static int install(const char* svc_name)
 {
 	int			i;
@@ -432,6 +454,9 @@ static int install(const char* svc_name)
 	return(0);
 }
 
+/****************************************************************************/
+/* Utility function to remove a service cleanly (stopping if necessary)		*/
+/****************************************************************************/
 static void remove_service(SC_HANDLE hSCManager, char* name, char* DISP_name)
 {
     SC_HANDLE		hService;
@@ -468,7 +493,9 @@ static void remove_service(SC_HANDLE hSCManager, char* name, char* DISP_name)
     CloseServiceHandle(hService);
 }
 
-
+/****************************************************************************/
+/* Uninstall one or all services											*/
+/****************************************************************************/
 static int uninstall(const char* svc_name)
 {
 	int			i;