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.

185 lines
5.6 KiB

  1. /***
  2. *w_env.c - W 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 from aw_env.c.
  19. * 03-03-98 RKP Supported 64 bits
  20. * 08-21-98 GJF Use CP_ACP instead of __lc_codepage.
  21. * 01-08-99 GJF Changes for 64-bit size_t.
  22. * 05-17-00 GB Use ERROR_CALL_NOT_IMPLEMENTED for existance of W API
  23. *
  24. *******************************************************************************/
  25. #include <cruntime.h>
  26. #include <internal.h>
  27. #include <stdlib.h>
  28. #include <setlocal.h>
  29. #include <awint.h>
  30. #include <dbgint.h>
  31. #define USE_W 1
  32. #define USE_A 2
  33. /***
  34. *LPVOID __cdecl __crtGetEnvironmentStringsW - Get wide environment.
  35. *
  36. *Purpose:
  37. * Internal support function. Tries to use NLS API call
  38. * GetEnvironmentStringsW if available and uses GetEnvironmentStringsA
  39. * if it must. If neither are available it fails and returns 0.
  40. *
  41. *Entry:
  42. * VOID
  43. *
  44. *Exit:
  45. * LPVOID - pointer to environment block
  46. *
  47. *Exceptions:
  48. *
  49. *******************************************************************************/
  50. LPVOID __cdecl __crtGetEnvironmentStringsW(
  51. VOID
  52. )
  53. {
  54. static int f_use = 0;
  55. void *penv = NULL;
  56. char *pch;
  57. wchar_t *pwch;
  58. wchar_t *wbuffer;
  59. int total_size = 0;
  60. int str_size;
  61. /*
  62. * Look for unstubbed '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 != (penv = 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. if ( NULL == penv )
  76. if ( NULL == (penv = GetEnvironmentStringsW()) )
  77. return NULL;
  78. /* find out how big a buffer is needed */
  79. pwch = penv;
  80. while ( *pwch != L'\0' ) {
  81. if ( *++pwch == L'\0' )
  82. pwch++;
  83. }
  84. total_size = (int)((char *)pwch - (char *)penv) +
  85. (int)sizeof( wchar_t );
  86. /* allocate the buffer */
  87. if ( NULL == (wbuffer = _malloc_crt( total_size )) ) {
  88. FreeEnvironmentStringsW( penv );
  89. return NULL;
  90. }
  91. /* copy environment strings to buffer */
  92. memcpy( wbuffer, penv, total_size );
  93. FreeEnvironmentStringsW( penv );
  94. return (LPVOID)wbuffer;
  95. }
  96. /* Use "A" version */
  97. if (USE_A == f_use || f_use == 0)
  98. {
  99. /*
  100. * Convert strings and return the requested information.
  101. */
  102. if ( NULL == penv )
  103. if ( NULL == (penv = GetEnvironmentStringsA()) )
  104. return NULL;
  105. pch = penv;
  106. /* find out how big a buffer we need */
  107. while ( *pch != '\0' )
  108. {
  109. if ( 0 == (str_size =
  110. MultiByteToWideChar( CP_ACP,
  111. MB_PRECOMPOSED,
  112. pch,
  113. -1,
  114. NULL,
  115. 0 )) )
  116. return 0;
  117. total_size += str_size;
  118. pch += strlen(pch) + 1;
  119. }
  120. /* room for final NULL */
  121. total_size++;
  122. /* allocate enough space for chars */
  123. if ( NULL == (wbuffer = (wchar_t *)
  124. _malloc_crt( total_size * sizeof( wchar_t ) )) )
  125. {
  126. FreeEnvironmentStringsA( penv );
  127. return NULL;
  128. }
  129. /* do the conversion */
  130. pch = penv;
  131. pwch = wbuffer;
  132. while (*pch != '\0')
  133. {
  134. if ( 0 == MultiByteToWideChar( CP_ACP,
  135. MB_PRECOMPOSED,
  136. pch,
  137. -1,
  138. pwch,
  139. total_size - (int)(pwch -
  140. wbuffer) ) )
  141. {
  142. _free_crt( wbuffer );
  143. FreeEnvironmentStringsA( penv );
  144. return NULL;
  145. }
  146. pch += strlen(pch) + 1;
  147. pwch += wcslen(pwch) + 1;
  148. }
  149. *pwch = L'\0';
  150. FreeEnvironmentStringsA( penv );
  151. return (LPVOID)wbuffer;
  152. }
  153. else /* f_use is neither USE_A nor USE_W */
  154. return NULL;
  155. }