ReactOS  0.4.13-dev-650-g34bf247
lock.c
Go to the documentation of this file.
1 /*
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
7  */
8 
9 /* INCLUDES *****************************************************************/
10 
11 #include "services.h"
12 
13 #include <time.h>
14 
15 #define NDEBUG
16 #include <debug.h>
17 
18 /* GLOBALS *******************************************************************/
19 
20 /* The unique user service start lock of the SCM */
22 
23 
24 /* FUNCTIONS *****************************************************************/
25 
26 /*
27  * NOTE: IsServiceController is TRUE if locked by the
28  * Service Control Manager, and FALSE otherwise.
29  */
30 DWORD
31 ScmAcquireServiceStartLock(IN BOOL IsServiceController,
32  OUT LPSC_RPC_LOCK lpLock)
33 {
34  DWORD dwRequiredSize;
35  DWORD dwError = ERROR_SUCCESS;
36 
37  *lpLock = NULL;
38 
39  /* Lock the service database exclusively */
41 
42  if (pServiceStartLock != NULL)
43  {
45  goto done;
46  }
47 
48  /* Allocate a new lock for the database */
49  dwRequiredSize = sizeof(START_LOCK);
50 
51  if (!IsServiceController)
52  {
53  /* FIXME: dwRequiredSize += RtlLengthSid(UserSid <-- to be retrieved); */
54  }
55 
58  dwRequiredSize);
59  if (pServiceStartLock == NULL)
60  {
61  dwError = ERROR_NOT_ENOUGH_MEMORY;
62  goto done;
63  }
64 
67 
68  /* FIXME: Retrieve the owner SID. Use IsServiceController. */
70 
72 
73 done:
74  /* Unlock the service database */
76 
77  return dwError;
78 }
79 
80 
81 DWORD
83 {
84  PSTART_LOCK pStartLock;
85  DWORD dwError = ERROR_SUCCESS;
86 
87  if (lpLock == NULL)
89 
90  pStartLock = (PSTART_LOCK)*lpLock;
91 
92  if (pStartLock->Tag != LOCK_TAG)
94 
95  /* Lock the service database exclusively */
97 
98  /* Release the lock handle */
99  if ((pStartLock == pServiceStartLock) &&
100  (pServiceStartLock != NULL))
101  {
104  *lpLock = NULL;
105 
106  dwError = ERROR_SUCCESS;
107  }
108  else
109  {
110  dwError = ERROR_INVALID_SERVICE_LOCK;
111  }
112 
113  /* Unlock the service database */
115 
116  return dwError;
117 }
118 
119 
120 /*
121  * Helper functions for RQueryServiceLockStatusW() and
122  * RQueryServiceLockStatusA().
123  * We suppose that lpLockStatus points to a valid
124  * well-sized buffer.
125  */
126 VOID
128 {
129  /* Lock the service database shared */
131 
132  if (pServiceStartLock != NULL)
133  {
134  lpLockStatus->fIsLocked = TRUE;
135 
136  /* FIXME: Retrieve the owner name. */
137  lpLockStatus->lpLockOwner = NULL;
138 
139  lpLockStatus->dwLockDuration = (DWORD)time(NULL) - pServiceStartLock->TimeWhenLocked;
140  }
141  else
142  {
143  lpLockStatus->fIsLocked = FALSE;
144 
145  wcscpy((LPWSTR)(lpLockStatus + 1), L"");
146  lpLockStatus->lpLockOwner = (LPWSTR)(ULONG_PTR)sizeof(QUERY_SERVICE_LOCK_STATUSW);
147 
148  lpLockStatus->dwLockDuration = 0;
149  }
150 
151  /* Unlock the service database */
153 
154  return;
155 }
156 
157 
158 VOID
160 {
161  /* Lock the service database shared */
163 
164  if (pServiceStartLock != NULL)
165  {
166  lpLockStatus->fIsLocked = TRUE;
167 
168  /* FIXME: Retrieve the owner name. */
169  lpLockStatus->lpLockOwner = NULL;
170 
171  lpLockStatus->dwLockDuration = (DWORD)time(NULL) - pServiceStartLock->TimeWhenLocked;
172  }
173  else
174  {
175  lpLockStatus->fIsLocked = FALSE;
176 
177  strcpy((LPSTR)(lpLockStatus + 1), "");
178  lpLockStatus->lpLockOwner = (LPSTR)(ULONG_PTR)sizeof(QUERY_SERVICE_LOCK_STATUSA);
179 
180  lpLockStatus->dwLockDuration = 0;
181  }
182 
183  /* Unlock the service database */
185 
186  return;
187 }
188 
189 /* EOF */
#define IN
Definition: typedefs.h:38
#define TRUE
Definition: types.h:120
#define ERROR_SUCCESS
Definition: deptool.c:10
BOOL ScmLockDatabaseExclusive(VOID)
Definition: database.c:2310
BOOL ScmLockDatabaseShared(VOID)
Definition: database.c:2317
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
SC_RPC_LOCK * LPSC_RPC_LOCK
Definition: svcctl.idl:24
__u16 time
Definition: mkdosfs.c:366
char * LPSTR
Definition: xmlstorage.h:182
#define DWORD
Definition: nt_native.h:44
uint32_t ULONG_PTR
Definition: typedefs.h:63
DWORD ScmAcquireServiceStartLock(IN BOOL IsServiceController, OUT LPSC_RPC_LOCK lpLock)
Definition: lock.c:31
unsigned int BOOL
Definition: ntddk_ex.h:94
static PSTART_LOCK pServiceStartLock
Definition: lock.c:21
smooth NULL
Definition: ftsmooth.c:416
struct _START_LOCK * PSTART_LOCK
struct _START_LOCK START_LOCK
struct _QUERY_SERVICE_LOCK_STATUSW QUERY_SERVICE_LOCK_STATUSW
#define GetProcessHeap()
Definition: compat.h:395
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
unsigned long DWORD
Definition: ntddk_ex.h:95
#define ERROR_SERVICE_DATABASE_LOCKED
Definition: winerror.h:606
struct _SID * PSID
Definition: eventlog.c:35
DWORD ScmReleaseServiceStartLock(IN OUT LPSC_RPC_LOCK lpLock)
Definition: lock.c:82
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
static const WCHAR L[]
Definition: oid.c:1250
PSID LockOwnerSid
Definition: services.h:92
DWORD TimeWhenLocked
Definition: services.h:91
struct _QUERY_SERVICE_LOCK_STATUSA QUERY_SERVICE_LOCK_STATUSA
#define ERROR_INVALID_SERVICE_LOCK
Definition: winerror.h:622
#define HEAP_ZERO_MEMORY
Definition: compat.h:123
#define OUT
Definition: typedefs.h:39
VOID ScmUnlockDatabase(VOID)
Definition: database.c:2324
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
#define LOCK_TAG
Definition: services.h:86
VOID ScmQueryServiceLockStatusA(OUT LPQUERY_SERVICE_LOCK_STATUSA lpLockStatus)
Definition: lock.c:159
WCHAR * LPWSTR
Definition: xmlstorage.h:184
DWORD Tag
Definition: services.h:90
#define HeapFree(x, y, z)
Definition: compat.h:394
VOID ScmQueryServiceLockStatusW(OUT LPQUERY_SERVICE_LOCK_STATUSW lpLockStatus)
Definition: lock.c:127