5 /* INCLUDES ****************************************************************/
19 /* GLOBALS *****************************************************************/
21 #define MANAGER_TAG 0x72674D68 /* 'hMgr' */
22 #define SERVICE_TAG 0x63765368 /* 'hSvc' */
24 typedef struct _SCMGR_HANDLE
32 typedef struct _MANAGER_HANDLE
36 /* FIXME: Insert more data here */
38 WCHAR DatabaseName
[1];
39 } MANAGER_HANDLE
, *PMANAGER_HANDLE
;
42 typedef struct _SERVICE_HANDLE
47 PSERVICE ServiceEntry
;
49 /* FIXME: Insert more data here */
51 } SERVICE_HANDLE
, *PSERVICE_HANDLE
;
54 #define SC_MANAGER_READ \
55 (STANDARD_RIGHTS_READ | \
56 SC_MANAGER_QUERY_LOCK_STATUS | \
57 SC_MANAGER_ENUMERATE_SERVICE)
59 #define SC_MANAGER_WRITE \
60 (STANDARD_RIGHTS_WRITE | \
61 SC_MANAGER_MODIFY_BOOT_CONFIG | \
62 SC_MANAGER_CREATE_SERVICE)
64 #define SC_MANAGER_EXECUTE \
65 (STANDARD_RIGHTS_EXECUTE | \
67 SC_MANAGER_ENUMERATE_SERVICE | \
68 SC_MANAGER_CONNECT | \
69 SC_MANAGER_CREATE_SERVICE)
72 #define SERVICE_READ \
73 (STANDARD_RIGHTS_READ | \
74 SERVICE_INTERROGATE | \
75 SERVICE_ENUMERATE_DEPENDENTS | \
76 SERVICE_QUERY_STATUS | \
79 #define SERVICE_WRITE \
80 (STANDARD_RIGHTS_WRITE | \
81 SERVICE_CHANGE_CONFIG)
83 #define SERVICE_EXECUTE \
84 (STANDARD_RIGHTS_EXECUTE | \
85 SERVICE_USER_DEFINED_CONTROL | \
86 SERVICE_PAUSE_CONTINUE | \
91 /* VARIABLES ***************************************************************/
93 static GENERIC_MAPPING
94 ScmManagerMapping
= {SC_MANAGER_READ
,
97 SC_MANAGER_ALL_ACCESS
};
99 static GENERIC_MAPPING
100 ScmServiceMapping
= {SERVICE_READ
,
103 SC_MANAGER_ALL_ACCESS
};
106 /* FUNCTIONS ***************************************************************/
109 ScmStartRpcServer(VOID
)
113 DPRINT("ScmStartRpcServer() called");
115 Status
= RpcServerUseProtseqEp(L
"ncacn_np",
119 if (Status
!= RPC_S_OK
)
121 DPRINT1("RpcServerUseProtseqEp() failed (Status %lx)\n", Status
);
125 Status
= RpcServerRegisterIf(svcctl_ServerIfHandle
,
128 if (Status
!= RPC_S_OK
)
130 DPRINT1("RpcServerRegisterIf() failed (Status %lx)\n", Status
);
134 Status
= RpcServerListen(1, 20, TRUE
);
135 if (Status
!= RPC_S_OK
)
137 DPRINT1("RpcServerListen() failed (Status %lx)\n", Status
);
141 DPRINT("ScmStartRpcServer() done");
146 ScmCreateManagerHandle(LPWSTR lpDatabaseName
,
151 Ptr
= GlobalAlloc(GPTR
,
152 sizeof(MANAGER_HANDLE
) + wcslen(lpDatabaseName
) * sizeof(WCHAR
));
154 return ERROR_NOT_ENOUGH_MEMORY
;
156 Ptr
->Handle
.Tag
= MANAGER_TAG
;
157 Ptr
->Handle
.RefCount
= 1;
159 /* FIXME: initialize more data here */
161 wcscpy(Ptr
->DatabaseName
, lpDatabaseName
);
163 *Handle
= (SC_HANDLE
)Ptr
;
165 return ERROR_SUCCESS
;
170 ScmCreateServiceHandle(PSERVICE lpServiceEntry
,
175 Ptr
= GlobalAlloc(GPTR
,
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 GlobalFree(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 GlobalFree(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
);
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
);
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 GlobalAlloc(GPTR
, len
);
688 void __RPC_USER
midl_user_free(void __RPC_FAR
* ptr
)