5 /* INCLUDES ****************************************************************/
14 /* GLOBALS *****************************************************************/
16 #define MANAGER_TAG 0x72674D68 /* 'hMgr' */
17 #define SERVICE_TAG 0x63765368 /* 'hSvc' */
19 typedef struct _SCMGR_HANDLE
27 typedef struct _MANAGER_HANDLE
31 /* FIXME: Insert more data here */
33 WCHAR DatabaseName
[1];
34 } MANAGER_HANDLE
, *PMANAGER_HANDLE
;
37 typedef struct _SERVICE_HANDLE
42 PSERVICE ServiceEntry
;
44 /* FIXME: Insert more data here */
46 } SERVICE_HANDLE
, *PSERVICE_HANDLE
;
49 #define SC_MANAGER_READ \
50 (STANDARD_RIGHTS_READ | \
51 SC_MANAGER_QUERY_LOCK_STATUS | \
52 SC_MANAGER_ENUMERATE_SERVICE)
54 #define SC_MANAGER_WRITE \
55 (STANDARD_RIGHTS_WRITE | \
56 SC_MANAGER_MODIFY_BOOT_CONFIG | \
57 SC_MANAGER_CREATE_SERVICE)
59 #define SC_MANAGER_EXECUTE \
60 (STANDARD_RIGHTS_EXECUTE | \
62 SC_MANAGER_ENUMERATE_SERVICE | \
63 SC_MANAGER_CONNECT | \
64 SC_MANAGER_CREATE_SERVICE)
67 #define SERVICE_READ \
68 (STANDARD_RIGHTS_READ | \
69 SERVICE_INTERROGATE | \
70 SERVICE_ENUMERATE_DEPENDENTS | \
71 SERVICE_QUERY_STATUS | \
74 #define SERVICE_WRITE \
75 (STANDARD_RIGHTS_WRITE | \
76 SERVICE_CHANGE_CONFIG)
78 #define SERVICE_EXECUTE \
79 (STANDARD_RIGHTS_EXECUTE | \
80 SERVICE_USER_DEFINED_CONTROL | \
81 SERVICE_PAUSE_CONTINUE | \
86 /* VARIABLES ***************************************************************/
88 static GENERIC_MAPPING
89 ScmManagerMapping
= {SC_MANAGER_READ
,
92 SC_MANAGER_ALL_ACCESS
};
94 static GENERIC_MAPPING
95 ScmServiceMapping
= {SERVICE_READ
,
98 SC_MANAGER_ALL_ACCESS
};
101 /* FUNCTIONS ***************************************************************/
104 ScmStartRpcServer(VOID
)
108 DPRINT("ScmStartRpcServer() called");
110 Status
= RpcServerUseProtseqEp(L
"ncacn_np",
114 if (Status
!= RPC_S_OK
)
116 DPRINT1("RpcServerUseProtseqEp() failed (Status %lx)\n", Status
);
120 Status
= RpcServerRegisterIf(svcctl_ServerIfHandle
,
123 if (Status
!= RPC_S_OK
)
125 DPRINT1("RpcServerRegisterIf() failed (Status %lx)\n", Status
);
129 Status
= RpcServerListen(1, 20, TRUE
);
130 if (Status
!= RPC_S_OK
)
132 DPRINT1("RpcServerListen() failed (Status %lx)\n", Status
);
136 DPRINT("ScmStartRpcServer() done");
141 ScmCreateManagerHandle(LPWSTR lpDatabaseName
,
146 if (lpDatabaseName
== NULL
)
147 lpDatabaseName
= SERVICES_ACTIVE_DATABASEW
;
149 Ptr
= HeapAlloc(GetProcessHeap(),
151 sizeof(MANAGER_HANDLE
) + wcslen(lpDatabaseName
) * sizeof(WCHAR
));
153 return ERROR_NOT_ENOUGH_MEMORY
;
155 Ptr
->Handle
.Tag
= MANAGER_TAG
;
156 Ptr
->Handle
.RefCount
= 1;
158 /* FIXME: initialize more data here */
160 wcscpy(Ptr
->DatabaseName
, lpDatabaseName
);
162 *Handle
= (SC_HANDLE
)Ptr
;
164 return ERROR_SUCCESS
;
169 ScmCreateServiceHandle(PSERVICE lpServiceEntry
,
174 Ptr
= HeapAlloc(GetProcessHeap(),
176 sizeof(SERVICE_HANDLE
));
178 return ERROR_NOT_ENOUGH_MEMORY
;
180 Ptr
->Handle
.Tag
= SERVICE_TAG
;
181 Ptr
->Handle
.RefCount
= 1;
183 /* FIXME: initialize more data here */
184 Ptr
->ServiceEntry
= lpServiceEntry
;
186 *Handle
= (SC_HANDLE
)Ptr
;
188 return ERROR_SUCCESS
;
193 ScmCheckAccess(SC_HANDLE Handle
,
194 DWORD dwDesiredAccess
)
196 PMANAGER_HANDLE hMgr
;
198 hMgr
= (PMANAGER_HANDLE
)Handle
;
199 if (hMgr
->Handle
.Tag
== MANAGER_TAG
)
201 RtlMapGenericMask(&dwDesiredAccess
,
204 hMgr
->Handle
.DesiredAccess
= dwDesiredAccess
;
206 return ERROR_SUCCESS
;
208 else if (hMgr
->Handle
.Tag
== SERVICE_TAG
)
210 RtlMapGenericMask(&dwDesiredAccess
,
213 hMgr
->Handle
.DesiredAccess
= dwDesiredAccess
;
215 return ERROR_SUCCESS
;
218 return ERROR_INVALID_HANDLE
;
224 ScmrCloseServiceHandle(handle_t BindingHandle
,
225 unsigned int hScObject
)
227 PMANAGER_HANDLE hManager
;
229 DPRINT("ScmrCloseServiceHandle() called\n");
231 DPRINT("hScObject = %X\n", hScObject
);
234 return ERROR_INVALID_HANDLE
;
236 hManager
= (PMANAGER_HANDLE
)hScObject
;
237 if (hManager
->Handle
.Tag
== MANAGER_TAG
)
239 DPRINT("Found manager handle\n");
241 hManager
->Handle
.RefCount
--;
242 if (hManager
->Handle
.RefCount
== 0)
244 /* FIXME: add cleanup code */
246 HeapFree(GetProcessHeap(), 0, hManager
);
249 DPRINT("ScmrCloseServiceHandle() done\n");
250 return ERROR_SUCCESS
;
252 else if (hManager
->Handle
.Tag
== SERVICE_TAG
)
254 DPRINT("Found service handle\n");
256 hManager
->Handle
.RefCount
--;
257 if (hManager
->Handle
.RefCount
== 0)
259 /* FIXME: add cleanup code */
261 HeapFree(GetProcessHeap(), 0, hManager
);
264 DPRINT("ScmrCloseServiceHandle() done\n");
265 return ERROR_SUCCESS
;
268 DPRINT1("Invalid handle tag (Tag %lx)\n", hManager
->Handle
.Tag
);
270 return ERROR_INVALID_HANDLE
;
276 ScmrControlService(handle_t BindingHandle
,
277 unsigned int hService
,
278 unsigned long dwControl
,
279 LPSERVICE_STATUS lpServiceStatus
)
281 PSERVICE_HANDLE hSvc
;
284 DPRINT1("ScmrControlService() called\n");
286 hSvc
= (PSERVICE_HANDLE
)hService
;
287 if (hSvc
->Handle
.Tag
!= SERVICE_TAG
)
289 DPRINT1("Invalid handle tag!\n");
290 return ERROR_INVALID_HANDLE
;
294 /* FIXME: Check access rights */
297 lpService
= hSvc
->ServiceEntry
;
298 if (lpService
== NULL
)
300 DPRINT1("lpService == NULL!\n");
301 return ERROR_INVALID_HANDLE
;
305 /* FIXME: Send control code to the service */
308 /* Return service status information */
309 lpServiceStatus
->dwServiceType
= lpService
->Type
;
310 lpServiceStatus
->dwCurrentState
= lpService
->CurrentState
;
311 lpServiceStatus
->dwControlsAccepted
= lpService
->ControlsAccepted
;
312 lpServiceStatus
->dwWin32ExitCode
= lpService
->Win32ExitCode
;
313 lpServiceStatus
->dwServiceSpecificExitCode
= lpService
->ServiceSpecificExitCode
;
314 lpServiceStatus
->dwCheckPoint
= lpService
->CheckPoint
;
315 lpServiceStatus
->dwWaitHint
= lpService
->WaitHint
;
317 return ERROR_SUCCESS
;
323 ScmrDeleteService(handle_t BindingHandle
,
324 unsigned int hService
)
326 PSERVICE_HANDLE hSvc
;
329 DPRINT1("ScmrDeleteService() called\n");
331 hSvc
= (PSERVICE_HANDLE
)hService
;
332 if (hSvc
->Handle
.Tag
!= SERVICE_TAG
)
333 return ERROR_INVALID_HANDLE
;
335 if (!RtlAreAllAccessesGranted(hSvc
->Handle
.DesiredAccess
,
336 STANDARD_RIGHTS_REQUIRED
))
337 return ERROR_ACCESS_DENIED
;
339 lpService
= hSvc
->ServiceEntry
;
340 if (lpService
== NULL
)
342 DPRINT1("lpService == NULL!\n");
343 return ERROR_INVALID_HANDLE
;
346 /* FIXME: Mark service for delete */
348 return ERROR_SUCCESS
;
354 ScmrLockServiceDatabase(handle_t BindingHandle
,
355 unsigned int hSCManager
,
358 PMANAGER_HANDLE hMgr
;
360 DPRINT("ScmrLockServiceDatabase() called\n");
364 hMgr
= (PMANAGER_HANDLE
)hSCManager
;
365 if (hMgr
->Handle
.Tag
!= MANAGER_TAG
)
366 return ERROR_INVALID_HANDLE
;
368 if (!RtlAreAllAccessesGranted(hMgr
->Handle
.DesiredAccess
,
370 return ERROR_ACCESS_DENIED
;
372 /* FIXME: Lock the database */
373 *hLock
= 0x12345678; /* Dummy! */
375 return ERROR_SUCCESS
;
381 ScmrQueryServiceObjectSecurity(handle_t BindingHandle
)
383 DPRINT1("ScmrQueryServiceSecurity() is unimplemented\n");
384 return ERROR_CALL_NOT_IMPLEMENTED
;
390 ScmrSetServiceObjectSecurity(handle_t BindingHandle
)
392 DPRINT1("ScmrSetServiceSecurity() is unimplemented\n");
393 return ERROR_CALL_NOT_IMPLEMENTED
;
399 ScmrQueryServiceStatus(handle_t BindingHandle
,
400 unsigned int hService
,
401 LPSERVICE_STATUS lpServiceStatus
)
403 PSERVICE_HANDLE hSvc
;
406 DPRINT("ScmrQueryServiceStatus() called\n");
408 hSvc
= (PSERVICE_HANDLE
)hService
;
409 if (hSvc
->Handle
.Tag
!= SERVICE_TAG
)
411 DPRINT1("Invalid handle tag!\n");
412 return ERROR_INVALID_HANDLE
;
415 if (!RtlAreAllAccessesGranted(hSvc
->Handle
.DesiredAccess
,
416 SERVICE_QUERY_STATUS
))
418 DPRINT1("Insufficient access rights! 0x%lx\n", hSvc
->Handle
.DesiredAccess
);
419 return ERROR_ACCESS_DENIED
;
422 lpService
= hSvc
->ServiceEntry
;
423 if (lpService
== NULL
)
425 DPRINT1("lpService == NULL!\n");
426 return ERROR_INVALID_HANDLE
;
429 /* Return service status information */
430 lpServiceStatus
->dwServiceType
= lpService
->Type
;
431 lpServiceStatus
->dwCurrentState
= lpService
->CurrentState
;
432 lpServiceStatus
->dwControlsAccepted
= lpService
->ControlsAccepted
;
433 lpServiceStatus
->dwWin32ExitCode
= lpService
->Win32ExitCode
;
434 lpServiceStatus
->dwServiceSpecificExitCode
= lpService
->ServiceSpecificExitCode
;
435 lpServiceStatus
->dwCheckPoint
= lpService
->CheckPoint
;
436 lpServiceStatus
->dwWaitHint
= lpService
->WaitHint
;
438 return ERROR_SUCCESS
;
444 ScmrSetServiceStatus(handle_t BindingHandle
)
446 DPRINT1("ScmrSetServiceStatus() is unimplemented\n");
448 return ERROR_CALL_NOT_IMPLEMENTED
;
454 ScmrUnlockServiceDatabase(handle_t BindingHandle
,
457 DPRINT1("ScmrUnlockServiceDatabase() called\n");
459 return ERROR_SUCCESS
;
465 ScmrNotifyBootConfigStatus(handle_t BindingHandle
,
466 unsigned long BootAcceptable
)
468 DPRINT1("ScmrNotifyBootConfigStatus() called\n");
470 return ERROR_SUCCESS
;
478 ScmrCreateServiceW(handle_t BindingHandle
,
479 unsigned int hSCManager
,
480 wchar_t *lpServiceName
,
481 wchar_t *lpDisplayName
,
482 unsigned long dwDesiredAccess
,
483 unsigned long dwServiceType
,
484 unsigned long dwStartType
,
485 unsigned long dwErrorControl
,
486 wchar_t *lpBinaryPathName
,
487 wchar_t *lpLoadOrderGroup
,
488 unsigned long *lpdwTagId
,
489 wchar_t *lpDependencies
,
490 wchar_t *lpServiceStartName
,
493 DPRINT1("ScmrCreateServiceW() called\n");
494 if (lpdwTagId
!= NULL
)
496 return ERROR_SUCCESS
;
503 ScmrOpenSCManagerW(handle_t BindingHandle
,
504 wchar_t *lpMachineName
,
505 wchar_t *lpDatabaseName
,
506 unsigned long dwDesiredAccess
,
512 DPRINT("ScmrOpenSCManagerW() called\n");
513 DPRINT("lpMachineName = %p\n", lpMachineName
);
514 DPRINT("lpMachineName: %S\n", lpMachineName
);
515 DPRINT("lpDataBaseName = %p\n", lpDatabaseName
);
516 DPRINT("lpDataBaseName: %S\n", lpDatabaseName
);
517 DPRINT("dwDesiredAccess = %x\n", dwDesiredAccess
);
519 dwError
= ScmCreateManagerHandle(lpDatabaseName
,
521 if (dwError
!= ERROR_SUCCESS
)
523 DPRINT1("ScmCreateManagerHandle() failed (Error %lu)\n", dwError
);
527 /* Check the desired access */
528 dwError
= ScmCheckAccess(hHandle
,
529 dwDesiredAccess
| SC_MANAGER_CONNECT
);
530 if (dwError
!= ERROR_SUCCESS
)
532 DPRINT1("ScmCheckAccess() failed (Error %lu)\n", dwError
);
533 HeapFree(GetProcessHeap(), 0, hHandle
);
537 *hScm
= (unsigned int)hHandle
;
538 DPRINT("*hScm = %x\n", *hScm
);
540 DPRINT("ScmrOpenSCManagerW() done\n");
542 return ERROR_SUCCESS
;
548 ScmrOpenServiceW(handle_t BindingHandle
,
549 unsigned int hSCManager
,
550 wchar_t *lpServiceName
,
551 unsigned long dwDesiredAccess
,
552 unsigned int *hService
)
554 UNICODE_STRING ServiceName
;
556 PMANAGER_HANDLE hManager
;
560 DPRINT("ScmrOpenServiceW() called\n");
561 DPRINT("hSCManager = %x\n", hSCManager
);
562 DPRINT("lpServiceName = %p\n", lpServiceName
);
563 DPRINT("lpServiceName: %S\n", lpServiceName
);
564 DPRINT("dwDesiredAccess = %x\n", dwDesiredAccess
);
566 hManager
= (PMANAGER_HANDLE
)hSCManager
;
567 if (hManager
->Handle
.Tag
!= MANAGER_TAG
)
569 DPRINT1("Invalid manager handle!\n");
570 return ERROR_INVALID_HANDLE
;
573 /* FIXME: Lock the service list */
575 /* Get service database entry */
576 RtlInitUnicodeString(&ServiceName
,
579 lpService
= ScmGetServiceEntryByName(&ServiceName
);
580 if (lpService
== NULL
)
582 DPRINT1("Could not find a service!\n");
583 return ERROR_SERVICE_DOES_NOT_EXIST
;
586 /* Create a service handle */
587 dwError
= ScmCreateServiceHandle(lpService
,
589 if (dwError
!= ERROR_SUCCESS
)
591 DPRINT1("ScmCreateServiceHandle() failed (Error %lu)\n", dwError
);
595 /* Check the desired access */
596 dwError
= ScmCheckAccess(hHandle
,
598 if (dwError
!= ERROR_SUCCESS
)
600 DPRINT1("ScmCheckAccess() failed (Error %lu)\n", dwError
);
601 HeapFree(GetProcessHeap(), 0, hHandle
);
605 *hService
= (unsigned int)hHandle
;
606 DPRINT("*hService = %x\n", *hService
);
608 DPRINT("ScmrOpenServiceW() done\n");
610 return ERROR_SUCCESS
;
617 ScmrOpenSCManagerA(handle_t BindingHandle
,
619 char *lpDatabaseName
,
620 unsigned long dwDesiredAccess
,
623 UNICODE_STRING MachineName
;
624 UNICODE_STRING DatabaseName
;
627 DPRINT("ScmrOpenSCManagerA() called\n");
630 RtlCreateUnicodeStringFromAsciiz(&MachineName
,
634 RtlCreateUnicodeStringFromAsciiz(&DatabaseName
,
637 dwError
= ScmrOpenSCManagerW(BindingHandle
,
638 lpMachineName
? MachineName
.Buffer
: NULL
,
639 lpDatabaseName
? DatabaseName
.Buffer
: NULL
,
644 RtlFreeUnicodeString(&MachineName
);
647 RtlFreeUnicodeString(&DatabaseName
);
655 ScmrOpenServiceA(handle_t BindingHandle
,
656 unsigned int hSCManager
,
658 unsigned long dwDesiredAccess
,
659 unsigned int *hService
)
661 UNICODE_STRING ServiceName
;
664 DPRINT("ScmrOpenServiceA() called\n");
666 RtlCreateUnicodeStringFromAsciiz(&ServiceName
,
669 dwError
= ScmrOpenServiceW(BindingHandle
,
675 RtlFreeUnicodeString(&ServiceName
);
682 void __RPC_FAR
* __RPC_USER
midl_user_allocate(size_t len
)
684 return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, len
);
688 void __RPC_USER
midl_user_free(void __RPC_FAR
* ptr
)
690 HeapFree(GetProcessHeap(), 0, ptr
);