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 *****************************************************************/
17 /* GLOBALS *******************************************************************/
19 /* The unique user service start lock of the SCM */
20 static PSTART_LOCK pServiceStartLock
= NULL
;
23 /* FUNCTIONS *****************************************************************/
26 * NOTE: IsServiceController is TRUE if locked by the
27 * Service Control Manager, and FALSE otherwise.
30 ScmAcquireServiceStartLock(IN BOOL IsServiceController
,
31 OUT LPSC_RPC_LOCK lpLock
)
34 DWORD dwError
= ERROR_SUCCESS
;
38 /* Lock the service database exclusively */
39 ScmLockDatabaseExclusive();
41 if (pServiceStartLock
!= NULL
)
43 dwError
= ERROR_SERVICE_DATABASE_LOCKED
;
47 /* Allocate a new lock for the database */
48 dwRequiredSize
= sizeof(START_LOCK
);
50 if (!IsServiceController
)
52 /* FIXME: dwRequiredSize += RtlLengthSid(UserSid <-- to be retrieved); */
55 pServiceStartLock
= HeapAlloc(GetProcessHeap(),
58 if (pServiceStartLock
== NULL
)
60 dwError
= ERROR_NOT_ENOUGH_MEMORY
;
64 pServiceStartLock
->Tag
= LOCK_TAG
;
65 pServiceStartLock
->TimeWhenLocked
= (DWORD
)time(NULL
);
67 /* FIXME: Retrieve the owner SID. Use IsServiceController. */
68 pServiceStartLock
->LockOwnerSid
= (PSID
)NULL
;
70 *lpLock
= (LPSC_RPC_LOCK
)pServiceStartLock
;
73 /* Unlock the service database */
81 ScmReleaseServiceStartLock(IN OUT LPSC_RPC_LOCK lpLock
)
83 PSTART_LOCK pStartLock
;
84 DWORD dwError
= ERROR_SUCCESS
;
87 return ERROR_INVALID_SERVICE_LOCK
;
89 pStartLock
= (PSTART_LOCK
)*lpLock
;
91 if (pStartLock
->Tag
!= LOCK_TAG
)
92 return ERROR_INVALID_SERVICE_LOCK
;
94 /* Lock the service database exclusively */
95 ScmLockDatabaseExclusive();
97 /* Release the lock handle */
98 if ((pStartLock
== pServiceStartLock
) &&
99 (pServiceStartLock
!= NULL
))
101 HeapFree(GetProcessHeap(), 0, pServiceStartLock
);
102 pServiceStartLock
= NULL
;
105 dwError
= ERROR_SUCCESS
;
109 dwError
= ERROR_INVALID_SERVICE_LOCK
;
112 /* Unlock the service database */
120 * Helper functions for RQueryServiceLockStatusW() and
121 * RQueryServiceLockStatusA().
122 * We suppose that lpLockStatus points to a valid
126 ScmQueryServiceLockStatusW(OUT LPQUERY_SERVICE_LOCK_STATUSW lpLockStatus
)
128 /* Lock the service database shared */
129 ScmLockDatabaseShared();
131 if (pServiceStartLock
!= NULL
)
133 lpLockStatus
->fIsLocked
= TRUE
;
135 /* FIXME: Retrieve the owner name. */
136 lpLockStatus
->lpLockOwner
= NULL
;
138 lpLockStatus
->dwLockDuration
= (DWORD
)time(NULL
) - pServiceStartLock
->TimeWhenLocked
;
142 lpLockStatus
->fIsLocked
= FALSE
;
144 wcscpy((LPWSTR
)(lpLockStatus
+ 1), L
"");
145 lpLockStatus
->lpLockOwner
= (LPWSTR
)(ULONG_PTR
)sizeof(QUERY_SERVICE_LOCK_STATUSW
);
147 lpLockStatus
->dwLockDuration
= 0;
150 /* Unlock the service database */
158 ScmQueryServiceLockStatusA(OUT LPQUERY_SERVICE_LOCK_STATUSA lpLockStatus
)
160 /* Lock the service database shared */
161 ScmLockDatabaseShared();
163 if (pServiceStartLock
!= NULL
)
165 lpLockStatus
->fIsLocked
= TRUE
;
167 /* FIXME: Retrieve the owner name. */
168 lpLockStatus
->lpLockOwner
= NULL
;
170 lpLockStatus
->dwLockDuration
= (DWORD
)time(NULL
) - pServiceStartLock
->TimeWhenLocked
;
174 lpLockStatus
->fIsLocked
= FALSE
;
176 strcpy((LPSTR
)(lpLockStatus
+ 1), "");
177 lpLockStatus
->lpLockOwner
= (LPSTR
)(ULONG_PTR
)sizeof(QUERY_SERVICE_LOCK_STATUSA
);
179 lpLockStatus
->dwLockDuration
= 0;
182 /* Unlock the service database */