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
;
23 CsrIsConsoleHandle(HANDLE Handle
)
25 return ((ULONG_PTR
)Handle
& 0x10000003) == 0x3;
30 CsrRegisterObjectDefinitions(PCSRSS_OBJECT_DEFINITION NewDefinitions
)
33 PCSRSS_OBJECT_DEFINITION Scan
;
34 PCSRSS_OBJECT_DEFINITION New
;
37 for (Scan
= NewDefinitions
; 0 != Scan
->Type
; Scan
++)
42 New
= RtlAllocateHeap(CsrssApiHeap
, 0,
43 (ObjectDefinitionsCount
+ NewCount
)
44 * sizeof(CSRSS_OBJECT_DEFINITION
));
47 DPRINT1("Unable to allocate memory\n");
48 return STATUS_NO_MEMORY
;
50 if (0 != ObjectDefinitionsCount
)
52 RtlCopyMemory(New
, ObjectDefinitions
,
53 ObjectDefinitionsCount
* sizeof(CSRSS_OBJECT_DEFINITION
));
54 RtlFreeHeap(CsrssApiHeap
, 0, ObjectDefinitions
);
56 RtlCopyMemory(New
+ ObjectDefinitionsCount
, NewDefinitions
,
57 NewCount
* sizeof(CSRSS_OBJECT_DEFINITION
));
58 ObjectDefinitions
= New
;
59 ObjectDefinitionsCount
+= NewCount
;
61 return STATUS_SUCCESS
;
64 NTSTATUS WINAPI
CsrGetObject( PCSRSS_PROCESS_DATA ProcessData
, HANDLE Handle
, Object_t
**Object
, DWORD Access
)
66 ULONG_PTR h
= (ULONG_PTR
)Handle
>> 2;
67 DPRINT("CsrGetObject, Object: %x, %x, %x\n", Object
, Handle
, ProcessData
? ProcessData
->HandleTableSize
: 0);
69 RtlEnterCriticalSection(&ProcessData
->HandleTableLock
);
70 if (!CsrIsConsoleHandle(Handle
) || h
>= ProcessData
->HandleTableSize
71 || (*Object
= ProcessData
->HandleTable
[h
].Object
) == NULL
72 || ~ProcessData
->HandleTable
[h
].Access
& Access
)
74 DPRINT1("CsrGetObject returning invalid handle (%x)\n", Handle
);
75 RtlLeaveCriticalSection(&ProcessData
->HandleTableLock
);
76 return STATUS_INVALID_HANDLE
;
78 _InterlockedIncrement(&(*Object
)->ReferenceCount
);
79 RtlLeaveCriticalSection(&ProcessData
->HandleTableLock
);
80 // DbgPrint( "CsrGetObject returning\n" );
81 return STATUS_SUCCESS
;
86 CsrReleaseObjectByPointer(Object_t
*Object
)
91 if (_InterlockedDecrement(&Object
->ReferenceCount
) == 0)
93 for (DefIndex
= 0; DefIndex
< ObjectDefinitionsCount
; DefIndex
++)
95 if (Object
->Type
== ObjectDefinitions
[DefIndex
].Type
)
97 (ObjectDefinitions
[DefIndex
].CsrCleanupObjectProc
)(Object
);
98 return STATUS_SUCCESS
;
102 DPRINT1("CSR: Error: releasing unknown object type 0x%x", Object
->Type
);
105 return STATUS_SUCCESS
;
110 CsrReleaseObject(PCSRSS_PROCESS_DATA ProcessData
,
113 ULONG_PTR h
= (ULONG_PTR
)Handle
>> 2;
116 RtlEnterCriticalSection(&ProcessData
->HandleTableLock
);
117 if (h
>= ProcessData
->HandleTableSize
118 || (Object
= ProcessData
->HandleTable
[h
].Object
) == NULL
)
120 RtlLeaveCriticalSection(&ProcessData
->HandleTableLock
);
121 return STATUS_INVALID_HANDLE
;
123 ProcessData
->HandleTable
[h
].Object
= NULL
;
124 RtlLeaveCriticalSection(&ProcessData
->HandleTableLock
);
126 return CsrReleaseObjectByPointer(Object
);
129 NTSTATUS WINAPI
CsrInsertObject(PCSRSS_PROCESS_DATA ProcessData
,
138 RtlEnterCriticalSection(&ProcessData
->HandleTableLock
);
140 for (i
= 0; i
< ProcessData
->HandleTableSize
; i
++)
142 if (ProcessData
->HandleTable
[i
].Object
== NULL
)
147 if (i
>= ProcessData
->HandleTableSize
)
149 Block
= RtlAllocateHeap(CsrssApiHeap
,
151 (ProcessData
->HandleTableSize
+ 64) * sizeof(CSRSS_HANDLE
));
154 RtlLeaveCriticalSection(&ProcessData
->HandleTableLock
);
155 return(STATUS_UNSUCCESSFUL
);
158 ProcessData
->HandleTable
,
159 ProcessData
->HandleTableSize
* sizeof(CSRSS_HANDLE
));
160 Block
= _InterlockedExchangePointer((volatile void*)&ProcessData
->HandleTable
, Block
);
161 RtlFreeHeap( CsrssApiHeap
, 0, Block
);
162 ProcessData
->HandleTableSize
+= 64;
164 ProcessData
->HandleTable
[i
].Object
= Object
;
165 ProcessData
->HandleTable
[i
].Access
= Access
;
166 ProcessData
->HandleTable
[i
].Inheritable
= Inheritable
;
167 *Handle
= (HANDLE
)(ULONG_PTR
)((i
<< 2) | 0x3);
168 _InterlockedIncrement( &Object
->ReferenceCount
);
169 RtlLeaveCriticalSection(&ProcessData
->HandleTableLock
);
170 return(STATUS_SUCCESS
);
173 NTSTATUS WINAPI
CsrDuplicateHandleTable(PCSRSS_PROCESS_DATA SourceProcessData
,
174 PCSRSS_PROCESS_DATA TargetProcessData
)
178 if (TargetProcessData
->HandleTableSize
)
180 return STATUS_INVALID_PARAMETER
;
183 RtlEnterCriticalSection(&SourceProcessData
->HandleTableLock
);
185 /* we are called from CreateProcessData, it isn't necessary to lock the target process data */
187 TargetProcessData
->HandleTable
= RtlAllocateHeap(CsrssApiHeap
,
189 SourceProcessData
->HandleTableSize
* sizeof(CSRSS_HANDLE
));
190 if (TargetProcessData
->HandleTable
== NULL
)
192 RtlLeaveCriticalSection(&SourceProcessData
->HandleTableLock
);
193 return(STATUS_UNSUCCESSFUL
);
195 TargetProcessData
->HandleTableSize
= SourceProcessData
->HandleTableSize
;
196 for (i
= 0; i
< SourceProcessData
->HandleTableSize
; i
++)
198 if (SourceProcessData
->HandleTable
[i
].Object
!= NULL
199 && SourceProcessData
->HandleTable
[i
].Inheritable
)
201 TargetProcessData
->HandleTable
[i
] = SourceProcessData
->HandleTable
[i
];
202 _InterlockedIncrement( &SourceProcessData
->HandleTable
[i
].Object
->ReferenceCount
);
205 RtlLeaveCriticalSection(&SourceProcessData
->HandleTableLock
);
206 return(STATUS_SUCCESS
);
209 NTSTATUS WINAPI
CsrVerifyObject( PCSRSS_PROCESS_DATA ProcessData
, HANDLE Handle
)
211 ULONG_PTR h
= (ULONG_PTR
)Handle
>> 2;
213 if (h
>= ProcessData
->HandleTableSize
214 || ProcessData
->HandleTable
[h
].Object
== NULL
)
216 return STATUS_INVALID_HANDLE
;
219 return STATUS_SUCCESS
;