2 * Win32 process handles
4 * Copyright 1998 Alexandre Julliard
14 #define HTABLE_SIZE 0x30 /* Handle table initial size */
15 #define HTABLE_INC 0x10 /* Handle table increment */
17 /* Reserved access rights */
18 #define RESERVED_ALL (0x0007 << RESERVED_SHIFT)
19 #define RESERVED_SHIFT 25
20 #define RESERVED_INHERIT (HANDLE_FLAG_INHERIT<<RESERVED_SHIFT)
21 #define RESERVED_CLOSE_PROTECT (HANDLE_FLAG_PROTECT_FROM_CLOSE<<RESERVED_SHIFT)
24 /***********************************************************************
27 HANDLE_TABLE
*HANDLE_AllocTable( PDB32
*process
)
29 HANDLE_TABLE
*table
= HeapAlloc( process
->system_heap
, HEAP_ZERO_MEMORY
,
30 sizeof(HANDLE_TABLE
) +
31 (HTABLE_SIZE
-1) * sizeof(HANDLE_ENTRY
) );
32 if (!table
) return NULL
;
33 table
->count
= HTABLE_SIZE
;
38 /***********************************************************************
41 static BOOL32
HANDLE_GrowTable( PDB32
*process
)
46 table
= process
->handle_table
;
47 table
= HeapReAlloc( process
->system_heap
,
48 HEAP_ZERO_MEMORY
| HEAP_NO_SERIALIZE
, table
,
49 sizeof(HANDLE_TABLE
) +
50 (table
->count
+HTABLE_INC
-1) * sizeof(HANDLE_ENTRY
) );
53 table
->count
+= HTABLE_INC
;
54 process
->handle_table
= table
;
57 return (table
!= NULL
);
61 /***********************************************************************
64 * Allocate a handle for a kernel object and increment its refcount.
66 HANDLE32
HANDLE_Alloc( K32OBJ
*ptr
, DWORD access
, BOOL32 inherit
)
70 PDB32
*pdb
= PROCESS_Current();
74 /* Set the inherit reserved flag */
75 access
&= ~RESERVED_ALL
;
76 if (inherit
) access
|= RESERVED_INHERIT
;
79 K32OBJ_IncCount( ptr
);
80 entry
= pdb
->handle_table
->entries
;
81 for (h
= 0; h
< pdb
->handle_table
->count
; h
++, entry
++)
82 if (!entry
->ptr
) break;
83 if ((h
< pdb
->handle_table
->count
) || HANDLE_GrowTable( pdb
))
85 entry
= &pdb
->handle_table
->entries
[h
];
86 entry
->access
= access
;
89 return h
+ 1; /* Avoid handle 0 */
91 K32OBJ_DecCount( ptr
);
93 SetLastError( ERROR_OUTOFMEMORY
);
94 return INVALID_HANDLE_VALUE32
;
98 /***********************************************************************
101 * Retrieve a pointer to a kernel object and increments its reference count.
102 * The refcount must be decremented when the pointer is no longer used.
104 K32OBJ
*HANDLE_GetObjPtr( HANDLE32 handle
, K32OBJ_TYPE type
, DWORD access
)
107 PDB32
*pdb
= PROCESS_Current();
110 if ((handle
> 0) && (handle
<= pdb
->handle_table
->count
))
112 HANDLE_ENTRY
*entry
= &pdb
->handle_table
->entries
[handle
-1];
113 if ((entry
->access
& access
) != access
)
114 fprintf( stderr
, "Warning: handle %08x bad access (acc=%08lx req=%08lx)\n",
115 handle
, entry
->access
, access
);
117 if (ptr
&& ((type
== K32OBJ_UNKNOWN
) || (ptr
->type
== type
)))
118 K32OBJ_IncCount( ptr
);
123 if (!ptr
) SetLastError( ERROR_INVALID_HANDLE
);
128 /***********************************************************************
131 * Change the object pointer of a handle, and increment the refcount.
134 BOOL32
HANDLE_SetObjPtr( HANDLE32 handle
, K32OBJ
*ptr
, DWORD access
)
137 PDB32
*pdb
= PROCESS_Current();
140 if ((handle
> 0) && (handle
<= pdb
->handle_table
->count
))
142 HANDLE_ENTRY
*entry
= &pdb
->handle_table
->entries
[handle
-1];
143 K32OBJ
*old_ptr
= entry
->ptr
;
144 K32OBJ_IncCount( ptr
);
145 entry
->access
= access
;
147 if (old_ptr
) K32OBJ_DecCount( old_ptr
);
151 if (!ret
) SetLastError( ERROR_INVALID_HANDLE
);
156 /*********************************************************************
157 * CloseHandle (KERNEL32.23)
159 BOOL32 WINAPI
CloseHandle( HANDLE32 handle
)
162 PDB32
*pdb
= PROCESS_Current();
166 if ((handle
> 0) && (handle
<= pdb
->handle_table
->count
))
168 HANDLE_ENTRY
*entry
= &pdb
->handle_table
->entries
[handle
-1];
169 if ((ptr
= entry
->ptr
))
171 if (!(entry
->access
& RESERVED_CLOSE_PROTECT
))
175 K32OBJ_DecCount( ptr
);
178 /* FIXME: else SetLastError */
182 if (!ret
) SetLastError( ERROR_INVALID_HANDLE
);
187 /*********************************************************************
188 * GetHandleInformation (KERNEL32.336)
190 BOOL32 WINAPI
GetHandleInformation( HANDLE32 handle
, LPDWORD flags
)
193 PDB32
*pdb
= PROCESS_Current();
196 if ((handle
> 0) && (handle
<= pdb
->handle_table
->count
))
198 HANDLE_ENTRY
*entry
= &pdb
->handle_table
->entries
[handle
-1];
202 *flags
= (entry
->access
& RESERVED_ALL
) >> RESERVED_SHIFT
;
207 if (!ret
) SetLastError( ERROR_INVALID_HANDLE
);
212 /*********************************************************************
213 * SetHandleInformation (KERNEL32.653)
215 BOOL32 WINAPI
SetHandleInformation( HANDLE32 handle
, DWORD mask
, DWORD flags
)
218 PDB32
*pdb
= PROCESS_Current();
220 mask
= (mask
<< RESERVED_SHIFT
) & RESERVED_ALL
;
221 flags
= (flags
<< RESERVED_SHIFT
) & RESERVED_ALL
;
223 if ((handle
> 0) && (handle
<= pdb
->handle_table
->count
))
225 HANDLE_ENTRY
*entry
= &pdb
->handle_table
->entries
[handle
-1];
228 entry
->access
= (entry
->access
& ~mask
) | flags
;
233 if (!ret
) SetLastError( ERROR_INVALID_HANDLE
);