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.

576 lines
13 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1997.
  5. //
  6. // File: N C S T R I N G . H
  7. //
  8. // Contents: Common string routines.
  9. //
  10. // Notes:
  11. //
  12. // Author: shaunco 24 Mar 1997
  13. //
  14. //----------------------------------------------------------------------------
  15. #pragma once
  16. #include "ncdebug.h"
  17. #include "ncvalid.h"
  18. #include "ncmsz.h"
  19. #include "ncstl.h"
  20. const int c_cchGuidWithTerm = 39; // includes terminating null
  21. const int c_cbGuidWithTerm = c_cchGuidWithTerm * sizeof(WCHAR);
  22. inline ULONG CbOfSz (PCWSTR psz) { AssertH(psz); return wcslen (psz) * sizeof(WCHAR); }
  23. inline ULONG CbOfSza (PCSTR psza) { AssertH(psza); return strlen (psza) * sizeof(CHAR); }
  24. inline ULONG CbOfSzAndTerm (PCWSTR psz) { AssertH(psz); return (wcslen (psz) + 1) * sizeof(WCHAR); }
  25. inline ULONG CbOfSzaAndTerm (PCSTR psza) { AssertH(psza); return (strlen (psza) + 1) * sizeof(CHAR); }
  26. ULONG CbOfSzSafe (PCWSTR psz);
  27. ULONG CbOfSzaSafe (PCSTR psza);
  28. ULONG CbOfSzAndTermSafe (PCWSTR psz);
  29. ULONG CbOfSzaAndTermSafe (PCSTR psza);
  30. ULONG
  31. CchOfSzSafe (
  32. PCWSTR psz);
  33. inline ULONG CchToCb (ULONG cch) { return cch * sizeof(WCHAR); }
  34. struct MAP_SZ_DWORD
  35. {
  36. PCWSTR pszValue;
  37. DWORD dwValue;
  38. };
  39. PWSTR
  40. PszAllocateAndCopyPsz (
  41. PCWSTR pszSrc);
  42. extern const WCHAR c_szEmpty[];
  43. template<class T>
  44. VOID
  45. ConvertStringToColString (
  46. IN PCWSTR psz,
  47. IN const WCHAR chSeparator,
  48. OUT T& coll)
  49. {
  50. AssertSz(chSeparator, "Separator can not be \0");
  51. FreeCollectionAndItem(coll);
  52. if (NULL == psz)
  53. {
  54. return;
  55. }
  56. PWSTR pszBuf = new WCHAR[wcslen(psz) + 1];
  57. wcscpy(pszBuf, psz);
  58. WCHAR* pchString = pszBuf;
  59. WCHAR* pchSeparator;
  60. while (*pchString)
  61. {
  62. pchSeparator = wcschr(pchString, chSeparator);
  63. if (pchSeparator)
  64. {
  65. *pchSeparator = 0;
  66. }
  67. if (*pchString)
  68. {
  69. coll.push_back(new tstring(pchString));
  70. }
  71. if (pchSeparator)
  72. {
  73. pchString = pchSeparator + 1;
  74. }
  75. else
  76. {
  77. break;
  78. }
  79. }
  80. delete [] pszBuf;
  81. }
  82. template<class T>
  83. VOID
  84. ConvertColStringToString (
  85. IN const T& coll,
  86. IN const WCHAR chSeparator,
  87. OUT tstring& str)
  88. {
  89. AssertSz(chSeparator, "Separator can not be \0");
  90. if (chSeparator)
  91. {
  92. T::const_iterator iter = coll.begin();
  93. while (iter != coll.end())
  94. {
  95. str += (*iter)->c_str();
  96. ++iter;
  97. if (iter != coll.end())
  98. {
  99. str += chSeparator;
  100. }
  101. }
  102. }
  103. }
  104. DWORD
  105. WINAPIV
  106. DwFormatString (
  107. PCWSTR pszFmt,
  108. PWSTR pszBuf,
  109. DWORD cchBuf,
  110. ...);
  111. DWORD
  112. WINAPIV
  113. DwFormatStringWithLocalAlloc (
  114. PCWSTR pszFmt,
  115. PWSTR* ppszBuf,
  116. ...);
  117. enum NC_IGNORE_SPACES
  118. {
  119. NC_IGNORE,
  120. NC_DONT_IGNORE,
  121. };
  122. BOOL
  123. FFindStringInCommaSeparatedList (
  124. PCWSTR pszSubString,
  125. PCWSTR pszList,
  126. NC_IGNORE_SPACES eIgnoreSpaces,
  127. DWORD* pdwPosition);
  128. enum NC_FIND_ACTION
  129. {
  130. NC_NO_ACTION,
  131. NC_REMOVE_FIRST_MATCH,
  132. NC_REMOVE_ALL_MATCHES,
  133. };
  134. inline BOOL
  135. FFindFirstMatch (
  136. NC_FIND_ACTION eAction)
  137. {
  138. return (NC_NO_ACTION == eAction) || (NC_REMOVE_FIRST_MATCH == eAction);
  139. }
  140. //+---------------------------------------------------------------------------
  141. //
  142. // Function: FIsBstrEmpty
  143. //
  144. // Purpose: Determines if the given BSTR is "empty" meaning the pointer
  145. // is NULL or the string is 0-length.
  146. //
  147. // Arguments:
  148. // bstr [in] BSTR to check.
  149. //
  150. // Returns: TRUE if the BSTR is empty, FALSE if not.
  151. //
  152. // Author: danielwe 20 May 1997
  153. //
  154. // Notes:
  155. //
  156. inline
  157. BOOL
  158. FIsBstrEmpty (
  159. BSTR bstr)
  160. {
  161. return !(bstr && *bstr);
  162. }
  163. //+---------------------------------------------------------------------------
  164. //
  165. // Function: FIsStrEmpty
  166. //
  167. // Purpose: Determines if the given PCWSTR is "empty" meaning the pointer
  168. // is NULL or the string is 0-length.
  169. //
  170. // Arguments:
  171. // bstr [in] BSTR to check.
  172. //
  173. // Returns: TRUE if the BSTR is empty, FALSE if not.
  174. //
  175. // Author: danielwe 20 May 1997
  176. //
  177. // Notes:
  178. //
  179. inline
  180. BOOL
  181. FIsStrEmpty (
  182. PCWSTR psz)
  183. {
  184. return !(psz && *psz);
  185. }
  186. //+---------------------------------------------------------------------------
  187. //
  188. // Function: FIsPrefix
  189. //
  190. // Purpose: Returns whether a string is a prefix of another string.
  191. //
  192. // Arguments:
  193. // pszPrefix [in] Potential prefix
  194. // pszString [in] String that may begin with the prefix
  195. //
  196. // Returns: TRUE if given prefix string is a prefix of the target string.
  197. //
  198. // Author: danielwe 24 Mar 1997
  199. //
  200. // Notes: Uses CompareString with the default locale.
  201. //
  202. inline
  203. BOOL
  204. FIsPrefix (
  205. PCWSTR pszPrefix,
  206. PCWSTR pszString)
  207. {
  208. Assert (pszPrefix);
  209. Assert (pszString);
  210. return (0 == _wcsnicmp(pszPrefix, pszString, wcslen(pszPrefix)));
  211. }
  212. BOOL
  213. FIsSubstr (
  214. PCWSTR pszSubString,
  215. PCWSTR pszString);
  216. HRESULT
  217. HrAddStringToDelimitedSz (
  218. PCWSTR pszAddString,
  219. PCWSTR pszIn,
  220. WCHAR chDelimiter,
  221. DWORD dwFlags,
  222. DWORD dwStringIndex,
  223. PWSTR* ppszOut);
  224. HRESULT
  225. HrRemoveStringFromDelimitedSz (
  226. PCWSTR pszRemove,
  227. PCWSTR pszIn,
  228. WCHAR chDelimiter,
  229. DWORD dwFlags,
  230. PWSTR* ppszOut);
  231. //+---------------------------------------------------------------------------
  232. //
  233. // Function: template<class T> ColStringToMultiSz
  234. //
  235. // Purpose: Convert an STL collection of tstring pointers to a multi-sz.
  236. //
  237. // Arguments:
  238. // listStr [in] list of tstring pointers to put in the multi-sz.
  239. // ppszOut [out] the returned multi-sz.
  240. //
  241. // Returns: nothing.
  242. //
  243. // Author: shaunco 10 Apr 1997
  244. //
  245. // Notes: The output multi-sz should be freed using delete.
  246. //
  247. template<class T>
  248. VOID
  249. ColStringToMultiSz (
  250. const T& colStr,
  251. PWSTR* ppszOut)
  252. {
  253. Assert (ppszOut);
  254. // Count up the count of characters consumed by the list of strings.
  255. // This count includes the null terminator of each string.
  256. //
  257. T::const_iterator iter;
  258. UINT cch = 0;
  259. for (iter = colStr.begin(); iter != colStr.end(); iter++)
  260. {
  261. tstring* pstr = *iter;
  262. if (!pstr->empty())
  263. {
  264. cch += (UINT)(pstr->length() + 1);
  265. }
  266. }
  267. if (cch)
  268. {
  269. // Allocate the multi-sz. Assumes new will throw on error.
  270. //
  271. PWSTR pszOut = new WCHAR [cch + 1];
  272. *ppszOut = pszOut;
  273. // Copy the strings to the multi-sz.
  274. //
  275. for (iter = colStr.begin(); iter != colStr.end(); iter++)
  276. {
  277. tstring* pstr = *iter;
  278. if (!pstr->empty())
  279. {
  280. lstrcpyW (pszOut, pstr->c_str());
  281. pszOut += pstr->length() + 1;
  282. }
  283. }
  284. // Null terminate the multi-sz.
  285. Assert (pszOut == *ppszOut + cch);
  286. *pszOut = 0;
  287. }
  288. else
  289. {
  290. *ppszOut = NULL;
  291. }
  292. }
  293. //+---------------------------------------------------------------------------
  294. //
  295. // Function: template<class T> DeleteColString
  296. //
  297. // Purpose: Empty a list of tstring and delete each tstring as it is
  298. // removed.
  299. //
  300. // Arguments:
  301. // pcolstr [inout] Collection of tstring pointers to delete and empty
  302. //
  303. // Returns: nothing
  304. //
  305. // Author: mikemi 30 Apr 1997
  306. //
  307. // Notes:
  308. //
  309. // template<class T>
  310. // VOID
  311. // DeleteColString (
  312. // T* pcolstr)
  313. VOID
  314. DeleteColString (
  315. list<tstring*>* pcolstr);
  316. VOID
  317. DeleteColString (
  318. vector<tstring*>* pcolstr);
  319. //+---------------------------------------------------------------------------
  320. //
  321. // Function: template<class T> MultiSzToColString
  322. //
  323. // Purpose: Convert an multi-sz buffer to a STL collection of tstring
  324. // pointers.
  325. //
  326. // Arguments:
  327. // pmsz [in] the multi-sz to convert (Can be NULL)
  328. // pcolstr [out] list of tstring pointers to add allocated tstrings to
  329. //
  330. // Returns: nothing
  331. //
  332. // Author: mikemi 30 Apr 1997
  333. //
  334. // Notes: The output collection should be freed using DeleteColString.
  335. // This function will delete the collection list passed
  336. //
  337. template<class T>
  338. VOID
  339. MultiSzToColString (
  340. PCWSTR pmsz,
  341. T* pcolstr)
  342. {
  343. Assert (pcolstr);
  344. if (!pcolstr->empty())
  345. {
  346. DeleteColString (pcolstr);
  347. }
  348. if (pmsz)
  349. {
  350. while (*pmsz)
  351. {
  352. tstring* pstr = new tstring;
  353. if (pstr)
  354. {
  355. *pstr = pmsz;
  356. pcolstr->push_back (pstr);
  357. }
  358. // get the next string even if new failed
  359. pmsz += lstrlen (pmsz) + 1;
  360. }
  361. }
  362. }
  363. //+---------------------------------------------------------------------------
  364. //
  365. // Function: template<class T> RemoveDupsInColPtr
  366. //
  367. // Purpose: Remove all duplicate entries in an STL collection of pointers
  368. // to objects.
  369. //
  370. // Arguments:
  371. // pcol [inout] Collection of pointers to objects.
  372. //
  373. // Returns: nothing
  374. //
  375. // Author: mikemi 03 May 1997
  376. //
  377. // Notes: The objects pointed at should have a comparison operator
  378. //
  379. template<class T>
  380. VOID
  381. RemoveDupsInColPtr (
  382. T* pcol)
  383. {
  384. Assert (pcol);
  385. // remove duplicates
  386. //
  387. T::iterator posItem;
  388. T::iterator pos;
  389. T::value_type pItem;
  390. T::value_type p;
  391. posItem = pcol->begin();
  392. while (posItem != pcol->end())
  393. {
  394. pItem = *posItem;
  395. // for every other item, remove the duplicates
  396. pos = posItem;
  397. pos++;
  398. while (pos != pcol->end())
  399. {
  400. p = *pos;
  401. if ( *pItem == *p )
  402. {
  403. pos = pcol->erase( pos );
  404. delete p;
  405. }
  406. else
  407. {
  408. pos++;
  409. }
  410. }
  411. // increment afterwards due to fact that we are removing,
  412. // and otherwise could have removed the item it pointed to
  413. posItem++;
  414. }
  415. }
  416. //+---------------------------------------------------------------------------
  417. //
  418. // Function: template<class T> CopyColPtr
  419. //
  420. // Purpose: Copies one collection of pointers into another.
  421. //
  422. // Arguments:
  423. // pcolDest [out] Collection of pointers to objects.
  424. // pcolSrc [in] Collection of pointers to objects.
  425. //
  426. // Returns: nothing
  427. //
  428. // Author: BillBe 13 Jun 1998
  429. //
  430. // Notes:
  431. //
  432. template<class T>
  433. VOID
  434. CopyColPtr (T* pcolDest, const T& colSrc)
  435. {
  436. Assert (pcolDest);
  437. T::iterator posItem;
  438. // Clear out destination
  439. pcolDest->erase(pcolDest->begin(), pcolDest->end());
  440. // Go through each item in pcolSrc and add to pcolDest
  441. //
  442. posItem = colSrc.begin();
  443. while (posItem != colSrc.end())
  444. {
  445. pcolDest->push_back(*posItem);
  446. posItem++;
  447. }
  448. }
  449. PCWSTR
  450. SzLoadStringPcch (
  451. HINSTANCE hinst,
  452. UINT unId,
  453. int* pcch);
  454. //+---------------------------------------------------------------------------
  455. //
  456. // Function: SzLoadString
  457. //
  458. // Purpose: Load a resource string. (This function will never return NULL.)
  459. //
  460. // Arguments:
  461. // hinst [in] Instance handle of module with the string resource.
  462. // unId [in] Resource ID of the string to load.
  463. //
  464. // Returns: Pointer to the constant string.
  465. //
  466. // Author: shaunco 24 Mar 1997
  467. //
  468. // Notes: See SzLoadStringPcch()
  469. //
  470. inline
  471. PCWSTR
  472. SzLoadString (
  473. HINSTANCE hinst,
  474. UINT unId)
  475. {
  476. int cch;
  477. return SzLoadStringPcch(hinst, unId, &cch);
  478. }
  479. PSTR
  480. SzaDupSza (
  481. IN PCSTR pszaSrc);
  482. PWSTR
  483. SzDupSz (
  484. IN PCWSTR pszSrc);
  485. #define GetNextCommaSeparatedToken(pStart, pEnd, cch) \
  486. pStart = pEnd; \
  487. while (*pStart && (*pStart == L' ' || *pStart == L',')) \
  488. { \
  489. pStart++; \
  490. } \
  491. \
  492. pEnd = pStart; \
  493. while (*pEnd && *pEnd != L' ' && *pEnd != L',') \
  494. { \
  495. pEnd++; \
  496. } \
  497. \
  498. cch = (DWORD)(pEnd - pStart);
  499. BOOL
  500. FSubstringMatch (
  501. IN PCWSTR pStr1,
  502. IN PCWSTR pStr2,
  503. OUT const WCHAR** ppStart,
  504. OUT ULONG* pcch);