summaryrefslogtreecommitdiff
path: root/ports/winnt/instsrv/instsrv.c
diff options
context:
space:
mode:
Diffstat (limited to 'ports/winnt/instsrv/instsrv.c')
-rw-r--r--ports/winnt/instsrv/instsrv.c461
1 files changed, 461 insertions, 0 deletions
diff --git a/ports/winnt/instsrv/instsrv.c b/ports/winnt/instsrv/instsrv.c
new file mode 100644
index 0000000..b3acc9f
--- /dev/null
+++ b/ports/winnt/instsrv/instsrv.c
@@ -0,0 +1,461 @@
+/*
+ * File: instsrv.c
+ * Purpose: To install a new service and to insert registry entries.
+ *
+ */
+#ifndef __RPCASYNC_H__
+#define __RPCASYNC_H__ /* Skip asynch rpc inclusion */
+#endif
+
+#include <windows.h>
+#include <stdio.h>
+
+#define PERR(api) printf("\n%s: Error %d from %s on line %d", \
+ __FILE__, GetLastError(), api, __LINE__);
+
+#define MSG_FOR_ACCESS_DENIED "You aren't authorized to do this - please see your system Administrator"
+#define MSG_1_FOR_BAD_PATH "The fully qualified path name to the .exe must be given, and"
+#define MSG_2_FOR_BAD_PATH " the drive letter must be for a fixed disk (e.g., not a net drive)"
+
+SC_HANDLE schService;
+SC_HANDLE schSCManager;
+int ok2;
+
+VOID DisplayHelp(VOID);
+
+/* --------------------------------------------------------------------------------------- */
+
+int InstallService(LPCTSTR serviceName, LPCTSTR displayName, LPCTSTR serviceExe)
+{
+ LPCTSTR lpszBinaryPathName = serviceExe;
+ TCHAR lpszRootPathName[] ="?:\\";
+
+ if ( (':' != *(lpszBinaryPathName+1)) || ('\\' != *(lpszBinaryPathName+2)) )
+ { printf("\n%s",MSG_1_FOR_BAD_PATH);
+ printf("\n%s\n",MSG_2_FOR_BAD_PATH);
+ return 1;
+ }
+
+ #define DRIVE_TYPE_INDETERMINATE 0
+ #define ROOT_DIR_DOESNT_EXIST 1
+
+ *lpszRootPathName = *(lpszBinaryPathName+0) ;
+
+ switch ( GetDriveType(lpszRootPathName) )
+ {
+ case DRIVE_FIXED :
+ { // OK
+ break;
+ }
+ case ROOT_DIR_DOESNT_EXIST :
+ { printf("\n%s",MSG_1_FOR_BAD_PATH);
+ printf("\n the root directory where the .exe is specified to be must exist, and");
+ printf("\n%s\n",MSG_2_FOR_BAD_PATH);
+ return 1;
+ }
+ case DRIVE_TYPE_INDETERMINATE :
+ case DRIVE_REMOVABLE :
+ case DRIVE_REMOTE :
+ case DRIVE_CDROM :
+ case DRIVE_RAMDISK :
+ { printf("\n%s",MSG_1_FOR_BAD_PATH);
+ printf("\n%s\n",MSG_2_FOR_BAD_PATH);
+ return 1;
+ }
+ default :
+ { printf("\n%s",MSG_1_FOR_BAD_PATH);
+ printf("\n%s\n",MSG_2_FOR_BAD_PATH);
+ return 1;
+ }
+ }
+
+ if (INVALID_HANDLE_VALUE == CreateFile(lpszBinaryPathName,
+ GENERIC_READ,
+ FILE_SHARE_READ,
+ NULL,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL))
+ {
+ printf("\n%s",MSG_1_FOR_BAD_PATH);
+ printf("\n the file must exist, and");
+ printf("\n%s\n",MSG_2_FOR_BAD_PATH);
+ return 1;
+ }
+
+ schService = CreateService(
+ schSCManager, // SCManager database
+ serviceName, // name of service
+ displayName, // name to display
+ SERVICE_ALL_ACCESS, // desired access
+ SERVICE_WIN32_OWN_PROCESS, // service type
+ SERVICE_AUTO_START, // start type
+ SERVICE_ERROR_NORMAL, // error control type
+ lpszBinaryPathName, // service's binary
+ NULL, // no load ordering group
+ NULL, // no tag identifier
+ NULL, // no dependencies
+ NULL, // Local System account
+ NULL); // null password
+
+ if (NULL == schService)
+ { switch (GetLastError())
+ {
+ case ERROR_ACCESS_DENIED :
+ { printf("\n%s",MSG_FOR_ACCESS_DENIED);
+ break;
+ }
+ case ERROR_SERVICE_EXISTS :
+ { printf("\nThe %s service is already installed",serviceName);
+ printf("\nRemove it first if you need to re-install a new version\n");
+ break;
+ }
+ default :
+ { PERR("CreateService");
+ }
+ }
+ return 1;
+ }
+ else
+
+ CloseServiceHandle(schService);
+ return 0;
+}
+
+/* --------------------------------------------------------------------------------------- */
+
+int RemoveService(LPCTSTR serviceName)
+{
+ {
+ #define SZ_ENUM_BUF 4096
+ ENUM_SERVICE_STATUS essServiceStatus[SZ_ENUM_BUF];
+ DWORD dwBufSize = sizeof(essServiceStatus);
+ DWORD dwBytesNeeded = 0;
+ DWORD dwServicesReturned = 0;
+ DWORD dwResumeHandle = 0;
+ DWORD dwI = 0;
+ BOOLEAN bFound = FALSE;
+
+ if (!EnumServicesStatus(schSCManager,
+ SERVICE_WIN32,
+ SERVICE_ACTIVE,
+ (LPENUM_SERVICE_STATUS)&essServiceStatus,
+ dwBufSize,
+ &dwBytesNeeded,
+ &dwServicesReturned,
+ &dwResumeHandle))
+ { switch (GetLastError())
+ {
+ case ERROR_ACCESS_DENIED :
+ { printf("\n%s",MSG_FOR_ACCESS_DENIED);
+ break;
+ }
+ default :
+ { PERR("EnumServicesStatus");
+ }
+ }
+ return 1;
+ }
+
+ for (dwI=0; dwI<dwServicesReturned; dwI++)
+ { if(0 == _stricmp(essServiceStatus[dwI].lpServiceName,serviceName))
+ { bFound = TRUE;
+ break;
+ }
+ }
+
+ if (bFound)
+ { printf("\nThe %s service cannot be removed until it has been stopped.",serviceName);
+ printf("\nTo stop the %s service, use the Stop button in the Control",serviceName);
+ printf("\n Panel Services applet\n");
+ return 1;
+ }
+ }
+
+ schService = OpenService(schSCManager,
+ serviceName,
+ SERVICE_ALL_ACCESS);
+ if (NULL == schService)
+ { switch (GetLastError())
+ {
+ case ERROR_ACCESS_DENIED :
+ { printf("\n%s",MSG_FOR_ACCESS_DENIED);
+ break;
+ }
+ case ERROR_SERVICE_DOES_NOT_EXIST :
+ { printf("\nThe %s service is not installed, so cannot be removed\n",serviceName);
+ break;
+ }
+ default :
+ { PERR("OpenService");
+ }
+ }
+ return 1;
+ }
+
+ if (DeleteService(schService))
+ { printf("\nDelete of Service \"Network Time Protocol\" was SUCCESSFUL\n");
+ return 0;
+ }
+ else
+ { switch (GetLastError())
+ {
+ case ERROR_ACCESS_DENIED :
+ { printf("\n%s",MSG_FOR_ACCESS_DENIED);
+ break;
+ }
+ default :
+ { PERR("DeleteService");
+ }
+ }
+ return 1;
+ }
+}
+
+/* --------------------------------------------------------------------------------------- */
+
+int addSourceToRegistry(LPSTR pszAppname, LPSTR pszMsgDLL)
+{
+ HKEY hk; /* registry key handle */
+ DWORD dwData;
+ BOOL bSuccess;
+ char regarray[200];
+ char *lpregarray = regarray;
+
+ /* When an application uses the RegisterEventSource or OpenEventLog
+ function to get a handle of an event log, the event loggging service
+ searches for the specified source name in the registry. You can add a
+ new source name to the registry by opening a new registry subkey
+ under the Application key and adding registry values to the new
+ subkey. */
+
+ strcpy(lpregarray, "SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\");
+ strcat(lpregarray, pszAppname);
+ /* Create a new key for our application */
+ bSuccess = RegCreateKey(HKEY_LOCAL_MACHINE, lpregarray, &hk);
+ if(bSuccess != ERROR_SUCCESS)
+ {
+ PERR("RegCreateKey");
+ return 1;
+ }
+
+ /* Add the Event-ID message-file name to the subkey. */
+ bSuccess = RegSetValueEx(hk, /* subkey handle */
+ "EventMessageFile", /* value name */
+ 0, /* must be zero */
+ REG_EXPAND_SZ, /* value type */
+ (LPBYTE) pszMsgDLL, /* address of value data */
+ strlen(pszMsgDLL) + 1); /* length of value data */
+ if(bSuccess != ERROR_SUCCESS)
+ {
+ PERR("RegSetValueEx");
+ return 1;
+ }
+
+ /* Set the supported types flags and addit to the subkey. */
+ dwData = EVENTLOG_ERROR_TYPE | EVENTLOG_WARNING_TYPE |
+ EVENTLOG_INFORMATION_TYPE;
+ bSuccess = RegSetValueEx(hk, /* subkey handle */
+ "TypesSupported", /* value name */
+ 0, /* must be zero */
+ REG_DWORD, /* value type */
+ (LPBYTE) &dwData, /* address of value data */
+ sizeof(DWORD)); /* length of value data */
+ if(bSuccess != ERROR_SUCCESS)
+ {
+ PERR("RegSetValueEx");
+ return 1;
+ }
+ RegCloseKey(hk);
+ return 0;
+}
+
+/* --------------------------------------------------------------------------------------- */
+
+int addKeysToRegistry()
+
+{
+ HKEY hk; /* registry key handle */
+ BOOL bSuccess;
+ char myarray[200];
+ char *lpmyarray = myarray;
+ int arsize = 0;
+
+ /* now add the depends on service key */
+
+ /* Create a new key for our application */
+ bSuccess = RegCreateKey(HKEY_LOCAL_MACHINE,
+ "SYSTEM\\CurrentControlSet\\Services\\NTP", &hk);
+ if(bSuccess != ERROR_SUCCESS)
+ {
+ PERR("RegCreateKey");
+ return 1;
+ }
+
+ strcpy(lpmyarray,"TcpIp");
+ lpmyarray = lpmyarray + 6;
+ arsize = arsize + 6;
+ strcpy(lpmyarray,"Afd");
+ lpmyarray = lpmyarray + 4;
+ arsize = arsize + 4;
+ arsize = arsize + 2;
+ strcpy(lpmyarray,"\0\0");
+
+ bSuccess = RegSetValueEx(hk, /* subkey handle */
+ "DependOnService", /* value name */
+ 0, /* must be zero */
+ REG_MULTI_SZ, /* value type */
+ (LPBYTE) &myarray, /* address of value data */
+ arsize); /* length of value data */
+ if(bSuccess != ERROR_SUCCESS)
+ {
+ PERR("RegSetValueEx");
+ return 1;
+ }
+
+ RegCloseKey(hk);
+ return 0;
+}
+
+/* --------------------------------------------------------------------------------------- */
+
+int main(int argc, char *argv[])
+{
+ #define SZ_NAME_BUF 270 // 256 is max, add a little
+ UCHAR ucNameBuf[SZ_NAME_BUF] = "NTP";
+ LPTSTR lpszServName = (LPTSTR)&ucNameBuf;
+
+ UCHAR ucDNameBuf[SZ_NAME_BUF] = "Network Time Protocol";
+ LPTSTR lpszDispName = (LPTSTR)&ucDNameBuf;
+
+
+ UCHAR ucExeNBuf[SZ_NAME_BUF] = "";
+ LPTSTR lpszExeName = (LPTSTR)&ucExeNBuf;
+
+ BOOL bRemovingService = FALSE;
+ char *p;
+
+ int ok = 0;
+
+ // check if Win32s, if so, display notice and terminate
+ if( GetVersion() & 0x80000000 )
+ {
+ MessageBox( NULL,
+ "This application cannot run on Windows 3.1.\n"
+ "This application will now terminate.",
+ "NAMED",
+ MB_OK | MB_ICONSTOP | MB_SETFOREGROUND );
+ return( 1 );
+ }
+ if (argc == 2)
+ bRemovingService = (!stricmp(argv[1], "remove"));
+
+ if(!bRemovingService)
+ {
+
+
+ if (argc != 2)
+ {
+ DisplayHelp();
+ return(1);
+ }
+
+ p=argv[1];
+ if ( ('/' == *p)
+ || ('-' == *p) )
+ {
+ DisplayHelp();
+ return(1);
+ }
+
+
+ }
+
+ if (strlen(argv[1]) > 256)
+ {
+ printf("\nThe service name cannot be longer than 256 characters\n");
+ return(1);
+ }
+
+
+
+ bRemovingService = (!stricmp(argv[1], "remove"));
+ schSCManager = OpenSCManager(
+ NULL, // machine (NULL == local)
+ NULL, // database (NULL == default)
+ SC_MANAGER_ALL_ACCESS); // access required
+
+ if (NULL == schSCManager)
+ { switch (GetLastError())
+ {
+ case ERROR_ACCESS_DENIED :
+ { printf("\n%s",MSG_FOR_ACCESS_DENIED);
+ break;
+ }
+ default :
+ { PERR("OpenSCManager");
+ }
+ }
+ return (0);
+ }
+
+ if (bRemovingService)
+ {
+ ok = RemoveService(lpszServName);
+ }
+ else
+ {
+ /* get the exe name */
+ strcpy(lpszExeName,argv[1]);
+ ok = InstallService(lpszServName, lpszDispName, lpszExeName);
+ }
+
+ CloseServiceHandle(schSCManager);
+
+ if (!bRemovingService)
+ {
+ if (ok == 0)
+ { /* Set the Event-ID message-file name. */
+ ok = addSourceToRegistry("NTP", lpszExeName);
+ if (ok == 0)
+ ok = addKeysToRegistry();
+ else return ok;
+
+ if (ok == 0)
+ {
+ printf("\nThe \"Network Time Protocol\" service was successfully created.\n");
+ printf("\nDon't forget!!! You must now go to the Control Panel and");
+ printf("\n use the Services applet to change the account name and");
+ printf("\n password that the NTP Service will use when");
+ printf("\n it starts.");
+ printf("\nTo do this: use the Startup button in the Services applet,");
+ printf("\n and (for example) specify the desired account and");
+ printf("\n correct password.");
+ printf("\nAlso, use the Services applet to ensure this newly installed");
+ printf("\n service starts automatically on bootup.\n");
+ return 0;
+ }
+ }
+ else return ok;
+ }
+ return 0;
+}
+
+/* --------------------------------------------------------------------------------------- */
+
+VOID DisplayHelp(VOID)
+{
+ printf("Installs or removes the NTP service.\n");
+ printf("To install the NTP service,\n");
+ printf("type INSTSRV <path> \n");
+ printf("Where:\n");
+ printf(" path Absolute path to the NTP service, name.exe. You must\n");
+ printf(" use a fully qualified path and the drive letter must be for a\n");
+ printf(" fixed, local drive.\n\n");
+ printf("For example, INSTSRV i:\\winnt\\system32\\ntpd.exe\n");
+ printf("To remove the NTP service,\n");
+ printf("type INSTSRV remove \n");
+
+}
+
+/* EOF */