2 * PROJECT: ReactOS Service Control Manager
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: base/system/services/lock.c
5 * PURPOSE: User-side Services Start Serialization Lock functions
6 * COPYRIGHT: Copyright 2012 Hermès Bélusca
9 /* INCLUDES *****************************************************************/
18 /* GLOBALS *******************************************************************/
20 /* The unique user service start lock of the SCM */
21 static PSTART_LOCK pServiceStartLock
= NULL
;
24 /* FUNCTIONS *****************************************************************/
27 * NOTE: IsServiceController is TRUE if locked by the
28 * Service Control Manager, and FALSE otherwise.
31 ScmAcquireServiceStartLock(IN BOOL IsServiceController
,
32 OUT LPSC_RPC_LOCK lpLock
)
35 DWORD dwError
= ERROR_SUCCESS
;
39 /* Lock the service database exclusively */
40 ScmLockDatabaseExclusive();
42 if (pServiceStartLock
!= NULL
)
44 dwError
= ERROR_SERVICE_DATABASE_LOCKED
;
48 /* Allocate a new lock for the database */
49 dwRequiredSize
= sizeof(START_LOCK
);
51 if (!IsServiceController
)
53 /* FIXME: dwRequiredSize += RtlLengthSid(UserSid <-- to be retrieved); */
56 pServiceStartLock
= HeapAlloc(GetProcessHeap(),
59 if (pServiceStartLock
== NULL
)
61 dwError
= ERROR_NOT_ENOUGH_MEMORY
;
65 pServiceStartLock
->Tag
= LOCK_TAG
;
66 pServiceStartLock
->TimeWhenLocked
= (DWORD
)time(NULL
);
68 /* FIXME: Retrieve the owner SID. Use IsServiceController. */
69 pServiceStartLock
->LockOwnerSid
= (PSID
)NULL
;
71 *lpLock
= (LPSC_RPC_LOCK
)pServiceStartLock
;
74 /* Unlock the service database */
82 ScmReleaseServiceStartLock(IN OUT LPSC_RPC_LOCK lpLock
)
84 PSTART_LOCK pStartLock
;
85 DWORD dwError
= ERROR_SUCCESS
;
88 return ERROR_INVALID_SERVICE_LOCK
;
90 pStartLock
= (PSTART_LOCK
)*lpLock
;
92 if (pStartLock
->Tag
!= LOCK_TAG
)
93 return ERROR_INVALID_SERVICE_LOCK
;
95 /* Lock the service database exclusively */
96 ScmLockDatabaseExclusive();
98 /* Release the lock handle */
99 if ((pStartLock
== pServiceStartLock
) &&
100 (pServiceStartLock
!= NULL
))
102 HeapFree(GetProcessHeap(), 0, pServiceStartLock
);
103 pServiceStartLock
= NULL
;
106 dwError
= ERROR_SUCCESS
;
110 dwError
= ERROR_INVALID_SERVICE_LOCK
;
113 /* Unlock the service database */
121 * Helper functions for RQueryServiceLockStatusW() and
122 * RQueryServiceLockStatusA().
123 * We suppose that lpLockStatus points to a valid
127 ScmQueryServiceLockStatusW(OUT LPQUERY_SERVICE_LOCK_STATUSW lpLockStatus
)
129 /* Lock the service database shared */
130 ScmLockDatabaseShared();
132 if (pServiceStartLock
!= NULL
)
134 lpLockStatus
->fIsLocked
= TRUE
;
136 /* FIXME: Retrieve the owner name. */
137 lpLockStatus
->lpLockOwner
= NULL
;
139 lpLockStatus
->dwLockDuration
= (DWORD
)time(NULL
) - pServiceStartLock
->TimeWhenLocked
;
143 lpLockStatus
->fIsLocked
= FALSE
;
145 wcscpy((LPWSTR
)(lpLockStatus
+ 1), L
"");
146 lpLockStatus
->lpLockOwner
= (LPWSTR
)(ULONG_PTR
)sizeof(QUERY_SERVICE_LOCK_STATUSW
);
148 lpLockStatus
->dwLockDuration
= 0;
151 /* Unlock the service database */
159 ScmQueryServiceLockStatusA(OUT LPQUERY_SERVICE_LOCK_STATUSA lpLockStatus
)
161 /* Lock the service database shared */
162 ScmLockDatabaseShared();
164 if (pServiceStartLock
!= NULL
)
166 lpLockStatus
->fIsLocked
= TRUE
;
168 /* FIXME: Retrieve the owner name. */
169 lpLockStatus
->lpLockOwner
= NULL
;
171 lpLockStatus
->dwLockDuration
= (DWORD
)time(NULL
) - pServiceStartLock
->TimeWhenLocked
;
175 lpLockStatus
->fIsLocked
= FALSE
;
177 strcpy((LPSTR
)(lpLockStatus
+ 1), "");
178 lpLockStatus
->lpLockOwner
= (LPSTR
)(ULONG_PTR
)sizeof(QUERY_SERVICE_LOCK_STATUSA
);
180 lpLockStatus
->dwLockDuration
= 0;
183 /* Unlock the service database */