~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Wine Cross Reference
wine/dlls/ntdll/atom.c

Version: ~ [ wine-1.1.33 ] ~ [ wine-1.1.32 ] ~ [ wine-1.1.31 ] ~ [ wine-1.1.30 ] ~ [ wine-1.1.29 ] ~ [ wine-1.1.28 ] ~ [ wine-1.1.27 ] ~ [ wine-1.1.26 ] ~ [ wine-1.1.25 ] ~ [ wine-1.1.24 ] ~ [ wine-1.1.23 ] ~ [ wine-1.1.22 ] ~ [ wine-1.1.21 ] ~ [ wine-1.1.20 ] ~ [ wine-1.1.19 ] ~ [ wine-1.1.18 ] ~ [ wine-1.1.17 ] ~ [ wine-1.1.16 ] ~ [ wine-1.1.15 ] ~ [ wine-1.1.14 ] ~ [ wine-1.1.13 ] ~ [ wine-1.1.12 ] ~ [ wine-1.1.11 ] ~ [ wine-1.1.10 ] ~ [ wine-1.1.9 ] ~ [ wine-1.1.8 ] ~ [ wine-1.1.7 ] ~ [ wine-1.0.1 ] ~ [ wine-1.1.6 ] ~ [ wine-1.1.5 ] ~ [ wine-1.1.4 ] ~ [ wine-1.1.3 ] ~ [ wine-1.1.2 ] ~ [ wine-1.1.1 ] ~ [ wine-1.1.0 ] ~ [ wine-1.0 ] ~

  1 /*
  2  * Atom table functions
  3  *
  4  * Copyright 1993, 1994, 1995 Alexandre Julliard
  5  * Copyright 2004,2005 Eric Pouech
  6  *
  7  * This library is free software; you can redistribute it and/or
  8  * modify it under the terms of the GNU Lesser General Public
  9  * License as published by the Free Software Foundation; either
 10  * version 2.1 of the License, or (at your option) any later version.
 11  *
 12  * This library is distributed in the hope that it will be useful,
 13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 15  * Lesser General Public License for more details.
 16  *
 17  * You should have received a copy of the GNU Lesser General Public
 18  * License along with this library; if not, write to the Free Software
 19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 20  */
 21 
 22 #include "config.h"
 23 #include "wine/port.h"
 24 
 25 #include <stdlib.h>
 26 #include <stdarg.h>
 27 #include <stdio.h>
 28 #include <string.h>
 29 #include <ctype.h>
 30 
 31 #include "ntstatus.h"
 32 #define WIN32_NO_STATUS
 33 #include "windef.h"
 34 
 35 #include "wine/server.h"
 36 #include "wine/unicode.h"
 37 
 38 #include "wine/debug.h"
 39 
 40 WINE_DEFAULT_DEBUG_CHANNEL(atom);
 41 
 42 #define MAX_ATOM_LEN              255
 43 
 44 /******************************************************************
 45  *              is_integral_atom
 46  * Returns STATUS_SUCCESS if integral atom and 'pAtom' is filled
 47  *         STATUS_INVALID_PARAMETER if 'atomstr' is too long
 48  *         STATUS_MORE_ENTRIES otherwise
 49  */
 50 static NTSTATUS is_integral_atom( LPCWSTR atomstr, size_t len, RTL_ATOM* pAtom )
 51 {
 52     RTL_ATOM atom;
 53 
 54     if (HIWORD( atomstr ))
 55     {
 56         const WCHAR* ptr = atomstr;
 57         if (!len) return STATUS_OBJECT_NAME_INVALID;
 58 
 59         if (*ptr++ == '#')
 60         {
 61             atom = 0;
 62             while (ptr < atomstr + len && *ptr >= '' && *ptr <= '9')
 63             {
 64                 atom = atom * 10 + *ptr++ - '';
 65             }
 66             if (ptr > atomstr + 1 && ptr == atomstr + len) goto done;
 67         }
 68         if (len > MAX_ATOM_LEN) return STATUS_INVALID_PARAMETER;
 69         return STATUS_MORE_ENTRIES;
 70     }
 71     else atom = LOWORD( atomstr );
 72 done:
 73     if (!atom || atom >= MAXINTATOM) return STATUS_INVALID_PARAMETER;
 74     *pAtom = atom;
 75     return STATUS_SUCCESS;
 76 }
 77 
 78 /******************************************************************
 79  *              RtlDeleteAtomFromAtomTable (NTDLL.@)
 80  */
 81 NTSTATUS WINAPI RtlDeleteAtomFromAtomTable( RTL_ATOM_TABLE table, RTL_ATOM atom )
 82 {
 83     NTSTATUS    status;
 84 
 85     TRACE( "%p %x\n", table, atom );
 86     if (!table) status = STATUS_INVALID_PARAMETER;
 87     else
 88     {
 89         SERVER_START_REQ( delete_atom )
 90         {
 91             req->atom = atom;
 92             req->table = wine_server_obj_handle( table );
 93             status = wine_server_call( req );
 94         }
 95         SERVER_END_REQ;
 96     }
 97     return status;
 98 }
 99 
100 /******************************************************************
101  *              integral_atom_name (internal)
102  *
103  * Helper for fetching integral (local/global) atoms names.
104  */
105 static ULONG integral_atom_name(WCHAR* buffer, ULONG len, RTL_ATOM atom)
106 {
107     static const WCHAR fmt[] = {'#','%','u',0};
108     WCHAR tmp[16];
109     int ret;
110 
111     ret = sprintfW( tmp, fmt, atom );
112     if (!len) return ret * sizeof(WCHAR);
113     if (len <= ret) ret = len - 1;
114     memcpy( buffer, tmp, ret * sizeof(WCHAR) );
115     buffer[ret] = 0;
116     return ret * sizeof(WCHAR);
117 }
118 
119 /******************************************************************
120  *              RtlQueryAtomInAtomTable (NTDLL.@)
121  */
122 NTSTATUS WINAPI RtlQueryAtomInAtomTable( RTL_ATOM_TABLE table, RTL_ATOM atom, ULONG* ref,
123                                          ULONG* pin, WCHAR* name, ULONG* len )
124 {
125     NTSTATUS    status = STATUS_SUCCESS;
126     DWORD       wlen = 0;
127 
128     if (!table) status = STATUS_INVALID_PARAMETER;
129     else if (atom < MAXINTATOM)
130     {
131         if (!atom) return STATUS_INVALID_PARAMETER;
132         if (len) wlen = integral_atom_name( name, *len, atom);
133         if (ref) *ref = 1;
134         if (pin) *pin = 1;
135     }
136     else
137     {
138         SERVER_START_REQ( get_atom_information )
139         {
140             req->atom = atom;
141             req->table = wine_server_obj_handle( table );
142             if (len && *len && name)
143                 wine_server_set_reply( req, name, *len );
144             status = wine_server_call( req );
145             if (status == STATUS_SUCCESS)
146             {
147                 wlen = reply->total;
148                 if (ref) *ref = reply->count;
149                 if (pin) *pin = reply->pinned;
150             }
151         }
152         SERVER_END_REQ;
153     }
154     if (status == STATUS_SUCCESS && len)
155     {
156         if (*len)
157         {
158             wlen = min( *len - sizeof(WCHAR), wlen );
159             if (name) name[wlen / sizeof(WCHAR)] = 0;
160         }
161         else status = STATUS_BUFFER_TOO_SMALL;
162         *len = wlen;
163     }
164 
165     TRACE( "%p %x -> %s (%x)\n",
166            table, atom, len ? debugstr_wn(name, wlen / sizeof(WCHAR)) : NULL, status );
167     return status;
168 }
169 
170 /******************************************************************
171  *              RtlCreateAtomTable (NTDLL.@)
172  */
173 NTSTATUS WINAPI RtlCreateAtomTable( ULONG size, RTL_ATOM_TABLE* table )
174 {
175     NTSTATUS    status;
176 
177     if (*table)
178     {
179         if (size) status = STATUS_INVALID_PARAMETER;
180         else status = STATUS_SUCCESS;
181     }
182     else
183     {
184         SERVER_START_REQ( init_atom_table )
185         {
186             req->entries = size;
187             status = wine_server_call( req );
188             *table = wine_server_ptr_handle( reply->table );
189         }
190         SERVER_END_REQ;
191     }
192     return status;
193 }
194 
195 /******************************************************************
196  *              RtlDestroyAtomTable (NTDLL.@)
197  */
198 NTSTATUS WINAPI RtlDestroyAtomTable( RTL_ATOM_TABLE table )
199 {
200     if (!table) return STATUS_INVALID_PARAMETER;
201     return NtClose( table );
202 }
203 
204 /******************************************************************
205  *              RtlAddAtomToAtomTable (NTDLL.@)
206  */
207 NTSTATUS WINAPI RtlAddAtomToAtomTable( RTL_ATOM_TABLE table, const WCHAR* name, RTL_ATOM* atom )
208 {
209     NTSTATUS    status;
210 
211     if (!table) status = STATUS_INVALID_PARAMETER;
212     else
213     {
214         size_t len = HIWORD(name) ? strlenW(name) : 0;
215         status = is_integral_atom( name, len, atom );
216         if (status == STATUS_MORE_ENTRIES)
217         {
218             SERVER_START_REQ( add_atom )
219             {
220                 wine_server_add_data( req, name, len * sizeof(WCHAR) );
221                 req->table = wine_server_obj_handle( table );
222                 status = wine_server_call( req );
223                 *atom = reply->atom;
224             }
225             SERVER_END_REQ;
226         }
227     }
228     TRACE( "%p %s -> %x\n",
229            table, debugstr_w(name), status == STATUS_SUCCESS ? *atom : 0 );
230 
231     return status;
232 }
233 
234 /******************************************************************
235  *              RtlLookupAtomInAtomTable (NTDLL.@)
236  */
237 NTSTATUS WINAPI RtlLookupAtomInAtomTable( RTL_ATOM_TABLE table, const WCHAR* name, RTL_ATOM* atom )
238 {
239     NTSTATUS    status;
240 
241     if (!table) status = STATUS_INVALID_PARAMETER;
242     else
243     {
244         size_t len = HIWORD(name) ? strlenW(name) : 0;
245         status = is_integral_atom( name, len, atom );
246         if (status == STATUS_MORE_ENTRIES)
247         {
248             SERVER_START_REQ( find_atom )
249             {
250                 wine_server_add_data( req, name, len * sizeof(WCHAR) );
251                 req->table = wine_server_obj_handle( table );
252                 status = wine_server_call( req );
253                 *atom = reply->atom;
254             }
255             SERVER_END_REQ;
256         }
257     }
258     TRACE( "%p %s -> %x\n",
259            table, debugstr_w(name), status == STATUS_SUCCESS ? *atom : 0 );
260     return status;
261 }
262 
263 /******************************************************************
264  *              RtlEmptyAtomTable (NTDLL.@)
265  */
266 NTSTATUS WINAPI RtlEmptyAtomTable( RTL_ATOM_TABLE table, BOOLEAN delete_pinned )
267 {
268     NTSTATUS    status;
269 
270     if (!table) status = STATUS_INVALID_PARAMETER;
271     else
272     {
273         SERVER_START_REQ( empty_atom_table )
274         {
275             req->table = wine_server_obj_handle( table );
276             req->if_pinned = delete_pinned;
277             status = wine_server_call( req );
278         }
279         SERVER_END_REQ;
280     }
281     return status;
282 }
283 
284 /******************************************************************
285  *              RtlPinAtomInAtomTable (NTDLL.@)
286  */
287 NTSTATUS WINAPI RtlPinAtomInAtomTable( RTL_ATOM_TABLE table, RTL_ATOM atom )
288 {
289     NTSTATUS status;
290 
291     if (!table) return STATUS_INVALID_PARAMETER;
292     if (atom < MAXINTATOM) return STATUS_SUCCESS;
293 
294     SERVER_START_REQ( set_atom_information )
295     {
296         req->table = wine_server_obj_handle( table );
297         req->atom = atom;
298         req->pinned = TRUE;
299         status = wine_server_call( req );
300     }
301     SERVER_END_REQ;
302 
303     return status;
304 }
305 
306 /*************************************************
307  *        Global handle table management
308  *************************************************/
309 
310 /******************************************************************
311  *              NtAddAtom (NTDLL.@)
312  */
313 NTSTATUS WINAPI NtAddAtom( const WCHAR* name, ULONG length, RTL_ATOM* atom )
314 {
315     NTSTATUS    status;
316 
317     status = is_integral_atom( name, length / sizeof(WCHAR), atom );
318     if (status == STATUS_MORE_ENTRIES)
319     {
320         SERVER_START_REQ( add_atom )
321         {
322             wine_server_add_data( req, name, length );
323             req->table = 0;
324             status = wine_server_call( req );
325             *atom = reply->atom;
326         }
327         SERVER_END_REQ;
328     }
329     TRACE( "%s -> %x\n",
330            debugstr_wn(name, length/sizeof(WCHAR)), status == STATUS_SUCCESS ? *atom : 0 );
331     return status;
332 }
333 
334 /******************************************************************
335  *              NtDeleteAtom (NTDLL.@)
336  */
337 NTSTATUS WINAPI NtDeleteAtom(RTL_ATOM atom)
338 {
339     NTSTATUS    status;
340 
341     SERVER_START_REQ( delete_atom )
342     {
343         req->atom = atom;
344         req->table = 0;
345         status = wine_server_call( req );
346     }
347     SERVER_END_REQ;
348     return status;
349 }
350 
351 /******************************************************************
352  *              NtFindAtom (NTDLL.@)
353  */
354 NTSTATUS WINAPI NtFindAtom( const WCHAR* name, ULONG length, RTL_ATOM* atom )
355 {
356     NTSTATUS    status;
357 
358     status = is_integral_atom( name, length / sizeof(WCHAR), atom );
359     if (status == STATUS_MORE_ENTRIES)
360     {
361         SERVER_START_REQ( find_atom )
362         {
363             wine_server_add_data( req, name, length );
364             req->table = 0;
365             status = wine_server_call( req );
366             *atom = reply->atom;
367         }
368         SERVER_END_REQ;
369     }
370     TRACE( "%s -> %x\n",
371            debugstr_wn(name, length/sizeof(WCHAR)), status == STATUS_SUCCESS ? *atom : 0 );
372     return status;
373 }
374 
375 /******************************************************************
376  *              NtQueryInformationAtom (NTDLL.@)
377  */
378 NTSTATUS WINAPI NtQueryInformationAtom( RTL_ATOM atom, ATOM_INFORMATION_CLASS class,
379                                         PVOID ptr, ULONG size, PULONG psize )
380 {
381     NTSTATUS status;
382 
383     switch (class)
384     {
385     case AtomBasicInformation:
386         {
387             ULONG name_len;
388             ATOM_BASIC_INFORMATION* abi = ptr;
389 
390             if (size < sizeof(ATOM_BASIC_INFORMATION))
391                 return STATUS_INVALID_PARAMETER;
392             name_len = size - sizeof(ATOM_BASIC_INFORMATION);
393 
394             if (atom < MAXINTATOM)
395             {
396                 if (atom)
397                 {
398                     abi->NameLength = integral_atom_name( abi->Name, name_len, atom );
399                     status = (name_len) ? STATUS_SUCCESS : STATUS_BUFFER_TOO_SMALL;
400                     abi->ReferenceCount = 1;
401                     abi->Pinned = 1;
402                 }
403                 else status = STATUS_INVALID_PARAMETER;
404             }
405             else
406             {
407                 SERVER_START_REQ( get_atom_information )
408                 {
409                     req->atom = atom;
410                     req->table = 0;
411                     if (name_len) wine_server_set_reply( req, abi->Name, name_len );
412                     status = wine_server_call( req );
413                     if (status == STATUS_SUCCESS)
414                     {
415                         name_len = wine_server_reply_size( reply );
416                         if (name_len)
417                         {
418                             abi->NameLength = name_len;
419                             abi->Name[name_len / sizeof(WCHAR)] = '\0';
420                         }
421                         else
422                         {
423                             name_len = reply->total;
424                             abi->NameLength = name_len;
425                             status = STATUS_BUFFER_TOO_SMALL;
426                         }
427                         abi->ReferenceCount = reply->count;
428                         abi->Pinned = reply->pinned;
429                     }
430                     else name_len = 0;
431                 }
432                 SERVER_END_REQ;
433             }
434             TRACE( "%x -> %s (%u)\n", 
435                    atom, debugstr_wn(abi->Name, abi->NameLength / sizeof(WCHAR)),
436                    status );
437             if (psize)
438                 *psize = sizeof(ATOM_BASIC_INFORMATION) + name_len;
439         }
440         break;
441     default:
442         FIXME( "Unsupported class %u\n", class );
443         status = STATUS_INVALID_INFO_CLASS;
444         break;
445     }
446     return status;
447 }
448 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.