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.

232 lines
4.4 KiB

  1. //+--------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1996 - 1999
  5. //
  6. // File: string.cpp
  7. //
  8. // Contents: Cert Server wrapper routines
  9. //
  10. //---------------------------------------------------------------------------
  11. #include <pch.cpp>
  12. #pragma hdrstop
  13. #define __dwFILE__ __dwFILE_CERTLIB_STRING_CPP__
  14. extern HINSTANCE g_hInstance;
  15. DWORD g_cStringAlloc;
  16. DWORD g_cStringUsed;
  17. typedef struct _RESOURCESTRING
  18. {
  19. DWORD id;
  20. WCHAR const *pwsz;
  21. } RESOURCESTRING;
  22. #define CRS_CHUNK 100
  23. RESOURCESTRING *g_rgrs = NULL;
  24. DWORD g_crsMax = 0;
  25. DWORD g_crs = 0;
  26. RESOURCESTRING *
  27. AllocStringHeader()
  28. {
  29. if (g_crs >= g_crsMax)
  30. {
  31. DWORD cb = (CRS_CHUNK + g_crsMax) * sizeof(g_rgrs[0]);
  32. RESOURCESTRING *rgrsT;
  33. if (NULL == g_rgrs)
  34. {
  35. rgrsT = (RESOURCESTRING *) LocalAlloc(LMEM_FIXED, cb);
  36. }
  37. else
  38. {
  39. rgrsT = (RESOURCESTRING *) LocalReAlloc(g_rgrs, cb, LMEM_MOVEABLE);
  40. }
  41. if (NULL == rgrsT)
  42. {
  43. DBGPRINT((
  44. DBG_SS_CERTLIB,
  45. "Error allocating resource string header\n"));
  46. return(NULL);
  47. }
  48. g_rgrs = rgrsT;
  49. g_crsMax += CRS_CHUNK;
  50. }
  51. return(&g_rgrs[g_crs++]);
  52. }
  53. #define cwcRESOURCEMIN 128
  54. #define cwcRESOURCEMAX 8192
  55. WCHAR *
  56. myLoadResourceStringNoCache(
  57. IN HINSTANCE hInstance,
  58. IN DWORD ResourceId)
  59. {
  60. HRESULT hr;
  61. WCHAR awc[cwcRESOURCEMIN];
  62. WCHAR *pwsz = NULL;
  63. DWORD cwc;
  64. WCHAR *pwszString = NULL;
  65. pwsz = awc;
  66. cwc = ARRAYSIZE(awc);
  67. for (;;)
  68. {
  69. if (!LoadString(hInstance, ResourceId, pwsz, cwc))
  70. {
  71. hr = myHLastError();
  72. if (S_OK == hr)
  73. {
  74. hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
  75. }
  76. DBGPRINT((
  77. DBG_SS_CERTLIB,
  78. "LoadString(%d) -> %x\n",
  79. ResourceId,
  80. hr));
  81. _JumpError(hr, error, "LoadString");
  82. }
  83. #if 0
  84. DBGPRINT((
  85. DBG_SS_CERTLIBI,
  86. "myLoadResourceString(%d) %x/%x\n",
  87. ResourceId,
  88. wcslen(pwsz),
  89. cwc));
  90. #endif
  91. // if there's any room left, the resource was not truncated.
  92. // if the buffer is already at the maximum size we support, we just
  93. // live with the truncation.
  94. if (wcslen(pwsz) < cwc - 1 || cwcRESOURCEMAX <= cwc)
  95. {
  96. break;
  97. }
  98. // LoadString filled the buffer completely, so the string may have
  99. // been truncated. Double the buffer size and try again.
  100. DBGPRINT((
  101. DBG_SS_CERTLIBI,
  102. "myLoadResourceString(%d) %x/%x ==> %x\n",
  103. ResourceId,
  104. wcslen(pwsz),
  105. cwc,
  106. cwc << 1));
  107. if (awc != pwsz)
  108. {
  109. LocalFree(pwsz);
  110. pwsz = NULL;
  111. }
  112. cwc <<= 1;
  113. pwsz = (WCHAR *) LocalAlloc(LMEM_FIXED, cwc * sizeof(WCHAR));
  114. if (NULL == pwsz)
  115. {
  116. hr = E_OUTOFMEMORY;
  117. _JumpError(hr, error, "LocalAlloc");
  118. }
  119. }
  120. hr = myDupString(pwsz, &pwszString);
  121. _JumpIfError(hr, error, "myDupString");
  122. error:
  123. if (NULL != pwsz && awc != pwsz)
  124. {
  125. LocalFree(pwsz);
  126. }
  127. if (NULL == pwszString)
  128. {
  129. SetLastError(hr);
  130. }
  131. return(pwszString);
  132. }
  133. WCHAR const *
  134. myLoadResourceString(
  135. IN DWORD ResourceId)
  136. {
  137. DWORD i;
  138. WCHAR const *pwszString = NULL;
  139. WCHAR *pwszAlloc;
  140. for (i = 0; i < g_crs; i++)
  141. {
  142. if (g_rgrs[i].id == ResourceId)
  143. {
  144. pwszString = g_rgrs[i].pwsz;
  145. break;
  146. }
  147. }
  148. if (NULL == pwszString)
  149. {
  150. RESOURCESTRING *prs;
  151. pwszAlloc = myLoadResourceStringNoCache(g_hInstance, ResourceId);
  152. if (NULL == pwszAlloc)
  153. {
  154. goto error; // myLoadResourceStringNoCache sets LastError
  155. }
  156. prs = AllocStringHeader();
  157. if (NULL != prs)
  158. {
  159. prs->id = ResourceId;
  160. prs->pwsz = pwszAlloc;
  161. }
  162. pwszString = pwszAlloc;
  163. g_cStringAlloc++;
  164. }
  165. g_cStringUsed++;
  166. CSASSERT(NULL != pwszString);
  167. error:
  168. return(pwszString);
  169. }
  170. VOID
  171. myFreeResourceStrings(
  172. IN char const *DBGPARMREFERENCED(pszModule))
  173. {
  174. DWORD i;
  175. if (0 != g_cStringAlloc || 0 != g_crs || 0 != g_cStringUsed)
  176. {
  177. DBGPRINT((
  178. DBG_SS_CERTLIBI,
  179. "%hs Strings: alloc = %d, saved = %d, used = %d\n",
  180. pszModule,
  181. g_cStringAlloc,
  182. g_crs,
  183. g_cStringUsed));
  184. }
  185. if (NULL != g_rgrs)
  186. {
  187. for (i = 0; i < g_crs; i++)
  188. {
  189. LocalFree(const_cast<WCHAR *>(g_rgrs[i].pwsz));
  190. g_rgrs[i].pwsz = NULL;
  191. g_rgrs[i].id = 0;
  192. }
  193. LocalFree(g_rgrs);
  194. g_rgrs = NULL;
  195. }
  196. g_crsMax = 0;
  197. g_crs = 0;
  198. g_cStringAlloc = 0;
  199. g_cStringUsed = 0;
  200. }