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
,
161 RtlEnterCriticalSection(&ProcessData
->HandleTableLock
);
163 for (i
= 0; i
< ProcessData
->HandleTableSize
; i
++)
165 if (ProcessData
->HandleTable
[i
].Object
== NULL
)
170 if (i
>= ProcessData
->HandleTableSize
)
172 Block
= RtlAllocateHeap(CsrssApiHeap
,
174 (ProcessData
->HandleTableSize
+ 64) * sizeof(CSRSS_HANDLE
));
177 RtlLeaveCriticalSection(&ProcessData
->HandleTableLock
);
178 return(STATUS_UNSUCCESSFUL
);
181 ProcessData
->HandleTable
,
182 ProcessData
->HandleTableSize
* sizeof(CSRSS_HANDLE
));
183 Block
= _InterlockedExchangePointer((void* volatile)&ProcessData
->HandleTable
, Block
);
184 RtlFreeHeap( CsrssApiHeap
, 0, Block
);
185 ProcessData
->HandleTableSize
+= 64;
187 ProcessData
->HandleTable
[i
].Object
= Object
;
188 ProcessData
->HandleTable
[i
].Access
= Access
;
189 ProcessData
->HandleTable
[i
].Inheritable
= Inheritable
;
190 *Handle
= UlongToHandle((i
<< 2) | 0x3);
191 _InterlockedIncrement( &Object
->ReferenceCount
);
192 RtlLeaveCriticalSection(&ProcessData
->HandleTableLock
);
193 return(STATUS_SUCCESS
);
198 CsrDuplicateHandleTable(
199 PCSRSS_PROCESS_DATA SourceProcessData
,
200 PCSRSS_PROCESS_DATA TargetProcessData
)
204 if (TargetProcessData
->HandleTableSize
)
206 return STATUS_INVALID_PARAMETER
;
209 RtlEnterCriticalSection(&SourceProcessData
->HandleTableLock
);
211 /* we are called from CreateProcessData, it isn't necessary to lock the target process data */
213 TargetProcessData
->HandleTable
= RtlAllocateHeap(CsrssApiHeap
,
215 SourceProcessData
->HandleTableSize
216 * sizeof(CSRSS_HANDLE
));
217 if (TargetProcessData
->HandleTable
== NULL
)
219 RtlLeaveCriticalSection(&SourceProcessData
->HandleTableLock
);
220 return(STATUS_UNSUCCESSFUL
);
222 TargetProcessData
->HandleTableSize
= SourceProcessData
->HandleTableSize
;
223 for (i
= 0; i
< SourceProcessData
->HandleTableSize
; i
++)
225 if (SourceProcessData
->HandleTable
[i
].Object
!= NULL
&&
226 SourceProcessData
->HandleTable
[i
].Inheritable
)
228 TargetProcessData
->HandleTable
[i
] = SourceProcessData
->HandleTable
[i
];
229 _InterlockedIncrement( &SourceProcessData
->HandleTable
[i
].Object
->ReferenceCount
);
232 RtlLeaveCriticalSection(&SourceProcessData
->HandleTableLock
);
233 return(STATUS_SUCCESS
);
239 PCSRSS_PROCESS_DATA ProcessData
,
242 ULONG_PTR h
= (ULONG_PTR
)Handle
>> 2;
244 if (h
>= ProcessData
->HandleTableSize
||
245 ProcessData
->HandleTable
[h
].Object
== NULL
)
247 return STATUS_INVALID_HANDLE
;
250 return STATUS_SUCCESS
;