Hello,
Yes, I use Fossil on Windows NT 4.0...
It works okay, but not out of the box -- NT 4 doesn't support the
ChangeServiceConfig2W and QueryServiceConfig2W functions and displays a
dialog box saying "The procedure entry point ChangeServiceConfig2W could
not be located in the dynamic link library ADVAPI32.dll." as soon as
fossil.exe is run.
I had been just commenting out the offending code, but finally got
around implementing a better fix. The attached patch modifies winhttp.c
to load the offending functions at run time and only call them if they
actually exist. I tested the patch with mingw32 and a few different
versions of MSVC, and verified that the "fossil winsrv" command still
works. (I sent in a contributor agreement earlier this month.)
Edward Berner
Index: src/winhttp.c
==================================================================
--- src/winhttp.c
+++ src/winhttp.c
@@ -455,10 +455,19 @@
}
}
return 0;
}
+/*
+** The ChangeServiceConfig2W and QueryServiceConfig2W functions are
+** loaded at run time in the cmd_win32_service function. These
+** typedefs provide proper types for the function pointers.
+*/
+typedef BOOL (WINAPI *CHANGESERVICECONFIG2W)(SC_HANDLE, DWORD, LPVOID);
+typedef BOOL (WINAPI *QUERYSERVICECONFIG2W)(SC_HANDLE, DWORD, LPBYTE,
+ DWORD, LPDWORD);
+
/* dupe ifdef needed for mkindex
** COMMAND: winsrv*
** Usage: fossil winsrv METHOD ?SERVICE-NAME? ?OPTIONS?
**
** Where METHOD is one of: create delete show start stop.
@@ -562,10 +571,25 @@
*/
void cmd_win32_service(void){
int n;
const char *zMethod;
const char *zSvcName = "Fossil-DSCM"; /* Default service name */
+ HINSTANCE hinstLib = NULL;
+ CHANGESERVICECONFIG2W ChangeServiceConfig2WAddr = NULL;
+ QUERYSERVICECONFIG2W QueryServiceConfig2WAddr = NULL;
+
+ /* The ChangeServiceConfig2W and QueryServiceConfig2W functions are
+ ** not supported on Windows NT 4.0, so we load them at run time with
+ ** GetProcAddress and only call them if they exist.
+ */
+ hinstLib = LoadLibrary(TEXT("advapi32.dll"));
+ if( NULL != hinstLib ){
+ ChangeServiceConfig2WAddr =
+ (CHANGESERVICECONFIG2W) GetProcAddress(hinstLib,
"ChangeServiceConfig2W");
+ QueryServiceConfig2WAddr =
+ (QUERYSERVICECONFIG2W) GetProcAddress(hinstLib, "QueryServiceConfig2W");
+ }
if( g.argc<3 ){
usage("create|delete|show|start|stop ...");
}
zMethod = g.argv[2];
@@ -649,11 +673,13 @@
fossil_utf8_to_unicode(zUsername), /* Service account */
fossil_utf8_to_unicode(zPassword) /* Account password */
);
if( !hSvc ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
/* Set the service description. */
- ChangeServiceConfig2W(hSvc, SERVICE_CONFIG_DESCRIPTION, &svcDescr);
+ if( ChangeServiceConfig2WAddr ){
+ ChangeServiceConfig2WAddr(hSvc, SERVICE_CONFIG_DESCRIPTION, &svcDescr);
+ }
fossil_print("Service '%s' successfully created.\n", zSvcName);
CloseServiceHandle(hSvc);
CloseServiceHandle(hScm);
}else
if( strncmp(zMethod, "delete", n)==0 ){
@@ -764,19 +790,24 @@
case SERVICE_AUTO_START: zSvcStartType = zSvcStartTypes[2]; break;
case SERVICE_DEMAND_START: zSvcStartType = zSvcStartTypes[3]; break;
case SERVICE_DISABLED: zSvcStartType = zSvcStartTypes[4]; break;
}
/* Get the service description. */
- bStatus = QueryServiceConfig2W(hSvc, SERVICE_CONFIG_DESCRIPTION,
- NULL, 0, &nRequired);
- if( !bStatus && GetLastError()!=ERROR_INSUFFICIENT_BUFFER ){
- fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
+ if( QueryServiceConfig2WAddr ){
+ bStatus = QueryServiceConfig2WAddr(hSvc, SERVICE_CONFIG_DESCRIPTION,
+ NULL, 0, &nRequired);
+ if( !bStatus && GetLastError()!=ERROR_INSUFFICIENT_BUFFER ){
+ fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
+ }
+ pSvcDescr = fossil_malloc(nRequired);
+ bStatus = QueryServiceConfig2WAddr(hSvc, SERVICE_CONFIG_DESCRIPTION,
+ (LPBYTE)pSvcDescr, nRequired, &nRequired);
+ if( !bStatus ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
+ }else{
+ pSvcDescr = fossil_malloc(sizeof(SERVICE_DESCRIPTIONW));
+ pSvcDescr->lpDescription = L"";
}
- pSvcDescr = fossil_malloc(nRequired);
- bStatus = QueryServiceConfig2W(hSvc, SERVICE_CONFIG_DESCRIPTION,
- (LPBYTE)pSvcDescr, nRequired, &nRequired);
- if( !bStatus ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
/* Retrieves the current status of the specified service. */
bStatus = QueryServiceStatus(hSvc, &sstat);
if( !bStatus ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
/* Translate the current state. */
switch( sstat.dwCurrentState ){
@@ -883,8 +914,11 @@
}else
{
fossil_fatal("METHOD should be one of:"
" create delete show start stop");
}
+ if( NULL != hinstLib ){
+ FreeLibrary(hinstLib);
+ }
return;
}
#endif /* _WIN32 -- This code is for win32 only */
_______________________________________________
fossil-users mailing list
[email protected]
http://lists.fossil-scm.org:8080/cgi-bin/mailman/listinfo/fossil-users