- Return correct error. Spotted by Thomas.
[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/cid.c
6 * PURPOSE: Client ID (CID) management
7 *
8 * PROGRAMMERS: Thomas Weidenmueller <w3seek@reactos.com>
9 */
10
11 /* INCLUDES ******************************************************************/
12
13 #include <ntoskrnl.h>
14 #define NDEBUG
15 #include <internal/debug.h>
16
17 /* GLOBALS ******************************************************************/
18
19 PHANDLE_TABLE PspCidTable = NULL;
20
21 #define CID_FLAG_PROCESS 0x1
22 #define CID_FLAG_THREAD 0x2
23 #define CID_FLAGS_MASK (CID_FLAG_PROCESS | CID_FLAG_THREAD)
24
25 /* FUNCTIONS *****************************************************************/
26
27 VOID INIT_FUNCTION
28 PsInitClientIDManagment(VOID)
29 {
30 PspCidTable = ExCreateHandleTable(NULL);
31 ASSERT(PspCidTable);
32 }
33
34 NTSTATUS
35 PsCreateCidHandle(PVOID Object, POBJECT_TYPE ObjectType, PHANDLE Handle)
36 {
37 HANDLE_TABLE_ENTRY NewEntry;
38 LONG ExHandle;
39
40 PAGED_CODE();
41
42 NewEntry.u1.Object = Object;
43 if(ObjectType == PsThreadType)
44 NewEntry.u2.GrantedAccess = CID_FLAG_THREAD;
45 else if(ObjectType == PsProcessType)
46 NewEntry.u2.GrantedAccess = CID_FLAG_PROCESS;
47 else
48 {
49 DPRINT1("Can't create CID handles for %wZ objects\n", &ObjectType->Name);
50 KEBUGCHECK(0);
51 }
52
53 ExHandle = ExCreateHandle(PspCidTable,
54 &NewEntry);
55 if(ExHandle != EX_INVALID_HANDLE)
56 {
57 *Handle = EX_HANDLE_TO_HANDLE(ExHandle);
58 return STATUS_SUCCESS;
59 }
60
61 return STATUS_UNSUCCESSFUL;
62 }
63
64 NTSTATUS
65 PsDeleteCidHandle(HANDLE CidHandle, POBJECT_TYPE ObjectType)
66 {
67 PHANDLE_TABLE_ENTRY Entry;
68 LONG ExHandle = HANDLE_TO_EX_HANDLE(CidHandle);
69
70 PAGED_CODE();
71
72 KeEnterCriticalRegion();
73
74 Entry = ExMapHandleToPointer(PspCidTable,
75 ExHandle);
76 if(Entry != NULL)
77 {
78 if((ObjectType == PsThreadType && ((Entry->u2.GrantedAccess & CID_FLAGS_MASK) == CID_FLAG_THREAD)) ||
79 (ObjectType == PsProcessType && ((Entry->u2.GrantedAccess & CID_FLAGS_MASK) == CID_FLAG_PROCESS)))
80 {
81 ExDestroyHandleByEntry(PspCidTable,
82 Entry,
83 ExHandle);
84 KeLeaveCriticalRegion();
85 return STATUS_SUCCESS;
86 }
87 else
88 {
89 ExUnlockHandleTableEntry(PspCidTable,
90 Entry);
91 KeLeaveCriticalRegion();
92 return STATUS_OBJECT_TYPE_MISMATCH;
93 }
94 }
95 KeLeaveCriticalRegion();
96 return STATUS_INVALID_HANDLE;
97 }
98
99 PHANDLE_TABLE_ENTRY
100 PsLookupCidHandle(HANDLE CidHandle, POBJECT_TYPE ObjectType, PVOID *Object)
101 {
102 PHANDLE_TABLE_ENTRY Entry;
103
104 PAGED_CODE();
105
106 KeEnterCriticalRegion();
107
108 Entry = ExMapHandleToPointer(PspCidTable,
109 HANDLE_TO_EX_HANDLE(CidHandle));
110 if(Entry != NULL)
111 {
112 if((ObjectType == PsProcessType && ((Entry->u2.GrantedAccess & CID_FLAGS_MASK) == CID_FLAG_PROCESS)) ||
113 (ObjectType == PsThreadType && ((Entry->u2.GrantedAccess & CID_FLAGS_MASK) == CID_FLAG_THREAD)))
114 {
115 *Object = Entry->u1.Object;
116 return Entry;
117 }
118 else
119 {
120 DPRINT1("CID Obj type mismatch handle 0x%x %wZ vs 0x%x\n", CidHandle,
121 &ObjectType->Name, Entry->u2.GrantedAccess);
122 ExUnlockHandleTableEntry(PspCidTable,
123 Entry);
124 }
125 }
126
127 KeLeaveCriticalRegion();
128
129 return NULL;
130 }
131
132 /*
133 * @implemented
134 */
135 NTSTATUS STDCALL
136 PsLookupProcessThreadByCid(IN PCLIENT_ID Cid,
137 OUT PEPROCESS *Process OPTIONAL,
138 OUT PETHREAD *Thread)
139 {
140 PHANDLE_TABLE_ENTRY CidEntry;
141 PETHREAD FoundThread;
142 NTSTATUS Status = STATUS_INVALID_CID;
143
144 PAGED_CODE();
145
146 ASSERT(Thread);
147 ASSERT(Cid);
148
149 CidEntry = PsLookupCidHandle(Cid->UniqueThread, PsThreadType, (PVOID*)&FoundThread);
150 if(CidEntry != NULL)
151 {
152 ObReferenceObject(FoundThread);
153
154 PsUnlockCidHandle(CidEntry);
155
156 if(Process != NULL)
157 {
158 *Process = FoundThread->ThreadsProcess;
159 }
160 *Thread = FoundThread;
161 Status = STATUS_SUCCESS;
162 }
163
164 return Status;
165 }
166
167
168 /*
169 * @implemented
170 */
171 NTSTATUS STDCALL
172 PsLookupThreadByThreadId(IN HANDLE ThreadId,
173 OUT PETHREAD *Thread)
174 {
175 PHANDLE_TABLE_ENTRY CidEntry;
176 PETHREAD FoundThread;
177 NTSTATUS Status = STATUS_INVALID_CID;
178
179 PAGED_CODE();
180
181 ASSERT(Thread);
182
183 CidEntry = PsLookupCidHandle(ThreadId, PsThreadType, (PVOID*)&FoundThread);
184 if(CidEntry != NULL)
185 {
186 ObReferenceObject(FoundThread);
187
188 PsUnlockCidHandle(CidEntry);
189
190 *Thread = FoundThread;
191 Status = STATUS_SUCCESS;
192 }
193
194 return Status;
195 }
196
197 VOID
198 PsUnlockCidHandle(PHANDLE_TABLE_ENTRY CidEntry)
199 {
200 PAGED_CODE();
201
202 ExUnlockHandleTableEntry(PspCidTable,
203 CidEntry);
204 KeLeaveCriticalRegion();
205 }
206
207 /* EOF */