Annotation of embedaddon/ntp/ports/winnt/instsrv/instsrv.c, revision 1.1
1.1 ! misho 1: /*
! 2: * File: instsrv.c
! 3: * Purpose: To install a new service and to insert registry entries.
! 4: *
! 5: */
! 6: #ifndef __RPCASYNC_H__
! 7: #define __RPCASYNC_H__ /* Skip asynch rpc inclusion */
! 8: #endif
! 9:
! 10: #include <windows.h>
! 11: #include <stdio.h>
! 12:
! 13: #define PERR(api) printf("\n%s: Error %d from %s on line %d", \
! 14: __FILE__, GetLastError(), api, __LINE__);
! 15:
! 16: #define MSG_FOR_ACCESS_DENIED "You aren't authorized to do this - please see your system Administrator"
! 17: #define MSG_1_FOR_BAD_PATH "The fully qualified path name to the .exe must be given, and"
! 18: #define MSG_2_FOR_BAD_PATH " the drive letter must be for a fixed disk (e.g., not a net drive)"
! 19:
! 20: SC_HANDLE schService;
! 21: SC_HANDLE schSCManager;
! 22: int ok2;
! 23:
! 24: VOID DisplayHelp(VOID);
! 25:
! 26: /* --------------------------------------------------------------------------------------- */
! 27:
! 28: int InstallService(LPCTSTR serviceName, LPCTSTR displayName, LPCTSTR serviceExe)
! 29: {
! 30: LPCTSTR lpszBinaryPathName = serviceExe;
! 31: TCHAR lpszRootPathName[] ="?:\\";
! 32:
! 33: if ( (':' != *(lpszBinaryPathName+1)) || ('\\' != *(lpszBinaryPathName+2)) )
! 34: { printf("\n%s",MSG_1_FOR_BAD_PATH);
! 35: printf("\n%s\n",MSG_2_FOR_BAD_PATH);
! 36: return 1;
! 37: }
! 38:
! 39: #define DRIVE_TYPE_INDETERMINATE 0
! 40: #define ROOT_DIR_DOESNT_EXIST 1
! 41:
! 42: *lpszRootPathName = *(lpszBinaryPathName+0) ;
! 43:
! 44: switch ( GetDriveType(lpszRootPathName) )
! 45: {
! 46: case DRIVE_FIXED :
! 47: { // OK
! 48: break;
! 49: }
! 50: case ROOT_DIR_DOESNT_EXIST :
! 51: { printf("\n%s",MSG_1_FOR_BAD_PATH);
! 52: printf("\n the root directory where the .exe is specified to be must exist, and");
! 53: printf("\n%s\n",MSG_2_FOR_BAD_PATH);
! 54: return 1;
! 55: }
! 56: case DRIVE_TYPE_INDETERMINATE :
! 57: case DRIVE_REMOVABLE :
! 58: case DRIVE_REMOTE :
! 59: case DRIVE_CDROM :
! 60: case DRIVE_RAMDISK :
! 61: { printf("\n%s",MSG_1_FOR_BAD_PATH);
! 62: printf("\n%s\n",MSG_2_FOR_BAD_PATH);
! 63: return 1;
! 64: }
! 65: default :
! 66: { printf("\n%s",MSG_1_FOR_BAD_PATH);
! 67: printf("\n%s\n",MSG_2_FOR_BAD_PATH);
! 68: return 1;
! 69: }
! 70: }
! 71:
! 72: if (INVALID_HANDLE_VALUE == CreateFile(lpszBinaryPathName,
! 73: GENERIC_READ,
! 74: FILE_SHARE_READ,
! 75: NULL,
! 76: OPEN_EXISTING,
! 77: FILE_ATTRIBUTE_NORMAL,
! 78: NULL))
! 79: {
! 80: printf("\n%s",MSG_1_FOR_BAD_PATH);
! 81: printf("\n the file must exist, and");
! 82: printf("\n%s\n",MSG_2_FOR_BAD_PATH);
! 83: return 1;
! 84: }
! 85:
! 86: schService = CreateService(
! 87: schSCManager, // SCManager database
! 88: serviceName, // name of service
! 89: displayName, // name to display
! 90: SERVICE_ALL_ACCESS, // desired access
! 91: SERVICE_WIN32_OWN_PROCESS, // service type
! 92: SERVICE_AUTO_START, // start type
! 93: SERVICE_ERROR_NORMAL, // error control type
! 94: lpszBinaryPathName, // service's binary
! 95: NULL, // no load ordering group
! 96: NULL, // no tag identifier
! 97: NULL, // no dependencies
! 98: NULL, // Local System account
! 99: NULL); // null password
! 100:
! 101: if (NULL == schService)
! 102: { switch (GetLastError())
! 103: {
! 104: case ERROR_ACCESS_DENIED :
! 105: { printf("\n%s",MSG_FOR_ACCESS_DENIED);
! 106: break;
! 107: }
! 108: case ERROR_SERVICE_EXISTS :
! 109: { printf("\nThe %s service is already installed",serviceName);
! 110: printf("\nRemove it first if you need to re-install a new version\n");
! 111: break;
! 112: }
! 113: default :
! 114: { PERR("CreateService");
! 115: }
! 116: }
! 117: return 1;
! 118: }
! 119: else
! 120:
! 121: CloseServiceHandle(schService);
! 122: return 0;
! 123: }
! 124:
! 125: /* --------------------------------------------------------------------------------------- */
! 126:
! 127: int RemoveService(LPCTSTR serviceName)
! 128: {
! 129: {
! 130: #define SZ_ENUM_BUF 4096
! 131: ENUM_SERVICE_STATUS essServiceStatus[SZ_ENUM_BUF];
! 132: DWORD dwBufSize = sizeof(essServiceStatus);
! 133: DWORD dwBytesNeeded = 0;
! 134: DWORD dwServicesReturned = 0;
! 135: DWORD dwResumeHandle = 0;
! 136: DWORD dwI = 0;
! 137: BOOLEAN bFound = FALSE;
! 138:
! 139: if (!EnumServicesStatus(schSCManager,
! 140: SERVICE_WIN32,
! 141: SERVICE_ACTIVE,
! 142: (LPENUM_SERVICE_STATUS)&essServiceStatus,
! 143: dwBufSize,
! 144: &dwBytesNeeded,
! 145: &dwServicesReturned,
! 146: &dwResumeHandle))
! 147: { switch (GetLastError())
! 148: {
! 149: case ERROR_ACCESS_DENIED :
! 150: { printf("\n%s",MSG_FOR_ACCESS_DENIED);
! 151: break;
! 152: }
! 153: default :
! 154: { PERR("EnumServicesStatus");
! 155: }
! 156: }
! 157: return 1;
! 158: }
! 159:
! 160: for (dwI=0; dwI<dwServicesReturned; dwI++)
! 161: { if(0 == _stricmp(essServiceStatus[dwI].lpServiceName,serviceName))
! 162: { bFound = TRUE;
! 163: break;
! 164: }
! 165: }
! 166:
! 167: if (bFound)
! 168: { printf("\nThe %s service cannot be removed until it has been stopped.",serviceName);
! 169: printf("\nTo stop the %s service, use the Stop button in the Control",serviceName);
! 170: printf("\n Panel Services applet\n");
! 171: return 1;
! 172: }
! 173: }
! 174:
! 175: schService = OpenService(schSCManager,
! 176: serviceName,
! 177: SERVICE_ALL_ACCESS);
! 178: if (NULL == schService)
! 179: { switch (GetLastError())
! 180: {
! 181: case ERROR_ACCESS_DENIED :
! 182: { printf("\n%s",MSG_FOR_ACCESS_DENIED);
! 183: break;
! 184: }
! 185: case ERROR_SERVICE_DOES_NOT_EXIST :
! 186: { printf("\nThe %s service is not installed, so cannot be removed\n",serviceName);
! 187: break;
! 188: }
! 189: default :
! 190: { PERR("OpenService");
! 191: }
! 192: }
! 193: return 1;
! 194: }
! 195:
! 196: if (DeleteService(schService))
! 197: { printf("\nDelete of Service \"Network Time Protocol\" was SUCCESSFUL\n");
! 198: return 0;
! 199: }
! 200: else
! 201: { switch (GetLastError())
! 202: {
! 203: case ERROR_ACCESS_DENIED :
! 204: { printf("\n%s",MSG_FOR_ACCESS_DENIED);
! 205: break;
! 206: }
! 207: default :
! 208: { PERR("DeleteService");
! 209: }
! 210: }
! 211: return 1;
! 212: }
! 213: }
! 214:
! 215: /* --------------------------------------------------------------------------------------- */
! 216:
! 217: int addSourceToRegistry(LPSTR pszAppname, LPSTR pszMsgDLL)
! 218: {
! 219: HKEY hk; /* registry key handle */
! 220: DWORD dwData;
! 221: BOOL bSuccess;
! 222: char regarray[200];
! 223: char *lpregarray = regarray;
! 224:
! 225: /* When an application uses the RegisterEventSource or OpenEventLog
! 226: function to get a handle of an event log, the event loggging service
! 227: searches for the specified source name in the registry. You can add a
! 228: new source name to the registry by opening a new registry subkey
! 229: under the Application key and adding registry values to the new
! 230: subkey. */
! 231:
! 232: strcpy(lpregarray, "SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\");
! 233: strcat(lpregarray, pszAppname);
! 234: /* Create a new key for our application */
! 235: bSuccess = RegCreateKey(HKEY_LOCAL_MACHINE, lpregarray, &hk);
! 236: if(bSuccess != ERROR_SUCCESS)
! 237: {
! 238: PERR("RegCreateKey");
! 239: return 1;
! 240: }
! 241:
! 242: /* Add the Event-ID message-file name to the subkey. */
! 243: bSuccess = RegSetValueEx(hk, /* subkey handle */
! 244: "EventMessageFile", /* value name */
! 245: 0, /* must be zero */
! 246: REG_EXPAND_SZ, /* value type */
! 247: (LPBYTE) pszMsgDLL, /* address of value data */
! 248: strlen(pszMsgDLL) + 1); /* length of value data */
! 249: if(bSuccess != ERROR_SUCCESS)
! 250: {
! 251: PERR("RegSetValueEx");
! 252: return 1;
! 253: }
! 254:
! 255: /* Set the supported types flags and addit to the subkey. */
! 256: dwData = EVENTLOG_ERROR_TYPE | EVENTLOG_WARNING_TYPE |
! 257: EVENTLOG_INFORMATION_TYPE;
! 258: bSuccess = RegSetValueEx(hk, /* subkey handle */
! 259: "TypesSupported", /* value name */
! 260: 0, /* must be zero */
! 261: REG_DWORD, /* value type */
! 262: (LPBYTE) &dwData, /* address of value data */
! 263: sizeof(DWORD)); /* length of value data */
! 264: if(bSuccess != ERROR_SUCCESS)
! 265: {
! 266: PERR("RegSetValueEx");
! 267: return 1;
! 268: }
! 269: RegCloseKey(hk);
! 270: return 0;
! 271: }
! 272:
! 273: /* --------------------------------------------------------------------------------------- */
! 274:
! 275: int addKeysToRegistry()
! 276:
! 277: {
! 278: HKEY hk; /* registry key handle */
! 279: BOOL bSuccess;
! 280: char myarray[200];
! 281: char *lpmyarray = myarray;
! 282: int arsize = 0;
! 283:
! 284: /* now add the depends on service key */
! 285:
! 286: /* Create a new key for our application */
! 287: bSuccess = RegCreateKey(HKEY_LOCAL_MACHINE,
! 288: "SYSTEM\\CurrentControlSet\\Services\\NTP", &hk);
! 289: if(bSuccess != ERROR_SUCCESS)
! 290: {
! 291: PERR("RegCreateKey");
! 292: return 1;
! 293: }
! 294:
! 295: strcpy(lpmyarray,"TcpIp");
! 296: lpmyarray = lpmyarray + 6;
! 297: arsize = arsize + 6;
! 298: strcpy(lpmyarray,"Afd");
! 299: lpmyarray = lpmyarray + 4;
! 300: arsize = arsize + 4;
! 301: arsize = arsize + 2;
! 302: strcpy(lpmyarray,"\0\0");
! 303:
! 304: bSuccess = RegSetValueEx(hk, /* subkey handle */
! 305: "DependOnService", /* value name */
! 306: 0, /* must be zero */
! 307: REG_MULTI_SZ, /* value type */
! 308: (LPBYTE) &myarray, /* address of value data */
! 309: arsize); /* length of value data */
! 310: if(bSuccess != ERROR_SUCCESS)
! 311: {
! 312: PERR("RegSetValueEx");
! 313: return 1;
! 314: }
! 315:
! 316: RegCloseKey(hk);
! 317: return 0;
! 318: }
! 319:
! 320: /* --------------------------------------------------------------------------------------- */
! 321:
! 322: int main(int argc, char *argv[])
! 323: {
! 324: #define SZ_NAME_BUF 270 // 256 is max, add a little
! 325: UCHAR ucNameBuf[SZ_NAME_BUF] = "NTP";
! 326: LPTSTR lpszServName = (LPTSTR)&ucNameBuf;
! 327:
! 328: UCHAR ucDNameBuf[SZ_NAME_BUF] = "Network Time Protocol";
! 329: LPTSTR lpszDispName = (LPTSTR)&ucDNameBuf;
! 330:
! 331:
! 332: UCHAR ucExeNBuf[SZ_NAME_BUF] = "";
! 333: LPTSTR lpszExeName = (LPTSTR)&ucExeNBuf;
! 334:
! 335: BOOL bRemovingService = FALSE;
! 336: char *p;
! 337:
! 338: int ok = 0;
! 339:
! 340: // check if Win32s, if so, display notice and terminate
! 341: if( GetVersion() & 0x80000000 )
! 342: {
! 343: MessageBox( NULL,
! 344: "This application cannot run on Windows 3.1.\n"
! 345: "This application will now terminate.",
! 346: "NAMED",
! 347: MB_OK | MB_ICONSTOP | MB_SETFOREGROUND );
! 348: return( 1 );
! 349: }
! 350: if (argc == 2)
! 351: bRemovingService = (!stricmp(argv[1], "remove"));
! 352:
! 353: if(!bRemovingService)
! 354: {
! 355:
! 356:
! 357: if (argc != 2)
! 358: {
! 359: DisplayHelp();
! 360: return(1);
! 361: }
! 362:
! 363: p=argv[1];
! 364: if ( ('/' == *p)
! 365: || ('-' == *p) )
! 366: {
! 367: DisplayHelp();
! 368: return(1);
! 369: }
! 370:
! 371:
! 372: }
! 373:
! 374: if (strlen(argv[1]) > 256)
! 375: {
! 376: printf("\nThe service name cannot be longer than 256 characters\n");
! 377: return(1);
! 378: }
! 379:
! 380:
! 381:
! 382: bRemovingService = (!stricmp(argv[1], "remove"));
! 383: schSCManager = OpenSCManager(
! 384: NULL, // machine (NULL == local)
! 385: NULL, // database (NULL == default)
! 386: SC_MANAGER_ALL_ACCESS); // access required
! 387:
! 388: if (NULL == schSCManager)
! 389: { switch (GetLastError())
! 390: {
! 391: case ERROR_ACCESS_DENIED :
! 392: { printf("\n%s",MSG_FOR_ACCESS_DENIED);
! 393: break;
! 394: }
! 395: default :
! 396: { PERR("OpenSCManager");
! 397: }
! 398: }
! 399: return (0);
! 400: }
! 401:
! 402: if (bRemovingService)
! 403: {
! 404: ok = RemoveService(lpszServName);
! 405: }
! 406: else
! 407: {
! 408: /* get the exe name */
! 409: strcpy(lpszExeName,argv[1]);
! 410: ok = InstallService(lpszServName, lpszDispName, lpszExeName);
! 411: }
! 412:
! 413: CloseServiceHandle(schSCManager);
! 414:
! 415: if (!bRemovingService)
! 416: {
! 417: if (ok == 0)
! 418: { /* Set the Event-ID message-file name. */
! 419: ok = addSourceToRegistry("NTP", lpszExeName);
! 420: if (ok == 0)
! 421: ok = addKeysToRegistry();
! 422: else return ok;
! 423:
! 424: if (ok == 0)
! 425: {
! 426: printf("\nThe \"Network Time Protocol\" service was successfully created.\n");
! 427: printf("\nDon't forget!!! You must now go to the Control Panel and");
! 428: printf("\n use the Services applet to change the account name and");
! 429: printf("\n password that the NTP Service will use when");
! 430: printf("\n it starts.");
! 431: printf("\nTo do this: use the Startup button in the Services applet,");
! 432: printf("\n and (for example) specify the desired account and");
! 433: printf("\n correct password.");
! 434: printf("\nAlso, use the Services applet to ensure this newly installed");
! 435: printf("\n service starts automatically on bootup.\n");
! 436: return 0;
! 437: }
! 438: }
! 439: else return ok;
! 440: }
! 441: return 0;
! 442: }
! 443:
! 444: /* --------------------------------------------------------------------------------------- */
! 445:
! 446: VOID DisplayHelp(VOID)
! 447: {
! 448: printf("Installs or removes the NTP service.\n");
! 449: printf("To install the NTP service,\n");
! 450: printf("type INSTSRV <path> \n");
! 451: printf("Where:\n");
! 452: printf(" path Absolute path to the NTP service, name.exe. You must\n");
! 453: printf(" use a fully qualified path and the drive letter must be for a\n");
! 454: printf(" fixed, local drive.\n\n");
! 455: printf("For example, INSTSRV i:\\winnt\\system32\\ntpd.exe\n");
! 456: printf("To remove the NTP service,\n");
! 457: printf("type INSTSRV remove \n");
! 458:
! 459: }
! 460:
! 461: /* EOF */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>