9a9381f304b7b2c30e224b6500964407541aab0d
[reactos.git] / subsys / csrss / api / handle.c
1 /* $Id$
2  *
3  * reactos/subsys/csrss/api/handle.c
4  *
5  * Console I/O functions
6  *
7  * ReactOS Operating System
8  */
9
10 /* INCLUDES ******************************************************************/
11
12 #include <ddk/ntddk.h>
13
14 #include <csrss/csrss.h>
15 #include "api.h"
16 #include <ntdll/rtl.h>
17
18 /* FUNCTIONS *****************************************************************/
19
20 NTSTATUS STDCALL CsrGetObject( PCSRSS_PROCESS_DATA ProcessData, HANDLE Handle, Object_t **Object )
21 {
22    ULONG h = (((ULONG)Handle) >> 2) - 1;
23   //   DbgPrint( "CsrGetObject, Object: %x, %x, %x\n", Object, Handle, ProcessData->HandleTableSize );
24    if( h >= ProcessData->HandleTableSize )
25      {
26        DbgPrint( "CsrGetObject returning invalid handle\n" );
27        return STATUS_INVALID_HANDLE;
28      }
29    *Object = ProcessData->HandleTable[h];
30    //   DbgPrint( "CsrGetObject returning\n" );
31    return *Object ? STATUS_SUCCESS : STATUS_INVALID_HANDLE;
32 }
33
34
35 NTSTATUS STDCALL CsrReleaseObject(PCSRSS_PROCESS_DATA ProcessData,
36                           HANDLE Handle)
37 {
38    Object_t *Object;
39    ULONG h = (((ULONG)Handle) >> 2) - 1;
40    if( h >= ProcessData->HandleTableSize || ProcessData->HandleTable[h] == 0 )
41       return STATUS_INVALID_HANDLE;
42    /* dec ref count */
43    Object = ProcessData->HandleTable[h];
44    if( InterlockedDecrement( &Object->ReferenceCount ) == 0 )
45       switch( Object->Type )
46          {
47          case CSRSS_CONSOLE_MAGIC: CsrDeleteConsole( (PCSRSS_CONSOLE) Object );
48             break;
49          case CSRSS_SCREEN_BUFFER_MAGIC: CsrDeleteScreenBuffer( (PCSRSS_SCREEN_BUFFER) Object );
50             break;
51          default: DbgPrint( "CSR: Error: releaseing unknown object type" );
52          }
53    ProcessData->HandleTable[h] = 0;
54    return STATUS_SUCCESS;
55 }
56
57 NTSTATUS STDCALL CsrInsertObject( PCSRSS_PROCESS_DATA ProcessData, PHANDLE Handle, Object_t *Object )
58 {
59    ULONG i;
60    PVOID* NewBlock;
61
62    for (i = 0; i < ProcessData->HandleTableSize; i++)
63      {
64         if (ProcessData->HandleTable[i] == NULL)
65           {
66              ProcessData->HandleTable[i] = Object;
67              *Handle = (HANDLE)(((i + 1) << 2) | 0x3);
68              InterlockedIncrement( &Object->ReferenceCount );
69              return(STATUS_SUCCESS);
70           }
71      }
72    NewBlock = RtlAllocateHeap(CsrssApiHeap,
73                               HEAP_ZERO_MEMORY,
74                               (ProcessData->HandleTableSize + 64) * 
75                               sizeof(HANDLE));
76    if (NewBlock == NULL)
77      {
78         return(STATUS_UNSUCCESSFUL);
79      }
80    RtlCopyMemory(NewBlock, 
81                  ProcessData->HandleTable,
82                  ProcessData->HandleTableSize * sizeof(HANDLE));
83    RtlFreeHeap( CsrssApiHeap, 0, ProcessData->HandleTable );
84    ProcessData->HandleTable = (Object_t **)NewBlock;
85    ProcessData->HandleTable[i] = Object;   
86    *Handle = (HANDLE)(((i + 1) << 2) | 0x3);
87    InterlockedIncrement( &Object->ReferenceCount );
88    ProcessData->HandleTableSize = ProcessData->HandleTableSize + 64;
89    return(STATUS_SUCCESS);
90 }
91
92
93 /* EOF */