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

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

Version: ~ [ wine-1.5.30 ] ~ [ wine-1.5.29 ] ~ [ wine-1.5.28 ] ~ [ wine-1.5.27 ] ~ [ wine-1.5.26 ] ~ [ wine-1.5.25 ] ~ [ wine-1.5.24 ] ~ [ wine-1.5.23 ] ~ [ wine-1.5.22 ] ~ [ wine-1.5.21 ] ~ [ wine-1.5.20 ] ~ [ wine-1.5.19 ] ~ [ wine-1.5.18 ] ~ [ wine-1.5.17 ] ~ [ wine-1.5.16 ] ~ [ wine-1.5.15 ] ~ [ wine-1.5.14 ] ~ [ wine-1.5.13 ] ~ [ wine-1.5.12 ] ~ [ wine-1.5.11 ] ~ [ wine-1.5.10 ] ~ [ wine-1.5.9 ] ~ [ wine-1.5.8 ] ~ [ wine-1.5.7 ] ~ [ wine-1.4.1 ] ~ [ wine-1.5.6 ] ~ [ wine-1.5.5 ] ~ [ wine-1.5.4 ] ~ [ wine-1.5.3 ] ~ [ wine-1.5.2 ] ~ [ wine-1.5.1 ] ~ [ wine-1.5.0 ] ~ [ wine-1.4 ] ~ [ wine-1.4-rc6 ] ~ [ wine-1.4-rc5 ] ~ [ wine-1.4-rc4 ] ~ [ wine-1.4-rc3 ] ~ [ wine-1.4-rc2 ] ~ [ wine-1.4-rc1 ] ~ [ wine-1.3.37 ] ~ [ wine-1.3.36 ] ~ [ wine-1.3.35 ] ~ [ wine-1.3.34 ] ~ [ wine-1.3.33 ] ~ [ wine-1.3.32 ] ~ [ wine-1.3.31 ] ~ [ wine-1.3.30 ] ~ [ wine-1.3.29 ] ~ [ wine-1.3.28 ] ~ [ wine-1.3.27 ] ~ [ wine-1.3.26 ] ~ [ wine-1.3.25 ] ~ [ wine-1.3.24 ] ~ [ wine-1.3.23 ] ~ [ wine-1.3.22 ] ~ [ wine-1.3.21 ] ~ [ wine-1.3.20 ] ~ [ wine-1.3.19 ] ~ [ wine-1.3.18 ] ~ [ wine-1.2.3 ] ~ [ wine-1.3.17 ] ~ [ wine-1.3.16 ] ~ [ wine-1.3.15 ] ~ [ wine-1.3.14 ] ~ [ wine-1.3.13 ] ~ [ wine-1.3.12 ] ~ [ wine-1.3.11 ] ~ [ wine-1.3.10 ] ~ [ wine-1.3.9 ] ~ [ wine-1.2.2 ] ~ [ wine-1.3.8 ] ~ [ wine-1.3.7 ] ~ [ wine-1.3.6 ] ~ [ wine-1.3.5 ] ~ [ wine-1.2.1 ] ~ [ wine-1.3.4 ] ~ [ wine-1.3.3 ] ~ [ wine-1.3.2 ] ~ [ wine-1.3.1 ] ~ [ wine-1.3.0 ] ~ [ wine-1.2 ] ~ [ wine-1.2-rc7 ] ~ [ wine-1.2-rc6 ] ~ [ wine-1.2-rc5 ] ~ [ wine-1.2-rc4 ] ~ [ wine-1.2-rc3 ] ~ [ wine-1.2-rc2 ] ~ [ wine-1.2-rc1 ] ~ [ wine-1.1.44 ] ~ [ wine-1.1.43 ] ~ [ wine-1.1.42 ] ~ [ wine-1.1.41 ] ~ [ wine-1.1.40 ] ~ [ wine-1.1.39 ] ~ [ wine-1.1.38 ] ~ [ wine-1.1.37 ] ~ [ wine-1.1.36 ] ~ [ wine-1.1.35 ] ~ [ wine-1.1.34 ] ~ [ 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  *
  6  * This library is free software; you can redistribute it and/or
  7  * modify it under the terms of the GNU Lesser General Public
  8  * License as published by the Free Software Foundation; either
  9  * version 2.1 of the License, or (at your option) any later version.
 10  *
 11  * This library is distributed in the hope that it will be useful,
 12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 14  * Lesser General Public License for more details.
 15  *
 16  * You should have received a copy of the GNU Lesser General Public
 17  * License along with this library; if not, write to the Free Software
 18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 19  */
 20 
 21 #include "config.h"
 22 #include "wine/port.h"
 23 
 24 #include <stdlib.h>
 25 #include <stdarg.h>
 26 #include <stdio.h>
 27 #include <string.h>
 28 #include <ctype.h>
 29 
 30 #include "windef.h"
 31 #include "winbase.h"
 32 #include "winerror.h"
 33 #include "winternl.h"
 34 
 35 #include "wine/exception.h"
 36 #include "wine/unicode.h"
 37 #include "kernel_private.h"
 38 
 39 #define MAX_ATOM_LEN 255
 40 #define IS_INTATOM(x)   (((ULONG_PTR)(x) >> 16) == 0)
 41 
 42 /******************************************************************
 43  *              get_local_table
 44  *
 45  * Returns the local atom table for this process (and create it if doesn't
 46  * exist yet)
 47  */
 48 static RTL_ATOM_TABLE get_local_table(DWORD entries)
 49 {
 50     static RTL_ATOM_TABLE local_table;
 51 
 52     if (!local_table)
 53     {
 54         NTSTATUS        status;
 55         RTL_ATOM_TABLE  table = NULL;
 56 
 57         if ((status = RtlCreateAtomTable( entries, &table )))
 58             SetLastError( RtlNtStatusToDosError( status ) );
 59         else if (InterlockedCompareExchangePointer((void*)&local_table, table, NULL) != NULL)
 60             RtlDestroyAtomTable( table );
 61     }
 62 
 63     return local_table;
 64 }
 65 
 66 
 67 /***********************************************************************
 68  *           InitAtomTable   (KERNEL32.@)
 69  *
 70  * Initialise the global atom table.
 71  *
 72  * PARAMS
 73  *  entries [I] The number of entries to reserve in the table.
 74  *
 75  * RETURNS
 76  *  Success: TRUE.
 77  *  Failure: FALSE.
 78  */
 79 BOOL WINAPI InitAtomTable( DWORD entries )
 80 {
 81     return get_local_table( entries ) ? TRUE : FALSE;
 82 }
 83 
 84 /******************************************************************
 85  *              check_integral_atom
 86  *
 87  * Check if a string (ANSI or UNICODE) is in fact an integral atom
 88  * (but doesn't check the "#1234" form)
 89  */
 90 static inline BOOL check_integral_atom( const void* ptr, ATOM* patom)
 91 {
 92     if (!IS_INTATOM( ptr )) return FALSE;
 93     if ((*patom = LOWORD( ptr )) >= MAXINTATOM)
 94     {
 95         SetLastError( ERROR_INVALID_PARAMETER );
 96         *patom = 0;
 97     }
 98     return TRUE;
 99 }
100 
101 /***********************************************************************
102  *           GlobalAddAtomA   (KERNEL32.@)
103  *
104  * Add a character string to the global atom table and return a unique
105  * value identifying it.
106  *
107  * RETURNS
108  *      Success: The atom allocated to str.
109  *      Failure: 0.
110  */
111 ATOM WINAPI GlobalAddAtomA( LPCSTR str /* [in] String to add */ )
112 {
113     ATOM atom = 0;
114     __TRY
115     {
116         if (!check_integral_atom( str, &atom ))
117         {
118             WCHAR buffer[MAX_ATOM_LEN];
119             DWORD len = MultiByteToWideChar( CP_ACP, 0, str, strlen(str), buffer, MAX_ATOM_LEN );
120             if (!len) SetLastError( ERROR_INVALID_PARAMETER );
121             else
122             {
123                 NTSTATUS status = NtAddAtom( buffer, len * sizeof(WCHAR), &atom );
124                 if (status)
125                 {
126                     SetLastError( RtlNtStatusToDosError( status ) );
127                     atom = 0;
128                 }
129             }
130         }
131     }
132     __EXCEPT_PAGE_FAULT
133     {
134         SetLastError( ERROR_INVALID_PARAMETER );
135         atom = 0;
136     }
137     __ENDTRY
138     return atom;
139 }
140 
141 
142 /***********************************************************************
143  *           AddAtomA   (KERNEL32.@)
144  *
145  * Add a character string to the global atom table and return a unique
146  * value identifying it.
147  *
148  * RETURNS
149  *      Success: The atom allocated to str.
150  *      Failure: 0.
151  */
152 ATOM WINAPI AddAtomA( LPCSTR str /* [in] String to add */ )
153 {
154     ATOM atom = 0;
155 
156     if (!check_integral_atom( str, &atom ))
157     {
158         WCHAR           buffer[MAX_ATOM_LEN + 1];
159         DWORD           len;
160         RTL_ATOM_TABLE  table;
161 
162         len = MultiByteToWideChar( CP_ACP, 0, str, -1, buffer, MAX_ATOM_LEN + 1 );
163         if (!len) SetLastError( ERROR_INVALID_PARAMETER );
164         else if ((table = get_local_table( 0 )))
165         {
166             NTSTATUS status = RtlAddAtomToAtomTable( table, buffer, &atom );
167             if (status)
168             {
169                 SetLastError( RtlNtStatusToDosError( status ) );
170                 atom = 0;
171             }
172         }
173     }
174     return atom;
175 }
176 
177 /***********************************************************************
178  *           GlobalAddAtomW   (KERNEL32.@)
179  *
180  * Unicode version of GlobalAddAtomA.
181  */
182 ATOM WINAPI GlobalAddAtomW( LPCWSTR str )
183 {
184     ATOM        atom = 0;
185     NTSTATUS    status;
186 
187     if (!check_integral_atom( str, &atom ) && 
188         (status = NtAddAtom( str, strlenW( str ) * sizeof(WCHAR), &atom )))
189     {
190         SetLastError( RtlNtStatusToDosError( status ) );
191         atom = 0;
192     }
193     return atom;
194 }
195 
196 
197 /***********************************************************************
198  *           AddAtomW   (KERNEL32.@)
199  *
200  * Unicode version of AddAtomA.          
201  */
202 ATOM WINAPI AddAtomW( LPCWSTR str )
203 {
204     ATOM                atom = 0;
205     RTL_ATOM_TABLE      table;
206 
207     if (!check_integral_atom( str, &atom ) && (table = get_local_table( 0 )))
208     {
209         NTSTATUS status = RtlAddAtomToAtomTable( table, str, &atom );
210         if (status)
211         {
212             SetLastError( RtlNtStatusToDosError( status ) );
213             atom = 0;
214         }
215     }
216     return atom;
217 }
218 
219 
220 /***********************************************************************
221  *           GlobalDeleteAtom   (KERNEL32.@)
222  *
223  * Decrement the reference count of a string atom.  If the count is
224  * zero, the string associated with the atom is removed from the table.
225  *
226  * RETURNS
227  *      Success: 0.
228  *      Failure: atom.
229  */
230 ATOM WINAPI GlobalDeleteAtom( ATOM atom /* [in] Atom to delete */ )
231 {
232     if (atom >= MAXINTATOM)
233     {
234         NTSTATUS status = NtDeleteAtom( atom );
235         if (status)
236         {
237             SetLastError( RtlNtStatusToDosError( status ) );
238             return atom;
239         }
240     }
241     return 0;
242 }
243 
244 
245 /***********************************************************************
246  *           DeleteAtom   (KERNEL32.@)
247  *
248  * Decrement the reference count of a string atom.  If the count becomes
249  * zero, the string associated with the atom is removed from the table.
250  *
251  * RETURNS
252  *      Success: 0.
253  *      Failure: atom
254  */
255 ATOM WINAPI DeleteAtom( ATOM atom /* [in] Atom to delete */ )
256 {
257     NTSTATUS            status;
258     RTL_ATOM_TABLE      table;
259 
260     if (atom >= MAXINTATOM)
261     {
262         if (!(table = get_local_table( 0 ))) return atom;
263         status = RtlDeleteAtomFromAtomTable( table, atom );
264         if (status)
265         {
266             SetLastError( RtlNtStatusToDosError( status ) );
267             return atom;
268         }
269     }
270     return 0;
271 }
272 
273 
274 /***********************************************************************
275  *           GlobalFindAtomA   (KERNEL32.@)
276  *
277  * Get the atom associated with a string.
278  *
279  * RETURNS
280  *      Success: The associated atom.
281  *      Failure: 0.
282  */
283 ATOM WINAPI GlobalFindAtomA( LPCSTR str /* [in] Pointer to string to search for */ )
284 {
285     ATOM atom = 0;
286 
287     if (!check_integral_atom( str, &atom ))
288     {
289         WCHAR buffer[MAX_ATOM_LEN];
290         DWORD len = MultiByteToWideChar( CP_ACP, 0, str, strlen(str), buffer, MAX_ATOM_LEN );
291 
292         if (!len) SetLastError( ERROR_INVALID_PARAMETER );
293         else
294         {
295             NTSTATUS status = NtFindAtom( buffer, len * sizeof(WCHAR), &atom );
296             if (status)
297             {
298                 SetLastError( RtlNtStatusToDosError( status ) );
299                 atom = 0;
300             }
301         }
302     }
303     return atom;
304 }
305 
306 /***********************************************************************
307  *           FindAtomA   (KERNEL32.@)
308  *
309  * Get the atom associated with a string.
310  *
311  * RETURNS
312  *      Success: The associated atom.
313  *      Failure: 0.
314  */
315 ATOM WINAPI FindAtomA( LPCSTR str /* [in] Pointer to string to find */ )
316 {
317     ATOM atom = 0;
318 
319     if (!check_integral_atom( str, &atom ))
320     {
321         WCHAR           buffer[MAX_ATOM_LEN + 1];
322         DWORD           len;
323         RTL_ATOM_TABLE  table;
324 
325         len = MultiByteToWideChar( CP_ACP, 0, str, -1, buffer, MAX_ATOM_LEN + 1 );
326         if (!len) SetLastError( ERROR_INVALID_PARAMETER );
327         else if ((table = get_local_table( 0 )))
328         {
329             NTSTATUS status = RtlLookupAtomInAtomTable( table, buffer, &atom );
330             if (status)
331             {
332                 SetLastError( RtlNtStatusToDosError( status ) );
333                 atom = 0;
334             }
335         }
336     }
337     return atom;
338 }
339 
340 
341 /***********************************************************************
342  *           GlobalFindAtomW   (KERNEL32.@)
343  *
344  * Unicode version of GlobalFindAtomA.
345  */
346 ATOM WINAPI GlobalFindAtomW( LPCWSTR str )
347 {
348     ATOM atom = 0;
349 
350     if (!check_integral_atom( str, &atom ))
351     {
352         NTSTATUS status = NtFindAtom( str, strlenW( str ) * sizeof(WCHAR), &atom );
353         if (status)
354         {
355             SetLastError( RtlNtStatusToDosError( status ) );
356             atom = 0;
357         }
358     }
359     return atom;
360 }
361 
362 
363 /***********************************************************************
364  *           FindAtomW   (KERNEL32.@)
365  *
366  * Unicode version of FindAtomA.
367  */
368 ATOM WINAPI FindAtomW( LPCWSTR str )
369 {
370     ATOM                atom = 0;
371     NTSTATUS            status;
372     RTL_ATOM_TABLE      table;
373 
374     if ((table = get_local_table( 0 )))
375     {
376         status = RtlLookupAtomInAtomTable( table, str, &atom );
377         if (status)
378         {
379             SetLastError( RtlNtStatusToDosError( status ) );
380             atom = 0;
381         }
382     }
383     return atom;
384 }
385 
386 
387 /***********************************************************************
388  *           GlobalGetAtomNameA   (KERNEL32.@)
389  *
390  * Get a copy of the string associated with an atom.
391  *
392  * RETURNS
393  *      Success: The length of the returned string in characters.
394  *      Failure: 0.
395  */
396 UINT WINAPI GlobalGetAtomNameA(
397               ATOM atom,    /* [in]  Atom identifier */
398               LPSTR buffer, /* [out] Pointer to buffer for atom string */
399               INT count )   /* [in]  Size of buffer */
400 {
401     WCHAR       tmpW[MAX_ATOM_LEN + 1];
402     UINT        wlen, len = 0, c;
403 
404     if (count <= 0) SetLastError( ERROR_MORE_DATA );
405     else if ((wlen = GlobalGetAtomNameW( atom, tmpW, MAX_ATOM_LEN + 1 )))
406     {
407         char    tmp[MAX_ATOM_LEN + 1];
408 
409         len = WideCharToMultiByte( CP_ACP, 0, tmpW, wlen, tmp, MAX_ATOM_LEN + 1, NULL, NULL );
410         c = min(len, count - 1);
411         memcpy(buffer, tmp, c);
412         buffer[c] = '\0';
413         if (len >= count)
414         {
415             len = 0;
416             SetLastError( ERROR_MORE_DATA );
417         }
418     }
419     return len;
420 }
421 
422 
423 /***********************************************************************
424  *           GetAtomNameA   (KERNEL32.@)
425  *
426  * Get a copy of the string associated with an atom.
427  *
428  * RETURNS
429  *      Success: The length of the returned string in characters.
430  *      Failure: 0.
431  */
432 UINT WINAPI GetAtomNameA(
433               ATOM atom,    /* [in]  Atom */
434               LPSTR buffer, /* [out] Pointer to string for atom string */
435               INT count)    /* [in]  Size of buffer */
436 {
437     WCHAR       tmpW[MAX_ATOM_LEN + 1];
438     UINT        wlen, len = 0, c;
439 
440     if (count <= 0) SetLastError( ERROR_MORE_DATA );
441     else if ((wlen = GetAtomNameW( atom, tmpW, MAX_ATOM_LEN + 1 )))
442     {
443         char    tmp[MAX_ATOM_LEN + 1];
444 
445         len = WideCharToMultiByte( CP_ACP, 0, tmpW, wlen, tmp, MAX_ATOM_LEN + 1, NULL, NULL );
446         c = min(len, count - 1);
447         memcpy(buffer, tmp, c);
448         buffer[c] = '\0';
449         if (len >= count)
450         {
451             len = c;
452             SetLastError( ERROR_MORE_DATA );
453         }
454     }
455     return len;
456 }
457 
458 
459 /***********************************************************************
460  *           GlobalGetAtomNameW   (KERNEL32.@)
461  *
462  * Unicode version of GlobalGetAtomNameA.
463  */
464 UINT WINAPI GlobalGetAtomNameW( ATOM atom, LPWSTR buffer, INT count )
465 {
466     char        ptr[sizeof(ATOM_BASIC_INFORMATION) + MAX_ATOM_LEN * sizeof(WCHAR)];
467     ATOM_BASIC_INFORMATION*     abi = (ATOM_BASIC_INFORMATION*)ptr;
468     ULONG       ptr_size = sizeof(ATOM_BASIC_INFORMATION) + MAX_ATOM_LEN * sizeof(WCHAR);
469     NTSTATUS    status;
470     UINT        length = 0;
471 
472     if (count <= 0)
473     {
474         SetLastError( ERROR_MORE_DATA );
475         return 0;
476     }
477     status = NtQueryInformationAtom( atom, AtomBasicInformation, (void*)ptr, ptr_size, NULL );
478     if (status) SetLastError( RtlNtStatusToDosError( status ) );
479     else
480     {
481         length = min( abi->NameLength / sizeof(WCHAR), count);
482         memcpy( buffer, abi->Name, length * sizeof(WCHAR) );
483         /* yes, the string will not be null terminated if the passed buffer
484          * is one WCHAR too small (and it's not an error)
485          */
486         if (length < abi->NameLength / sizeof(WCHAR))
487         {
488             SetLastError( ERROR_MORE_DATA );
489             length = count;
490         }
491         else if (length < count) buffer[length] = '\0';
492     }
493     return length;
494 }
495 
496 
497 /***********************************************************************
498  *           GetAtomNameW   (KERNEL32.@)
499  *
500  * Unicode version of GetAtomNameA.
501  */
502 UINT WINAPI GetAtomNameW( ATOM atom, LPWSTR buffer, INT count )
503 {
504     NTSTATUS            status;
505     RTL_ATOM_TABLE      table;
506     DWORD               length;
507     WCHAR               tmp[MAX_ATOM_LEN + 1];
508 
509     if (count <= 0)
510     {
511         SetLastError( ERROR_MORE_DATA );
512         return 0;
513     }
514     if (!(table = get_local_table( 0 ))) return 0;
515     length = sizeof(tmp);
516     status = RtlQueryAtomInAtomTable( table, atom, NULL, NULL, tmp, &length );
517     if (status)
518     {
519         SetLastError( RtlNtStatusToDosError( status ) );
520         return 0;
521     }
522     length = min(length, (count - 1) * sizeof(WCHAR));
523     if (length) memcpy(buffer, tmp, length);
524     else SetLastError( ERROR_INSUFFICIENT_BUFFER );
525     length /= sizeof(WCHAR);
526     buffer[length] = '\0';
527     return length;
528 }
529 

~ [ 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.