update for HEAD-2003050101
[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 #define NDEBUG
19 #include <debug.h>
20
21 /* FUNCTIONS *****************************************************************/
22
23 NTSTATUS STDCALL CsrGetObject( PCSRSS_PROCESS_DATA ProcessData, HANDLE Handle, Object_t **Object )
24 {
25    ULONG h = (((ULONG)Handle) >> 2) - 1;
26    DPRINT("CsrGetObject, Object: %x, %x, %x\n", Object, Handle, ProcessData ? ProcessData->HandleTableSize : 0);
27
28    if (ProcessData == NULL)
29    {
30       return STATUS_INVALID_PARAMETER;
31    }
32    if( h >= ProcessData->HandleTableSize )
33      {
34        DPRINT("CsrGetObject returning invalid handle\n");
35        return STATUS_INVALID_HANDLE;
36      }
37    *Object = ProcessData->HandleTable[h];
38    //   DbgPrint( "CsrGetObject returning\n" );
39    return *Object ? STATUS_SUCCESS : STATUS_INVALID_HANDLE;
40 }
41
42
43 NTSTATUS STDCALL CsrReleaseObject(PCSRSS_PROCESS_DATA ProcessData,
44                           HANDLE Handle)
45 {
46    Object_t *Object;
47    ULONG h = (((ULONG)Handle) >> 2) - 1;
48    if (ProcessData == NULL)
49    {
50       return STATUS_INVALID_PARAMETER;
51    }
52    if( h >= ProcessData->HandleTableSize || ProcessData->HandleTable[h] == 0 )
53       return STATUS_INVALID_HANDLE;
54    /* dec ref count */
55    Object = ProcessData->HandleTable[h];
56    if( InterlockedDecrement( &Object->ReferenceCount ) == 0 )
57       switch( Object->Type )
58          {
59          case CSRSS_CONSOLE_MAGIC: CsrDeleteConsole( (PCSRSS_CONSOLE) Object );
60             break;
61          case CSRSS_SCREEN_BUFFER_MAGIC: CsrDeleteScreenBuffer( (PCSRSS_SCREEN_BUFFER) Object );
62             break;
63          default: DbgPrint( "CSR: Error: releaseing unknown object type" );
64          }
65    ProcessData->HandleTable[h] = 0;
66    return STATUS_SUCCESS;
67 }
68
69 NTSTATUS STDCALL CsrInsertObject( PCSRSS_PROCESS_DATA ProcessData, PHANDLE Handle, Object_t *Object )
70 {
71    ULONG i;
72    PVOID* NewBlock;
73
74    if (ProcessData == NULL)
75    {
76       return STATUS_INVALID_PARAMETER;
77    }
78
79    for (i = 0; i < ProcessData->HandleTableSize; i++)
80      {
81         if (ProcessData->HandleTable[i] == NULL)
82           {
83              ProcessData->HandleTable[i] = Object;
84              *Handle = (HANDLE)(((i + 1) << 2) | 0x3);
85              InterlockedIncrement( &Object->ReferenceCount );
86              return(STATUS_SUCCESS);
87           }
88      }
89    NewBlock = RtlAllocateHeap(CsrssApiHeap,
90                               HEAP_ZERO_MEMORY,
91                               (ProcessData->HandleTableSize + 64) * 
92                               sizeof(HANDLE));
93    if (NewBlock == NULL)
94      {
95         return(STATUS_UNSUCCESSFUL);
96      }
97    RtlCopyMemory(NewBlock, 
98                  ProcessData->HandleTable,
99                  ProcessData->HandleTableSize * sizeof(HANDLE));
100    RtlFreeHeap( CsrssApiHeap, 0, ProcessData->HandleTable );
101    ProcessData->HandleTable = (Object_t **)NewBlock;
102    ProcessData->HandleTable[i] = Object;   
103    *Handle = (HANDLE)(((i + 1) << 2) | 0x3);
104    InterlockedIncrement( &Object->ReferenceCount );
105    ProcessData->HandleTableSize = ProcessData->HandleTableSize + 64;
106    return(STATUS_SUCCESS);
107 }
108
109 NTSTATUS STDCALL CsrVerifyObject( PCSRSS_PROCESS_DATA ProcessData, HANDLE Handle )
110 {
111   ULONG h = (((ULONG)Handle) >> 2) - 1;
112
113   if (ProcessData == NULL)
114   {
115       return STATUS_INVALID_PARAMETER;
116   }
117   if (h >= ProcessData->HandleTableSize)
118     {
119       return STATUS_INVALID_HANDLE;
120     }
121
122   return ProcessData->HandleTable[h] ? STATUS_SUCCESS : STATUS_INVALID_HANDLE;
123 }
124
125 /* EOF */