- Implement ScmrChangeServiceConfigW stub.
[reactos.git] / reactos / subsys / system / services / rpcserver.c
1 /*
2
3 */
4
5 /* INCLUDES ****************************************************************/
6
7 #include "services.h"
8 #include "svcctl_s.h"
9
10 #define NDEBUG
11 #include <debug.h>
12
13
14 /* GLOBALS *****************************************************************/
15
16 #define MANAGER_TAG 0x72674D68 /* 'hMgr' */
17 #define SERVICE_TAG 0x63765368 /* 'hSvc' */
18
19 typedef struct _SCMGR_HANDLE
20 {
21 DWORD Tag;
22 DWORD RefCount;
23 DWORD DesiredAccess;
24 } SCMGR_HANDLE;
25
26
27 typedef struct _MANAGER_HANDLE
28 {
29 SCMGR_HANDLE Handle;
30
31 /* FIXME: Insert more data here */
32
33 WCHAR DatabaseName[1];
34 } MANAGER_HANDLE, *PMANAGER_HANDLE;
35
36
37 typedef struct _SERVICE_HANDLE
38 {
39 SCMGR_HANDLE Handle;
40
41 DWORD DesiredAccess;
42 PSERVICE ServiceEntry;
43
44 /* FIXME: Insert more data here */
45
46 } SERVICE_HANDLE, *PSERVICE_HANDLE;
47
48
49 #define SC_MANAGER_READ \
50 (STANDARD_RIGHTS_READ | \
51 SC_MANAGER_QUERY_LOCK_STATUS | \
52 SC_MANAGER_ENUMERATE_SERVICE)
53
54 #define SC_MANAGER_WRITE \
55 (STANDARD_RIGHTS_WRITE | \
56 SC_MANAGER_MODIFY_BOOT_CONFIG | \
57 SC_MANAGER_CREATE_SERVICE)
58
59 #define SC_MANAGER_EXECUTE \
60 (STANDARD_RIGHTS_EXECUTE | \
61 SC_MANAGER_LOCK | \
62 SC_MANAGER_ENUMERATE_SERVICE | \
63 SC_MANAGER_CONNECT | \
64 SC_MANAGER_CREATE_SERVICE)
65
66
67 #define SERVICE_READ \
68 (STANDARD_RIGHTS_READ | \
69 SERVICE_INTERROGATE | \
70 SERVICE_ENUMERATE_DEPENDENTS | \
71 SERVICE_QUERY_STATUS | \
72 SERVICE_QUERY_CONFIG)
73
74 #define SERVICE_WRITE \
75 (STANDARD_RIGHTS_WRITE | \
76 SERVICE_CHANGE_CONFIG)
77
78 #define SERVICE_EXECUTE \
79 (STANDARD_RIGHTS_EXECUTE | \
80 SERVICE_USER_DEFINED_CONTROL | \
81 SERVICE_PAUSE_CONTINUE | \
82 SERVICE_STOP | \
83 SERVICE_START)
84
85
86 /* VARIABLES ***************************************************************/
87
88 static GENERIC_MAPPING
89 ScmManagerMapping = {SC_MANAGER_READ,
90 SC_MANAGER_WRITE,
91 SC_MANAGER_EXECUTE,
92 SC_MANAGER_ALL_ACCESS};
93
94 static GENERIC_MAPPING
95 ScmServiceMapping = {SERVICE_READ,
96 SERVICE_WRITE,
97 SERVICE_EXECUTE,
98 SC_MANAGER_ALL_ACCESS};
99
100
101 /* FUNCTIONS ***************************************************************/
102
103 VOID
104 ScmStartRpcServer(VOID)
105 {
106 RPC_STATUS Status;
107
108 DPRINT("ScmStartRpcServer() called");
109
110 Status = RpcServerUseProtseqEpW(L"ncacn_np",
111 10,
112 L"\\pipe\\ntsvcs",
113 NULL);
114 if (Status != RPC_S_OK)
115 {
116 DPRINT1("RpcServerUseProtseqEpW() failed (Status %lx)\n", Status);
117 return;
118 }
119
120 Status = RpcServerRegisterIf(svcctl_ServerIfHandle,
121 NULL,
122 NULL);
123 if (Status != RPC_S_OK)
124 {
125 DPRINT1("RpcServerRegisterIf() failed (Status %lx)\n", Status);
126 return;
127 }
128
129 Status = RpcServerListen(1, 20, TRUE);
130 if (Status != RPC_S_OK)
131 {
132 DPRINT1("RpcServerListen() failed (Status %lx)\n", Status);
133 return;
134 }
135
136 DPRINT("ScmStartRpcServer() done");
137 }
138
139
140 static DWORD
141 ScmCreateManagerHandle(LPWSTR lpDatabaseName,
142 SC_HANDLE *Handle)
143 {
144 PMANAGER_HANDLE Ptr;
145
146 if (lpDatabaseName == NULL)
147 lpDatabaseName = SERVICES_ACTIVE_DATABASEW;
148
149 Ptr = HeapAlloc(GetProcessHeap(),
150 HEAP_ZERO_MEMORY,
151 sizeof(MANAGER_HANDLE) + wcslen(lpDatabaseName) * sizeof(WCHAR));
152 if (Ptr == NULL)
153 return ERROR_NOT_ENOUGH_MEMORY;
154
155 Ptr->Handle.Tag = MANAGER_TAG;
156 Ptr->Handle.RefCount = 1;
157
158 /* FIXME: initialize more data here */
159
160 wcscpy(Ptr->DatabaseName, lpDatabaseName);
161
162 *Handle = (SC_HANDLE)Ptr;
163
164 return ERROR_SUCCESS;
165 }
166
167
168 static DWORD
169 ScmCreateServiceHandle(PSERVICE lpServiceEntry,
170 SC_HANDLE *Handle)
171 {
172 PSERVICE_HANDLE Ptr;
173
174 Ptr = HeapAlloc(GetProcessHeap(),
175 HEAP_ZERO_MEMORY,
176 sizeof(SERVICE_HANDLE));
177 if (Ptr == NULL)
178 return ERROR_NOT_ENOUGH_MEMORY;
179
180 Ptr->Handle.Tag = SERVICE_TAG;
181 Ptr->Handle.RefCount = 1;
182
183 /* FIXME: initialize more data here */
184 Ptr->ServiceEntry = lpServiceEntry;
185
186 *Handle = (SC_HANDLE)Ptr;
187
188 return ERROR_SUCCESS;
189 }
190
191
192 static DWORD
193 ScmCheckAccess(SC_HANDLE Handle,
194 DWORD dwDesiredAccess)
195 {
196 PMANAGER_HANDLE hMgr;
197
198 hMgr = (PMANAGER_HANDLE)Handle;
199 if (hMgr->Handle.Tag == MANAGER_TAG)
200 {
201 RtlMapGenericMask(&dwDesiredAccess,
202 &ScmManagerMapping);
203
204 hMgr->Handle.DesiredAccess = dwDesiredAccess;
205
206 return ERROR_SUCCESS;
207 }
208 else if (hMgr->Handle.Tag == SERVICE_TAG)
209 {
210 RtlMapGenericMask(&dwDesiredAccess,
211 &ScmServiceMapping);
212
213 hMgr->Handle.DesiredAccess = dwDesiredAccess;
214
215 return ERROR_SUCCESS;
216 }
217
218 return ERROR_INVALID_HANDLE;
219 }
220
221
222 /* Function 0 */
223 unsigned long
224 ScmrCloseServiceHandle(handle_t BindingHandle,
225 unsigned int hScObject)
226 {
227 PMANAGER_HANDLE hManager;
228
229 DPRINT("ScmrCloseServiceHandle() called\n");
230
231 DPRINT("hScObject = %X\n", hScObject);
232
233 if (hScObject == 0)
234 return ERROR_INVALID_HANDLE;
235
236 hManager = (PMANAGER_HANDLE)hScObject;
237 if (hManager->Handle.Tag == MANAGER_TAG)
238 {
239 DPRINT("Found manager handle\n");
240
241 hManager->Handle.RefCount--;
242 if (hManager->Handle.RefCount == 0)
243 {
244 /* FIXME: add cleanup code */
245
246 HeapFree(GetProcessHeap(), 0, hManager);
247 }
248
249 DPRINT("ScmrCloseServiceHandle() done\n");
250 return ERROR_SUCCESS;
251 }
252 else if (hManager->Handle.Tag == SERVICE_TAG)
253 {
254 DPRINT("Found service handle\n");
255
256 hManager->Handle.RefCount--;
257 if (hManager->Handle.RefCount == 0)
258 {
259 /* FIXME: add cleanup code */
260
261 HeapFree(GetProcessHeap(), 0, hManager);
262 }
263
264 DPRINT("ScmrCloseServiceHandle() done\n");
265 return ERROR_SUCCESS;
266 }
267
268 DPRINT1("Invalid handle tag (Tag %lx)\n", hManager->Handle.Tag);
269
270 return ERROR_INVALID_HANDLE;
271 }
272
273
274 /* Function 1 */
275 unsigned long
276 ScmrControlService(handle_t BindingHandle,
277 unsigned int hService,
278 unsigned long dwControl,
279 LPSERVICE_STATUS lpServiceStatus)
280 {
281 PSERVICE_HANDLE hSvc;
282 PSERVICE lpService;
283
284 DPRINT1("ScmrControlService() called\n");
285
286 hSvc = (PSERVICE_HANDLE)hService;
287 if (hSvc->Handle.Tag != SERVICE_TAG)
288 {
289 DPRINT1("Invalid handle tag!\n");
290 return ERROR_INVALID_HANDLE;
291 }
292
293
294 /* FIXME: Check access rights */
295
296
297 lpService = hSvc->ServiceEntry;
298 if (lpService == NULL)
299 {
300 DPRINT1("lpService == NULL!\n");
301 return ERROR_INVALID_HANDLE;
302 }
303
304
305 /* FIXME: Send control code to the service */
306
307
308 /* Return service status information */
309 RtlCopyMemory(lpServiceStatus,
310 &lpService->Status,
311 sizeof(SERVICE_STATUS));
312
313 return ERROR_SUCCESS;
314 }
315
316
317 /* Function 2 */
318 unsigned long
319 ScmrDeleteService(handle_t BindingHandle,
320 unsigned int hService)
321 {
322 PSERVICE_HANDLE hSvc;
323 PSERVICE lpService;
324 DWORD dwError;
325
326 DPRINT1("ScmrDeleteService() called\n");
327
328 hSvc = (PSERVICE_HANDLE)hService;
329 if (hSvc->Handle.Tag != SERVICE_TAG)
330 return ERROR_INVALID_HANDLE;
331
332 if (!RtlAreAllAccessesGranted(hSvc->Handle.DesiredAccess,
333 STANDARD_RIGHTS_REQUIRED))
334 return ERROR_ACCESS_DENIED;
335
336 lpService = hSvc->ServiceEntry;
337 if (lpService == NULL)
338 {
339 DPRINT1("lpService == NULL!\n");
340 return ERROR_INVALID_HANDLE;
341 }
342
343 /* FIXME: Acquire service database lock exclusively */
344
345 /* Mark service for delete */
346 dwError = ScmMarkServiceForDelete(lpService);
347
348 /* FIXME: Release service database lock */
349
350 DPRINT1("ScmrDeleteService() done\n");
351
352 return dwError;
353 }
354
355
356 /* Function 3 */
357 unsigned long
358 ScmrLockServiceDatabase(handle_t BindingHandle,
359 unsigned int hSCManager,
360 unsigned int *hLock)
361 {
362 PMANAGER_HANDLE hMgr;
363
364 DPRINT("ScmrLockServiceDatabase() called\n");
365
366 *hLock = 0;
367
368 hMgr = (PMANAGER_HANDLE)hSCManager;
369 if (hMgr->Handle.Tag != MANAGER_TAG)
370 return ERROR_INVALID_HANDLE;
371
372 if (!RtlAreAllAccessesGranted(hMgr->Handle.DesiredAccess,
373 SC_MANAGER_LOCK))
374 return ERROR_ACCESS_DENIED;
375
376 /* FIXME: Lock the database */
377 *hLock = 0x12345678; /* Dummy! */
378
379 return ERROR_SUCCESS;
380 }
381
382
383 /* Function 4 */
384 unsigned long
385 ScmrQueryServiceObjectSecurity(handle_t BindingHandle)
386 {
387 DPRINT1("ScmrQueryServiceSecurity() is unimplemented\n");
388 return ERROR_CALL_NOT_IMPLEMENTED;
389 }
390
391
392 /* Function 5 */
393 unsigned long
394 ScmrSetServiceObjectSecurity(handle_t BindingHandle)
395 {
396 DPRINT1("ScmrSetServiceSecurity() is unimplemented\n");
397 return ERROR_CALL_NOT_IMPLEMENTED;
398 }
399
400
401 /* Function 6 */
402 unsigned long
403 ScmrQueryServiceStatus(handle_t BindingHandle,
404 unsigned int hService,
405 LPSERVICE_STATUS lpServiceStatus)
406 {
407 PSERVICE_HANDLE hSvc;
408 PSERVICE lpService;
409
410 DPRINT("ScmrQueryServiceStatus() called\n");
411
412 hSvc = (PSERVICE_HANDLE)hService;
413 if (hSvc->Handle.Tag != SERVICE_TAG)
414 {
415 DPRINT1("Invalid handle tag!\n");
416 return ERROR_INVALID_HANDLE;
417 }
418
419 if (!RtlAreAllAccessesGranted(hSvc->Handle.DesiredAccess,
420 SERVICE_QUERY_STATUS))
421 {
422 DPRINT1("Insufficient access rights! 0x%lx\n", hSvc->Handle.DesiredAccess);
423 return ERROR_ACCESS_DENIED;
424 }
425
426 lpService = hSvc->ServiceEntry;
427 if (lpService == NULL)
428 {
429 DPRINT1("lpService == NULL!\n");
430 return ERROR_INVALID_HANDLE;
431 }
432
433 /* Return service status information */
434 RtlCopyMemory(lpServiceStatus,
435 &lpService->Status,
436 sizeof(SERVICE_STATUS));
437
438 return ERROR_SUCCESS;
439 }
440
441
442 /* Function 7 */
443 unsigned long
444 ScmrSetServiceStatus(handle_t BindingHandle)
445 {
446 DPRINT1("ScmrSetServiceStatus() is unimplemented\n");
447 /* FIXME */
448 return ERROR_CALL_NOT_IMPLEMENTED;
449 }
450
451
452 /* Function 8 */
453 unsigned long
454 ScmrUnlockServiceDatabase(handle_t BindingHandle,
455 unsigned int hLock)
456 {
457 DPRINT1("ScmrUnlockServiceDatabase() called\n");
458 /* FIXME */
459 return ERROR_SUCCESS;
460 }
461
462
463 /* Function 9 */
464 unsigned long
465 ScmrNotifyBootConfigStatus(handle_t BindingHandle,
466 unsigned long BootAcceptable)
467 {
468 DPRINT1("ScmrNotifyBootConfigStatus() called\n");
469 /* FIXME */
470 return ERROR_SUCCESS;
471 }
472
473
474 /* Function 11 */
475 unsigned long
476 ScmrChangeServiceConfigW(handle_t BiningHandle,
477 unsigned int hService,
478 unsigned long dwServiceType,
479 unsigned long dwStartType,
480 unsigned long dwErrorControl,
481 wchar_t *lpBinaryPathName,
482 wchar_t *lpLoadOrderGroup,
483 unsigned long *lpdwTagId, /* in, out, unique */
484 wchar_t *lpDependencies,
485 unsigned long dwDependenciesLength,
486 wchar_t *lpServiceStartName,
487 wchar_t *lpPassword,
488 unsigned long dwPasswordLength,
489 wchar_t *lpDisplayName)
490 {
491 DPRINT1("ScmrChangeServiceConfigW() called\n");
492 DPRINT1("dwServiceType = %lu\n", dwServiceType);
493 DPRINT1("dwStartType = %lu\n", dwStartType);
494 DPRINT1("dwErrorControl = %lu\n", dwErrorControl);
495 DPRINT1("lpBinaryPathName = %S\n", lpBinaryPathName);
496 DPRINT1("lpLoadOrderGroup = %S\n", lpLoadOrderGroup);
497 DPRINT1("lpDisplayName = %S\n", lpDisplayName);
498
499 return ERROR_SUCCESS;
500 }
501
502
503 static DWORD
504 CreateServiceKey(LPWSTR lpServiceName,
505 PHKEY phKey)
506 {
507 HKEY hServicesKey = NULL;
508 DWORD dwDisposition;
509 DWORD dwError;
510
511 *phKey = NULL;
512
513 dwError = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
514 L"System\\CurrentControlSet\\Services",
515 0,
516 KEY_WRITE,
517 &hServicesKey);
518 if (dwError != ERROR_SUCCESS)
519 return dwError;
520
521 dwError = RegCreateKeyExW(hServicesKey,
522 lpServiceName,
523 0,
524 NULL,
525 REG_OPTION_NON_VOLATILE,
526 KEY_WRITE,
527 NULL,
528 phKey,
529 &dwDisposition);
530 #if 0
531 if ((dwError == ERROR_SUCCESS) &&
532 (dwDisposition == REG_OPENED_EXISTING_KEY))
533 {
534 RegCloseKey(*phKey);
535 *phKey = NULL;
536 dwError = ERROR_SERVICE_EXISTS;
537 }
538 #endif
539
540 RegCloseKey(hServicesKey);
541
542 return dwError;
543 }
544
545
546 /* Function 12 */
547 unsigned long
548 ScmrCreateServiceW(handle_t BindingHandle,
549 unsigned int hSCManager,
550 wchar_t *lpServiceName,
551 wchar_t *lpDisplayName,
552 unsigned long dwDesiredAccess,
553 unsigned long dwServiceType,
554 unsigned long dwStartType,
555 unsigned long dwErrorControl,
556 wchar_t *lpBinaryPathName,
557 wchar_t *lpLoadOrderGroup,
558 unsigned long *lpdwTagId, /* in, out */
559 wchar_t *lpDependencies,
560 unsigned long dwDependenciesLength,
561 wchar_t *lpServiceStartName,
562 wchar_t *lpPassword,
563 unsigned long dwPasswordLength,
564 unsigned int *hService) /* out */
565 {
566 PMANAGER_HANDLE hManager;
567 DWORD dwError = ERROR_SUCCESS;
568 PSERVICE lpService = NULL;
569 SC_HANDLE hServiceHandle = NULL;
570 LPWSTR lpImagePath = NULL;
571 HKEY hServiceKey = NULL;
572
573 DPRINT1("ScmrCreateServiceW() called\n");
574 DPRINT1("lpServiceName = %S\n", lpServiceName);
575 DPRINT1("lpDisplayName = %S\n", lpDisplayName);
576 DPRINT1("dwDesiredAccess = %lx\n", dwDesiredAccess);
577 DPRINT1("dwServiceType = %lu\n", dwServiceType);
578 DPRINT1("dwStartType = %lu\n", dwStartType);
579 DPRINT1("dwErrorControl = %lu\n", dwErrorControl);
580 DPRINT1("lpBinaryPathName = %S\n", lpBinaryPathName);
581 DPRINT1("lpLoadOrderGroup = %S\n", lpLoadOrderGroup);
582
583 hManager = (PMANAGER_HANDLE)hSCManager;
584 if (hManager->Handle.Tag != MANAGER_TAG)
585 {
586 DPRINT1("Invalid manager handle!\n");
587 return ERROR_INVALID_HANDLE;
588 }
589
590 /* Check access rights */
591 if (!RtlAreAllAccessesGranted(hManager->Handle.DesiredAccess,
592 SC_MANAGER_CREATE_SERVICE))
593 {
594 DPRINT1("Insufficient access rights! 0x%lx\n",
595 hManager->Handle.DesiredAccess);
596 return ERROR_ACCESS_DENIED;
597 }
598
599 /* Fail if the service already exists! */
600 if (ScmGetServiceEntryByName(lpServiceName) != NULL)
601 return ERROR_SERVICE_EXISTS;
602
603 if (dwServiceType & SERVICE_DRIVER)
604 {
605 /* FIXME: Adjust the image path */
606 lpImagePath = HeapAlloc(GetProcessHeap(),
607 HEAP_ZERO_MEMORY,
608 (wcslen(lpBinaryPathName) + 1) * sizeof(WCHAR));
609 if (lpImagePath == NULL)
610 {
611 dwError = ERROR_NOT_ENOUGH_MEMORY;
612 goto done;
613 }
614 wcscpy(lpImagePath, lpBinaryPathName);
615 }
616
617 /* Allocate a new service entry */
618 dwError = ScmCreateNewServiceRecord(lpServiceName,
619 &lpService);
620 if (dwError != ERROR_SUCCESS)
621 goto done;
622
623 /* Fill the new service entry */
624 lpService->Status.dwServiceType = dwServiceType;
625 lpService->dwStartType = dwStartType;
626 lpService->dwErrorControl = dwErrorControl;
627
628 /* FIXME: set lpLoadOrderGroup, lpDependencies etc. */
629
630
631 /* Write service data to the registry */
632 /* Create the service key */
633 dwError = CreateServiceKey(lpServiceName, &hServiceKey);
634 if (dwError != ERROR_SUCCESS)
635 goto done;
636
637 /* Set the display name */
638 if (lpDisplayName != NULL && *lpDisplayName != 0)
639 {
640 RegSetValueExW(hServiceKey,
641 L"DisplayName",
642 0,
643 REG_SZ,
644 (LPBYTE)lpDisplayName,
645 (wcslen(lpDisplayName) + 1) * sizeof(WCHAR));
646 }
647
648 /* Set the service type */
649 dwError = RegSetValueExW(hServiceKey,
650 L"Type",
651 0,
652 REG_DWORD,
653 (LPBYTE)&dwServiceType,
654 sizeof(DWORD));
655 if (dwError != ERROR_SUCCESS)
656 goto done;
657
658 /* Set the start value */
659 dwError = RegSetValueExW(hServiceKey,
660 L"Start",
661 0,
662 REG_DWORD,
663 (LPBYTE)&dwStartType,
664 sizeof(DWORD));
665 if (dwError != ERROR_SUCCESS)
666 goto done;
667
668 /* Set the error control value */
669 dwError = RegSetValueExW(hServiceKey,
670 L"ErrorControl",
671 0,
672 REG_DWORD,
673 (LPBYTE)&dwErrorControl,
674 sizeof(DWORD));
675 if (dwError != ERROR_SUCCESS)
676 goto done;
677
678 /* Set the image path */
679 if (dwServiceType & SERVICE_WIN32)
680 {
681 dwError = RegSetValueExW(hServiceKey,
682 L"ImagePath",
683 0,
684 REG_EXPAND_SZ,
685 (LPBYTE)lpBinaryPathName,
686 (wcslen(lpBinaryPathName) + 1) * sizeof(WCHAR));
687 if (dwError != ERROR_SUCCESS)
688 goto done;
689 }
690 else if (dwServiceType & SERVICE_DRIVER)
691 {
692 dwError = RegSetValueExW(hServiceKey,
693 L"ImagePath",
694 0,
695 REG_EXPAND_SZ,
696 (LPBYTE)lpImagePath,
697 (wcslen(lpImagePath) + 1) *sizeof(WCHAR));
698 if (dwError != ERROR_SUCCESS)
699 goto done;
700 }
701
702 /* Set the group name */
703 if (lpLoadOrderGroup != NULL && *lpLoadOrderGroup != 0)
704 {
705 dwError = RegSetValueExW(hServiceKey,
706 L"Group",
707 0,
708 REG_SZ,
709 (LPBYTE)lpLoadOrderGroup,
710 (wcslen(lpLoadOrderGroup) + 1) * sizeof(WCHAR));
711 if (dwError != ERROR_SUCCESS)
712 goto done;
713 }
714
715 if (lpdwTagId != NULL)
716 {
717 /* FIXME: Write tag */
718 }
719
720 /* Write dependencies */
721 if (lpDependencies != NULL && *lpDependencies != 0)
722 {
723 dwError = ScmWriteDependencies(hServiceKey,
724 lpDependencies,
725 dwDependenciesLength);
726 if (dwError != ERROR_SUCCESS)
727 goto done;
728 }
729
730 if (lpPassword != NULL)
731 {
732 /* FIXME: Write password */
733 }
734
735 dwError = ScmCreateServiceHandle(lpService,
736 &hServiceHandle);
737 if (dwError != ERROR_SUCCESS)
738 goto done;
739
740 dwError = ScmCheckAccess(hServiceHandle,
741 dwDesiredAccess);
742 if (dwError != ERROR_SUCCESS)
743 goto done;
744
745 done:;
746 if (hServiceKey != NULL)
747 RegCloseKey(hServiceKey);
748
749 if (dwError == ERROR_SUCCESS)
750 {
751 DPRINT1("hService %lx\n", hServiceHandle);
752 *hService = (unsigned int)hServiceHandle;
753
754 if (lpdwTagId != NULL)
755 *lpdwTagId = 0; /* FIXME */
756 }
757 else
758 {
759 if (hServiceHandle != NULL)
760 {
761 /* Remove the service handle */
762 HeapFree(GetProcessHeap(), 0, hServiceHandle);
763 }
764
765 if (lpService != NULL)
766 {
767 /* FIXME: remove the service entry */
768 }
769 }
770
771 if (lpImagePath != NULL)
772 HeapFree(GetProcessHeap(), 0, lpImagePath);
773
774 DPRINT1("ScmrCreateServiceW() done (Error %lu)\n", dwError);
775
776 return dwError;
777 }
778
779
780 /* Function 15 */
781 unsigned long
782 ScmrOpenSCManagerW(handle_t BindingHandle,
783 wchar_t *lpMachineName,
784 wchar_t *lpDatabaseName,
785 unsigned long dwDesiredAccess,
786 unsigned int *hScm)
787 {
788 DWORD dwError;
789 SC_HANDLE hHandle;
790
791 DPRINT("ScmrOpenSCManagerW() called\n");
792 DPRINT("lpMachineName = %p\n", lpMachineName);
793 DPRINT("lpMachineName: %S\n", lpMachineName);
794 DPRINT("lpDataBaseName = %p\n", lpDatabaseName);
795 DPRINT("lpDataBaseName: %S\n", lpDatabaseName);
796 DPRINT("dwDesiredAccess = %x\n", dwDesiredAccess);
797
798 dwError = ScmCreateManagerHandle(lpDatabaseName,
799 &hHandle);
800 if (dwError != ERROR_SUCCESS)
801 {
802 DPRINT1("ScmCreateManagerHandle() failed (Error %lu)\n", dwError);
803 return dwError;
804 }
805
806 /* Check the desired access */
807 dwError = ScmCheckAccess(hHandle,
808 dwDesiredAccess | SC_MANAGER_CONNECT);
809 if (dwError != ERROR_SUCCESS)
810 {
811 DPRINT1("ScmCheckAccess() failed (Error %lu)\n", dwError);
812 HeapFree(GetProcessHeap(), 0, hHandle);
813 return dwError;
814 }
815
816 *hScm = (unsigned int)hHandle;
817 DPRINT("*hScm = %x\n", *hScm);
818
819 DPRINT("ScmrOpenSCManagerW() done\n");
820
821 return ERROR_SUCCESS;
822 }
823
824
825 /* Function 16 */
826 unsigned int
827 ScmrOpenServiceW(handle_t BindingHandle,
828 unsigned int hSCManager,
829 wchar_t *lpServiceName,
830 unsigned long dwDesiredAccess,
831 unsigned int *hService)
832 {
833 PSERVICE lpService;
834 PMANAGER_HANDLE hManager;
835 SC_HANDLE hHandle;
836 DWORD dwError;
837
838 DPRINT("ScmrOpenServiceW() called\n");
839 DPRINT("hSCManager = %x\n", hSCManager);
840 DPRINT("lpServiceName = %p\n", lpServiceName);
841 DPRINT("lpServiceName: %S\n", lpServiceName);
842 DPRINT("dwDesiredAccess = %x\n", dwDesiredAccess);
843
844 hManager = (PMANAGER_HANDLE)hSCManager;
845 if (hManager->Handle.Tag != MANAGER_TAG)
846 {
847 DPRINT1("Invalid manager handle!\n");
848 return ERROR_INVALID_HANDLE;
849 }
850
851 /* FIXME: Lock the service list */
852
853 /* Get service database entry */
854 lpService = ScmGetServiceEntryByName(lpServiceName);
855 if (lpService == NULL)
856 {
857 DPRINT1("Could not find a service!\n");
858 return ERROR_SERVICE_DOES_NOT_EXIST;
859 }
860
861 /* Create a service handle */
862 dwError = ScmCreateServiceHandle(lpService,
863 &hHandle);
864 if (dwError != ERROR_SUCCESS)
865 {
866 DPRINT1("ScmCreateServiceHandle() failed (Error %lu)\n", dwError);
867 return dwError;
868 }
869
870 /* Check the desired access */
871 dwError = ScmCheckAccess(hHandle,
872 dwDesiredAccess);
873 if (dwError != ERROR_SUCCESS)
874 {
875 DPRINT1("ScmCheckAccess() failed (Error %lu)\n", dwError);
876 HeapFree(GetProcessHeap(), 0, hHandle);
877 return dwError;
878 }
879
880 *hService = (unsigned int)hHandle;
881 DPRINT("*hService = %x\n", *hService);
882
883 DPRINT("ScmrOpenServiceW() done\n");
884
885 return ERROR_SUCCESS;
886 }
887
888
889
890 /* Function 27 */
891 unsigned long
892 ScmrOpenSCManagerA(handle_t BindingHandle,
893 char *lpMachineName,
894 char *lpDatabaseName,
895 unsigned long dwDesiredAccess,
896 unsigned int *hScm)
897 {
898 UNICODE_STRING MachineName;
899 UNICODE_STRING DatabaseName;
900 DWORD dwError;
901
902 DPRINT("ScmrOpenSCManagerA() called\n");
903
904 if (lpMachineName)
905 RtlCreateUnicodeStringFromAsciiz(&MachineName,
906 lpMachineName);
907
908 if (lpDatabaseName)
909 RtlCreateUnicodeStringFromAsciiz(&DatabaseName,
910 lpDatabaseName);
911
912 dwError = ScmrOpenSCManagerW(BindingHandle,
913 lpMachineName ? MachineName.Buffer : NULL,
914 lpDatabaseName ? DatabaseName.Buffer : NULL,
915 dwDesiredAccess,
916 hScm);
917
918 if (lpMachineName)
919 RtlFreeUnicodeString(&MachineName);
920
921 if (lpDatabaseName)
922 RtlFreeUnicodeString(&DatabaseName);
923
924 return dwError;
925 }
926
927
928 /* Function 28 */
929 unsigned int
930 ScmrOpenServiceA(handle_t BindingHandle,
931 unsigned int hSCManager,
932 char *lpServiceName,
933 unsigned long dwDesiredAccess,
934 unsigned int *hService)
935 {
936 UNICODE_STRING ServiceName;
937 DWORD dwError;
938
939 DPRINT("ScmrOpenServiceA() called\n");
940
941 RtlCreateUnicodeStringFromAsciiz(&ServiceName,
942 lpServiceName);
943
944 dwError = ScmrOpenServiceW(BindingHandle,
945 hSCManager,
946 ServiceName.Buffer,
947 dwDesiredAccess,
948 hService);
949
950 RtlFreeUnicodeString(&ServiceName);
951
952 return dwError;
953 }
954
955
956
957 void __RPC_FAR * __RPC_USER midl_user_allocate(size_t len)
958 {
959 return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len);
960 }
961
962
963 void __RPC_USER midl_user_free(void __RPC_FAR * ptr)
964 {
965 HeapFree(GetProcessHeap(), 0, ptr);
966 }
967
968 /* EOF */