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

  1. /***
  2. *a_env.c - A 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 __crtGetEnvironmentStringsA - Get normal environment block
  23. *
  24. *Purpose:
  25. *       Internal support function. Since GetEnvironmentStrings returns in OEM
  26. *       and we want ANSI (note that GetEnvironmentVariable returns ANSI!) and
  27. *       SetFileApistoAnsi() does not affect it, we have no choice but to
  28. *       obtain the block in wide character and convert to ANSI.
  29. *
  30. *Entry:
  31. *       VOID
  32. *
  33. *Exit:
  34. *       LPVOID - pointer to environment block
  35. *
  36. *Exceptions:
  37. *
  38. *******************************************************************************/
  39.  
  40. LPVOID __cdecl __crtGetEnvironmentStringsA(
  41.         VOID
  42.         )
  43. {
  44.         static int f_use = 0;
  45.         wchar_t *wEnv = NULL;
  46.         wchar_t *wTmp;
  47.         char *aEnv = NULL;
  48.         char *aTmp;
  49.         int nSizeW;
  50.         int nSizeA;
  51.  
  52.         /*
  53.          * Look for 'preferred' flavor. Otherwise use available flavor.
  54.          * Must actually call the function to ensure it's not a stub.
  55.          */
  56.  
  57.         if ( 0 == f_use )
  58.         {
  59.             if ( NULL != (wEnv = GetEnvironmentStringsW()) )
  60.                 f_use = USE_W;
  61.  
  62.             else if ( NULL != (aEnv = GetEnvironmentStringsA()) )
  63.                 f_use = USE_A;
  64.  
  65.             else
  66.                 return NULL;
  67.         }
  68.  
  69.         /* Use "W" version */
  70.  
  71.         if (USE_W == f_use)
  72.         {
  73.             /* obtain wide environment block */
  74.             if ( NULL == wEnv )
  75.                 if ( NULL == (wEnv = GetEnvironmentStringsW()) )
  76.                     return NULL;
  77.  
  78.             /* look for double null that indicates end of block */
  79.             wTmp = wEnv;
  80.             while ( *wTmp != L'\0' ) {
  81.                 if ( *++wTmp == L'\0' )
  82.                     wTmp++;
  83.             }
  84.  
  85.             /* calculate total size of block, including all nulls */
  86.             nSizeW = wTmp - wEnv + 1;
  87.  
  88.             /* find out how much space needed for multi-byte environment */
  89.             nSizeA = WideCharToMultiByte(   CP_ACP,
  90.                                             0,
  91.                                             wEnv,
  92.                                             nSizeW,
  93.                                             NULL,
  94.                                             0,
  95.                                             NULL,
  96.                                             NULL );
  97.  
  98.             /* allocate space for multi-byte string */
  99.             if ( (nSizeA == 0) ||
  100.                  ((aEnv = (char *)_malloc_crt(nSizeA)) == NULL) )
  101.             {
  102.                 FreeEnvironmentStringsW( wEnv );
  103.                 return NULL;
  104.             }
  105.  
  106.             /* do the conversion */
  107.             if ( !WideCharToMultiByte(  CP_ACP,
  108.                                         0,
  109.                                         wEnv,
  110.                                         nSizeW,
  111.                                         aEnv,
  112.                                         nSizeA,
  113.                                         NULL,
  114.                                         NULL ) )
  115.             {
  116.                 _free_crt( aEnv );
  117.                 aEnv = NULL;
  118.             }
  119.  
  120.             FreeEnvironmentStringsW( wEnv );
  121.             return aEnv;
  122.         }
  123.  
  124.         /* Use "A" version */
  125.  
  126.         if ( USE_A == f_use )
  127.         {
  128.             if ( NULL == aEnv )
  129.                 if ( NULL == (aEnv = GetEnvironmentStringsA()) )
  130.                     return NULL;
  131.  
  132.             /* determine how big a buffer is needed */
  133.  
  134.             aTmp = aEnv;
  135.  
  136.             while ( *aTmp != '\0' ) {
  137.                 if ( *++aTmp == '\0' )
  138.                     aTmp++;
  139.             }
  140.  
  141.             nSizeA = aTmp - aEnv + 1;
  142.  
  143.             if ( NULL == (aTmp = _malloc_crt( nSizeA )) ) {
  144.                 FreeEnvironmentStringsA( aEnv );
  145.                 return NULL;
  146.             }
  147.  
  148.             memcpy( aTmp, aEnv, nSizeA );
  149.  
  150.             FreeEnvironmentStringsA( aEnv );
  151.  
  152.             return aTmp;
  153.         }
  154.  
  155.         return NULL;
  156. }
  157.