3 * reactos/subsys/csrss/api/handle.c
5 * CSRSS handle functions
7 * ReactOS Operating System
10 /* INCLUDES ******************************************************************/
17 /* FUNCTIONS *****************************************************************/
19 static unsigned ObjectDefinitionsCount
= 0;
20 static PCSRSS_OBJECT_DEFINITION ObjectDefinitions
= NULL
;
24 CsrIsConsoleHandle(HANDLE Handle
)
26 return ((ULONG_PTR
)Handle
& 0x10000003) == 0x3;
32 CsrRegisterObjectDefinitions(
33 PCSRSS_OBJECT_DEFINITION NewDefinitions
)
36 PCSRSS_OBJECT_DEFINITION Scan
;
37 PCSRSS_OBJECT_DEFINITION New
;
40 for (Scan
= NewDefinitions
; 0 != Scan
->Type
; Scan
++)
45 New
= RtlAllocateHeap(CsrssApiHeap
,
47 (ObjectDefinitionsCount
+ NewCount
)
48 * sizeof(CSRSS_OBJECT_DEFINITION
));
51 DPRINT1("Unable to allocate memory\n");
52 return STATUS_NO_MEMORY
;
55 if (0 != ObjectDefinitionsCount
)
59 ObjectDefinitionsCount
* sizeof(CSRSS_OBJECT_DEFINITION
));
60 RtlFreeHeap(CsrssApiHeap
, 0, ObjectDefinitions
);
63 RtlCopyMemory(New
+ ObjectDefinitionsCount
,
65 NewCount
* sizeof(CSRSS_OBJECT_DEFINITION
));
66 ObjectDefinitions
= New
;
67 ObjectDefinitionsCount
+= NewCount
;
69 return STATUS_SUCCESS
;
75 PCSRSS_PROCESS_DATA ProcessData
,
80 ULONG_PTR h
= (ULONG_PTR
)Handle
>> 2;
82 DPRINT("CsrGetObject, Object: %x, %x, %x\n",
83 Object
, Handle
, ProcessData
? ProcessData
->HandleTableSize
: 0);
85 RtlEnterCriticalSection(&ProcessData
->HandleTableLock
);
86 if (!CsrIsConsoleHandle(Handle
) || h
>= ProcessData
->HandleTableSize
87 || (*Object
= ProcessData
->HandleTable
[h
].Object
) == NULL
88 || ~ProcessData
->HandleTable
[h
].Access
& Access
)
90 DPRINT1("CsrGetObject returning invalid handle (%x)\n", Handle
);
91 RtlLeaveCriticalSection(&ProcessData
->HandleTableLock
);
92 return STATUS_INVALID_HANDLE
;
94 _InterlockedIncrement(&(*Object
)->ReferenceCount
);
95 RtlLeaveCriticalSection(&ProcessData
->HandleTableLock
);
96 // DbgPrint( "CsrGetObject returning\n" );
97 return STATUS_SUCCESS
;
103 CsrReleaseObjectByPointer(
109 if (_InterlockedDecrement(&Object
->ReferenceCount
) == 0)
111 for (DefIndex
= 0; DefIndex
< ObjectDefinitionsCount
; DefIndex
++)
113 if (Object
->Type
== ObjectDefinitions
[DefIndex
].Type
)
115 (ObjectDefinitions
[DefIndex
].CsrCleanupObjectProc
)(Object
);
116 return STATUS_SUCCESS
;
120 DPRINT1("CSR: Error: releasing unknown object type 0x%x", Object
->Type
);
123 return STATUS_SUCCESS
;
130 PCSRSS_PROCESS_DATA ProcessData
,
133 ULONG_PTR h
= (ULONG_PTR
)Handle
>> 2;
136 RtlEnterCriticalSection(&ProcessData
->HandleTableLock
);
137 if (h
>= ProcessData
->HandleTableSize
138 || (Object
= ProcessData
->HandleTable
[h
].Object
) == NULL
)
140 RtlLeaveCriticalSection(&ProcessData
->HandleTableLock
);
141 return STATUS_INVALID_HANDLE
;
143 ProcessData
->HandleTable
[h
].Object
= NULL
;
144 RtlLeaveCriticalSection(&ProcessData
->HandleTableLock
);
146 return CsrReleaseObjectByPointer(Object
);
152 PCSRSS_PROCESS_DATA ProcessData
)
154 ULONG HandleTableSize
;
155 PCSRSS_HANDLE HandleTable
;
156 PCSRSS_CONSOLE Console
;
159 /* Close all console handles and detach process from console */
160 RtlEnterCriticalSection(&ProcessData
->HandleTableLock
);
161 HandleTableSize
= ProcessData
->HandleTableSize
;
162 HandleTable
= ProcessData
->HandleTable
;
163 Console
= ProcessData
->Console
;
164 ProcessData
->HandleTableSize
= 0;
165 ProcessData
->HandleTable
= NULL
;
166 ProcessData
->Console
= NULL
;
167 RtlLeaveCriticalSection(&ProcessData
->HandleTableLock
);
169 for (i
= 0; i
< HandleTableSize
; i
++)
171 if (HandleTable
[i
].Object
!= NULL
)
172 CsrReleaseObjectByPointer(HandleTable
[i
].Object
);
174 RtlFreeHeap(CsrssApiHeap
, 0, HandleTable
);
178 RtlEnterCriticalSection((PRTL_CRITICAL_SECTION
)&Console
->Header
.Lock
);
179 RemoveEntryList(&ProcessData
->ProcessEntry
);
180 RtlLeaveCriticalSection((PRTL_CRITICAL_SECTION
)&Console
->Header
.Lock
);
181 CsrReleaseObjectByPointer(&Console
->Header
);
182 return STATUS_SUCCESS
;
185 return STATUS_INVALID_PARAMETER
;
191 PCSRSS_PROCESS_DATA ProcessData
,
200 RtlEnterCriticalSection(&ProcessData
->HandleTableLock
);
202 for (i
= 0; i
< ProcessData
->HandleTableSize
; i
++)
204 if (ProcessData
->HandleTable
[i
].Object
== NULL
)
209 if (i
>= ProcessData
->HandleTableSize
)
211 Block
= RtlAllocateHeap(CsrssApiHeap
,
213 (ProcessData
->HandleTableSize
+ 64) * sizeof(CSRSS_HANDLE
));
216 RtlLeaveCriticalSection(&ProcessData
->HandleTableLock
);
217 return(STATUS_UNSUCCESSFUL
);
220 ProcessData
->HandleTable
,
221 ProcessData
->HandleTableSize
* sizeof(CSRSS_HANDLE
));
222 Block
= _InterlockedExchangePointer((void* volatile)&ProcessData
->HandleTable
, Block
);
223 RtlFreeHeap( CsrssApiHeap
, 0, Block
);
224 ProcessData
->HandleTableSize
+= 64;
226 ProcessData
->HandleTable
[i
].Object
= Object
;
227 ProcessData
->HandleTable
[i
].Access
= Access
;
228 ProcessData
->HandleTable
[i
].Inheritable
= Inheritable
;
229 *Handle
= UlongToHandle((i
<< 2) | 0x3);
230 _InterlockedIncrement( &Object
->ReferenceCount
);
231 RtlLeaveCriticalSection(&ProcessData
->HandleTableLock
);
232 return(STATUS_SUCCESS
);
237 CsrDuplicateHandleTable(
238 PCSRSS_PROCESS_DATA SourceProcessData
,
239 PCSRSS_PROCESS_DATA TargetProcessData
)
243 if (TargetProcessData
->HandleTableSize
)
245 return STATUS_INVALID_PARAMETER
;
248 RtlEnterCriticalSection(&SourceProcessData
->HandleTableLock
);
250 /* we are called from CreateProcessData, it isn't necessary to lock the target process data */
252 TargetProcessData
->HandleTable
= RtlAllocateHeap(CsrssApiHeap
,
254 SourceProcessData
->HandleTableSize
255 * sizeof(CSRSS_HANDLE
));
256 if (TargetProcessData
->HandleTable
== NULL
)
258 RtlLeaveCriticalSection(&SourceProcessData
->HandleTableLock
);
259 return(STATUS_UNSUCCESSFUL
);
261 TargetProcessData
->HandleTableSize
= SourceProcessData
->HandleTableSize
;
262 for (i
= 0; i
< SourceProcessData
->HandleTableSize
; i
++)
264 if (SourceProcessData
->HandleTable
[i
].Object
!= NULL
&&
265 SourceProcessData
->HandleTable
[i
].Inheritable
)
267 TargetProcessData
->HandleTable
[i
] = SourceProcessData
->HandleTable
[i
];
268 _InterlockedIncrement( &SourceProcessData
->HandleTable
[i
].Object
->ReferenceCount
);
271 RtlLeaveCriticalSection(&SourceProcessData
->HandleTableLock
);
272 return(STATUS_SUCCESS
);
278 PCSRSS_PROCESS_DATA ProcessData
,
281 ULONG_PTR h
= (ULONG_PTR
)Handle
>> 2;
283 if (h
>= ProcessData
->HandleTableSize
||
284 ProcessData
->HandleTable
[h
].Object
== NULL
)
286 return STATUS_INVALID_HANDLE
;
289 return STATUS_SUCCESS
;