Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

167 lines
5.1 KiB

  1. /***
  2. *a_env.c - A version of GetEnvironmentStrings.
  3. *
  4. * Copyright (c) 1993-2001, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. * Use GetEnvironmentStringsW if available, otherwise use A version.
  8. *
  9. *Revision History:
  10. * 03-29-94 CFW Module created.
  11. * 12-27-94 CFW Call direct, all OS's have stubs.
  12. * 01-10-95 CFW Debug CRT allocs.
  13. * 04-07-95 CFW Create __crtGetEnvironmentStringsA.
  14. * 07-03-95 GJF Modified to always malloc a buffer for the
  15. * environment strings, and to free the OS's buffer.
  16. * 06-10-96 GJF Initialize aEnv and wEnv to NULL in
  17. * __crtGetEnvironmentStringsA. Also, detab-ed.
  18. * 05-14-97 GJF Split off W version into another file and renamed this
  19. * one as a_env.c.
  20. * 03-03-98 RKP Supported 64 bits
  21. * 05-17-00 GB Use ERROR_CALL_NOT_IMPLEMENTED for existance of W API
  22. *
  23. *******************************************************************************/
  24. #include <cruntime.h>
  25. #include <internal.h>
  26. #include <stdlib.h>
  27. #include <setlocal.h>
  28. #include <awint.h>
  29. #include <dbgint.h>
  30. #define USE_W 1
  31. #define USE_A 2
  32. /***
  33. *LPVOID __cdecl __crtGetEnvironmentStringsA - Get normal environment block
  34. *
  35. *Purpose:
  36. * Internal support function. Since GetEnvironmentStrings returns in OEM
  37. * and we want ANSI (note that GetEnvironmentVariable returns ANSI!) and
  38. * SetFileApistoAnsi() does not affect it, we have no choice but to
  39. * obtain the block in wide character and convert to ANSI.
  40. *
  41. *Entry:
  42. * VOID
  43. *
  44. *Exit:
  45. * LPVOID - pointer to environment block
  46. *
  47. *Exceptions:
  48. *
  49. *******************************************************************************/
  50. LPVOID __cdecl __crtGetEnvironmentStringsA(
  51. VOID
  52. )
  53. {
  54. static int f_use = 0;
  55. wchar_t *wEnv = NULL;
  56. wchar_t *wTmp;
  57. char *aEnv = NULL;
  58. char *aTmp;
  59. int nSizeW;
  60. int nSizeA;
  61. /*
  62. * Look for 'preferred' flavor. Otherwise use available flavor.
  63. * Must actually call the function to ensure it's not a stub.
  64. */
  65. if ( 0 == f_use )
  66. {
  67. if ( NULL != (wEnv = GetEnvironmentStringsW()) )
  68. f_use = USE_W;
  69. else if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
  70. f_use = USE_A;
  71. }
  72. /* Use "W" version */
  73. if (USE_W == f_use)
  74. {
  75. /* obtain wide environment block */
  76. if ( NULL == wEnv )
  77. if ( NULL == (wEnv = GetEnvironmentStringsW()) )
  78. return NULL;
  79. /* look for double null that indicates end of block */
  80. wTmp = wEnv;
  81. while ( *wTmp != L'\0' ) {
  82. if ( *++wTmp == L'\0' )
  83. wTmp++;
  84. }
  85. /* calculate total size of block, including all nulls */
  86. nSizeW = (int)(wTmp - wEnv + 1);
  87. /* find out how much space needed for multi-byte environment */
  88. nSizeA = WideCharToMultiByte( CP_ACP,
  89. 0,
  90. wEnv,
  91. nSizeW,
  92. NULL,
  93. 0,
  94. NULL,
  95. NULL );
  96. /* allocate space for multi-byte string */
  97. if ( (nSizeA == 0) ||
  98. ((aEnv = (char *)_malloc_crt(nSizeA)) == NULL) )
  99. {
  100. FreeEnvironmentStringsW( wEnv );
  101. return NULL;
  102. }
  103. /* do the conversion */
  104. if ( !WideCharToMultiByte( CP_ACP,
  105. 0,
  106. wEnv,
  107. nSizeW,
  108. aEnv,
  109. nSizeA,
  110. NULL,
  111. NULL ) )
  112. {
  113. _free_crt( aEnv );
  114. aEnv = NULL;
  115. }
  116. FreeEnvironmentStringsW( wEnv );
  117. return aEnv;
  118. }
  119. /* Use "A" version */
  120. if (USE_A == f_use || f_use == 0)
  121. {
  122. if ( NULL == aEnv )
  123. if ( NULL == (aEnv = GetEnvironmentStringsA()) )
  124. return NULL;
  125. /* determine how big a buffer is needed */
  126. aTmp = aEnv;
  127. while ( *aTmp != '\0' ) {
  128. if ( *++aTmp == '\0' )
  129. aTmp++;
  130. }
  131. nSizeA = (int)(aTmp - aEnv + 1);
  132. if ( NULL == (aTmp = _malloc_crt( nSizeA )) ) {
  133. FreeEnvironmentStringsA( aEnv );
  134. return NULL;
  135. }
  136. memcpy( aTmp, aEnv, nSizeA );
  137. FreeEnvironmentStringsA( aEnv );
  138. return aTmp;
  139. }
  140. return NULL;
  141. }