2005-01-06 13:58:04 +00:00
|
|
|
/* $Id$
|
1999-12-26 15:50:53 +00:00
|
|
|
*
|
|
|
|
* reactos/subsys/csrss/api/handle.c
|
|
|
|
*
|
2003-12-02 11:38:47 +00:00
|
|
|
* CSRSS handle functions
|
1999-12-26 15:50:53 +00:00
|
|
|
*
|
|
|
|
* ReactOS Operating System
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* INCLUDES ******************************************************************/
|
|
|
|
|
2005-07-01 03:03:06 +00:00
|
|
|
#include "csrss.h"
|
1999-12-26 15:50:53 +00:00
|
|
|
|
2003-03-09 21:41:00 +00:00
|
|
|
#define NDEBUG
|
|
|
|
#include <debug.h>
|
|
|
|
|
1999-12-26 15:50:53 +00:00
|
|
|
/* FUNCTIONS *****************************************************************/
|
|
|
|
|
2003-12-02 11:38:47 +00:00
|
|
|
static unsigned ObjectDefinitionsCount = 0;
|
|
|
|
static PCSRSS_OBJECT_DEFINITION ObjectDefinitions = NULL;
|
|
|
|
|
2005-05-30 20:13:35 +00:00
|
|
|
BOOL
|
|
|
|
CsrIsConsoleHandle(HANDLE Handle)
|
|
|
|
{
|
|
|
|
return ((((ULONG)Handle) & 0x10000003) == 0x3) ? TRUE : FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-12-02 11:38:47 +00:00
|
|
|
NTSTATUS FASTCALL
|
|
|
|
CsrRegisterObjectDefinitions(PCSRSS_OBJECT_DEFINITION NewDefinitions)
|
|
|
|
{
|
|
|
|
unsigned NewCount;
|
|
|
|
PCSRSS_OBJECT_DEFINITION Scan;
|
|
|
|
PCSRSS_OBJECT_DEFINITION New;
|
|
|
|
|
|
|
|
NewCount = 0;
|
|
|
|
for (Scan = NewDefinitions; 0 != Scan->Type; Scan++)
|
|
|
|
{
|
|
|
|
NewCount++;
|
|
|
|
}
|
|
|
|
|
|
|
|
New = RtlAllocateHeap(CsrssApiHeap, 0,
|
|
|
|
(ObjectDefinitionsCount + NewCount)
|
|
|
|
* sizeof(CSRSS_OBJECT_DEFINITION));
|
|
|
|
if (NULL == New)
|
|
|
|
{
|
|
|
|
DPRINT1("Unable to allocate memory\n");
|
|
|
|
return STATUS_NO_MEMORY;
|
|
|
|
}
|
|
|
|
if (0 != ObjectDefinitionsCount)
|
|
|
|
{
|
|
|
|
RtlCopyMemory(New, ObjectDefinitions,
|
|
|
|
ObjectDefinitionsCount * sizeof(CSRSS_OBJECT_DEFINITION));
|
|
|
|
RtlFreeHeap(CsrssApiHeap, 0, ObjectDefinitions);
|
|
|
|
}
|
|
|
|
RtlCopyMemory(New + ObjectDefinitionsCount, NewDefinitions,
|
|
|
|
NewCount * sizeof(CSRSS_OBJECT_DEFINITION));
|
|
|
|
ObjectDefinitions = New;
|
|
|
|
ObjectDefinitionsCount += NewCount;
|
|
|
|
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2001-08-14 12:57:16 +00:00
|
|
|
NTSTATUS STDCALL CsrGetObject( PCSRSS_PROCESS_DATA ProcessData, HANDLE Handle, Object_t **Object )
|
1999-12-30 01:51:42 +00:00
|
|
|
{
|
2004-01-11 17:31:16 +00:00
|
|
|
ULONG h = (((ULONG)Handle) >> 2) - 1;
|
|
|
|
DPRINT("CsrGetObject, Object: %x, %x, %x\n", Object, Handle, ProcessData ? ProcessData->HandleTableSize : 0);
|
2003-03-09 21:41:00 +00:00
|
|
|
|
2004-01-11 17:31:16 +00:00
|
|
|
if (ProcessData == NULL)
|
|
|
|
{
|
2003-03-09 21:41:00 +00:00
|
|
|
return STATUS_INVALID_PARAMETER;
|
2004-01-11 17:31:16 +00:00
|
|
|
}
|
2005-05-30 20:13:35 +00:00
|
|
|
if (!CsrIsConsoleHandle(Handle) || ProcessData->HandleTableSize <= h)
|
2004-01-11 17:31:16 +00:00
|
|
|
{
|
|
|
|
DPRINT1("CsrGetObject returning invalid handle\n");
|
|
|
|
return STATUS_INVALID_HANDLE;
|
|
|
|
}
|
|
|
|
*Object = ProcessData->HandleTable[h];
|
|
|
|
// DbgPrint( "CsrGetObject returning\n" );
|
|
|
|
return *Object ? STATUS_SUCCESS : STATUS_INVALID_HANDLE;
|
2000-04-23 17:44:53 +00:00
|
|
|
}
|
|
|
|
|
1999-12-30 01:51:42 +00:00
|
|
|
|
2003-12-02 11:38:47 +00:00
|
|
|
NTSTATUS STDCALL
|
|
|
|
CsrReleaseObjectByPointer(Object_t *Object)
|
1999-12-30 01:51:42 +00:00
|
|
|
{
|
2003-12-02 11:38:47 +00:00
|
|
|
BOOL Found;
|
|
|
|
unsigned DefIndex;
|
|
|
|
|
|
|
|
/* dec ref count */
|
|
|
|
if (InterlockedDecrement(&Object->ReferenceCount) == 0)
|
|
|
|
{
|
|
|
|
Found = FALSE;
|
|
|
|
for (DefIndex = 0; ! Found && DefIndex < ObjectDefinitionsCount; DefIndex++)
|
|
|
|
{
|
|
|
|
if (Object->Type == ObjectDefinitions[DefIndex].Type)
|
|
|
|
{
|
|
|
|
(ObjectDefinitions[DefIndex].CsrCleanupObjectProc)(Object);
|
|
|
|
Found = TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (! Found)
|
|
|
|
{
|
|
|
|
DPRINT1("CSR: Error: releaseing unknown object type 0x%x", Object->Type);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
NTSTATUS STDCALL
|
|
|
|
CsrReleaseObject(PCSRSS_PROCESS_DATA ProcessData,
|
|
|
|
HANDLE Handle)
|
|
|
|
{
|
|
|
|
ULONG h = (((ULONG)Handle) >> 2) - 1;
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
|
|
|
if (ProcessData == NULL)
|
|
|
|
{
|
2003-03-09 21:41:00 +00:00
|
|
|
return STATUS_INVALID_PARAMETER;
|
2003-12-02 11:38:47 +00:00
|
|
|
}
|
2005-05-30 20:13:35 +00:00
|
|
|
if (!CsrIsConsoleHandle(Handle) || h >= ProcessData->HandleTableSize || ProcessData->HandleTable[h] == NULL)
|
2003-12-02 11:38:47 +00:00
|
|
|
{
|
2000-04-23 17:44:53 +00:00
|
|
|
return STATUS_INVALID_HANDLE;
|
2003-12-02 11:38:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Status = CsrReleaseObjectByPointer(ProcessData->HandleTable[h]);
|
|
|
|
|
2005-05-26 19:22:45 +00:00
|
|
|
RtlEnterCriticalSection(&ProcessData->HandleTableLock);
|
|
|
|
ProcessData->HandleTable[h] = 0;
|
|
|
|
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
|
2003-12-02 11:38:47 +00:00
|
|
|
return Status;
|
1999-12-30 01:51:42 +00:00
|
|
|
}
|
|
|
|
|
2001-08-14 12:57:16 +00:00
|
|
|
NTSTATUS STDCALL CsrInsertObject( PCSRSS_PROCESS_DATA ProcessData, PHANDLE Handle, Object_t *Object )
|
1999-12-30 01:51:42 +00:00
|
|
|
{
|
|
|
|
ULONG i;
|
2005-05-30 20:13:35 +00:00
|
|
|
PVOID* Block;
|
2000-04-23 17:44:53 +00:00
|
|
|
|
2003-03-09 21:41:00 +00:00
|
|
|
if (ProcessData == NULL)
|
|
|
|
{
|
|
|
|
return STATUS_INVALID_PARAMETER;
|
|
|
|
}
|
|
|
|
|
2005-05-26 19:22:45 +00:00
|
|
|
RtlEnterCriticalSection(&ProcessData->HandleTableLock);
|
|
|
|
|
1999-12-30 01:51:42 +00:00
|
|
|
for (i = 0; i < ProcessData->HandleTableSize; i++)
|
|
|
|
{
|
|
|
|
if (ProcessData->HandleTable[i] == NULL)
|
|
|
|
{
|
2005-05-26 19:22:45 +00:00
|
|
|
break;
|
1999-12-30 01:51:42 +00:00
|
|
|
}
|
|
|
|
}
|
2005-05-26 19:22:45 +00:00
|
|
|
if (i >= ProcessData->HandleTableSize)
|
1999-12-30 01:51:42 +00:00
|
|
|
{
|
2005-05-30 20:13:35 +00:00
|
|
|
Block = RtlAllocateHeap(CsrssApiHeap,
|
|
|
|
HEAP_ZERO_MEMORY,
|
|
|
|
(ProcessData->HandleTableSize + 64) * sizeof(HANDLE));
|
|
|
|
if (Block == NULL)
|
2005-05-26 19:22:45 +00:00
|
|
|
{
|
|
|
|
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
|
|
|
|
return(STATUS_UNSUCCESSFUL);
|
|
|
|
}
|
2005-05-30 20:13:35 +00:00
|
|
|
RtlCopyMemory(Block,
|
2005-05-26 19:22:45 +00:00
|
|
|
ProcessData->HandleTable,
|
|
|
|
ProcessData->HandleTableSize * sizeof(HANDLE));
|
2005-05-30 20:13:35 +00:00
|
|
|
Block = InterlockedExchangePointer(&ProcessData->HandleTable, Block);
|
|
|
|
RtlFreeHeap( CsrssApiHeap, 0, Block );
|
2005-05-26 19:22:45 +00:00
|
|
|
ProcessData->HandleTableSize += 64;
|
1999-12-30 01:51:42 +00:00
|
|
|
}
|
2005-05-08 04:07:56 +00:00
|
|
|
ProcessData->HandleTable[i] = Object;
|
2000-03-26 22:00:10 +00:00
|
|
|
*Handle = (HANDLE)(((i + 1) << 2) | 0x3);
|
2001-01-21 00:11:54 +00:00
|
|
|
InterlockedIncrement( &Object->ReferenceCount );
|
2005-05-26 19:22:45 +00:00
|
|
|
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
|
1999-12-30 01:51:42 +00:00
|
|
|
return(STATUS_SUCCESS);
|
|
|
|
}
|
2000-04-23 17:44:53 +00:00
|
|
|
|
2003-03-05 22:51:48 +00:00
|
|
|
NTSTATUS STDCALL CsrVerifyObject( PCSRSS_PROCESS_DATA ProcessData, HANDLE Handle )
|
|
|
|
{
|
|
|
|
ULONG h = (((ULONG)Handle) >> 2) - 1;
|
|
|
|
|
2003-03-09 21:41:00 +00:00
|
|
|
if (ProcessData == NULL)
|
2005-05-30 20:13:35 +00:00
|
|
|
{
|
2003-03-09 21:41:00 +00:00
|
|
|
return STATUS_INVALID_PARAMETER;
|
2005-05-30 20:13:35 +00:00
|
|
|
}
|
|
|
|
if (!CsrIsConsoleHandle(Handle) || h >= ProcessData->HandleTableSize)
|
2003-03-05 22:51:48 +00:00
|
|
|
{
|
|
|
|
return STATUS_INVALID_HANDLE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ProcessData->HandleTable[h] ? STATUS_SUCCESS : STATUS_INVALID_HANDLE;
|
|
|
|
}
|
2000-04-23 17:44:53 +00:00
|
|
|
|
2001-08-14 12:57:16 +00:00
|
|
|
/* EOF */
|