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.

391 lines
9.8 KiB

  1. // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
  2. // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
  3. // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
  4. // PARTICULAR PURPOSE.
  5. //
  6. // Copyright 2001 - 2003 Microsoft Corporation. All Rights Reserved.
  7. //
  8. // FILE: Features.cpp
  9. //
  10. //
  11. // PURPOSE: Implementation wrapper class for WinXP PS Driver Features and Options.
  12. //
  13. //
  14. //
  15. // PLATFORMS: Windows XP, Windows Server 2003
  16. //
  17. //
  18. #include "precomp.h"
  19. #include "debug.h"
  20. #include "oemui.h"
  21. #include "stringutils.h"
  22. // StrSafe.h needs to be included last
  23. // to disallow bad string functions.
  24. #include <STRSAFE.H>
  25. // Create a list of pointers to the strings
  26. // in a multi-sz.
  27. HRESULT MakeStrPtrList(HANDLE hHeap, PCSTR pmszMultiSz, PCSTR **pppszList, PWORD pwCount)
  28. {
  29. PCSTR *ppszList = NULL;
  30. HRESULT hrResult = S_OK;
  31. // Validate parameters
  32. if( (NULL == hHeap)
  33. ||
  34. (NULL == pmszMultiSz)
  35. ||
  36. (NULL == pppszList)
  37. ||
  38. (NULL == pwCount)
  39. )
  40. {
  41. return E_INVALIDARG;
  42. }
  43. // Get the count of strings in the multi-sz.
  44. *pwCount = mstrcount(pmszMultiSz);
  45. if(0 == *pwCount)
  46. {
  47. WARNING(DLLTEXT("MakeStrPtrList() pmszMultiSz contains no strings.\r\n"));
  48. goto Exit;
  49. }
  50. // Allocate pointer list.
  51. *pppszList = (PCSTR *) HeapAlloc(hHeap, HEAP_ZERO_MEMORY, (*pwCount) * sizeof(PCSTR));
  52. if(NULL == *pppszList)
  53. {
  54. ERR(ERRORTEXT("MakeStrPtrList() failed to allote array of PCSTR.\r\n"));
  55. hrResult = E_OUTOFMEMORY;
  56. goto Exit;
  57. }
  58. ppszList = *pppszList;
  59. // Walk multi-sz mapping string pointers.
  60. for(WORD wIndex = 0; wIndex < *pwCount; ++wIndex)
  61. {
  62. ppszList[wIndex] = pmszMultiSz;
  63. pmszMultiSz += lstrlenA(pmszMultiSz) + 1;
  64. }
  65. Exit:
  66. return hrResult;
  67. }
  68. // Determine how many strings are in the multi-sz.
  69. WORD mstrcount(PCSTR pmszMultiSz)
  70. {
  71. WORD wCount = 0;
  72. // NULL string pointers have no strings.
  73. if(NULL == pmszMultiSz)
  74. {
  75. return 0;
  76. }
  77. // Walk list of strings counting them.
  78. while(pmszMultiSz[0] != '\0')
  79. {
  80. ++wCount;
  81. pmszMultiSz += lstrlenA(pmszMultiSz) + 1;
  82. }
  83. return wCount;
  84. }
  85. // Allocates and converts ANSI string to Unicode.
  86. PWSTR MakeUnicodeString(HANDLE hHeap, PCSTR pszAnsi)
  87. {
  88. int nSize = 0;
  89. PWSTR pszUnicode = NULL;
  90. // Validate parameters
  91. if( (NULL == hHeap)
  92. ||
  93. (NULL == pszAnsi)
  94. )
  95. {
  96. return NULL;
  97. }
  98. // Get the size needed for UNICODE string.
  99. nSize = MultiByteToWideChar(CP_ACP, 0, pszAnsi, -1, NULL, 0);
  100. if(0 != nSize)
  101. {
  102. // Allocate unicode string.
  103. pszUnicode = (PWSTR) HeapAlloc(hHeap, 0, nSize * sizeof(WCHAR));
  104. if(NULL != pszUnicode)
  105. {
  106. // Convert ANSI to Unicode
  107. nSize = MultiByteToWideChar(CP_ACP, 0, pszAnsi, -1, pszUnicode, nSize);
  108. if(0 == nSize)
  109. {
  110. // INVARIANT: failed to convert.
  111. // free buffer and return NULL.
  112. HeapFree(hHeap, 0, pszUnicode);
  113. pszUnicode = NULL;
  114. }
  115. }
  116. }
  117. return pszUnicode;
  118. }
  119. // Allocates and copies source string.
  120. PWSTR MakeStringCopy(HANDLE hHeap, PCWSTR pszSource)
  121. {
  122. PWSTR pszCopy = NULL;
  123. DWORD dwSize;
  124. // Validate parameters
  125. if( (NULL == hHeap)
  126. ||
  127. (NULL == pszSource)
  128. )
  129. {
  130. return NULL;
  131. }
  132. // Allocate memory for string duplication, and duplicate the string.
  133. dwSize = (wcslen(pszSource) + 1) * sizeof(WCHAR);
  134. pszCopy = (PWSTR) HeapAlloc(hHeap, HEAP_ZERO_MEMORY, dwSize);
  135. if(NULL != pszCopy)
  136. {
  137. HRESULT hResult;
  138. hResult = StringCbCopyW(pszCopy, dwSize, pszSource);
  139. if(FAILED(hResult))
  140. {
  141. HeapFree(hHeap, 0, pszCopy);
  142. pszCopy = NULL;
  143. SetLastError(hResult);
  144. }
  145. }
  146. return pszCopy;
  147. }
  148. // Allocates and copies source string.
  149. PSTR MakeStringCopy(HANDLE hHeap, PCSTR pszSource)
  150. {
  151. PSTR pszCopy = NULL;
  152. DWORD dwSize;
  153. // Validate parameters
  154. if( (NULL == hHeap)
  155. ||
  156. (NULL == pszSource)
  157. )
  158. {
  159. return NULL;
  160. }
  161. // Allocate memory for string duplication, and duplicate the string.
  162. dwSize = (lstrlenA(pszSource) + 1) * sizeof(CHAR);
  163. pszCopy = (PSTR) HeapAlloc(hHeap, HEAP_ZERO_MEMORY, dwSize);
  164. if(NULL != pszCopy)
  165. {
  166. HRESULT hResult;
  167. hResult = StringCbCopyA(pszCopy, dwSize, pszSource);
  168. if(FAILED(hResult))
  169. {
  170. HeapFree(hHeap, 0, pszCopy);
  171. pszCopy = NULL;
  172. SetLastError(hResult);
  173. }
  174. }
  175. return pszCopy;
  176. }
  177. // Frees list of strings.
  178. // NOTE: don't use this for string list made with MakeStrPtrList(), since
  179. // the strings pointed to be list made with MakeStrPtrList() will
  180. // be freed when the multi-sz is freed.
  181. void FreeStringList(HANDLE hHeap, PWSTR *ppszList, WORD wCount)
  182. {
  183. // Validate parameters.
  184. if( (NULL == hHeap)
  185. ||
  186. (NULL == ppszList)
  187. )
  188. {
  189. return;
  190. }
  191. // Free each of the strings in the list.
  192. for(WORD wIndex = 0; wIndex < wCount; ++wIndex)
  193. {
  194. if(NULL != ppszList[wIndex]) HeapFree(hHeap, 0, ppszList[wIndex]);
  195. }
  196. // Free list.
  197. HeapFree(hHeap, 0, ppszList);
  198. }
  199. // Retrieves pointer to a String resource.
  200. HRESULT GetStringResource(HANDLE hHeap, HMODULE hModule, UINT uResource, PWSTR *ppszString)
  201. {
  202. int nResult;
  203. DWORD dwSize = MAX_PATH;
  204. PWSTR pszString = NULL;
  205. HRESULT hrResult = S_OK;
  206. VERBOSE(DLLTEXT("GetStringResource(%#x, %#x, %d) entered.\r\n"), hHeap, hModule, uResource);
  207. // Validate parameters.
  208. if( (NULL == hHeap)
  209. ||
  210. (NULL == ppszString)
  211. )
  212. {
  213. return E_INVALIDARG;
  214. }
  215. // Allocate buffer for string resource from heap; let the driver clean it up.
  216. pszString = (PWSTR) HeapAlloc(hHeap, HEAP_ZERO_MEMORY, dwSize * sizeof(WCHAR));
  217. if(NULL == pszString)
  218. {
  219. ERR(ERRORTEXT("GetStringResource() failed to allocate string buffer!\r\n"));
  220. hrResult = E_OUTOFMEMORY;
  221. goto Exit;
  222. }
  223. // Load string resource; resize after loading so as not to waste memory.
  224. nResult = LoadString(hModule, uResource, pszString, dwSize);
  225. if(nResult > 0)
  226. {
  227. PWSTR pszTemp;
  228. VERBOSE(DLLTEXT("LoadString() returned %d!\r\n"), nResult);
  229. VERBOSE(DLLTEXT("String load was \"%s\".\r\n"), pszString);
  230. pszTemp = (PWSTR) HeapReAlloc(hHeap, HEAP_ZERO_MEMORY, pszString, (nResult + 1) * sizeof(WCHAR));
  231. if(NULL != pszTemp)
  232. {
  233. pszString = pszTemp;
  234. }
  235. else
  236. {
  237. WARNING(DLLTEXT("GetStringResource() HeapReAlloc() of string retrieved failed! (Last Error was %d)\r\n"), GetLastError());
  238. }
  239. }
  240. else
  241. {
  242. DWORD dwError = GetLastError();
  243. ERR(ERRORTEXT("LoadString() returned %d! (Last Error was %d)\r\n"), nResult, GetLastError());
  244. ERR(ERRORTEXT("GetStringResource() failed to load string resource %d!\r\n"), uResource);
  245. HeapFree(hHeap, 0, pszString);
  246. pszString = NULL;
  247. hrResult = HRESULT_FROM_WIN32(dwError);
  248. }
  249. Exit:
  250. // Save string pointer to caller.
  251. // NOTE: string pointer will be NULL on failure.
  252. *ppszString = pszString;
  253. return hrResult;
  254. }
  255. // Retrieves pointer to a String resource.
  256. HRESULT GetStringResource(HANDLE hHeap, HMODULE hModule, UINT uResource, PSTR *ppszString)
  257. {
  258. int nResult;
  259. DWORD dwSize = MAX_PATH;
  260. PSTR pszString = NULL;
  261. HRESULT hrResult = S_OK;
  262. VERBOSE(DLLTEXT("GetStringResource(%#x, %#x, %d) entered.\r\n"), hHeap, hModule, uResource);
  263. // Validate parameters.
  264. if( (NULL == hHeap)
  265. ||
  266. (NULL == ppszString)
  267. )
  268. {
  269. return E_INVALIDARG;
  270. }
  271. // Allocate buffer for string resource from heap; let the driver clean it up.
  272. pszString = (PSTR) HeapAlloc(hHeap, HEAP_ZERO_MEMORY, dwSize * sizeof(WCHAR));
  273. if(NULL == pszString)
  274. {
  275. ERR(ERRORTEXT("GetStringResource() failed to allocate string buffer!\r\n"));
  276. hrResult = E_OUTOFMEMORY;
  277. goto Exit;
  278. }
  279. // Load string resource; resize after loading so as not to waste memory.
  280. nResult = LoadStringA(hModule, uResource, pszString, dwSize);
  281. if(nResult > 0)
  282. {
  283. PSTR pszTemp;
  284. VERBOSE(DLLTEXT("LoadString() returned %d!\r\n"), nResult);
  285. VERBOSE(DLLTEXT("String load was \"%hs\".\r\n"), pszString);
  286. pszTemp = (PSTR) HeapReAlloc(hHeap, HEAP_ZERO_MEMORY, pszString, nResult + 1);
  287. if(NULL != pszTemp)
  288. {
  289. pszString = pszTemp;
  290. }
  291. else
  292. {
  293. WARNING(DLLTEXT("GetStringResource() HeapReAlloc() of string retrieved failed! (Last Error was %d)\r\n"), GetLastError());
  294. }
  295. }
  296. else
  297. {
  298. DWORD dwError = GetLastError();
  299. ERR(ERRORTEXT("LoadString() returned %d! (Last Error was %d)\r\n"), nResult, GetLastError());
  300. ERR(ERRORTEXT("GetStringResource() failed to load string resource %d!\r\n"), uResource);
  301. HeapFree(hHeap, 0, pszString);
  302. pszString = NULL;
  303. hrResult = HRESULT_FROM_WIN32(dwError);
  304. }
  305. Exit:
  306. // Save string pointer to caller.
  307. // NOTE: string pointer will be NULL on failure.
  308. *ppszString = pszString;
  309. return hrResult;
  310. }