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.

405 lines
9.9 KiB

  1. /********************************************************************
  2. Copyright (c) 1999-2000 Microsoft Corporation
  3. Module Name:
  4. util.cpp
  5. Abstract:
  6. utility functions implementation
  7. Revision History:
  8. DerekM created 05/01/99
  9. ********************************************************************/
  10. #include "stdafx.h"
  11. #include "util.h"
  12. /////////////////////////////////////////////////////////////////////////////
  13. // tracing
  14. #ifdef THIS_FILE
  15. #undef THIS_FILE
  16. #endif
  17. static char __szTraceSourceFile[] = __FILE__;
  18. #define THIS_FILE __szTraceSourceFile
  19. HANDLE g_hPFPrivateHeap = NULL;
  20. //////////////////////////////////////////////////////////////////////////////
  21. // string stuff
  22. // ***************************************************************************
  23. WCHAR *MyStrStrIW(const WCHAR *wcs1, const WCHAR *wcs2)
  24. {
  25. WCHAR *cp = (WCHAR *)wcs1;
  26. WCHAR *s1, *s2;
  27. while (*cp != '\0')
  28. {
  29. s1 = cp;
  30. s2 = (WCHAR *) wcs2;
  31. while (*s1 != '\0' && *s2 !='\0' && (towlower(*s1) - towlower(*s2)) == 0)
  32. s1++, s2++;
  33. if (*s2 == '\0')
  34. return(cp);
  35. cp++;
  36. }
  37. return(NULL);
  38. }
  39. // ***************************************************************************
  40. CHAR *MyStrStrIA(const CHAR *cs1, const CHAR *cs2)
  41. {
  42. CHAR *cp = (CHAR *)cs1;
  43. CHAR *s1, *s2;
  44. while (*cp != '\0')
  45. {
  46. s1 = cp;
  47. s2 = (CHAR *) cs2;
  48. while (*s1 != '\0' && *s2 !='\0' && (tolower(*s1) - tolower(*s2)) == 0)
  49. s1++, s2++;
  50. if (*s2 == '\0')
  51. return(cp);
  52. cp++;
  53. }
  54. return(NULL);
  55. }
  56. // **************************************************************************
  57. HRESULT MyURLEncode(LPWSTR wszDest, DWORD cchDest, LPWSTR wszSrc)
  58. {
  59. USE_TRACING("URLEncode");
  60. HRESULT hr = NOERROR;
  61. DWORD cb;
  62. CHAR *pszDest = NULL, *pszSrc;
  63. CHAR *szSrcBuf, *szDestBuf, ch;
  64. VALIDATEPARM(hr, (wszDest == NULL || wszSrc == NULL));
  65. if (FAILED(hr))
  66. goto done;
  67. // alloc enuf space to hold the src array as bytes
  68. cb = (wcslen(wszSrc) + 1) * sizeof(WCHAR);
  69. __try
  70. {
  71. szSrcBuf = (CHAR *)_alloca(cb);
  72. szDestBuf = (CHAR *)_alloca(cb * 3);
  73. _ASSERT(szSrcBuf != NULL);
  74. }
  75. __except(1)
  76. {
  77. szSrcBuf = NULL;
  78. szDestBuf = NULL;
  79. }
  80. VALIDATEEXPR(hr, (szSrcBuf == NULL || szDestBuf == NULL), E_OUTOFMEMORY);
  81. if (FAILED(hr))
  82. goto done;
  83. // convert to multibyte so I can properly URL encode the string
  84. TESTBOOL(hr, (WideCharToMultiByte(CP_ACP, 0, wszSrc, -1, szSrcBuf, cb,
  85. NULL, NULL) != 0));
  86. if (FAILED(hr))
  87. goto done;
  88. pszDest = szDestBuf;
  89. for(pszSrc = szSrcBuf; *pszSrc != L'\0'; pszSrc++)
  90. {
  91. if (isalpha(*pszSrc) || isdigit(*pszSrc))
  92. {
  93. *pszDest++ = *pszSrc;
  94. }
  95. else
  96. {
  97. *pszDest++ = L'%';
  98. // get the trailing byte
  99. ch = (*pszSrc >> 4) & 0x0F;
  100. *pszDest++ = (ch < 10) ? ch + L'0' : (ch - 10) + L'A';
  101. ch = *pszSrc & 0x0F;
  102. *pszDest++ = (ch < 10) ? ch + L'0' : (ch - 10) + L'A';
  103. }
  104. }
  105. *pszDest = '\0';
  106. // convert back to unicode
  107. TESTBOOL(hr, (MultiByteToWideChar(CP_ACP, 0, szDestBuf, -1, wszDest,
  108. cchDest) != 0));
  109. if (FAILED(hr))
  110. goto done;
  111. done:
  112. return hr;
  113. }
  114. ////////////////////////////////////////////////////////////////////////////
  115. // File mapping
  116. // **************************************************************************
  117. HRESULT OpenFileMapped(LPWSTR wszFile, LPVOID *ppvFile, DWORD *pcbFile)
  118. {
  119. USE_TRACING("OpenFileMapped");
  120. HRESULT hr = NOERROR;
  121. HANDLE hMMF = NULL;
  122. HANDLE hFile = INVALID_HANDLE_VALUE;
  123. LPVOID pvFile = NULL;
  124. DWORD cbFile = 0;
  125. VALIDATEPARM(hr, (wszFile == NULL || ppvFile == NULL));
  126. if (FAILED(hr))
  127. goto done;
  128. *ppvFile = NULL;
  129. if (pcbFile != NULL)
  130. *pcbFile = 0;
  131. hFile = CreateFileW(wszFile, GENERIC_READ, FILE_SHARE_READ, NULL,
  132. OPEN_EXISTING, 0, NULL);
  133. TESTBOOL(hr, (hFile != INVALID_HANDLE_VALUE));
  134. if (FAILED(hr))
  135. goto done;
  136. cbFile = GetFileSize(hFile, NULL);
  137. TESTBOOL(hr, (cbFile != (DWORD)-1));
  138. if (FAILED(hr))
  139. goto done;
  140. hMMF = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, cbFile, NULL);
  141. TESTBOOL(hr, (hMMF != NULL));
  142. if (FAILED(hr))
  143. goto done;
  144. pvFile = MapViewOfFile(hMMF, FILE_MAP_READ, 0, 0, 0);
  145. TESTBOOL(hr, (pvFile != NULL));
  146. if (FAILED(hr))
  147. goto done;
  148. *ppvFile = pvFile;
  149. if (pcbFile != NULL)
  150. *pcbFile = cbFile;
  151. done:
  152. if (hMMF != NULL)
  153. CloseHandle(hMMF);
  154. if (hFile != NULL)
  155. CloseHandle(hFile);
  156. return hr;
  157. }
  158. // **************************************************************************
  159. HRESULT DeleteTempFile(LPWSTR wszFile)
  160. {
  161. USE_TRACING("DeleteTempFile");
  162. HRESULT hr = NOERROR;
  163. WCHAR *pwsz;
  164. if (wszFile == NULL)
  165. return NOERROR;
  166. // strip off the extension at the end (if it's not a .tmp)
  167. for(pwsz = wszFile + wcslen(wszFile); *pwsz != L'.' && pwsz > wszFile; pwsz--);
  168. if (pwsz > wszFile && _wcsicmp(pwsz, L".tmp") != 0)
  169. *pwsz = L'\0';
  170. if (DeleteFileW(wszFile) == FALSE)
  171. hr = Err2HR(GetLastError());
  172. // can do this even if the extension was a tmp since the value pointed to
  173. // by pwsz is '.' if it's greater than wszFile...
  174. if (pwsz > wszFile)
  175. *pwsz = L'.';
  176. return hr;
  177. }
  178. //////////////////////////////////////////////////////////////////////////////
  179. // Registry stuff
  180. // **************************************************************************
  181. HRESULT OpenRegKey(HKEY hkeyMain, LPCWSTR wszSubKey, BOOL fWantWrite,
  182. HKEY *phkey)
  183. {
  184. USE_TRACING("OpenRegKey");
  185. HRESULT hr = NOERROR;
  186. REGSAM samDesired;
  187. DWORD dwErr;
  188. VALIDATEPARM(hr, (hkeyMain == NULL || wszSubKey == NULL || phkey == NULL));
  189. if (FAILED(hr))
  190. goto done;
  191. *phkey = NULL;
  192. samDesired = (fWantWrite) ? KEY_ALL_ACCESS : KEY_READ;
  193. // first try calling RegCreateKeyEx to make sure we create the key if
  194. // it doesn't exist
  195. TESTERR(hr, RegCreateKeyExW(hkeyMain, wszSubKey, 0, NULL, 0, samDesired,
  196. NULL, phkey, NULL));
  197. if (FAILED(hr))
  198. {
  199. // ok, that didn't work, so try opening the key instead
  200. TESTERR(hr, RegOpenKeyExW(hkeyMain, wszSubKey, 0, samDesired, phkey));
  201. }
  202. done:
  203. return hr;
  204. }
  205. // **************************************************************************
  206. HRESULT ReadRegEntry(HKEY hkey, LPCWSTR wszValName, DWORD *pdwType,
  207. PBYTE pbBuffer, DWORD *pcbBuffer, PBYTE pbDefault,
  208. DWORD cbDefault)
  209. {
  210. USE_TRACING("ReadRegEntry");
  211. HRESULT hr = NOERROR;
  212. DWORD dwErr;
  213. VALIDATEPARM(hr, (hkey == NULL || wszValName == NULL));
  214. if (FAILED(hr))
  215. goto done;
  216. dwErr = RegQueryValueExW(hkey, wszValName, 0, pdwType, pbBuffer,
  217. pcbBuffer);
  218. VALIDATEEXPR(hr, (dwErr != ERROR_PATH_NOT_FOUND &&
  219. dwErr != ERROR_FILE_NOT_FOUND), Err2HR(dwErr));
  220. if (FAILED(hr))
  221. goto done;
  222. if (dwErr != ERROR_SUCCESS && pbDefault != NULL)
  223. {
  224. VALIDATEPARM(hr, (pcbBuffer == NULL && pbBuffer != NULL));
  225. if (FAILED(hr))
  226. goto done;
  227. // if the receiving buffer is NULL, just return the error that
  228. // RegQueryValueEx gave us cuz the user doesn't really want the
  229. // value anyway
  230. VALIDATEEXPR(hr, (pcbBuffer == NULL), Err2HR(dwErr));
  231. if (FAILED(hr))
  232. goto done;
  233. if (pbBuffer == NULL)
  234. {
  235. *pcbBuffer = cbDefault;
  236. hr = NOERROR;
  237. goto done;
  238. }
  239. else if (cbDefault > *pcbBuffer)
  240. {
  241. *pcbBuffer = cbDefault;
  242. hr = Err2HR(ERROR_MORE_DATA);
  243. goto done;
  244. }
  245. CopyMemory(pbBuffer, pbDefault, cbDefault);
  246. *pcbBuffer = cbDefault;
  247. if (pdwType != NULL)
  248. *pdwType = REG_BINARY;
  249. hr = NOERROR;
  250. goto done;
  251. }
  252. done:
  253. return hr;
  254. }
  255. /////////////////////////////////////////////////////////////////////////////
  256. // ia64 data alignment workarounds
  257. #ifdef _WIN64
  258. // ***************************************************************************
  259. ULONG64 AlignTo8Bytes(PBYTE pb)
  260. {
  261. ULONG64 ul;
  262. switch((DWORD_PTR)pb & 0x8)
  263. {
  264. // yay! already aligned
  265. case 0:
  266. ul = *(ULONG64 *)pb;
  267. break;
  268. case 1:
  269. case 5:
  270. ul = *pb << 56;
  271. ul |= *(ULONG32 *)(pb + 1) << 24;
  272. ul |= *(USHORT *)(pb + 5) << 8;
  273. ul |= *(pb + 7);
  274. break;
  275. case 2:
  276. case 6:
  277. ul = *(USHORT *)pb << 48;
  278. ul |= *(ULONG32 *)(pb + 2) << 16;
  279. ul |= *(USHORT *)(pb + 6);
  280. break;
  281. case 3:
  282. case 7:
  283. ul = *pb << 56;
  284. ul |= *(USHORT *)(pb + 1) << 48;
  285. ul |= *(ULONG32 *)(pb + 3) << 16;
  286. ul |= *(pb + 7);
  287. break;
  288. case 4:
  289. ul = *(ULONG32 *)pb << 32;
  290. ul |= *(ULONG32 *)(pb + 4);
  291. break;
  292. }
  293. return ul;
  294. }
  295. // ***************************************************************************
  296. ULONG32 AlignTo4Bytes(PBYTE pb)
  297. {
  298. ULONG32 ul;
  299. switch((DWORD_PTR)pb & 0x4)
  300. {
  301. // yay! already aligned
  302. case 0:
  303. ul = *(ULONG32 *)pb;
  304. break;
  305. case 1:
  306. case 3:
  307. ul = *pb << 24;
  308. ul |= *(short *)(pb + 1) << 8;
  309. ul |= *(pb + 3);
  310. break;
  311. case 2:
  312. ul = *(short *)pb << 16;
  313. ul |= *(short *)(pb + 2);
  314. break;
  315. }
  316. return ul;
  317. }
  318. #endif