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