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
)Handle
) & 0x10000003) == 0x3) ? TRUE
: FALSE
;
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 STDCALL
CsrGetObject( PCSRSS_PROCESS_DATA ProcessData
, HANDLE Handle
, Object_t
**Object
)
66 ULONG h
= (((ULONG
)Handle
) >> 2) - 1;
67 DPRINT("CsrGetObject, Object: %x, %x, %x\n", Object
, Handle
, ProcessData
? ProcessData
->HandleTableSize
: 0);
69 if (ProcessData
== NULL
)
71 return STATUS_INVALID_PARAMETER
;
73 if (!CsrIsConsoleHandle(Handle
) || ProcessData
->HandleTableSize
<= h
)
75 DPRINT1("CsrGetObject returning invalid handle (%x)\n", Handle
);
76 return STATUS_INVALID_HANDLE
;
78 *Object
= ProcessData
->HandleTable
[h
];
79 // DbgPrint( "CsrGetObject returning\n" );
80 return *Object
? STATUS_SUCCESS
: STATUS_INVALID_HANDLE
;
85 CsrReleaseObjectByPointer(Object_t
*Object
)
91 if (InterlockedDecrement(&Object
->ReferenceCount
) == 0)
94 for (DefIndex
= 0; ! Found
&& DefIndex
< ObjectDefinitionsCount
; DefIndex
++)
96 if (Object
->Type
== ObjectDefinitions
[DefIndex
].Type
)
98 (ObjectDefinitions
[DefIndex
].CsrCleanupObjectProc
)(Object
);
105 DPRINT1("CSR: Error: releaseing unknown object type 0x%x", Object
->Type
);
109 return STATUS_SUCCESS
;
114 CsrReleaseObject(PCSRSS_PROCESS_DATA ProcessData
,
117 ULONG h
= (((ULONG
)Handle
) >> 2) - 1;
120 if (ProcessData
== NULL
)
122 return STATUS_INVALID_PARAMETER
;
124 if (!CsrIsConsoleHandle(Handle
) || h
>= ProcessData
->HandleTableSize
|| ProcessData
->HandleTable
[h
] == NULL
)
126 return STATUS_INVALID_HANDLE
;
129 Status
= CsrReleaseObjectByPointer(ProcessData
->HandleTable
[h
]);
131 RtlEnterCriticalSection(&ProcessData
->HandleTableLock
);
132 ProcessData
->HandleTable
[h
] = 0;
133 RtlLeaveCriticalSection(&ProcessData
->HandleTableLock
);
137 NTSTATUS STDCALL
CsrInsertObject( PCSRSS_PROCESS_DATA ProcessData
, PHANDLE Handle
, Object_t
*Object
)
142 if (ProcessData
== NULL
)
144 return STATUS_INVALID_PARAMETER
;
147 RtlEnterCriticalSection(&ProcessData
->HandleTableLock
);
149 for (i
= 0; i
< ProcessData
->HandleTableSize
; i
++)
151 if (ProcessData
->HandleTable
[i
] == NULL
)
156 if (i
>= ProcessData
->HandleTableSize
)
158 Block
= RtlAllocateHeap(CsrssApiHeap
,
160 (ProcessData
->HandleTableSize
+ 64) * sizeof(HANDLE
));
163 RtlLeaveCriticalSection(&ProcessData
->HandleTableLock
);
164 return(STATUS_UNSUCCESSFUL
);
167 ProcessData
->HandleTable
,
168 ProcessData
->HandleTableSize
* sizeof(HANDLE
));
169 Block
= InterlockedExchangePointer(&ProcessData
->HandleTable
, Block
);
170 RtlFreeHeap( CsrssApiHeap
, 0, Block
);
171 ProcessData
->HandleTableSize
+= 64;
173 ProcessData
->HandleTable
[i
] = Object
;
174 *Handle
= (HANDLE
)(((i
+ 1) << 2) | 0x3);
175 InterlockedIncrement( &Object
->ReferenceCount
);
176 RtlLeaveCriticalSection(&ProcessData
->HandleTableLock
);
177 return(STATUS_SUCCESS
);
180 NTSTATUS STDCALL
CsrDuplicateHandleTable(PCSRSS_PROCESS_DATA SourceProcessData
,
181 PCSRSS_PROCESS_DATA TargetProcessData
)
185 if (SourceProcessData
== NULL
||
186 TargetProcessData
== NULL
||
187 TargetProcessData
->HandleTableSize
)
189 return STATUS_INVALID_PARAMETER
;
192 RtlEnterCriticalSection(&SourceProcessData
->HandleTableLock
);
194 /* we are called from CreateProcessData, it isn't necessary to lock the target process data */
196 TargetProcessData
->HandleTable
= RtlAllocateHeap(CsrssApiHeap
,
198 SourceProcessData
->HandleTableSize
* sizeof(HANDLE
));
199 if (TargetProcessData
->HandleTable
== NULL
)
201 RtlLeaveCriticalSection(&SourceProcessData
->HandleTableLock
);
202 return(STATUS_UNSUCCESSFUL
);
204 TargetProcessData
->HandleTableSize
= SourceProcessData
->HandleTableSize
;
205 for (i
= 0; i
< SourceProcessData
->HandleTableSize
; i
++)
207 if (SourceProcessData
->HandleTable
[i
])
209 TargetProcessData
->HandleTable
[i
] = SourceProcessData
->HandleTable
[i
];
210 InterlockedIncrement( &SourceProcessData
->HandleTable
[i
]->ReferenceCount
);
213 RtlLeaveCriticalSection(&SourceProcessData
->HandleTableLock
);
214 return(STATUS_SUCCESS
);
217 NTSTATUS STDCALL
CsrVerifyObject( PCSRSS_PROCESS_DATA ProcessData
, HANDLE Handle
)
219 ULONG h
= (((ULONG
)Handle
) >> 2) - 1;
221 if (ProcessData
== NULL
)
223 return STATUS_INVALID_PARAMETER
;
225 if (!CsrIsConsoleHandle(Handle
) || h
>= ProcessData
->HandleTableSize
)
227 return STATUS_INVALID_HANDLE
;
230 return ProcessData
->HandleTable
[h
] ? STATUS_SUCCESS
: STATUS_INVALID_HANDLE
;