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>