4 * Copyright 1996 Alexandre Julliard
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 /* The following are fully implemented in the server and could be removed */
25 extern const K32OBJ_OPS SEMAPHORE_Ops;
26 extern const K32OBJ_OPS EVENT_Ops;
27 extern const K32OBJ_OPS MUTEX_Ops;
28 extern const K32OBJ_OPS PIPE_Ops;
30 static const K32OBJ_OPS K32OBJ_NullOps =
35 const K32OBJ_OPS * const K32OBJ_Ops[K32OBJ_NBOBJECTS] =
38 &SEMAPHORE_Ops, /* K32OBJ_SEMAPHORE */
39 &EVENT_Ops, /* K32OBJ_EVENT */
40 &MUTEX_Ops, /* K32OBJ_MUTEX */
41 &K32OBJ_NullOps, /* K32OBJ_CRITICAL_SECTION */
42 &PROCESS_Ops, /* K32OBJ_PROCESS */
43 &THREAD_Ops, /* K32OBJ_THREAD */
44 &FILE_Ops, /* K32OBJ_FILE */
45 &CHANGE_Ops, /* K32OBJ_CHANGE */
46 &CONSOLE_Ops, /* K32OBJ_CONSOLE */
47 &K32OBJ_NullOps, /* K32OBJ_SCREEN_BUFFER */
48 &MEM_MAPPED_FILE_Ops, /* K32OBJ_MEM_MAPPED_FILE */
49 &K32OBJ_NullOps, /* K32OBJ_SERIAL */
50 &DEVICE_Ops, /* K32OBJ_DEVICE_IOCTL */
51 &PIPE_Ops, /* K32OBJ_PIPE */
52 &K32OBJ_NullOps, /* K32OBJ_MAILSLOT */
53 &K32OBJ_NullOps, /* K32OBJ_TOOLHELP_SNAPSHOT */
54 &K32OBJ_NullOps /* K32OBJ_SOCKET */
65 static NAME_ENTRY *K32OBJ_FirstEntry = NULL;
68 /***********************************************************************
71 void K32OBJ_IncCount( K32OBJ *ptr )
73 assert( ptr->type && ((unsigned)ptr->type < K32OBJ_NBOBJECTS) );
77 assert( ptr->refcount > 0 ); /* No wrap-around allowed */
81 /***********************************************************************
84 void K32OBJ_DecCount( K32OBJ *ptr )
88 assert( ptr->type && ((unsigned)ptr->type < K32OBJ_NBOBJECTS) );
89 assert( ptr->refcount > 0 );
97 /* Check if the object has a name entry and free it */
99 pptr = &K32OBJ_FirstEntry;
100 while (*pptr && ((*pptr)->obj != ptr)) pptr = &(*pptr)->next;
103 NAME_ENTRY *entry = *pptr;
105 HeapFree( SystemHeap, 0, entry );
108 /* Free the object */
110 if (K32OBJ_Ops[ptr->type]->destroy) K32OBJ_Ops[ptr->type]->destroy( ptr );
115 /***********************************************************************
118 * Check if a pointer is a valid kernel object
120 BOOL32 K32OBJ_IsValid( K32OBJ *ptr, K32OBJ_TYPE type )
122 if (IsBadReadPtr32( ptr, sizeof(*ptr) )) return FALSE;
123 return (ptr->type == type);
127 /***********************************************************************
130 * Add a name entry for an object. We don't check for duplicates here.
131 * FIXME: should use some sort of hashing.
133 BOOL32 K32OBJ_AddName( K32OBJ *obj, LPCSTR name )
138 if (!name) return TRUE; /* Anonymous object */
139 len = strlen( name );
141 if (!(entry = HeapAlloc( SystemHeap, 0, sizeof(NAME_ENTRY) + len )))
144 SetLastError( ERROR_OUTOFMEMORY );
147 entry->next = K32OBJ_FirstEntry;
150 lstrcpy32A( entry->name, name );
151 K32OBJ_FirstEntry = entry;
157 /***********************************************************************
160 * Create a named kernel object.
161 * Returns NULL if there was an error _or_ if the object already existed.
162 * The refcount of the object must be decremented once it is initialized.
164 K32OBJ *K32OBJ_Create( K32OBJ_TYPE type, DWORD size, LPCSTR name, int server_handle,
165 DWORD access, SECURITY_ATTRIBUTES *sa, HANDLE32 *handle)
167 BOOL32 inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
169 /* Check if the name already exists */
171 K32OBJ *obj = K32OBJ_FindName( name );
174 if (obj->type == type)
176 SetLastError( ERROR_ALREADY_EXISTS );
177 *handle = HANDLE_Alloc( PROCESS_Current(), obj, access, inherit, server_handle );
181 SetLastError( ERROR_DUP_NAME );
182 *handle = INVALID_HANDLE_VALUE32;
183 if (server_handle != -1) CLIENT_CloseHandle( server_handle );
185 K32OBJ_DecCount( obj );
189 /* Create the object */
192 if (!(obj = HeapAlloc( SystemHeap, 0, size )))
195 *handle = INVALID_HANDLE_VALUE32;
196 if (server_handle != -1) CLIENT_CloseHandle( server_handle );
202 /* Add a name for it */
204 if (!K32OBJ_AddName( obj, name ))
206 /* Don't call the destroy function, as the object wasn't
207 * initialized properly */
208 HeapFree( SystemHeap, 0, obj );
210 *handle = INVALID_HANDLE_VALUE32;
211 if (server_handle != -1) CLIENT_CloseHandle( server_handle );
215 /* Allocate a handle */
217 *handle = HANDLE_Alloc( PROCESS_Current(), obj, access, inherit, server_handle );
223 /***********************************************************************
226 * Find the object referenced by a given name.
227 * The reference count is incremented.
229 K32OBJ *K32OBJ_FindName( LPCSTR name )
234 if (!name) return NULL; /* Anonymous object */
235 len = strlen( name );
237 entry = K32OBJ_FirstEntry;
240 if ((len == entry->len) && !strcmp( name, entry->name))
242 K32OBJ *obj = entry->obj;
243 K32OBJ_IncCount( obj );
254 /***********************************************************************
255 * K32OBJ_FindNameType
257 * Find an object by name and check its type.
258 * The reference count is incremented.
260 K32OBJ *K32OBJ_FindNameType( LPCSTR name, K32OBJ_TYPE type )
262 K32OBJ *obj = K32OBJ_FindName( name );
263 if (!obj) return NULL;
264 if (obj->type == type) return obj;
265 SetLastError( ERROR_DUP_NAME );
266 K32OBJ_DecCount( obj );