Annotation of embedaddon/ntp/ports/winnt/instsrv/instsrv.c, revision 1.1.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>