migrate substitution keywords to SVN
[reactos.git] / reactos / ntoskrnl / ps / cid.c
1 /* $Id$
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/ps/clientid.c
6 * PURPOSE: Client ID (CID) management
7 * PROGRAMMER: Thomas Weidenmueller <w3seek@reactos.com>
8 * REVISION HISTORY:
9 * 9/20/2004: Created
10 */
11
12 /* INCLUDES ******************************************************************/
13
14 #include <ntoskrnl.h>
15 #define NDEBUG
16 #include <internal/debug.h>
17
18 /* GLOBALS ******************************************************************/
19
20 /*
21 * FIXME - use a global handle table instead!
22 */
23
24 KSPIN_LOCK CidLock;
25 LIST_ENTRY CidHead;
26 KEVENT CidReleaseEvent;
27 LONG CidCounter = 0;
28 LARGE_INTEGER ShortDelay, LongDelay;
29
30 #define TAG_CIDOBJECT TAG('C', 'I', 'D', 'O')
31
32 /* FUNCTIONS *****************************************************************/
33
34 VOID INIT_FUNCTION
35 PsInitClientIDManagment(VOID)
36 {
37 InitializeListHead(&CidHead);
38 KeInitializeSpinLock(&CidLock);
39 KeInitializeEvent(&CidReleaseEvent, SynchronizationEvent, FALSE);
40 ShortDelay.QuadPart = -100LL;
41 LongDelay.QuadPart = -100000LL;
42 }
43
44 VOID
45 PspReferenceCidObject(PCID_OBJECT Object)
46 {
47 InterlockedIncrement(&Object->ref);
48 }
49
50 VOID
51 PspDereferenceCidObject(PCID_OBJECT Object)
52 {
53 if(InterlockedDecrement(&Object->ref) == 0)
54 {
55 ExFreePool(Object);
56 }
57 }
58
59 NTSTATUS
60 PsCreateCidHandle(PVOID Object, POBJECT_TYPE ObjectType, PHANDLE Handle)
61 {
62 KIRQL oldIrql;
63 PCID_OBJECT cido = ExAllocatePoolWithTag(NonPagedPool,
64 sizeof(CID_OBJECT),
65 TAG_CIDOBJECT);
66 if(cido != NULL)
67 {
68 cido->ref = 1;
69 ExInitializeFastMutex(&cido->Lock);
70 cido->Obj.Object = Object;
71
72 KeAcquireSpinLock(&CidLock, &oldIrql);
73 cido->Handle = (HANDLE)(++CidCounter);
74 InsertTailList(&CidHead, &cido->Entry);
75 KeReleaseSpinLock(&CidLock, oldIrql);
76
77 *Handle = cido->Handle;
78 return STATUS_SUCCESS;
79 }
80
81 return STATUS_INSUFFICIENT_RESOURCES;
82 }
83
84 NTSTATUS
85 PsDeleteCidHandle(HANDLE CidHandle, POBJECT_TYPE ObjectType)
86 {
87 PCID_OBJECT cido, Found = NULL;
88 PLIST_ENTRY Current;
89 KIRQL oldIrql;
90
91 if(CidHandle == NULL)
92 {
93 return STATUS_INVALID_PARAMETER;
94 }
95
96 KeAcquireSpinLock(&CidLock, &oldIrql);
97 Current = CidHead.Flink;
98 while(Current != &CidHead)
99 {
100 cido = CONTAINING_RECORD(Current, CID_OBJECT, Entry);
101 if(cido->Handle == CidHandle)
102 {
103 RemoveEntryList(&cido->Entry);
104 cido->Handle = NULL;
105 Found = cido;
106 break;
107 }
108 Current = Current->Flink;
109 }
110 KeReleaseSpinLock(&CidLock, oldIrql);
111
112 if(Found != NULL)
113 {
114 PspDereferenceCidObject(Found);
115 return STATUS_SUCCESS;
116 }
117
118 return STATUS_UNSUCCESSFUL;
119 }
120
121 PCID_OBJECT
122 PsLockCidHandle(HANDLE CidHandle, POBJECT_TYPE ObjectType)
123 {
124 PCID_OBJECT cido, Found = NULL;
125 PLIST_ENTRY Current;
126 KIRQL oldIrql;
127
128 if(CidHandle == NULL)
129 {
130 return NULL;
131 }
132
133 KeAcquireSpinLock(&CidLock, &oldIrql);
134 Current = CidHead.Flink;
135 while(Current != &CidHead)
136 {
137 cido = CONTAINING_RECORD(Current, CID_OBJECT, Entry);
138 if(cido->Handle == CidHandle)
139 {
140 Found = cido;
141 PspReferenceCidObject(Found);
142 break;
143 }
144 Current = Current->Flink;
145 }
146 KeReleaseSpinLock(&CidLock, oldIrql);
147
148 if(Found != NULL)
149 {
150 ExAcquireFastMutex(&Found->Lock);
151 }
152
153 return Found;
154 }
155
156 VOID
157 PsUnlockCidObject(PCID_OBJECT CidObject)
158 {
159 ExReleaseFastMutex(&CidObject->Lock);
160 PspDereferenceCidObject(CidObject);
161 }
162
163 /* EOF */