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.

524 lines
12 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1997.
  5. //
  6. // File: K K U T I L S . C P P
  7. //
  8. // Contents: Misc. helper functions
  9. //
  10. // Notes:
  11. //
  12. // Author: kumarp 14 Jan 1997
  13. //
  14. //----------------------------------------------------------------------------
  15. #include "pch.h"
  16. #pragma hdrstop
  17. #include "kkutils.h"
  18. #include "ncreg.h"
  19. extern const WCHAR c_szRegKeyServices[];
  20. // ----------------------------------------------------------------------
  21. //
  22. // Function: AddOnlyOnceToStringList
  23. //
  24. // Purpose: Add the specified string to the list if it is not present
  25. // in that list
  26. //
  27. // Arguments:
  28. // psl [in] list of strings
  29. // pszString [in] string to add
  30. //
  31. // Returns: None
  32. //
  33. // Author: kumarp 23-December-97
  34. //
  35. // Notes:
  36. //
  37. void AddOnlyOnceToStringList(IN TStringList* psl, IN PCWSTR pszString)
  38. {
  39. AssertValidReadPtr(psl);
  40. AssertValidReadPtr(pszString);
  41. if (!FIsInStringList(*psl, pszString))
  42. {
  43. AddAtEndOfStringList(*psl, pszString);
  44. }
  45. }
  46. // ----------------------------------------------------------------------
  47. //
  48. // Function: ConvertDelimitedListToStringList
  49. //
  50. // Purpose: Convert a delimited list to a TStringList
  51. //
  52. // Arguments:
  53. // strDelimitedList [in] delimited list
  54. // chDelimiter [in] delimiter
  55. // slList [out] list of string items
  56. //
  57. // Returns: None
  58. //
  59. // Author: kumarp 23-December-97
  60. //
  61. // Notes:
  62. //
  63. void ConvertDelimitedListToStringList(IN const tstring& strDelimitedList,
  64. IN WCHAR chDelimiter,
  65. OUT TStringList &slList)
  66. {
  67. PCWSTR pszDelimitedList = strDelimitedList.c_str();
  68. DWORD i=0, dwStart;
  69. // should this be EraseAndDeleteAll() ??
  70. //EraseAll(&slList);
  71. EraseAndDeleteAll(&slList);
  72. tstring strTemp;
  73. DWORD dwNumChars;
  74. // the two spaces are intentional
  75. static WCHAR szCharsToSkip[] = L" \t";
  76. szCharsToSkip[0] = chDelimiter;
  77. while (pszDelimitedList[i])
  78. {
  79. dwStart = i;
  80. while (pszDelimitedList[i] &&
  81. !wcschr(szCharsToSkip, pszDelimitedList[i]))
  82. {
  83. ++i;
  84. }
  85. // if each item is enclosed in quotes. strip the quotes
  86. dwNumChars = i - dwStart;
  87. if (pszDelimitedList[dwStart] == '"')
  88. {
  89. dwStart++;
  90. dwNumChars -= 2;
  91. }
  92. strTemp = strDelimitedList.substr(dwStart, dwNumChars);
  93. slList.insert(slList.end(), new tstring(strTemp));
  94. // skip spaces and delimiter
  95. //
  96. while (pszDelimitedList[i] &&
  97. wcschr(szCharsToSkip, pszDelimitedList[i]))
  98. {
  99. ++i;
  100. }
  101. }
  102. }
  103. // ----------------------------------------------------------------------
  104. //
  105. // Function: ConvertCommaDelimitedListToStringList
  106. //
  107. // Purpose: Convert a comma delimited list to a TStringList
  108. //
  109. // Arguments:
  110. // strDelimitedList [in] comma delimited list
  111. // slList [out] list of string items
  112. //
  113. // Returns: None
  114. //
  115. // Author: kumarp 23-December-97
  116. //
  117. // Notes:
  118. //
  119. void ConvertCommaDelimitedListToStringList(IN const tstring& strDelimitedList, OUT TStringList &slList)
  120. {
  121. ConvertDelimitedListToStringList(strDelimitedList, (WCHAR) ',', slList);
  122. }
  123. // ----------------------------------------------------------------------
  124. //
  125. // Function: ConvertSpaceDelimitedListToStringList
  126. //
  127. // Purpose: Convert a space delimited list to a TStringList
  128. //
  129. // Arguments:
  130. // strDelimitedList [in] Space delimited list
  131. // slList [out] list of string items
  132. //
  133. // Returns: None
  134. //
  135. // Author: kumarp 23-December-97
  136. //
  137. // Notes:
  138. //
  139. void ConvertSpaceDelimitedListToStringList(IN const tstring& strDelimitedList,
  140. OUT TStringList &slList)
  141. {
  142. ConvertDelimitedListToStringList(strDelimitedList, ' ', slList);
  143. }
  144. void ConvertStringListToCommaList(IN const TStringList &slList, OUT tstring &strList)
  145. {
  146. ConvertStringListToDelimitedList(slList, strList, ',');
  147. }
  148. void ConvertStringListToDelimitedList(IN const TStringList &slList,
  149. OUT tstring &strList, IN WCHAR chDelimiter)
  150. {
  151. TStringListIter pos = slList.begin();
  152. tstring strTemp;
  153. WORD i=0;
  154. static const WCHAR szSpecialChars[] = L" %=";
  155. while (pos != slList.end())
  156. {
  157. strTemp = **pos++;
  158. //
  159. // put quotes around any strings that have chars that setupapi doesn't like.
  160. //
  161. if (strTemp.empty() ||
  162. (L'\"' != *(strTemp.c_str()) &&
  163. wcscspn(strTemp.c_str(), szSpecialChars) < strTemp.size()))
  164. {
  165. strTemp = '"' + strTemp + '"';
  166. }
  167. if (i)
  168. {
  169. strList = strList + chDelimiter + strTemp;
  170. }
  171. else
  172. {
  173. strList = strTemp;
  174. }
  175. ++i;
  176. }
  177. }
  178. // ----------------------------------------------------------------------
  179. //
  180. // Function: IsBoolString
  181. //
  182. // Purpose: Parse a string to decide if it represents a boolean value
  183. //
  184. // Arguments:
  185. // pszStr [in] string
  186. // pbValue [out] pointer to BOOL value parsed
  187. //
  188. // Returns: TRUE on success, FALSE otherwise
  189. //
  190. // Author: kumarp 12-February-98
  191. //
  192. // Notes:
  193. //
  194. BOOL IsBoolString(IN PCWSTR pszStr, OUT BOOL *pbValue)
  195. {
  196. if ((!_wcsicmp(pszStr, L"yes")) ||
  197. (!_wcsicmp(pszStr, L"true")) ||
  198. (!_wcsicmp(pszStr, L"1")))
  199. {
  200. *pbValue = TRUE;
  201. return TRUE;
  202. }
  203. else if ((!_wcsicmp(pszStr, L"no")) ||
  204. (!_wcsicmp(pszStr, L"false")) ||
  205. (!_wcsicmp(pszStr, L"0")))
  206. {
  207. *pbValue = FALSE;
  208. return TRUE;
  209. }
  210. else
  211. {
  212. return FALSE;
  213. }
  214. }
  215. // ----------------------------------------------------------------------
  216. //
  217. // Function: FIsInStringArray
  218. //
  219. // Purpose: Find out if a string exists in an array
  220. //
  221. // Arguments:
  222. // ppszStrings [in] array of strings
  223. // cNumStrings [in] num strings in array
  224. // pszStringToFind [in] string to find
  225. //
  226. // Returns: TRUE on success, FALSE otherwise
  227. //
  228. // Author: kumarp 12-February-98
  229. //
  230. // Notes:
  231. //
  232. BOOL FIsInStringArray(
  233. IN const PCWSTR* ppszStrings,
  234. IN DWORD cNumStrings,
  235. IN PCWSTR pszStringToFind,
  236. OUT UINT* puIndex)
  237. {
  238. for (DWORD isz = 0; isz < cNumStrings; isz++)
  239. {
  240. if (!lstrcmpiW(ppszStrings[isz], pszStringToFind))
  241. {
  242. if (puIndex)
  243. {
  244. *puIndex = isz;
  245. }
  246. return TRUE;
  247. }
  248. }
  249. return FALSE;
  250. }
  251. // ----------------------------------------------------------------------
  252. //
  253. // Function: HrRegOpenServiceKey
  254. //
  255. // Purpose: Open reg key for the given service
  256. //
  257. // Arguments:
  258. // szServiceName [in] name of service
  259. // samDesired [in] SAM required
  260. // phKey [out] pointer to handle of reg key
  261. //
  262. // Returns: S_OK on success, otherwise an error code
  263. //
  264. // Author: kumarp 12-February-98
  265. //
  266. // Notes:
  267. //
  268. HRESULT HrRegOpenServiceKey(
  269. IN PCWSTR pszServiceName,
  270. IN REGSAM samDesired,
  271. OUT HKEY* phKey)
  272. {
  273. DefineFunctionName("HrRegOpenServiceKey");
  274. AssertValidReadPtr(pszServiceName);
  275. AssertValidWritePtr(phKey);
  276. *phKey = NULL;
  277. HRESULT hr;
  278. tstring strService;
  279. strService = c_szRegKeyServices;
  280. strService += L"\\";
  281. strService += pszServiceName;
  282. hr = HrRegOpenKeyEx(HKEY_LOCAL_MACHINE, strService.c_str(),
  283. samDesired, phKey);
  284. TraceErrorOptional(__FUNCNAME__, hr,
  285. (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr));
  286. return hr;
  287. }
  288. // ----------------------------------------------------------------------
  289. //
  290. // Function: HrRegOpenServiceSubKey
  291. //
  292. // Purpose: Open sub key of a service key
  293. //
  294. // Arguments:
  295. // pszServiceName [in] name of service
  296. // pszSubKey [in] name of sub key
  297. // samDesired [in] SAM required
  298. // phKey [out] pointer to handle of key opened
  299. //
  300. // Returns: S_OK on success, otherwise an error code
  301. //
  302. // Author: kumarp 12-February-98
  303. //
  304. // Notes:
  305. //
  306. HRESULT HrRegOpenServiceSubKey(
  307. IN PCWSTR pszServiceName,
  308. IN PCWSTR pszSubKey,
  309. IN REGSAM samDesired,
  310. OUT HKEY* phKey)
  311. {
  312. AssertValidReadPtr(pszServiceName);
  313. AssertValidReadPtr(pszSubKey);
  314. AssertValidWritePtr(phKey);
  315. DefineFunctionName("HrRegOpenServiceSubKey");
  316. HRESULT hr = S_OK;
  317. tstring strKey;
  318. strKey = pszServiceName;
  319. strKey += L"\\";
  320. strKey += pszSubKey;
  321. hr = HrRegOpenServiceKey(strKey.c_str(), samDesired, phKey);
  322. TraceError(__FUNCNAME__, hr);
  323. return hr;
  324. }
  325. // ----------------------------------------------------------------------
  326. //
  327. // Function: FIsServiceKeyPresent
  328. //
  329. // Purpose: Check if a service reg key is present
  330. //
  331. // Arguments:
  332. // pszServiceName [in] name of service
  333. //
  334. // Returns: TRUE on success, FALSE otherwise
  335. //
  336. // Author: kumarp 12-February-98
  337. //
  338. // Notes:
  339. //
  340. BOOL FIsServiceKeyPresent(IN PCWSTR pszServiceName)
  341. {
  342. BOOL fResult = FALSE;
  343. HKEY hkeyService;
  344. HRESULT hr;
  345. hr = HrRegOpenServiceKey(pszServiceName, KEY_READ, &hkeyService);
  346. if (S_OK == hr)
  347. {
  348. // we just wanted to see if service is installed
  349. RegCloseKey(hkeyService);
  350. fResult = TRUE;
  351. }
  352. return fResult;
  353. }
  354. // ----------------------------------------------------------------------
  355. //
  356. // Function: EraseAndDeleteAll
  357. //
  358. // Purpose: Erase each element and then delete string array
  359. //
  360. // Arguments:
  361. // sa [in] pointer to array of strings
  362. //
  363. // Returns: None
  364. //
  365. // Author: kumarp 12-February-98
  366. //
  367. // Notes:
  368. //
  369. void EraseAndDeleteAll(IN TStringArray* sa)
  370. {
  371. for (size_t i=0; i < sa->size(); i++)
  372. {
  373. delete (*sa)[i];
  374. }
  375. sa->erase(sa->begin(), sa->end());
  376. }
  377. // ----------------------------------------------------------------------
  378. //
  379. // Function: AppendToPath
  380. //
  381. // Purpose: Append a subpath/filename to a path
  382. //
  383. // Arguments:
  384. // pstrPath [in] path
  385. // szItem [in] item to append
  386. //
  387. // Returns: None
  388. //
  389. // Author: kumarp 12-February-98
  390. //
  391. // Notes:
  392. //
  393. void AppendToPath(IN OUT tstring* pstrPath, IN PCWSTR szItem)
  394. {
  395. if (pstrPath->c_str()[pstrPath->size()-1] != L'\\')
  396. {
  397. *pstrPath += L'\\';
  398. }
  399. *pstrPath += szItem;
  400. }
  401. // ----------------------------------------------------------------------
  402. //
  403. // Function: ConvertDelimitedListToStringArray
  404. //
  405. // Purpose: Convert a delimited list to an array
  406. //
  407. // Arguments:
  408. // strDelimitedList [in] delimited list (e.g. "a,b,c")
  409. // chDelimiter [in] delimiter char
  410. // saStrings [out] array of strings
  411. //
  412. // Returns: None
  413. //
  414. // Author: kumarp 12-February-98
  415. //
  416. // Notes:
  417. //
  418. void ConvertDelimitedListToStringArray(
  419. IN const tstring& strDelimitedList,
  420. IN WCHAR chDelimiter,
  421. OUT TStringArray &saStrings)
  422. {
  423. PCWSTR pszDelimitedList = strDelimitedList.c_str();
  424. DWORD i=0, dwStart;
  425. EraseAndDeleteAll(&saStrings);
  426. tstring strTemp;
  427. DWORD dwNumChars;
  428. while (pszDelimitedList[i])
  429. {
  430. dwStart = i;
  431. while (pszDelimitedList[i] && (pszDelimitedList[i] != chDelimiter))
  432. {
  433. ++i;
  434. }
  435. // if each item is enclosed in quotes. strip the quotes
  436. dwNumChars = i - dwStart;
  437. if (pszDelimitedList[dwStart] == L'"')
  438. {
  439. dwStart++;
  440. dwNumChars -= 2;
  441. }
  442. strTemp = strDelimitedList.substr(dwStart, dwNumChars);
  443. saStrings.push_back(new tstring(strTemp));
  444. if (pszDelimitedList[i])
  445. {
  446. ++i;
  447. }
  448. }
  449. }
  450. // ----------------------------------------------------------------------
  451. //
  452. // Function: ConvertCommaDelimitedListToStringList
  453. //
  454. // Purpose: Convert a comma delimited list to an array
  455. //
  456. // Arguments:
  457. // strDelimitedList [in] delimited list (e.g. "a,b,c")
  458. // saStrings [out] array of strings
  459. //
  460. // Returns: None
  461. //
  462. // Author: kumarp 12-February-98
  463. //
  464. // Notes:
  465. //
  466. void ConvertCommaDelimitedListToStringArray(
  467. IN const tstring& strDelimitedList,
  468. OUT TStringArray &saStrings)
  469. {
  470. ConvertDelimitedListToStringArray(strDelimitedList, L',', saStrings);
  471. }