home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / vc98 / crt / src / w_env.c < prev    next >
C/C++ Source or Header  |  1998-06-17  |  5KB  |  172 lines

  1. /***
  2. *w_env.c - W version of GetEnvironmentStrings.
  3. *
  4. *       Copyright (c) 1993-1997, Microsoft Corporation.  All rights reserved.
  5. *
  6. *Purpose:
  7. *       Use GetEnvironmentStringsW if available, otherwise use A version.
  8. *
  9. *******************************************************************************/
  10.  
  11. #include <cruntime.h>
  12. #include <internal.h>
  13. #include <stdlib.h>
  14. #include <setlocal.h>
  15. #include <awint.h>
  16. #include <dbgint.h>
  17.  
  18. #define USE_W   1
  19. #define USE_A   2
  20.  
  21. /***
  22. *LPVOID __cdecl __crtGetEnvironmentStringsW - Get wide environment.
  23. *
  24. *Purpose:
  25. *       Internal support function. Tries to use NLS API call
  26. *       GetEnvironmentStringsW if available and uses GetEnvironmentStringsA
  27. *       if it must. If neither are available it fails and returns 0.
  28. *
  29. *Entry:
  30. *       VOID
  31. *
  32. *Exit:
  33. *       LPVOID - pointer to environment block
  34. *
  35. *Exceptions:
  36. *
  37. *******************************************************************************/
  38.  
  39. LPVOID __cdecl __crtGetEnvironmentStringsW(
  40.         VOID
  41.         )
  42. {
  43.         static int f_use = 0;
  44.         void *penv = NULL;
  45.         char *pch;
  46.         wchar_t *pwch;
  47.         wchar_t *wbuffer;
  48.         int total_size = 0;
  49.         int str_size;
  50.  
  51.         /*
  52.          * Look for unstubbed 'preferred' flavor. Otherwise use available flavor.
  53.          * Must actually call the function to ensure it's not a stub.
  54.          */
  55.  
  56.         if ( 0 == f_use )
  57.         {
  58.             if ( NULL != (penv = GetEnvironmentStringsW()) )
  59.                 f_use = USE_W;
  60.  
  61.             else if ( NULL != (penv = GetEnvironmentStringsA()) )
  62.                 f_use = USE_A;
  63.             else
  64.                 return NULL;
  65.         }
  66.  
  67.         /* Use "W" version */
  68.  
  69.         if ( USE_W == f_use )
  70.         {
  71.             if ( NULL == penv )
  72.                 if ( NULL == (penv = GetEnvironmentStringsW()) )
  73.                     return NULL;
  74.  
  75.             /* find out how big a buffer is needed */
  76.  
  77.             pwch = penv;
  78.             while ( *pwch != L'\0' ) {
  79.                 if ( *++pwch == L'\0' )
  80.                     pwch++;
  81.             }
  82.  
  83.             total_size = (char *)pwch - (char *)penv + sizeof( wchar_t );
  84.  
  85.             /* allocate the buffer */
  86.  
  87.             if ( NULL == (wbuffer = _malloc_crt( total_size )) ) {
  88.                 FreeEnvironmentStringsW( penv );
  89.                 return NULL;
  90.             }
  91.  
  92.             /* copy environment strings to buffer */
  93.  
  94.             memcpy( wbuffer, penv, total_size );
  95.  
  96.             FreeEnvironmentStringsW( penv );
  97.  
  98.             return (LPVOID)wbuffer;
  99.         }
  100.  
  101.         /* Use "A" version */
  102.  
  103.         if ( USE_A == f_use )
  104.         {
  105.             /*
  106.              * Convert strings and return the requested information.
  107.              */
  108.             if ( NULL == penv )
  109.                 if ( NULL == (penv = GetEnvironmentStringsA()) )
  110.                     return NULL;
  111.  
  112.             pch = penv;
  113.  
  114.             /* find out how big a buffer we need */
  115.             while ( *pch != '\0' )
  116.             {
  117.                 if ( 0 == (str_size =
  118.                       MultiByteToWideChar( __lc_codepage,
  119.                                            MB_PRECOMPOSED,
  120.                                            pch,
  121.                                            -1,
  122.                                            NULL,
  123.                                            0 )) )
  124.                     return 0;
  125.  
  126.                 total_size += str_size;
  127.                 pch += strlen(pch) + 1;
  128.             }
  129.  
  130.             /* room for final NULL */
  131.             total_size++;
  132.  
  133.             /* allocate enough space for chars */
  134.             if ( NULL == (wbuffer = (wchar_t *)
  135.                  _malloc_crt( total_size * sizeof( wchar_t ) )) )
  136.             {
  137.                 FreeEnvironmentStringsA( penv );
  138.                 return NULL;
  139.             }
  140.  
  141.             /* do the conversion */
  142.             pch = penv;
  143.             pwch = wbuffer;
  144.             while (*pch != '\0')
  145.             {
  146.                 if ( 0 == MultiByteToWideChar( __lc_codepage,
  147.                                                MB_PRECOMPOSED,
  148.                                                pch,
  149.                                                -1,
  150.                                                pwch,
  151.                                                total_size - (pwch -
  152.                                                  wbuffer) ) )
  153.                 {
  154.                     _free_crt( wbuffer );
  155.                     FreeEnvironmentStringsA( penv );
  156.                     return NULL;
  157.                 }
  158.  
  159.                 pch += strlen(pch) + 1;
  160.                 pwch += wcslen(pwch) + 1;
  161.             }
  162.             *pwch = L'\0';
  163.  
  164.             FreeEnvironmentStringsA( penv );
  165.  
  166.             return (LPVOID)wbuffer;
  167.  
  168.         }
  169.         else   /* f_use is neither USE_A nor USE_W */
  170.             return NULL;
  171. }
  172.