1 /* $Id: sdcache.c,v 1.1 2004/07/16 17:19:15 ekohl Exp $
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/ps/kill.c
6 * PURPOSE: Terminating a thread
7 * PROGRAMMER: David Welch (welch@cwcom.net)
12 /* INCLUDES *****************************************************************/
14 #include <ddk/ntddk.h>
15 #include <internal/ob.h>
18 #include <internal/debug.h>
21 /* TYPES ********************************************************************/
23 typedef struct _SD_CACHE_ENTRY
29 } SD_CACHE_ENTRY
, *PSD_CACHE_ENTRY
;
32 /* GLOBALS ******************************************************************/
34 PLIST_ENTRY ObpSdCache
;
35 KSPIN_LOCK ObpSdCacheSpinLock
;
39 #define SD_CACHE_ENTRIES 0x100
41 /* FUNCTIONS ****************************************************************/
48 ObpSdCache
= ExAllocatePool(NonPagedPool
,
49 SD_CACHE_ENTRIES
* sizeof(LIST_ENTRY
));
50 if (ObpSdCache
== NULL
)
52 return STATUS_INSUFFICIENT_RESOURCES
;
55 for (i
= 0; i
< SD_CACHE_ENTRIES
; i
++)
57 InitializeListHead(&ObpSdCache
[i
]);
60 KeInitializeSpinLock(&ObpSdCacheSpinLock
);
62 return STATUS_SUCCESS
;
69 KeAcquireSpinLock(&ObpSdCacheSpinLock
,
75 ObpSdCacheUnlock(VOID
)
77 KeReleaseSpinLock(&ObpSdCacheSpinLock
,
92 for (i
= 0; i
< Length
; i
++)
103 ObpHashSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor
)
114 RtlGetOwnerSecurityDescriptor(SecurityDescriptor
,
118 RtlGetGroupSecurityDescriptor(SecurityDescriptor
,
122 RtlGetDaclSecurityDescriptor(SecurityDescriptor
,
127 RtlGetSaclSecurityDescriptor(SecurityDescriptor
,
135 Value
+= ObpHash(Owner
, RtlLengthSid(Owner
));
140 Value
+= ObpHash(Group
, RtlLengthSid(Group
));
143 if (DaclPresent
== TRUE
&& Dacl
!= NULL
)
145 Value
+= ObpHash(Dacl
, Dacl
->AclSize
);
148 if (SaclPresent
== TRUE
&& Sacl
!= NULL
)
150 Value
+= ObpHash(Sacl
, Sacl
->AclSize
);
157 static PSD_CACHE_ENTRY
158 ObpCreateCacheEntry(IN PSECURITY_DESCRIPTOR SecurityDescriptor
,
161 OUT PSECURITY_DESCRIPTOR
*NewSD
)
163 PSECURITY_DESCRIPTOR Sd
;
164 PSD_CACHE_ENTRY CacheEntry
;
167 DPRINT("ObpCreateCacheEntry() called\n");
169 Length
= RtlLengthSecurityDescriptor(SecurityDescriptor
);
171 CacheEntry
= ExAllocatePool(NonPagedPool
,
172 sizeof(SD_CACHE_ENTRY
) + Length
);
173 if (CacheEntry
== NULL
)
175 DPRINT1("ExAllocatePool() failed\n");
179 CacheEntry
->HashValue
= HashValue
;
180 CacheEntry
->Index
= Index
;
181 CacheEntry
->RefCount
= 1;
183 Sd
= (PSECURITY_DESCRIPTOR
)(CacheEntry
+ 1);
190 DPRINT("ObpCreateCacheEntry() done\n");
197 ObpCompareSecurityDescriptors(IN PSECURITY_DESCRIPTOR Sd1
,
198 IN PSECURITY_DESCRIPTOR Sd2
)
203 Length1
= RtlLengthSecurityDescriptor(Sd1
);
204 Length2
= RtlLengthSecurityDescriptor(Sd2
);
205 if (Length1
!= Length2
)
208 if (RtlCompareMemory(Sd1
, Sd2
, Length1
) != Length1
)
216 ObpAddSecurityDescriptor(IN PSECURITY_DESCRIPTOR SourceSD
,
217 OUT PSECURITY_DESCRIPTOR
*DestinationSD
)
219 PSECURITY_DESCRIPTOR Sd
;
220 PLIST_ENTRY CurrentEntry
;
221 PSD_CACHE_ENTRY CacheEntry
;
226 DPRINT("ObpAddSecurityDescriptor() called\n");
228 HashValue
= ObpHashSecurityDescriptor(SourceSD
);
229 Index
= HashValue
& 0xFF;
233 if (!IsListEmpty(&ObpSdCache
[Index
]))
235 CurrentEntry
= ObpSdCache
[Index
].Flink
;
236 while (CurrentEntry
!= &ObpSdCache
[Index
])
238 CacheEntry
= CONTAINING_RECORD(CurrentEntry
,
241 Sd
= (PSECURITY_DESCRIPTOR
)(CacheEntry
+ 1);
243 if (CacheEntry
->HashValue
== HashValue
&&
244 ObpCompareSecurityDescriptors(SourceSD
, Sd
))
246 CacheEntry
->RefCount
++;
247 DPRINT("RefCount %lu\n", CacheEntry
->RefCount
);
252 DPRINT("ObpAddSecurityDescriptor() done\n");
254 return STATUS_SUCCESS
;
257 CurrentEntry
= CurrentEntry
->Flink
;
261 CacheEntry
= ObpCreateCacheEntry(SourceSD
,
265 if (CacheEntry
== NULL
)
267 DPRINT1("ObpCreateCacheEntry() failed\n");
268 Status
= STATUS_INSUFFICIENT_RESOURCES
;
272 DPRINT("RefCount 1\n");
273 InsertTailList(&ObpSdCache
[Index
], &CacheEntry
->ListEntry
);
274 Status
= STATUS_SUCCESS
;
279 DPRINT("ObpAddSecurityDescriptor() done\n");
286 ObpRemoveSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor
)
288 PSD_CACHE_ENTRY CacheEntry
;
290 DPRINT("ObpRemoveSecurityDescriptor() called\n");
294 CacheEntry
= (PSD_CACHE_ENTRY
)((ULONG_PTR
)SecurityDescriptor
- sizeof(SD_CACHE_ENTRY
));
296 CacheEntry
->RefCount
--;
297 DPRINT("RefCount %lu\n", CacheEntry
->RefCount
);
298 if (CacheEntry
->RefCount
== 0)
300 DPRINT("Remove cache entry\n");
301 RemoveEntryList(&CacheEntry
->ListEntry
);
302 ExFreePool(CacheEntry
);
307 DPRINT("ObpRemoveSecurityDescriptor() done\n");
309 return STATUS_SUCCESS
;