4 * Copyright 1996 Alexandre Julliard
15 /* The declarations are here to avoid including a lot of unnecessary files */
16 extern const K32OBJ_OPS PROCESS_Ops
;
17 extern const K32OBJ_OPS THREAD_Ops
;
19 static const K32OBJ_OPS K32OBJ_NullOps
=
24 static void K32OBJ_Destroy( K32OBJ
*obj
);
26 static const K32OBJ_OPS K32OBJ_DefaultOps
=
28 K32OBJ_Destroy
/* destroy */
32 const K32OBJ_OPS
* const K32OBJ_Ops
[K32OBJ_NBOBJECTS
] =
35 &K32OBJ_DefaultOps
, /* K32OBJ_SEMAPHORE */
36 &K32OBJ_DefaultOps
, /* K32OBJ_EVENT */
37 &K32OBJ_DefaultOps
, /* K32OBJ_MUTEX */
38 &K32OBJ_NullOps
, /* K32OBJ_CRITICAL_SECTION */
39 &PROCESS_Ops
, /* K32OBJ_PROCESS */
40 &THREAD_Ops
, /* K32OBJ_THREAD */
41 &K32OBJ_DefaultOps
, /* K32OBJ_FILE */
42 &K32OBJ_DefaultOps
, /* K32OBJ_CHANGE */
43 &K32OBJ_DefaultOps
, /* K32OBJ_CONSOLE */
44 &K32OBJ_NullOps
, /* K32OBJ_SCREEN_BUFFER */
45 &K32OBJ_DefaultOps
, /* K32OBJ_MEM_MAPPED_FILE */
46 &K32OBJ_NullOps
, /* K32OBJ_SERIAL */
47 &K32OBJ_NullOps
, /* K32OBJ_DEVICE_IOCTL */
48 &K32OBJ_DefaultOps
, /* K32OBJ_PIPE */
49 &K32OBJ_NullOps
, /* K32OBJ_MAILSLOT */
50 &K32OBJ_DefaultOps
, /* K32OBJ_TOOLHELP_SNAPSHOT */
51 &K32OBJ_NullOps
/* K32OBJ_SOCKET */
62 static NAME_ENTRY
*K32OBJ_FirstEntry
= NULL
;
65 /***********************************************************************
68 void K32OBJ_IncCount( K32OBJ
*ptr
)
70 assert( ptr
->type
&& ((unsigned)ptr
->type
< K32OBJ_NBOBJECTS
) );
74 assert( ptr
->refcount
> 0 ); /* No wrap-around allowed */
78 /***********************************************************************
81 void K32OBJ_DecCount( K32OBJ
*ptr
)
85 assert( ptr
->type
&& ((unsigned)ptr
->type
< K32OBJ_NBOBJECTS
) );
86 assert( ptr
->refcount
> 0 );
94 /* Check if the object has a name entry and free it */
96 pptr
= &K32OBJ_FirstEntry
;
97 while (*pptr
&& ((*pptr
)->obj
!= ptr
)) pptr
= &(*pptr
)->next
;
100 NAME_ENTRY
*entry
= *pptr
;
102 HeapFree( SystemHeap
, 0, entry
);
105 /* Free the object */
107 if (K32OBJ_Ops
[ptr
->type
]->destroy
) K32OBJ_Ops
[ptr
->type
]->destroy( ptr
);
112 /***********************************************************************
115 * Generic destroy functions for objects that don't need any special treatment.
117 static void K32OBJ_Destroy( K32OBJ
*obj
)
119 obj
->type
= K32OBJ_UNKNOWN
;
120 HeapFree( SystemHeap
, 0, obj
);
124 /***********************************************************************
127 * Check if a pointer is a valid kernel object
129 BOOL
K32OBJ_IsValid( K32OBJ
*ptr
, K32OBJ_TYPE type
)
131 if (IsBadReadPtr( ptr
, sizeof(*ptr
) )) return FALSE
;
132 return (ptr
->type
== type
);
136 /***********************************************************************
139 * Add a name entry for an object. We don't check for duplicates here.
140 * FIXME: should use some sort of hashing.
142 BOOL
K32OBJ_AddName( K32OBJ
*obj
, LPCSTR name
)
147 if (!name
) return TRUE
; /* Anonymous object */
148 len
= strlen( name
);
150 if (!(entry
= HeapAlloc( SystemHeap
, 0, sizeof(NAME_ENTRY
) + len
)))
153 SetLastError( ERROR_OUTOFMEMORY
);
156 entry
->next
= K32OBJ_FirstEntry
;
159 lstrcpyA( entry
->name
, name
);
160 K32OBJ_FirstEntry
= entry
;
166 /***********************************************************************
169 * Create a named kernel object.
170 * Returns NULL if there was an error _or_ if the object already existed.
171 * The refcount of the object must be decremented once it is initialized.
173 K32OBJ
*K32OBJ_Create( K32OBJ_TYPE type
, DWORD size
, LPCSTR name
, int server_handle
,
174 DWORD access
, SECURITY_ATTRIBUTES
*sa
, HANDLE
*handle
)
176 BOOL inherit
= (sa
&& (sa
->nLength
>=sizeof(*sa
)) && sa
->bInheritHandle
);
178 /* Check if the name already exists */
180 K32OBJ
*obj
= K32OBJ_FindName( name
);
183 if (obj
->type
== type
)
185 SetLastError( ERROR_ALREADY_EXISTS
);
186 *handle
= HANDLE_Alloc( PROCESS_Current(), obj
, access
, inherit
, server_handle
);
190 SetLastError( ERROR_DUP_NAME
);
191 *handle
= INVALID_HANDLE_VALUE
;
192 if (server_handle
!= -1) CLIENT_CloseHandle( server_handle
);
194 K32OBJ_DecCount( obj
);
198 /* Create the object */
201 if (!(obj
= HeapAlloc( SystemHeap
, 0, size
)))
204 *handle
= INVALID_HANDLE_VALUE
;
205 if (server_handle
!= -1) CLIENT_CloseHandle( server_handle
);
211 /* Add a name for it */
213 if (!K32OBJ_AddName( obj
, name
))
215 /* Don't call the destroy function, as the object wasn't
216 * initialized properly */
217 HeapFree( SystemHeap
, 0, obj
);
219 *handle
= INVALID_HANDLE_VALUE
;
220 if (server_handle
!= -1) CLIENT_CloseHandle( server_handle
);
224 /* Allocate a handle */
226 *handle
= HANDLE_Alloc( PROCESS_Current(), obj
, access
, inherit
, server_handle
);
232 /***********************************************************************
235 * Find the object referenced by a given name.
236 * The reference count is incremented.
238 K32OBJ
*K32OBJ_FindName( LPCSTR name
)
243 if (!name
) return NULL
; /* Anonymous object */
244 len
= strlen( name
);
246 entry
= K32OBJ_FirstEntry
;
249 if ((len
== entry
->len
) && !strcmp( name
, entry
->name
))
251 K32OBJ
*obj
= entry
->obj
;
252 K32OBJ_IncCount( obj
);
263 /***********************************************************************
264 * K32OBJ_FindNameType
266 * Find an object by name and check its type.
267 * The reference count is incremented.
269 K32OBJ
*K32OBJ_FindNameType( LPCSTR name
, K32OBJ_TYPE type
)
271 K32OBJ
*obj
= K32OBJ_FindName( name
);
272 if (!obj
) return NULL
;
273 if (obj
->type
== type
) return obj
;
274 SetLastError( ERROR_DUP_NAME
);
275 K32OBJ_DecCount( obj
);