Source code of Windows XP (NT5)
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.

249 lines
6.5 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1997 - 1999
  6. //
  7. // File: strings.cpp
  8. //
  9. // Useful string manipulation functions.
  10. //
  11. //--------------------------------------------------------------------------
  12. #include "pch.h"
  13. #pragma hdrstop
  14. #define StringByteSize(sz) \
  15. ((lstrlen(sz)+1)*sizeof(TCHAR))
  16. /*-----------------------------------------------------------------------------
  17. / LocalAllocString
  18. / ------------------
  19. / Allocate a string, and initialize it with the specified contents.
  20. /
  21. / In:
  22. / ppResult -> recieves pointer to the new string
  23. / pString -> string to initialize with
  24. /
  25. / Out:
  26. / HRESULT
  27. /----------------------------------------------------------------------------*/
  28. HRESULT LocalAllocString(LPTSTR* ppResult, LPCTSTR pString)
  29. {
  30. if ( !ppResult || !pString )
  31. return E_INVALIDARG;
  32. *ppResult = (LPTSTR)LocalAlloc(LPTR, StringByteSize(pString) );
  33. if ( !*ppResult )
  34. return E_OUTOFMEMORY;
  35. lstrcpy(*ppResult, pString);
  36. return S_OK; // success
  37. }
  38. /*----------------------------------------------------------------------------
  39. / LocalAllocStringLen
  40. / ---------------------
  41. / Given a length return a buffer of that size.
  42. /
  43. / In:
  44. / ppResult -> receives the pointer to the string
  45. / cLen = length in characters to allocate
  46. /
  47. / Out:
  48. / HRESULT
  49. /----------------------------------------------------------------------------*/
  50. HRESULT LocalAllocStringLen(LPTSTR* ppResult, UINT cLen)
  51. {
  52. if ( !ppResult || cLen == 0 )
  53. return E_INVALIDARG;
  54. *ppResult = (LPTSTR)LocalAlloc(LPTR, (cLen+1) * sizeof(TCHAR));
  55. return *ppResult ? S_OK:E_OUTOFMEMORY;
  56. }
  57. /*-----------------------------------------------------------------------------
  58. / LocalFreeString
  59. / -----------------
  60. / Release the string pointed to be *ppString (which can be null) and
  61. / then reset the pointer back to NULL.
  62. /
  63. / In:
  64. / ppString -> pointer to string pointer to be free'd
  65. /
  66. / Out:
  67. / -
  68. /----------------------------------------------------------------------------*/
  69. void LocalFreeString(LPTSTR* ppString)
  70. {
  71. if ( ppString )
  72. {
  73. if ( *ppString )
  74. LocalFree((HLOCAL)*ppString);
  75. *ppString = NULL;
  76. }
  77. }
  78. //*************************************************************
  79. //
  80. // SizeofStringResource
  81. //
  82. // Purpose: Find the length (in chars) of a string resource
  83. //
  84. // Parameters: HINSTANCE hInstance - module containing the string
  85. // UINT idStr - ID of string
  86. //
  87. //
  88. // Return: UINT - # of chars in string, not including NULL
  89. //
  90. // Notes: Based on code from user32.
  91. //
  92. //*************************************************************
  93. UINT
  94. SizeofStringResource(HINSTANCE hInstance,
  95. UINT idStr)
  96. {
  97. UINT cch = 0;
  98. HRSRC hRes = FindResource(hInstance, (LPTSTR)((LONG_PTR)(((USHORT)idStr >> 4) + 1)), RT_STRING);
  99. if (NULL != hRes)
  100. {
  101. HGLOBAL hStringSeg = LoadResource(hInstance, hRes);
  102. if (NULL != hStringSeg)
  103. {
  104. LPWSTR psz = (LPWSTR)LockResource(hStringSeg);
  105. if (NULL != psz)
  106. {
  107. idStr &= 0x0F;
  108. while(true)
  109. {
  110. cch = *psz++;
  111. if (idStr-- == 0)
  112. break;
  113. psz += cch;
  114. }
  115. }
  116. }
  117. }
  118. return cch;
  119. }
  120. //*************************************************************
  121. //
  122. // LoadStringAlloc
  123. //
  124. // Purpose: Loads a string resource into an alloc'd buffer
  125. //
  126. // Parameters: ppszResult - string resource returned here
  127. // hInstance - module to load string from
  128. // idStr - string resource ID
  129. //
  130. // Return: same as LoadString
  131. //
  132. // Notes: On successful return, the caller must
  133. // LocalFree *ppszResult
  134. //
  135. //*************************************************************
  136. int
  137. LoadStringAlloc(LPTSTR *ppszResult, HINSTANCE hInstance, UINT idStr)
  138. {
  139. int nResult = 0;
  140. UINT cch = SizeofStringResource(hInstance, idStr);
  141. if (cch)
  142. {
  143. cch++; // for NULL
  144. *ppszResult = (LPTSTR)LocalAlloc(LPTR, cch * sizeof(TCHAR));
  145. if (*ppszResult)
  146. nResult = LoadString(hInstance, idStr, *ppszResult, cch);
  147. }
  148. return nResult;
  149. }
  150. //*************************************************************
  151. //
  152. // String formatting functions
  153. //
  154. //*************************************************************
  155. DWORD
  156. FormatStringID(LPTSTR *ppszResult, HINSTANCE hInstance, UINT idStr, ...)
  157. {
  158. DWORD dwResult;
  159. va_list args;
  160. va_start(args, idStr);
  161. dwResult = vFormatStringID(ppszResult, hInstance, idStr, &args);
  162. va_end(args);
  163. return dwResult;
  164. }
  165. DWORD
  166. FormatString(LPTSTR *ppszResult, LPCTSTR pszFormat, ...)
  167. {
  168. DWORD dwResult;
  169. va_list args;
  170. va_start(args, pszFormat);
  171. dwResult = vFormatString(ppszResult, pszFormat, &args);
  172. va_end(args);
  173. return dwResult;
  174. }
  175. DWORD
  176. vFormatStringID(LPTSTR *ppszResult, HINSTANCE hInstance, UINT idStr, va_list *pargs)
  177. {
  178. DWORD dwResult = 0;
  179. LPTSTR pszFormat = NULL;
  180. if (LoadStringAlloc(&pszFormat, hInstance, idStr))
  181. {
  182. dwResult = vFormatString(ppszResult, pszFormat, pargs);
  183. LocalFree(pszFormat);
  184. }
  185. return dwResult;
  186. }
  187. DWORD
  188. vFormatString(LPTSTR *ppszResult, LPCTSTR pszFormat, va_list *pargs)
  189. {
  190. return FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_STRING,
  191. pszFormat,
  192. 0,
  193. 0,
  194. (LPTSTR)ppszResult,
  195. 1,
  196. pargs);
  197. }
  198. //*************************************************************
  199. //
  200. // GetSystemErrorText
  201. //
  202. // Purpose: Retrieve error text for a win32 error value
  203. //
  204. // Parameters: ppszResult - string resource returned here
  205. // dwErr - error ID
  206. //
  207. // Return: same as FormatMessage
  208. //
  209. // Notes: On successful return, the caller must
  210. // LocalFree *ppszResult
  211. //
  212. //*************************************************************
  213. DWORD
  214. GetSystemErrorText(LPTSTR *ppszResult, DWORD dwErr)
  215. {
  216. return FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
  217. NULL,
  218. dwErr,
  219. 0,
  220. (LPTSTR)ppszResult,
  221. 0,
  222. NULL);
  223. }