Fixed CHECK_STRING display.
[wine/multimedia.git] / scheduler / k32obj.c
blob3d67e95cefc5eed398fcc4a5ee7fb399e73713be
1 /*
2 * KERNEL32 objects
4 * Copyright 1996 Alexandre Julliard
5 */
7 #include <assert.h>
8 #include "winerror.h"
9 #include "k32obj.h"
10 #include "heap.h"
11 #include "process.h"
14 /* The declarations are here to avoid including a lot of unnecessary files */
15 extern const K32OBJ_OPS PROCESS_Ops;
16 extern const K32OBJ_OPS THREAD_Ops;
17 extern const K32OBJ_OPS FILE_Ops;
18 extern const K32OBJ_OPS CHANGE_Ops;
19 extern const K32OBJ_OPS MEM_MAPPED_FILE_Ops;
20 extern const K32OBJ_OPS DEVICE_Ops;
21 extern const K32OBJ_OPS CONSOLE_Ops;
22 extern const K32OBJ_OPS SNAPSHOT_Ops;
24 static const K32OBJ_OPS K32OBJ_NullOps =
26 NULL /* destroy */
29 static void K32OBJ_Destroy( K32OBJ *obj );
31 static const K32OBJ_OPS K32OBJ_DefaultOps =
33 K32OBJ_Destroy /* destroy */
37 const K32OBJ_OPS * const K32OBJ_Ops[K32OBJ_NBOBJECTS] =
39 NULL,
40 &K32OBJ_DefaultOps, /* K32OBJ_SEMAPHORE */
41 &K32OBJ_DefaultOps, /* K32OBJ_EVENT */
42 &K32OBJ_DefaultOps, /* K32OBJ_MUTEX */
43 &K32OBJ_NullOps, /* K32OBJ_CRITICAL_SECTION */
44 &PROCESS_Ops, /* K32OBJ_PROCESS */
45 &THREAD_Ops, /* K32OBJ_THREAD */
46 &FILE_Ops, /* K32OBJ_FILE */
47 &CHANGE_Ops, /* K32OBJ_CHANGE */
48 &CONSOLE_Ops, /* K32OBJ_CONSOLE */
49 &K32OBJ_NullOps, /* K32OBJ_SCREEN_BUFFER */
50 &MEM_MAPPED_FILE_Ops, /* K32OBJ_MEM_MAPPED_FILE */
51 &K32OBJ_NullOps, /* K32OBJ_SERIAL */
52 &DEVICE_Ops, /* K32OBJ_DEVICE_IOCTL */
53 &K32OBJ_DefaultOps, /* K32OBJ_PIPE */
54 &K32OBJ_NullOps, /* K32OBJ_MAILSLOT */
55 &K32OBJ_NullOps, /* K32OBJ_TOOLHELP_SNAPSHOT */
56 &K32OBJ_NullOps /* K32OBJ_SOCKET */
59 typedef struct _NE
61 struct _NE *next;
62 K32OBJ *obj;
63 UINT32 len;
64 char name[1];
65 } NAME_ENTRY;
67 static NAME_ENTRY *K32OBJ_FirstEntry = NULL;
70 /***********************************************************************
71 * K32OBJ_IncCount
73 void K32OBJ_IncCount( K32OBJ *ptr )
75 assert( ptr->type && ((unsigned)ptr->type < K32OBJ_NBOBJECTS) );
76 SYSTEM_LOCK();
77 ptr->refcount++;
78 SYSTEM_UNLOCK();
79 assert( ptr->refcount > 0 ); /* No wrap-around allowed */
83 /***********************************************************************
84 * K32OBJ_DecCount
86 void K32OBJ_DecCount( K32OBJ *ptr )
88 NAME_ENTRY **pptr;
90 assert( ptr->type && ((unsigned)ptr->type < K32OBJ_NBOBJECTS) );
91 assert( ptr->refcount > 0 );
92 SYSTEM_LOCK();
93 if (--ptr->refcount)
95 SYSTEM_UNLOCK();
96 return;
99 /* Check if the object has a name entry and free it */
101 pptr = &K32OBJ_FirstEntry;
102 while (*pptr && ((*pptr)->obj != ptr)) pptr = &(*pptr)->next;
103 if (*pptr)
105 NAME_ENTRY *entry = *pptr;
106 *pptr = entry->next;
107 HeapFree( SystemHeap, 0, entry );
110 /* Free the object */
112 if (K32OBJ_Ops[ptr->type]->destroy) K32OBJ_Ops[ptr->type]->destroy( ptr );
113 SYSTEM_UNLOCK();
117 /***********************************************************************
118 * K32OBJ_Destroy
120 * Generic destroy functions for objects that don't need any special treatment.
122 static void K32OBJ_Destroy( K32OBJ *obj )
124 obj->type = K32OBJ_UNKNOWN;
125 HeapFree( SystemHeap, 0, obj );
129 /***********************************************************************
130 * K32OBJ_IsValid
132 * Check if a pointer is a valid kernel object
134 BOOL32 K32OBJ_IsValid( K32OBJ *ptr, K32OBJ_TYPE type )
136 if (IsBadReadPtr32( ptr, sizeof(*ptr) )) return FALSE;
137 return (ptr->type == type);
141 /***********************************************************************
142 * K32OBJ_AddName
144 * Add a name entry for an object. We don't check for duplicates here.
145 * FIXME: should use some sort of hashing.
147 BOOL32 K32OBJ_AddName( K32OBJ *obj, LPCSTR name )
149 NAME_ENTRY *entry;
150 UINT32 len;
152 if (!name) return TRUE; /* Anonymous object */
153 len = strlen( name );
154 SYSTEM_LOCK();
155 if (!(entry = HeapAlloc( SystemHeap, 0, sizeof(NAME_ENTRY) + len )))
157 SYSTEM_UNLOCK();
158 SetLastError( ERROR_OUTOFMEMORY );
159 return FALSE;
161 entry->next = K32OBJ_FirstEntry;
162 entry->obj = obj;
163 entry->len = len;
164 lstrcpy32A( entry->name, name );
165 K32OBJ_FirstEntry = entry;
166 SYSTEM_UNLOCK();
167 return TRUE;
171 /***********************************************************************
172 * K32OBJ_Create
174 * Create a named kernel object.
175 * Returns NULL if there was an error _or_ if the object already existed.
176 * The refcount of the object must be decremented once it is initialized.
178 K32OBJ *K32OBJ_Create( K32OBJ_TYPE type, DWORD size, LPCSTR name, int server_handle,
179 DWORD access, SECURITY_ATTRIBUTES *sa, HANDLE32 *handle)
181 BOOL32 inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
183 /* Check if the name already exists */
185 K32OBJ *obj = K32OBJ_FindName( name );
186 if (obj)
188 if (obj->type == type)
190 SetLastError( ERROR_ALREADY_EXISTS );
191 *handle = HANDLE_Alloc( PROCESS_Current(), obj, access, inherit, server_handle );
193 else
195 SetLastError( ERROR_DUP_NAME );
196 *handle = INVALID_HANDLE_VALUE32;
197 if (server_handle != -1) CLIENT_CloseHandle( server_handle );
199 K32OBJ_DecCount( obj );
200 return NULL;
203 /* Create the object */
205 SYSTEM_LOCK();
206 if (!(obj = HeapAlloc( SystemHeap, 0, size )))
208 SYSTEM_UNLOCK();
209 *handle = INVALID_HANDLE_VALUE32;
210 if (server_handle != -1) CLIENT_CloseHandle( server_handle );
211 return NULL;
213 obj->type = type;
214 obj->refcount = 1;
216 /* Add a name for it */
218 if (!K32OBJ_AddName( obj, name ))
220 /* Don't call the destroy function, as the object wasn't
221 * initialized properly */
222 HeapFree( SystemHeap, 0, obj );
223 SYSTEM_UNLOCK();
224 *handle = INVALID_HANDLE_VALUE32;
225 if (server_handle != -1) CLIENT_CloseHandle( server_handle );
226 return NULL;
229 /* Allocate a handle */
231 *handle = HANDLE_Alloc( PROCESS_Current(), obj, access, inherit, server_handle );
232 SYSTEM_UNLOCK();
233 return obj;
237 /***********************************************************************
238 * K32OBJ_FindName
240 * Find the object referenced by a given name.
241 * The reference count is incremented.
243 K32OBJ *K32OBJ_FindName( LPCSTR name )
245 NAME_ENTRY *entry;
246 UINT32 len;
248 if (!name) return NULL; /* Anonymous object */
249 len = strlen( name );
250 SYSTEM_LOCK();
251 entry = K32OBJ_FirstEntry;
252 while (entry)
254 if ((len == entry->len) && !strcmp( name, entry->name))
256 K32OBJ *obj = entry->obj;
257 K32OBJ_IncCount( obj );
258 SYSTEM_UNLOCK();
259 return entry->obj;
261 entry = entry->next;
263 SYSTEM_UNLOCK();
264 return NULL;
268 /***********************************************************************
269 * K32OBJ_FindNameType
271 * Find an object by name and check its type.
272 * The reference count is incremented.
274 K32OBJ *K32OBJ_FindNameType( LPCSTR name, K32OBJ_TYPE type )
276 K32OBJ *obj = K32OBJ_FindName( name );
277 if (!obj) return NULL;
278 if (obj->type == type) return obj;
279 SetLastError( ERROR_DUP_NAME );
280 K32OBJ_DecCount( obj );
281 return NULL;