Fixed SetFocus that was broken when moved to x11drv.
[wine/multimedia.git] / scheduler / k32obj.c
blobf6543bf1ddc4eb080f89ac567350b8f38f0314ba
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 SEMAPHORE_Ops;
16 extern const K32OBJ_OPS EVENT_Ops;
17 extern const K32OBJ_OPS MUTEX_Ops;
18 extern const K32OBJ_OPS CRITICAL_SECTION_Ops;
19 extern const K32OBJ_OPS PROCESS_Ops;
20 extern const K32OBJ_OPS THREAD_Ops;
21 extern const K32OBJ_OPS FILE_Ops;
22 extern const K32OBJ_OPS CHANGE_Ops;
23 extern const K32OBJ_OPS MEM_MAPPED_FILE_Ops;
24 extern const K32OBJ_OPS DEVICE_Ops;
25 extern const K32OBJ_OPS CONSOLE_Ops;
26 extern const K32OBJ_OPS SNAPSHOT_Ops;
28 static const K32OBJ_OPS K32OBJ_NullOps =
30 NULL, /* signaled */
31 NULL, /* satisfied */
32 NULL, /* add_wait */
33 NULL, /* remove_wait */
34 NULL, /* read */
35 NULL, /* write */
36 NULL /* destroy */
39 const K32OBJ_OPS * const K32OBJ_Ops[K32OBJ_NBOBJECTS] =
41 NULL,
42 &SEMAPHORE_Ops, /* K32OBJ_SEMAPHORE */
43 &EVENT_Ops, /* K32OBJ_EVENT */
44 &MUTEX_Ops, /* K32OBJ_MUTEX */
45 &CRITICAL_SECTION_Ops, /* K32OBJ_CRITICAL_SECTION */
46 &PROCESS_Ops, /* K32OBJ_PROCESS */
47 &THREAD_Ops, /* K32OBJ_THREAD */
48 &FILE_Ops, /* K32OBJ_FILE */
49 &CHANGE_Ops, /* K32OBJ_CHANGE */
50 &CONSOLE_Ops, /* K32OBJ_CONSOLE */
51 &K32OBJ_NullOps, /* K32OBJ_SCREEN_BUFFER */
52 &MEM_MAPPED_FILE_Ops, /* K32OBJ_MEM_MAPPED_FILE */
53 &K32OBJ_NullOps, /* K32OBJ_SERIAL */
54 &DEVICE_Ops, /* K32OBJ_DEVICE_IOCTL */
55 &K32OBJ_NullOps, /* K32OBJ_PIPE */
56 &K32OBJ_NullOps, /* K32OBJ_MAILSLOT */
57 &K32OBJ_NullOps, /* K32OBJ_TOOLHELP_SNAPSHOT */
58 &K32OBJ_NullOps /* K32OBJ_SOCKET */
61 typedef struct _NE
63 struct _NE *next;
64 K32OBJ *obj;
65 UINT32 len;
66 char name[1];
67 } NAME_ENTRY;
69 static NAME_ENTRY *K32OBJ_FirstEntry = NULL;
72 /***********************************************************************
73 * K32OBJ_IncCount
75 void K32OBJ_IncCount( K32OBJ *ptr )
77 assert( ptr->type && ((unsigned)ptr->type < K32OBJ_NBOBJECTS) );
78 SYSTEM_LOCK();
79 ptr->refcount++;
80 SYSTEM_UNLOCK();
81 assert( ptr->refcount > 0 ); /* No wrap-around allowed */
85 /***********************************************************************
86 * K32OBJ_DecCount
88 void K32OBJ_DecCount( K32OBJ *ptr )
90 NAME_ENTRY **pptr;
92 assert( ptr->type && ((unsigned)ptr->type < K32OBJ_NBOBJECTS) );
93 assert( ptr->refcount > 0 );
94 SYSTEM_LOCK();
95 if (--ptr->refcount)
97 SYSTEM_UNLOCK();
98 return;
101 /* Check if the object has a name entry and free it */
103 pptr = &K32OBJ_FirstEntry;
104 while (*pptr && ((*pptr)->obj != ptr)) pptr = &(*pptr)->next;
105 if (*pptr)
107 NAME_ENTRY *entry = *pptr;
108 *pptr = entry->next;
109 HeapFree( SystemHeap, 0, entry );
112 /* Free the object */
114 if (K32OBJ_Ops[ptr->type]->destroy) K32OBJ_Ops[ptr->type]->destroy( ptr );
115 SYSTEM_UNLOCK();
119 /***********************************************************************
120 * K32OBJ_IsValid
122 * Check if a pointer is a valid kernel object
124 BOOL32 K32OBJ_IsValid( K32OBJ *ptr, K32OBJ_TYPE type )
126 if (IsBadReadPtr32( ptr, sizeof(*ptr) )) return FALSE;
127 return (ptr->type == type);
131 /***********************************************************************
132 * K32OBJ_AddName
134 * Add a name entry for an object. We don't check for duplicates here.
135 * FIXME: should use some sort of hashing.
137 BOOL32 K32OBJ_AddName( K32OBJ *obj, LPCSTR name )
139 NAME_ENTRY *entry;
140 UINT32 len;
142 if (!name) return TRUE; /* Anonymous object */
143 len = strlen( name );
144 SYSTEM_LOCK();
145 if (!(entry = HeapAlloc( SystemHeap, 0, sizeof(NAME_ENTRY) + len )))
147 SYSTEM_UNLOCK();
148 SetLastError( ERROR_OUTOFMEMORY );
149 return FALSE;
151 entry->next = K32OBJ_FirstEntry;
152 entry->obj = obj;
153 entry->len = len;
154 lstrcpy32A( entry->name, name );
155 K32OBJ_FirstEntry = entry;
156 SYSTEM_UNLOCK();
157 return TRUE;
161 /***********************************************************************
162 * K32OBJ_Create
164 * Create a named kernel object.
165 * Returns NULL if there was an error _or_ if the object already existed.
166 * The refcount of the object must be decremented once it is initialized.
168 K32OBJ *K32OBJ_Create( K32OBJ_TYPE type, DWORD size, LPCSTR name, int server_handle,
169 DWORD access, SECURITY_ATTRIBUTES *sa, HANDLE32 *handle)
171 BOOL32 inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
173 /* Check if the name already exists */
175 K32OBJ *obj = K32OBJ_FindName( name );
176 if (obj)
178 if (obj->type == type)
180 SetLastError( ERROR_ALREADY_EXISTS );
181 *handle = HANDLE_Alloc( PROCESS_Current(), obj, access, inherit, server_handle );
183 else
185 SetLastError( ERROR_DUP_NAME );
186 *handle = INVALID_HANDLE_VALUE32;
187 if (server_handle != -1) CLIENT_CloseHandle( server_handle );
189 K32OBJ_DecCount( obj );
190 return NULL;
193 /* Create the object */
195 SYSTEM_LOCK();
196 if (!(obj = HeapAlloc( SystemHeap, 0, size )))
198 SYSTEM_UNLOCK();
199 *handle = INVALID_HANDLE_VALUE32;
200 if (server_handle != -1) CLIENT_CloseHandle( server_handle );
201 return NULL;
203 obj->type = type;
204 obj->refcount = 1;
206 /* Add a name for it */
208 if (!K32OBJ_AddName( obj, name ))
210 /* Don't call the destroy function, as the object wasn't
211 * initialized properly */
212 HeapFree( SystemHeap, 0, obj );
213 SYSTEM_UNLOCK();
214 *handle = INVALID_HANDLE_VALUE32;
215 if (server_handle != -1) CLIENT_CloseHandle( server_handle );
216 return NULL;
219 /* Allocate a handle */
221 *handle = HANDLE_Alloc( PROCESS_Current(), obj, access, inherit, server_handle );
222 SYSTEM_UNLOCK();
223 return obj;
227 /***********************************************************************
228 * K32OBJ_FindName
230 * Find the object referenced by a given name.
231 * The reference count is incremented.
233 K32OBJ *K32OBJ_FindName( LPCSTR name )
235 NAME_ENTRY *entry;
236 UINT32 len;
238 if (!name) return NULL; /* Anonymous object */
239 len = strlen( name );
240 SYSTEM_LOCK();
241 entry = K32OBJ_FirstEntry;
242 while (entry)
244 if ((len == entry->len) && !strcmp( name, entry->name))
246 K32OBJ *obj = entry->obj;
247 K32OBJ_IncCount( obj );
248 SYSTEM_UNLOCK();
249 return entry->obj;
251 entry = entry->next;
253 SYSTEM_UNLOCK();
254 return NULL;
258 /***********************************************************************
259 * K32OBJ_FindNameType
261 * Find an object by name and check its type.
262 * The reference count is incremented.
264 K32OBJ *K32OBJ_FindNameType( LPCSTR name, K32OBJ_TYPE type )
266 K32OBJ *obj = K32OBJ_FindName( name );
267 if (!obj) return NULL;
268 if (obj->type == type) return obj;
269 SetLastError( ERROR_DUP_NAME );
270 K32OBJ_DecCount( obj );
271 return NULL;