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.

1824 lines
54 KiB

  1. /*++
  2. Copyright (c) 1998 Microsoft Corporation
  3. Module Name:
  4. strings.h
  5. Abstract:
  6. Declares the string utilities implemented in common\migutil.
  7. Author:
  8. Several
  9. Revision History:
  10. See SLM log
  11. --*/
  12. #include <mbstring.h>
  13. #include <wchar.h>
  14. typedef PVOID POOLHANDLE;
  15. #pragma once
  16. #define MAX_ENCODED_RULE (256*6)
  17. //
  18. // String sizing routines and unit conversion
  19. //
  20. #define LcharCountA _mbslen
  21. #define LcharCountW wcslen
  22. #define _ISMBCP (g_IsMbcp)
  23. #define _ISNOTMBCP (!g_IsMbcp)
  24. unsigned char * __cdecl our_mbsinc(
  25. const unsigned char *current
  26. );
  27. unsigned char * __cdecl our_mbsdec(
  28. const unsigned char *string,
  29. const unsigned char *current
  30. );
  31. unsigned int __cdecl our_mbsnextc (
  32. const unsigned char *s
  33. );
  34. size_t __cdecl our_mbclen (
  35. const unsigned char *c
  36. );
  37. unsigned char * __cdecl our_mbsstr (
  38. const unsigned char *str1,
  39. const unsigned char *str2
  40. );
  41. __inline
  42. PSTR
  43. LcharCountToPointerA (
  44. PCSTR String,
  45. UINT Char
  46. )
  47. {
  48. while (Char > 0) {
  49. //
  50. // this is a bogus assert since the function can be used with multi-sz as well
  51. //
  52. //MYASSERT (*String != 0);
  53. Char--;
  54. String = (PCSTR) _mbsinc ((const unsigned char *) String);
  55. }
  56. return (PSTR) String;
  57. }
  58. __inline
  59. PWSTR
  60. LcharCountToPointerW (
  61. PCWSTR String,
  62. UINT Char
  63. )
  64. {
  65. #ifdef DEBUG
  66. UINT u;
  67. for (u = 0 ; u < Char ; u++) {
  68. MYASSERT (String[u] != 0);
  69. }
  70. #endif
  71. return (PWSTR) (&String[Char]);
  72. }
  73. __inline
  74. UINT
  75. LcharCountABA (
  76. IN PCSTR Start,
  77. IN PCSTR EndPlusOne
  78. )
  79. {
  80. register UINT Count;
  81. Count = 0;
  82. while (Start < EndPlusOne) {
  83. MYASSERT (*Start != 0);
  84. Count++;
  85. Start = (PCSTR) _mbsinc ((const unsigned char *) Start);
  86. }
  87. return Count;
  88. }
  89. __inline
  90. UINT
  91. LcharCountABW (
  92. IN PCWSTR Start,
  93. IN PCWSTR EndPlusOne
  94. )
  95. {
  96. #ifdef DEBUG
  97. PCWSTR p;
  98. for (p = Start ; p < EndPlusOne ; p++) {
  99. MYASSERT (*p != 0);
  100. }
  101. #endif
  102. return EndPlusOne > Start ? (UINT)(EndPlusOne - Start) : 0;
  103. }
  104. __inline
  105. UINT
  106. LcharCountInByteRangeA (
  107. IN PCSTR Start,
  108. IN UINT Bytes
  109. )
  110. {
  111. register UINT Count;
  112. PCSTR EndPlusOne = (PCSTR) ((PBYTE) Start + Bytes);
  113. Count = 0;
  114. while (Start < EndPlusOne) {
  115. Count++;
  116. Start = (PCSTR) _mbsinc ((const unsigned char *) Start);
  117. }
  118. return Count;
  119. }
  120. __inline
  121. UINT
  122. LcharCountInByteRangeW (
  123. IN PCWSTR Start,
  124. IN UINT Bytes
  125. )
  126. {
  127. PCWSTR EndPlusOne = (PCWSTR) ((PBYTE) Start + Bytes);
  128. if (Start < EndPlusOne) {
  129. return (UINT) (UINT_PTR) (EndPlusOne - Start);
  130. }
  131. MYASSERT (FALSE);
  132. return 0;
  133. }
  134. __inline
  135. UINT
  136. LcharCountToBytesA (
  137. IN PCSTR Start,
  138. IN UINT LcharCount
  139. )
  140. {
  141. PCSTR EndPlusOne;
  142. EndPlusOne = LcharCountToPointerA (Start, LcharCount);
  143. return (UINT) (UINT_PTR) (EndPlusOne - Start);
  144. }
  145. __inline
  146. UINT
  147. LcharCountToBytesW (
  148. IN PCWSTR Start,
  149. IN UINT LcharCount
  150. )
  151. {
  152. return LcharCount * sizeof (WCHAR);
  153. }
  154. #define LcharCountToTcharsA LcharCountToBytesA
  155. __inline
  156. UINT
  157. LcharCountToTcharsW (
  158. IN PCWSTR Start,
  159. IN UINT LcharCount
  160. )
  161. {
  162. return LcharCount;
  163. }
  164. #define ByteCountA strlen
  165. #define ByteCountW(x) (wcslen(x)*sizeof(WCHAR))
  166. #define SizeOfStringA(str) (ByteCountA(str) + sizeof (CHAR))
  167. #define SizeOfStringW(str) (ByteCountW(str) + sizeof (WCHAR))
  168. __inline
  169. PSTR
  170. ByteCountToPointerA (
  171. PCSTR String,
  172. UINT BytePos
  173. )
  174. {
  175. return (PSTR)((PBYTE) String + BytePos);
  176. }
  177. __inline
  178. PWSTR
  179. ByteCountToPointerW (
  180. PCWSTR String,
  181. UINT BytePos
  182. )
  183. {
  184. return (PWSTR)((PBYTE) String + BytePos);
  185. }
  186. __inline
  187. UINT
  188. ByteCountABA (
  189. IN PCSTR Start,
  190. IN PCSTR EndPlusOne
  191. )
  192. {
  193. #ifdef DEBUG
  194. PCSTR p;
  195. for (p = Start ; p < EndPlusOne ; p = (PCSTR) _mbsinc ((const unsigned char *) p)) {
  196. MYASSERT (*p != 0);
  197. }
  198. #endif
  199. return EndPlusOne > Start ? (UINT)(EndPlusOne - Start) : 0;
  200. }
  201. __inline
  202. UINT
  203. ByteCountABW (
  204. IN PCWSTR Start,
  205. IN PCWSTR EndPlusOne
  206. )
  207. {
  208. #ifdef DEBUG
  209. PCWSTR p;
  210. for (p = Start ; p < EndPlusOne ; p++) {
  211. MYASSERT (*p != 0);
  212. }
  213. #endif
  214. return EndPlusOne > Start ? (UINT)(EndPlusOne - Start) * sizeof (WCHAR) : 0;
  215. }
  216. __inline
  217. UINT
  218. ByteCountToCharsA (
  219. IN PCSTR Start,
  220. IN UINT ByteCount
  221. )
  222. {
  223. PCSTR EndPlusOne;
  224. EndPlusOne = Start + ByteCount;
  225. return LcharCountABA (Start, EndPlusOne);
  226. }
  227. __inline
  228. UINT
  229. ByteCountToCharsW (
  230. IN PCWSTR Start,
  231. IN UINT ByteCount
  232. )
  233. {
  234. #ifdef DEBUG
  235. PCWSTR p;
  236. PCWSTR EndPlusOne;
  237. EndPlusOne = (PCWSTR) ((PBYTE) Start + ByteCount);
  238. for (p = Start ; p < EndPlusOne ; p++) {
  239. MYASSERT (*p != 0);
  240. }
  241. #endif
  242. return ByteCount / sizeof (WCHAR);
  243. }
  244. __inline
  245. UINT
  246. ByteCountToTcharsA (
  247. IN PCSTR Start,
  248. IN UINT ByteCount
  249. )
  250. {
  251. #ifdef DEBUG
  252. PCSTR p;
  253. PCSTR EndPlusOne;
  254. EndPlusOne = Start + ByteCount;
  255. for (p = Start ; p < EndPlusOne ; p = (PCSTR) _mbsinc ((const unsigned char *) p)) {
  256. MYASSERT (*p != 0);
  257. }
  258. #endif
  259. return ByteCount;
  260. }
  261. #define ByteCountToTcharsW ByteCountToCharsW
  262. #define TcharCountA strlen
  263. #define TcharCountW wcslen
  264. __inline
  265. PSTR
  266. TcharCountToPointerA (
  267. PCSTR String,
  268. UINT Tchars
  269. )
  270. {
  271. #ifdef DEBUG
  272. PCSTR p;
  273. PCSTR EndPlusOne;
  274. EndPlusOne = String + Tchars;
  275. for (p = String ; p < EndPlusOne ; p = (PCSTR) _mbsinc ((const unsigned char *) p)) {
  276. MYASSERT (*p != 0);
  277. }
  278. #endif
  279. return (PSTR) (String + Tchars);
  280. }
  281. __inline
  282. PWSTR
  283. TcharCountToPointerW (
  284. PCWSTR String,
  285. UINT Tchars
  286. )
  287. {
  288. #ifdef DEBUG
  289. PCWSTR p;
  290. PCWSTR EndPlusOne;
  291. EndPlusOne = String + Tchars;
  292. for (p = String ; p < EndPlusOne ; p++) {
  293. MYASSERT (*p != 0);
  294. }
  295. #endif
  296. return (PWSTR) (String + Tchars);
  297. }
  298. #define TcharCountABA ByteCountABA
  299. __inline
  300. UINT
  301. TcharCountABW (
  302. IN PCWSTR Start,
  303. IN PCWSTR EndPlusOne
  304. )
  305. {
  306. #ifdef DEBUG
  307. PCWSTR p;
  308. for (p = Start ; p < EndPlusOne ; p++) {
  309. MYASSERT (*p != 0);
  310. }
  311. #endif
  312. return EndPlusOne > Start ? (UINT)(EndPlusOne - Start) : 0;
  313. }
  314. #define TcharCountToCharsA ByteCountToCharsA
  315. __inline
  316. UINT
  317. TcharCountToCharsW (
  318. IN PCWSTR Start,
  319. IN UINT Tchars
  320. )
  321. {
  322. #ifdef DEBUG
  323. PCWSTR p;
  324. PCWSTR EndPlusOne;
  325. EndPlusOne = Start + Tchars;
  326. for (p = Start ; p < EndPlusOne ; p++) {
  327. MYASSERT (*p != 0);
  328. }
  329. #endif
  330. return Tchars;
  331. }
  332. __inline
  333. UINT
  334. TcharCountToBytesA (
  335. IN PCSTR Start,
  336. IN UINT Tchars
  337. )
  338. {
  339. #ifdef DEBUG
  340. PCSTR p;
  341. PCSTR EndPlusOne;
  342. EndPlusOne = Start + Tchars;
  343. for (p = Start ; p < EndPlusOne ; p = (PCSTR) _mbsinc ((const unsigned char *) p)) {
  344. MYASSERT (*p != 0);
  345. }
  346. #endif
  347. return Tchars;
  348. }
  349. __inline
  350. UINT
  351. TcharCountToBytesW (
  352. IN PCWSTR Start,
  353. IN UINT Tchars
  354. )
  355. {
  356. #ifdef DEBUG
  357. PCWSTR p;
  358. PCWSTR EndPlusOne;
  359. EndPlusOne = Start + Tchars;
  360. for (p = Start ; p < EndPlusOne ; p++) {
  361. MYASSERT (*p != 0);
  362. }
  363. #endif
  364. return Tchars * sizeof (WCHAR);
  365. }
  366. INT
  367. StringICompareByteCountA (
  368. IN PCSTR String1,
  369. IN PCSTR String2,
  370. IN SIZE_T ByteCount
  371. );
  372. INT
  373. StringCompareByteCountA (
  374. IN PCSTR String1,
  375. IN PCSTR String2,
  376. IN SIZE_T ByteCount
  377. );
  378. BOOL
  379. StringMemMatchA (
  380. IN PCSTR Buffer1,
  381. IN PCSTR Buffer2,
  382. IN SIZE_T ByteCount
  383. );
  384. BOOL
  385. StringMemMatchW (
  386. IN PCWSTR Buffer1,
  387. IN PCWSTR Buffer2,
  388. IN SIZE_T ByteCount
  389. );
  390. #define StackStringCopyA(stackbuf,src) _mbssafecpy(stackbuf,src,sizeof(stackbuf))
  391. #define StackStringCopyW(stackbuf,src) _wcssafecpy(stackbuf,src,sizeof(stackbuf))
  392. //
  393. // String comparison routines
  394. //
  395. #define StringCompareA _mbscmp
  396. #define StringCompareW wcscmp
  397. #define StringMatchA(str1,str2) (_mbscmp(str1,str2)==0)
  398. #define StringMatchW(str1,str2) (wcscmp(str1,str2)==0)
  399. #define StringICompareA _mbsicmp
  400. #define StringICompareW _wcsicmp
  401. #define StringIMatchA(str1,str2) (_mbsicmp(str1,str2)==0)
  402. #define StringIMatchW(str1,str2) (_wcsicmp(str1,str2)==0)
  403. #define StringCompareByteCountW(str1,str2,bytes) wcsncmp(str1,str2,ByteCountToCharsW(str1,bytes))
  404. #define StringMatchByteCountA(str1,str2,bytes) (StringMemMatchA(str1,str2,bytes))
  405. #define StringMatchByteCountW(str1,str2,bytes) (StringMemMatchW(str1,str2,bytes))
  406. #define StringICompareByteCountW(str1,str2,bytes) _wcsnicmp(str1,str2,ByteCountToCharsW(str1,bytes))
  407. #define StringIMatchByteCountA(str1,str2,bytes) (StringICompareByteCountA(str1,str2,bytes)==0)
  408. #define StringIMatchByteCountW(str1,str2,bytes) (_wcsnicmp(str1,str2,ByteCountToCharsW(str1,bytes))==0)
  409. #define StringCompareLcharCountA(str1,str2,chars) _mbsncmp(str1,str2,chars)
  410. #define StringCompareLcharCountW(str1,str2,chars) wcsncmp(str1,str2,chars)
  411. #define StringMatchLcharCountA(str1,str2,chars) (_mbsncmp(str1,str2,chars)==0)
  412. #define StringMatchLcharCountW(str1,str2,chars) (wcsncmp(str1,str2,chars)==0)
  413. #define StringICompareLcharCountA(str1,str2,chars) _mbsnicmp(str1,str2,chars)
  414. #define StringICompareLcharCountW(str1,str2,chars) _wcsnicmp(str1,str2,chars)
  415. #define StringIMatchLcharCountA(str1,str2,chars) (_mbsnicmp(str1,str2,chars)==0)
  416. #define StringIMatchLcharCountW(str1,str2,chars) (_wcsnicmp(str1,str2,chars)==0)
  417. #define StringCompareTcharCountA(str1,str2,tchars) StringCompareByteCountA(str1,str2,tchars)
  418. #define StringCompareTcharCountW(str1,str2,tchars) wcsncmp(str1,str2,tchars)
  419. #define StringMatchTcharCountA(str1,str2,tchars) (strncmp(str1,str2,tchars)==0)
  420. #define StringMatchTcharCountW(str1,str2,tchars) (wcsncmp(str1,str2,tchars)==0)
  421. #define StringICompareTcharCountA(str1,str2,tchars) StringICompareByteCountA (str1, str2, tchars)
  422. #define StringICompareTcharCountW(str1,str2,tchars) _wcsnicmp(str1,str2,tchars)
  423. #define StringIMatchTcharCountA(str1,str2,tchars) (StringICompareByteCountA(str1,str2,tchars)==0)
  424. #define StringIMatchTcharCountW(str1,str2,tchars) (_wcsnicmp(str1,str2,tchars)==0)
  425. INT
  426. StringCompareABA (
  427. IN PCSTR String,
  428. IN PCSTR Start,
  429. IN PCSTR End
  430. );
  431. INT
  432. StringCompareABW (
  433. IN PCWSTR String,
  434. IN PCWSTR Start,
  435. IN PCWSTR End
  436. );
  437. #define StringMatchABA(String,Start,End) (StringCompareABA(String,Start,End)==0)
  438. #define StringMatchABW(String,Start,End) (StringCompareABW(String,Start,End)==0)
  439. // stricmp that takes an end pointer instead of a length
  440. INT
  441. StringICompareABA (
  442. IN PCSTR String,
  443. IN PCSTR Start,
  444. IN PCSTR End
  445. );
  446. INT
  447. StringICompareABW (
  448. IN PCWSTR String,
  449. IN PCWSTR Start,
  450. IN PCWSTR End
  451. );
  452. PWSTR
  453. our_lstrcpynW (
  454. OUT PWSTR Dest,
  455. IN PCWSTR Src,
  456. IN INT NumChars
  457. );
  458. #define StringIMatchABA(String,Start,End) (StringICompareABA(String,Start,End)==0)
  459. #define StringIMatchABW(String,Start,End) (StringICompareABW(String,Start,End)==0)
  460. //
  461. // String copy routines
  462. //
  463. #define StringCopyA strcpy
  464. #define StringCopyW wcscpy
  465. // bytes
  466. #define StringCopyByteCountA(str1,str2,bytes) lstrcpynA(str1,str2,bytes)
  467. #define StringCopyByteCountW(str1,str2,bytes) our_lstrcpynW(str1,str2,(bytes)/sizeof(WCHAR))
  468. // logical characters (IMPORTANT: logical chars != TcharCount)
  469. #define StringCopyLcharCountA(str1,str2,mbchars) lstrcpynA(str1,str2,LcharCountToBytesA(str2,mbchars))
  470. #define StringCopyLcharCountW(str1,str2,wchars) our_lstrcpynW(str1,str2,wchars)
  471. // CHARs (A version) or WCHARs (W version)
  472. #define StringCopyTcharCountA(str1,str2,tchars) lstrcpynA(str1,str2,tchars)
  473. #define StringCopyTcharCountW(str1,str2,tchars) our_lstrcpynW(str1,str2,tchars)
  474. #define StringCopyABA(dest,stra,strb) StringCopyByteCountA((dest),(stra),(UINT) (UINT_PTR) ((PBYTE)(strb)-(PBYTE)(stra)+(INT)sizeof(CHAR)))
  475. #define StringCopyABW(dest,stra,strb) StringCopyByteCountW((dest),(stra),(UINT) (UINT_PTR) ((PBYTE)(strb)-(PBYTE)(stra)+(INT)sizeof(WCHAR)))
  476. //
  477. // String cat routines
  478. //
  479. #define StringCatA _mbsappend
  480. #define StringCatW _wcsappend
  481. //
  482. // Character search routines
  483. //
  484. #define GetEndOfStringA(s) strchr(s,0)
  485. #define GetEndOfStringW(s) wcschr(s,0)
  486. __inline
  487. UINT
  488. SizeOfMultiSzA (
  489. PCSTR MultiSz
  490. )
  491. {
  492. PCSTR Base;
  493. Base = MultiSz;
  494. while (*MultiSz) {
  495. MultiSz = GetEndOfStringA (MultiSz) + 1;
  496. }
  497. MultiSz++;
  498. return (UINT) (UINT_PTR) ((PBYTE) MultiSz - (PBYTE) Base);
  499. }
  500. __inline
  501. UINT
  502. SizeOfMultiSzW (
  503. PCWSTR MultiSz
  504. )
  505. {
  506. PCWSTR Base;
  507. Base = MultiSz;
  508. while (*MultiSz) {
  509. MultiSz = GetEndOfStringW (MultiSz) + 1;
  510. }
  511. MultiSz++;
  512. return (UINT) (UINT_PTR) ((PBYTE) MultiSz - (PBYTE) Base);
  513. }
  514. __inline
  515. UINT
  516. MultiSzSizeInCharsA (
  517. PCSTR MultiSz
  518. )
  519. {
  520. UINT Chars = 0;
  521. while (*MultiSz) {
  522. do {
  523. Chars++;
  524. MultiSz = (PCSTR) _mbsinc ((const unsigned char *) MultiSz);
  525. } while (*MultiSz);
  526. Chars++;
  527. MultiSz++;
  528. }
  529. Chars++;
  530. return Chars;
  531. }
  532. #define MultiSzSizeInCharsW(msz) (SizeOfMultiSzW(msz)/sizeof(WCHAR))
  533. PSTR
  534. GetPrevCharA (
  535. IN PCSTR StartStr,
  536. IN PCSTR CurrPtr,
  537. IN CHARTYPE SearchChar
  538. );
  539. PWSTR
  540. GetPrevCharW (
  541. IN PCWSTR StartStr,
  542. IN PCWSTR CurrPtr,
  543. IN WCHAR SearchChar
  544. );
  545. //
  546. // Pool allocation routines
  547. //
  548. PSTR
  549. RealAllocTextExA (
  550. IN POOLHANDLE Pool, OPTIONAL
  551. IN UINT ByteSize
  552. );
  553. PWSTR
  554. RealAllocTextExW (
  555. IN POOLHANDLE Pool, OPTIONAL
  556. IN UINT WcharSize
  557. );
  558. #define AllocTextExA(p,s) SETTRACKCOMMENT(PSTR,"AllocTextExA",__FILE__,__LINE__)\
  559. RealAllocTextExA(p,s)\
  560. CLRTRACKCOMMENT
  561. #define AllocTextExW(p,s) SETTRACKCOMMENT(PWSTR,"AllocTextExW",__FILE__,__LINE__)\
  562. RealAllocTextExW(p,s)\
  563. CLRTRACKCOMMENT
  564. #define AllocTextA(s) AllocTextExA(NULL,(s))
  565. #define AllocTextW(s) AllocTextExW(NULL,(s))
  566. VOID
  567. FreeTextExA (
  568. IN POOLHANDLE Pool, OPTIONAL
  569. IN PCSTR Text OPTIONAL
  570. );
  571. VOID
  572. FreeTextExW (
  573. IN POOLHANDLE Pool, OPTIONAL
  574. IN PCWSTR Text OPTIONAL
  575. );
  576. #define FreeTextA(t) FreeTextExA(NULL,t)
  577. #define FreeTextW(t) FreeTextExW(NULL,t)
  578. PSTR
  579. RealDuplicateTextExA (
  580. IN POOLHANDLE Pool, OPTIONAL
  581. IN PCSTR Text,
  582. IN UINT ExtraChars,
  583. OUT PSTR *NulChar OPTIONAL
  584. );
  585. PWSTR
  586. RealDuplicateTextExW (
  587. IN POOLHANDLE Pool, OPTIONAL
  588. IN PCWSTR Text,
  589. IN UINT ExtraChars,
  590. OUT PWSTR *NulChar OPTIONAL
  591. );
  592. #define DuplicateTextExA(p,t,c,n) SETTRACKCOMMENT(PSTR,"DuplicateTextExA",__FILE__,__LINE__)\
  593. RealDuplicateTextExA(p,t,c,n)\
  594. CLRTRACKCOMMENT
  595. #define DuplicateTextExW(p,t,c,n) SETTRACKCOMMENT(PWSTR,"DuplicateTextExW",__FILE__,__LINE__)\
  596. RealDuplicateTextExW(p,t,c,n)\
  597. CLRTRACKCOMMENT
  598. #define DuplicateTextA(text) DuplicateTextExA(NULL,text,0,NULL)
  599. #define DuplicateTextW(text) DuplicateTextExW(NULL,text,0,NULL)
  600. PSTR
  601. RealJoinTextExA (
  602. IN POOLHANDLE Pool, OPTIONAL
  603. IN PCSTR String1,
  604. IN PCSTR String2,
  605. IN PCSTR DelimeterString, OPTIONAL
  606. IN UINT ExtraChars,
  607. OUT PSTR *NulChar OPTIONAL
  608. );
  609. PWSTR
  610. RealJoinTextExW (
  611. IN POOLHANDLE Pool, OPTIONAL
  612. IN PCWSTR String1,
  613. IN PCWSTR String2,
  614. IN PCWSTR CenterString, OPTIONAL
  615. IN UINT ExtraChars,
  616. OUT PWSTR *NulChar OPTIONAL
  617. );
  618. #define JoinTextExA(p,s1,s2,cs,ec,nc) SETTRACKCOMMENT(PSTR,"JoinTextExA",__FILE__,__LINE__)\
  619. RealJoinTextExA(p,s1,s2,cs,ec,nc)\
  620. CLRTRACKCOMMENT
  621. #define JoinTextExW(p,s1,s2,cs,ec,nc) SETTRACKCOMMENT(PWSTR,"JoinTextExW",__FILE__,__LINE__)\
  622. RealJoinTextExW(p,s1,s2,cs,ec,nc)\
  623. CLRTRACKCOMMENT
  624. #define JoinTextA(str1,str2) JoinTextExA(NULL,str1,str2,NULL,0,NULL)
  625. #define JoinTextW(str1,str2) JoinTextExW(NULL,str1,str2,NULL,0,NULL)
  626. PSTR
  627. RealExpandEnvironmentTextExA (
  628. IN PCSTR InString,
  629. IN PCSTR * ExtraEnvironmentVariables OPTIONAL
  630. );
  631. PWSTR
  632. RealExpandEnvironmentTextExW (
  633. IN PCWSTR InString,
  634. IN PCWSTR * ExtraEnvironmentVariables OPTIONAL
  635. );
  636. #define ExpandEnvironmentTextExA(str,ev) SETTRACKCOMMENT(PSTR,"ExpandEnvironmentTextExA",__FILE__,__LINE__)\
  637. RealExpandEnvironmentTextExA(str,ev)\
  638. CLRTRACKCOMMENT
  639. #define ExpandEnvironmentTextExW(str,ev) SETTRACKCOMMENT(PWSTR,"ExpandEnvironmentTextExW",__FILE__,__LINE__)\
  640. RealExpandEnvironmentTextExW(str,ev)\
  641. CLRTRACKCOMMENT
  642. #define ExpandEnvironmentTextA(string) ExpandEnvironmentTextExA(string,NULL)
  643. #define ExpandEnvironmentTextW(string) ExpandEnvironmentTextExW(string,NULL)
  644. //
  645. // NOTE: IsLeadByte routine now takes a (const CHAR*) to be able to test for a
  646. // "naked lead byte" combination (LeadByte + NULL combination)
  647. // Thus, if it returns TRUE, it's safe to assume there is a trail byte after the lead
  648. // Function wraps IsDBCSLeadByte(), which tests ACP. Do not use
  649. // isleadbyte().
  650. //
  651. __inline
  652. BOOL
  653. IsLeadByte (
  654. IN PCSTR BytePtr
  655. )
  656. {
  657. return (!_ISNOTMBCP && BytePtr[0] && IsDBCSLeadByte (BytePtr[0])) ? BytePtr[1] != 0 : FALSE;
  658. }
  659. //
  660. // Command line routines
  661. //
  662. // Converts ANSI command line to array of args
  663. PSTR *
  664. CommandLineToArgvA (
  665. IN PCSTR CmdLine,
  666. OUT INT *NumArgs
  667. );
  668. //
  669. // Need both MBCS and UNICODE versions
  670. //
  671. // an atoi that supports decimal or hex
  672. DWORD _mbsnum (IN PCSTR szNum);
  673. DWORD _wcsnum (IN PCWSTR szNum);
  674. // a strcat that returns a pointer to the end of the string
  675. PSTR _mbsappend (OUT PSTR szDest, IN PCSTR szSrc);
  676. PWSTR _wcsappend (OUT PWSTR szDest, IN PCWSTR szSrc);
  677. // determines if an entire string is printable chars
  678. int _mbsisprint (PCSTR szStr);
  679. int _wcsisprint (PCWSTR szStr);
  680. // case-insensitive strstr
  681. PCSTR _mbsistr (PCSTR szStr, PCSTR szSubStr);
  682. PCWSTR _wcsistr (PCWSTR szStr, PCWSTR szSubStr);
  683. // copies the first character of str2 to str
  684. void _copymbchar (PSTR str1, PCSTR str2);
  685. #define _copywchar(dest,src) (*(dest)=*(src))
  686. // replaces a character in a multi-byte char string and maintains
  687. // the string integrity (may grow string by one byte)
  688. void _setmbchar (PSTR str, MBCHAR c);
  689. #define _setwchar(str,c) (*(str)=(c))
  690. // removes specified character from the end of a string, if it exists
  691. BOOL _mbsctrim (PSTR str, MBCHAR c);
  692. BOOL _wcsctrim (PWSTR str, WCHAR c);
  693. // Always adds a backslash, returns ptr to nul terminator
  694. PSTR AppendWackA (IN PSTR str);
  695. PWSTR AppendWackW (IN PWSTR str);
  696. // Calls AppendWack only if there is enough buffer space in str
  697. // buflen = size in bytes
  698. PSTR StringCbAppendWackA (IN PSTR str, IN UINT buflen);
  699. PWSTR StringCbAppendWackW (IN PWSTR str, IN UINT buflen);
  700. // Adds a backslash to the end of a DOS path (unless str is empty
  701. // or is only a drive letter)
  702. PSTR AppendDosWackA (IN PSTR str);
  703. PWSTR AppendDosWackW (IN PWSTR str);
  704. // Adds a backslash unless str is empty
  705. PSTR AppendUncWackA (IN PSTR str);
  706. PWSTR AppendUncWackW (IN PWSTR str);
  707. // Adds a backslash and identifies the correct naming convention (DOS,
  708. // or UNC)
  709. PSTR AppendPathWackA (IN PSTR str);
  710. PWSTR AppendPathWackW (IN PWSTR str);
  711. // Joins two paths together, allocates string in g_PathsPool
  712. PSTR
  713. RealJoinPathsExA (
  714. IN POOLHANDLE Pool, OPTIONAL
  715. IN PCSTR PathA,
  716. IN PCSTR PathB
  717. );
  718. PWSTR
  719. RealJoinPathsExW (
  720. IN POOLHANDLE Pool, OPTIONAL
  721. IN PCWSTR PathA,
  722. IN PCWSTR PathB
  723. );
  724. #define JoinPathsExA(pool,p1,p2) SETTRACKCOMMENT(PSTR,"JoinPathsA",__FILE__,__LINE__)\
  725. RealJoinPathsExA(pool,p1,p2)\
  726. CLRTRACKCOMMENT
  727. #define JoinPathsExW(pool,p1,p2) SETTRACKCOMMENT(PWSTR,"JoinPathsW",__FILE__,__LINE__)\
  728. RealJoinPathsExW(pool,p1,p2)\
  729. CLRTRACKCOMMENT
  730. #define JoinPathsA(p1,p2) JoinPathsExA(NULL,p1,p2)
  731. #define JoinPathsW(p1,p2) JoinPathsExW(NULL,p1,p2)
  732. // Routine to allocate a 1K buffer for path manipulation, allocated in g_PathsPool
  733. PSTR RealAllocPathStringA (IN DWORD Chars);
  734. PWSTR RealAllocPathStringW (IN DWORD Chars);
  735. #define DEFSIZE 0
  736. #define AllocPathStringA(chars) SETTRACKCOMMENT(PSTR,"AllocPathStringA",__FILE__,__LINE__)\
  737. RealAllocPathStringA(chars)\
  738. CLRTRACKCOMMENT
  739. #define AllocPathStringW(chars) SETTRACKCOMMENT(PWSTR,"AllocPathStringW",__FILE__,__LINE__)\
  740. RealAllocPathStringW(chars)\
  741. CLRTRACKCOMMENT
  742. // Routine to divide path into separate strings, each allocated in g_PathsPool
  743. VOID RealSplitPathA (IN PCSTR Path, OUT PSTR *Drive, OUT PSTR *Dir, OUT PSTR *File, OUT PSTR *Ext);
  744. VOID RealSplitPathW (IN PCWSTR Path, OUT PWSTR *Drive, OUT PWSTR *Dir, OUT PWSTR *File, OUT PWSTR *Ext);
  745. #define SplitPathA(path,dv,dir,f,e) SETTRACKCOMMENT_VOID ("SplitPathA",__FILE__,__LINE__)\
  746. RealSplitPathA(path,dv,dir,f,e)\
  747. CLRTRACKCOMMENT_VOID
  748. #define SplitPathW(path,dv,dir,f,e) SETTRACKCOMMENT_VOID ("SplitPathW",__FILE__,__LINE__)\
  749. RealSplitPathW(path,dv,dir,f,e)\
  750. CLRTRACKCOMMENT_VOID
  751. // Routine to extract the file from a path
  752. PCSTR GetFileNameFromPathA (IN PCSTR Path);
  753. PCWSTR GetFileNameFromPathW (IN PCWSTR Path);
  754. // Routine to extract the file extension from a path
  755. PCSTR GetFileExtensionFromPathA (IN PCSTR Path);
  756. PCWSTR GetFileExtensionFromPathW (IN PCWSTR Path);
  757. // Routine to extract the file extension from a path, including the dot, or the
  758. // end of the string if no extension exists
  759. PCSTR GetDotExtensionFromPathA (IN PCSTR Path);
  760. PCWSTR GetDotExtensionFromPathW (IN PCWSTR Path);
  761. // Routine to duplicate a path and allocate space for cat processing
  762. PSTR RealDuplicatePathStringA (IN PCSTR Path, IN DWORD ExtraBytes);
  763. PWSTR RealDuplicatePathStringW (IN PCWSTR Path, IN DWORD ExtraBytes);
  764. #define DuplicatePathStringA(path,eb) SETTRACKCOMMENT(PSTR,"DuplicatePathStringA",__FILE__,__LINE__)\
  765. RealDuplicatePathStringA(path,eb)\
  766. CLRTRACKCOMMENT
  767. #define DuplicatePathStringW(path,eb) SETTRACKCOMMENT(PWSTR,"DuplicatePathStringW",__FILE__,__LINE__)\
  768. RealDuplicatePathStringW(path,eb)\
  769. CLRTRACKCOMMENT
  770. // Routines to enumerate the PATH variable
  771. typedef struct _PATH_ENUMA {
  772. PSTR BufferPtr;
  773. PSTR PtrNextPath;
  774. PSTR PtrCurrPath;
  775. } PATH_ENUMA, *PPATH_ENUMA;
  776. BOOL
  777. EnumFirstPathExA (
  778. OUT PPATH_ENUMA PathEnum,
  779. IN PCSTR AdditionalPath,
  780. IN PCSTR WinDir,
  781. IN PCSTR SysDir,
  782. IN BOOL IncludeEnvPath
  783. );
  784. #define EnumFirstPathA(e,a,w,s) EnumFirstPathExA(e,a,w,s,TRUE)
  785. BOOL
  786. EnumNextPathA (
  787. IN OUT PPATH_ENUMA PathEnum
  788. );
  789. BOOL
  790. EnumPathAbortA (
  791. IN OUT PPATH_ENUMA PathEnum
  792. );
  793. // Frees a string allocated in g_PathsPool
  794. VOID
  795. FreePathStringExA (
  796. IN POOLHANDLE Pool, OPTIONAL
  797. IN PCSTR Path OPTIONAL
  798. );
  799. VOID
  800. FreePathStringExW (
  801. IN POOLHANDLE Pool, OPTIONAL
  802. IN PCWSTR Path OPTIONAL
  803. );
  804. #define FreePathStringA(p) FreePathStringExA(NULL,p)
  805. #define FreePathStringW(p) FreePathStringExW(NULL,p)
  806. // Removes a trailing backslash, if it exists
  807. #define RemoveWackAtEndA(str) _mbsctrim(str,'\\')
  808. #define RemoveWackAtEndW(str) _wcsctrim(str,L'\\')
  809. // Rule encoding functions used to encode a number of syntax-related
  810. // characters (backslash, brackets, asterisk, etc)
  811. PSTR EncodeRuleCharsA (PSTR szEncRule, DWORD mbstrEncRuleChars, PCSTR szRule);
  812. PWSTR EncodeRuleCharsW (PWSTR szEncRule, DWORD wstrEncRuleChars, PCWSTR szRule);
  813. // Rule decoding functions used to restore an encoded string
  814. MBCHAR GetNextRuleCharA (PCSTR *p_szRule, BOOL *p_bFromHex);
  815. WCHAR GetNextRuleCharW (PCWSTR *p_szRule, BOOL *p_bFromHex);
  816. PSTR DecodeRuleCharsA (PSTR szRule, DWORD mbstrRuleBufferChars, PCSTR szEncRule);
  817. PWSTR DecodeRuleCharsW (PWSTR szRule, DWORD wstrRuleBufferChars, PCWSTR szEncRule);
  818. PSTR DecodeRuleCharsABA (PSTR szRule, DWORD mbstrRuleBufferChars, PCSTR szEncRuleStart, PCSTR End);
  819. PWSTR DecodeRuleCharsABW (PWSTR szRule, DWORD wstrRuleBufferChars, PCWSTR szEncRuleStart, PCWSTR End);
  820. // Returns a pointer to the next non-space character (uses isspace)
  821. PCSTR SkipSpaceA (PCSTR szStr);
  822. PCWSTR SkipSpaceW (PCWSTR szStr);
  823. // Returns a pointer to the first space character at the end of a string,
  824. // or a pointer to the terminating nul if no space exists at the end of the
  825. // string. (Used for trimming space.)
  826. PCSTR SkipSpaceRA (PCSTR szBaseStr, PCSTR szStr);
  827. PCWSTR SkipSpaceRW (PCWSTR szBaseStr, PCWSTR szStr);
  828. // Truncates a string after the last non-whitepace character
  829. VOID TruncateTrailingSpaceA (IN OUT PSTR Str);
  830. VOID TruncateTrailingSpaceW (IN OUT PWSTR Str);
  831. // Returns TRUE if str matches wstrPattern. Case-sensitive, supports
  832. // multiple asterisks and question marks.
  833. BOOL IsPatternMatchA (PCSTR wstrPattern, PCSTR wstrStr);
  834. BOOL IsPatternMatchW (PCWSTR wstrPattern, PCWSTR wstrStr);
  835. // Returns TRUE if str matches wstrPattern. Case-sensitive, supports
  836. // multiple asterisks and question marks.
  837. BOOL IsPatternMatchABA (PCSTR Pattern, PCSTR Start, PCSTR End);
  838. BOOL IsPatternMatchABW (PCWSTR Pattern, PCWSTR Start, PCWSTR End);
  839. //
  840. // More powerful pattern matching
  841. //
  842. #define SEGMENTTYPE_UNKNOWN 0
  843. #define SEGMENTTYPE_EXACTMATCH 1
  844. #define SEGMENTTYPE_OPTIONAL 2
  845. #define SEGMENTTYPE_REQUIRED 3
  846. typedef struct {
  847. UINT Type;
  848. union {
  849. // exact match
  850. struct {
  851. PCSTR LowerCasePhrase;
  852. UINT PhraseBytes;
  853. } Exact;
  854. // optional
  855. struct {
  856. UINT MaxLen; // zero if any length
  857. PCSTR IncludeSet; OPTIONAL
  858. PCSTR ExcludeSet; OPTIONAL
  859. } Wildcard;
  860. };
  861. } SEGMENTA, *PSEGMENTA;
  862. typedef struct {
  863. UINT SegmentCount;
  864. PSEGMENTA Segment;
  865. } PATTERNPROPSA, *PPATTERNPROPSA;
  866. typedef struct {
  867. UINT PatternCount;
  868. POOLHANDLE Pool;
  869. PPATTERNPROPSA Pattern;
  870. } PARSEDPATTERNA, *PPARSEDPATTERNA;
  871. typedef struct {
  872. UINT Type;
  873. union {
  874. // exact match
  875. struct {
  876. PCWSTR LowerCasePhrase;
  877. UINT PhraseBytes;
  878. } Exact;
  879. // wildcard
  880. struct {
  881. UINT MaxLen; // zero if any length
  882. PCWSTR IncludeSet; OPTIONAL
  883. PCWSTR ExcludeSet; OPTIONAL
  884. } Wildcard;
  885. };
  886. } SEGMENTW, *PSEGMENTW;
  887. typedef struct {
  888. UINT SegmentCount;
  889. PSEGMENTW Segment;
  890. } PATTERNPROPSW, *PPATTERNPROPSW;
  891. typedef struct {
  892. UINT PatternCount;
  893. POOLHANDLE Pool;
  894. PPATTERNPROPSW Pattern;
  895. } PARSEDPATTERNW, *PPARSEDPATTERNW;
  896. BOOL
  897. IsPatternMatchExA (
  898. IN PCSTR Pattern,
  899. IN PCSTR Start,
  900. IN PCSTR End
  901. );
  902. BOOL
  903. IsPatternMatchExW (
  904. IN PCWSTR Pattern,
  905. IN PCWSTR Start,
  906. IN PCWSTR End
  907. );
  908. PPARSEDPATTERNA
  909. CreateParsedPatternA (
  910. IN PCSTR Pattern
  911. );
  912. PPARSEDPATTERNW
  913. CreateParsedPatternW (
  914. IN PCWSTR Pattern
  915. );
  916. BOOL
  917. TestParsedPatternA (
  918. IN PPARSEDPATTERNA ParsedPattern,
  919. IN PCSTR StringToTest
  920. );
  921. BOOL
  922. TestParsedPatternW (
  923. IN PPARSEDPATTERNW ParsedPattern,
  924. IN PCWSTR StringToTest
  925. );
  926. BOOL
  927. TestParsedPatternABA (
  928. IN PPARSEDPATTERNA ParsedPattern,
  929. IN PCSTR StringToTest,
  930. IN PCSTR EndPlusOne
  931. );
  932. BOOL
  933. TestParsedPatternABW (
  934. IN PPARSEDPATTERNW ParsedPattern,
  935. IN PCWSTR StringToTest,
  936. IN PCWSTR EndPlusOne
  937. );
  938. VOID
  939. PrintPattern (
  940. PCSTR Pattern,
  941. PPARSEDPATTERNA Struct
  942. );
  943. VOID
  944. DestroyParsedPatternA (
  945. IN PPARSEDPATTERNA ParsedPattern
  946. );
  947. VOID
  948. DestroyParsedPatternW (
  949. IN PPARSEDPATTERNW ParsedPattern
  950. );
  951. // Character counters
  952. UINT CountInstancesOfCharA (PCSTR String, MBCHAR Char);
  953. UINT CountInstancesOfCharW (PCWSTR String, WCHAR Char);
  954. UINT CountInstancesOfCharIA (PCSTR String, MBCHAR Char);
  955. UINT CountInstancesOfCharIW (PCWSTR String, WCHAR Char);
  956. //
  957. // Message Functions
  958. //
  959. // An AllocTable is an array of HLOCAL pointers that the message routines
  960. // return. This table is maintained to allow a single function to clean up
  961. // all strings at once.
  962. //
  963. // All "Ex" functions (ParseMessageEx, GetStringResourceEx, and so on)
  964. // require a valid AllocTable pointer. A caller obtains this pointer by
  965. // calling CreateAllocTable before processing any message. The caller
  966. // cleans up the entire table by calling DestroyAllocTable.
  967. //
  968. // A set of macros can be used for short-term strings. ParseMessage and
  969. // GetStringResource work the same as their Ex counterparts, but operate
  970. // on the process-wide g_ShortTermAllocTable. Short-term strings are
  971. // freed with FreeStringResource.
  972. //
  973. // A routine that calls ParseMessage and/or GetStringResource several times
  974. // in the same function wrap the calls between BeginMessageProcessing and
  975. // EndMessageProcessing. Only one thread in the process can do this at a
  976. // time, and when EndMessageProcessing is called, all strings allocated
  977. // by ParseMessage or GetResourceString in the processing section are
  978. // automatically freed.
  979. //
  980. // AllocTable creation/deletion
  981. PGROWBUFFER CreateAllocTable (VOID);
  982. VOID DestroyAllocTable (PGROWBUFFER AllocTable);
  983. // The "Ex" functions
  984. // ParseMessageEx retrieves the string resource via FormatMessage
  985. PCSTR ParseMessageExA (PGROWBUFFER AllocTable, PCSTR Template, PCSTR ArgArray[]);
  986. PCWSTR ParseMessageExW (PGROWBUFFER AllocTable, PCWSTR Template, PCWSTR ArgArray[]);
  987. // GetStringResourceEx retrives an argument-less string resource
  988. PCSTR GetStringResourceExA (PGROWBUFFER AllocTable, UINT ID);
  989. PCWSTR GetStringResourceExW (PGROWBUFFER AllocTable, UINT ID);
  990. // Frees resources allocated by ParseMessageEx, GetStringResourceEx and all macros
  991. VOID FreeStringResourceExA (PGROWBUFFER AllocTable, PCSTR String);
  992. VOID FreeStringResourceExW (PGROWBUFFER AllocTable, PCWSTR String);
  993. // Frees resources allocated by ParseMessageEx, GetStringResourceEx and all macros.
  994. // Tests String first; nulls when freed.
  995. VOID FreeStringResourcePtrExA (PGROWBUFFER AllocTable, PCSTR * String);
  996. VOID FreeStringResourcePtrExW (PGROWBUFFER AllocTable, PCWSTR * String);
  997. // Macros
  998. extern PGROWBUFFER g_ShortTermAllocTable;
  999. #define ParseMessageA(strid,args) ParseMessageExA(g_ShortTermAllocTable, strid, args)
  1000. #define ParseMessageW(strid,args) ParseMessageExW(g_ShortTermAllocTable, strid, args)
  1001. #define ParseMessageIDA(id,args) ParseMessageExA(g_ShortTermAllocTable, (PCSTR) (id), args)
  1002. #define ParseMessageIDW(id,args) ParseMessageExW(g_ShortTermAllocTable, (PCWSTR) (id), args)
  1003. #define ParseMessageIDExA(table,id,args) ParseMessageExA(table, (PCSTR) (id), args)
  1004. #define ParseMessageIDExW(table,id,args) ParseMessageExW(table, (PCWSTR) (id), args)
  1005. #define GetStringResourceA(id) GetStringResourceExA(g_ShortTermAllocTable, id)
  1006. #define GetStringResourceW(id) GetStringResourceExW(g_ShortTermAllocTable, id)
  1007. #define FreeStringResourceA(str) FreeStringResourceExA(g_ShortTermAllocTable, str)
  1008. #define FreeStringResourceW(str) FreeStringResourceExW(g_ShortTermAllocTable, str)
  1009. #define FreeStringResourcePtrA(str) FreeStringResourcePtrExA(g_ShortTermAllocTable, str)
  1010. #define FreeStringResourcePtrW(str) FreeStringResourcePtrExW(g_ShortTermAllocTable, str)
  1011. // Functions for single-threaded message-intensive processing loops
  1012. BOOL BeginMessageProcessing (VOID);
  1013. VOID EndMessageProcessing (VOID);
  1014. //
  1015. // The following message functions do not return strings, so they do not
  1016. // need cleanup.
  1017. //
  1018. // An odd variant--obtains message ID from a window's text and replaces
  1019. // it with the actual message. Useful in dialog box initialization.
  1020. VOID ParseMessageInWndA (HWND hwnd, PCSTR ArgArray[]);
  1021. VOID ParseMessageInWndW (HWND hwnd, PCWSTR ArgArray[]);
  1022. // Displays a message box using a message string
  1023. INT ResourceMessageBoxA (HWND hwndOwner, UINT ID, UINT Flags, PCSTR ArgArray[]);
  1024. INT ResourceMessageBoxW (HWND hwndOwner, UINT ID, UINT Flags, PCWSTR ArgArray[]);
  1025. //
  1026. // Functions that don't care about UNICODE or MBCS
  1027. // and realy shouldn't be in strings.h/.c
  1028. //
  1029. // Pushes dwError on a global error stack
  1030. void PushNewError (DWORD dwError);
  1031. // Pushes the return of GetLastError() on a global error stack
  1032. void PushError (void);
  1033. // Pops the last error from the global error stack, calls SetLastError
  1034. // and returns the popped error code.
  1035. DWORD PopError (void);
  1036. // Returns an int value for chars 0-9, a-f, A-F, and -1 for all others
  1037. int GetHexDigit (IN int c);
  1038. //
  1039. // Inline functions
  1040. //
  1041. // Returns the character at str[pos]
  1042. __inline MBCHAR _mbsgetc(PCSTR str, DWORD pos) {
  1043. return (MBCHAR) our_mbsnextc((const unsigned char *) LcharCountToPointerA ((PSTR) str, pos));
  1044. }
  1045. __inline WCHAR _wcsgetc(PCWSTR str, DWORD pos) {
  1046. return *LcharCountToPointerW ((PWSTR) str, pos);
  1047. }
  1048. // Sets the character at str[pos]
  1049. // Multibyte version may grow string by one byte.
  1050. __inline void _mbssetc(PSTR str, DWORD pos, MBCHAR c) {
  1051. _setmbchar (LcharCountToPointerA (str, pos), c);
  1052. }
  1053. __inline void _wcssetc(PWSTR str, DWORD pos, WCHAR c) {
  1054. *LcharCountToPointerW (str, pos) = c;
  1055. }
  1056. // Bug fix for C Runtime _tcsdec
  1057. __inline PWSTR _wcsdec2(PCWSTR base, PCWSTR p) {
  1058. if (base >= p) {
  1059. return NULL;
  1060. }
  1061. return (PWSTR) (p-1);
  1062. }
  1063. // Bug fix for C Runtime _tcsdec
  1064. __inline PSTR _mbsdec2(PCSTR base, PCSTR p) {
  1065. if (base >= p) {
  1066. return NULL;
  1067. }
  1068. return (PSTR) _mbsdec((const unsigned char *) base, (const unsigned char *) p);
  1069. }
  1070. // A handy strncpy with forced termination
  1071. PSTR _mbsnzcpy (PSTR dest, PCSTR src, int count);
  1072. PWSTR _wcsnzcpy (PWSTR dest, PCWSTR src, int count);
  1073. // A handy strncpy used for buffer overrun containment
  1074. #define _mbssafecpy(dest,src,bufsize) _mbsnzcpy(dest,src,(bufsize)-sizeof(CHAR))
  1075. #define _wcssafecpy(dest,src,bufsize) _wcsnzcpy(dest,src,(bufsize)-sizeof(WCHAR))
  1076. // strcpyab with forced termination and termination guard
  1077. PSTR _mbsnzcpyab (PSTR Dest, PCSTR Start, PCSTR End, int count);
  1078. PWSTR _wcsnzcpyab (PWSTR Dest, PCWSTR Start, PCWSTR End, int count);
  1079. // A handy strncpyab used for buffer overrun containment
  1080. #define _mbssafecpyab(dest,start,end,bufsize) _mbsnzcpyab(dest,start,end,(bufsize)-sizeof(CHAR))
  1081. #define _wcssafecpyab(dest,start,end,bufsize) _wcsnzcpyab(dest,start,end,(bufsize)-sizeof(WCHAR))
  1082. // Routine that checks string for a prefix
  1083. #define StringPrefixA(str,prefix) StringMatchLcharCountA(str,prefix,LcharCountA(prefix))
  1084. #define StringIPrefixA(str,prefix) StringIMatchLcharCountA(str,prefix,LcharCountA(prefix))
  1085. #define StringPrefixW(str,prefix) StringMatchLcharCountW(str,prefix,LcharCountW(prefix))
  1086. #define StringIPrefixW(str,prefix) StringIMatchLcharCountW(str,prefix,LcharCountW(prefix))
  1087. //
  1088. // Sub String Replacement functions.
  1089. //
  1090. BOOL StringReplaceW (PWSTR Buffer,DWORD MaxSize,PWSTR ReplaceStartPos,PWSTR ReplaceEndPos,PCWSTR NewString);
  1091. BOOL StringReplaceA (PSTR Buffer,DWORD MaxSize,PSTR ReplaceStartPos,PSTR ReplaceEndPos,PCSTR NewString);
  1092. //
  1093. // String table population from INF section
  1094. //
  1095. typedef enum {
  1096. CALLBACK_CONTINUE,
  1097. CALLBACK_SKIP,
  1098. CALLBACK_STOP
  1099. } CALLBACK_RESULT;
  1100. typedef CALLBACK_RESULT(ADDINFSECTION_PROTOTYPEA)(PCSTR String, PVOID * DataPtr,
  1101. UINT * DataSizePtr, PVOID CallbackData);
  1102. typedef CALLBACK_RESULT(ADDINFSECTION_PROTOTYPEW)(PCWSTR String, PVOID * DataPtr,
  1103. UINT * DataSizePtr, PVOID CallbackData);
  1104. typedef ADDINFSECTION_PROTOTYPEA * ADDINFSECTION_PROCA;
  1105. typedef ADDINFSECTION_PROTOTYPEW * ADDINFSECTION_PROCW;
  1106. #if 0
  1107. BOOL AddInfSectionToStringTableA (PVOID, HINF, PCSTR, INT, ADDINFSECTION_PROCA, PVOID);
  1108. BOOL AddInfSectionToStringTableW (PVOID, HINF, PCWSTR, INT, ADDINFSECTION_PROCW, PVOID);
  1109. #endif
  1110. UINT
  1111. CountInstancesOfSubStringA (
  1112. IN PCSTR SourceString,
  1113. IN PCSTR SearchString
  1114. );
  1115. UINT
  1116. CountInstancesOfSubStringW (
  1117. IN PCWSTR SourceString,
  1118. IN PCWSTR SearchString
  1119. );
  1120. PCSTR
  1121. StringSearchAndReplaceA (
  1122. IN PCSTR SourceString,
  1123. IN PCSTR SearchString,
  1124. IN PCSTR ReplaceString
  1125. );
  1126. PCWSTR
  1127. StringSearchAndReplaceW (
  1128. IN PCWSTR SourceString,
  1129. IN PCWSTR SearchString,
  1130. IN PCWSTR ReplaceString
  1131. );
  1132. typedef struct _MULTISZ_ENUMA {
  1133. PCSTR Buffer;
  1134. PCSTR CurrentString;
  1135. } MULTISZ_ENUMA, *PMULTISZ_ENUMA;
  1136. typedef struct _MULTISZ_ENUMW {
  1137. PCWSTR Buffer;
  1138. PCWSTR CurrentString;
  1139. } MULTISZ_ENUMW, *PMULTISZ_ENUMW;
  1140. BOOL
  1141. EnumNextMultiSzA (
  1142. IN OUT PMULTISZ_ENUMA MultiSzEnum
  1143. );
  1144. BOOL
  1145. EnumNextMultiSzW (
  1146. IN OUT PMULTISZ_ENUMW MultiSzEnum
  1147. );
  1148. BOOL
  1149. EnumFirstMultiSzA (
  1150. OUT PMULTISZ_ENUMA MultiSzEnum,
  1151. IN PCSTR MultiSzStr
  1152. );
  1153. BOOL
  1154. EnumFirstMultiSzW (
  1155. OUT PMULTISZ_ENUMW MultiSzEnum,
  1156. IN PCWSTR MultiSzStr
  1157. );
  1158. VOID
  1159. ToggleWacksW (
  1160. IN OUT PWSTR String,
  1161. IN BOOL Operation
  1162. );
  1163. VOID
  1164. ToggleWacksA (
  1165. IN OUT PSTR String,
  1166. IN BOOL Operation
  1167. );
  1168. PCSTR
  1169. SanitizePathA (
  1170. IN PCSTR FileSpec
  1171. );
  1172. PCWSTR
  1173. SanitizePathW (
  1174. IN PCWSTR FileSpec
  1175. );
  1176. PCSTR
  1177. ConvertSBtoDB (
  1178. PCSTR RootPath,
  1179. PCSTR FullPath,
  1180. PCSTR Limit
  1181. );
  1182. //
  1183. // TCHAR mappings
  1184. //
  1185. #ifdef UNICODE
  1186. #define LcharCount LcharCountW
  1187. #define LcharCountToPointer LcharCountToPointerW
  1188. #define LcharCountAB LcharCountABW
  1189. #define LcharCountInByteRange LcharCountInByteRangeW
  1190. #define LcharCountToBytes LcharCountToBytesW
  1191. #define LcharCountToTchars LcharCountToTcharsW
  1192. #define ByteCount ByteCountW
  1193. #define SizeOfString SizeOfStringW
  1194. #define SizeOfMultiSz SizeOfMultiSzW
  1195. #define MultiSzSizeInChars MultiSzSizeInCharsW
  1196. #define ByteCountToPointer ByteCountToPointerW
  1197. #define ByteCountAB ByteCountABW
  1198. #define ByteCountToChars ByteCountToCharsW
  1199. #define ByteCountToTchars ByteCountToTcharsW
  1200. #define TcharCount TcharCountW
  1201. #define TcharCountToPointer TcharCountToPointerW
  1202. #define TcharCountAB TcharCountABW
  1203. #define TcharCountToChars TcharCountToCharsW
  1204. #define TcharCountToBytes TcharCountToBytesW
  1205. #define StackStringCopy StackStringCopyW
  1206. #define StringCompare StringCompareW
  1207. #define StringMatch StringMatchW
  1208. #define StringICompare StringICompareW
  1209. #define StringIMatch StringIMatchW
  1210. #define StringCompareByteCount StringCompareByteCountW
  1211. #define StringMatchByteCount StringMatchByteCountW
  1212. #define StringICompareByteCount StringICompareByteCountW
  1213. #define StringIMatchByteCount StringIMatchByteCountW
  1214. #define StringCompareLcharCount StringCompareLcharCountW
  1215. #define StringMatchLcharCount StringMatchLcharCountW
  1216. #define StringICompareLcharCount StringICompareLcharCountW
  1217. #define StringIMatchLcharCount StringIMatchLcharCountW
  1218. #define StringCompareTcharCount StringCompareTcharCountW
  1219. #define StringMatchTcharCount StringMatchTcharCountW
  1220. #define StringICompareTcharCount StringICompareTcharCountW
  1221. #define StringIMatchTcharCount StringIMatchTcharCountW
  1222. #define StringCompareAB StringCompareABW
  1223. #define StringMatchAB StringMatchABW
  1224. #define StringICompareAB StringICompareABW
  1225. #define StringIMatchAB StringIMatchABW
  1226. #define StringCopy StringCopyW
  1227. #define StringCopyByteCount StringCopyByteCountW
  1228. #define StringCopyLcharCount StringCopyLcharCountW
  1229. #define StringCopyTcharCount StringCopyTcharCountW
  1230. #define StringCopyAB StringCopyABW
  1231. #define StringCat StringCatW
  1232. #define GetEndOfString GetEndOfStringW
  1233. #define GetPrevChar GetPrevCharW
  1234. #define StringMemMatch StringMemMatchW
  1235. #define AllocTextEx AllocTextExW
  1236. #define AllocText AllocTextW
  1237. #define FreeTextEx FreeTextExW
  1238. #define FreeText FreeTextW
  1239. #define DuplicateText DuplicateTextW
  1240. #define DuplicateTextEx DuplicateTextExW
  1241. #define JoinTextEx JoinTextExW
  1242. #define JoinText JoinTextW
  1243. #define ExpandEnvironmentText ExpandEnvironmentTextW
  1244. #define ExpandEnvironmentTextEx ExpandEnvironmentTextExW
  1245. #define CommandLineToArgv CommandLineToArgvW
  1246. #define _tcsdec2 _wcsdec2
  1247. #define _copytchar _copywchar
  1248. #define _settchar _setwchar
  1249. #define _tcsgetc _wcsgetc
  1250. #define _tcssetc _wcssetc
  1251. #define _tcsnum _wcsnum
  1252. #define _tcsappend _wcsappend
  1253. #define _tcsistr _wcsistr
  1254. #define _tcsisprint _wcsisprint
  1255. #define _tcsnzcpy _wcsnzcpy
  1256. #define _tcssafecpy _wcssafecpy
  1257. #define _tcsnzcpyab _wcsnzcpyab
  1258. #define _tcssafecpyab _wcssafecpyab
  1259. #define StringPrefix StringPrefixW
  1260. #define StringIPrefix StringIPrefixW
  1261. #define _tcsctrim _wcsctrim
  1262. #define StringCbAppendWack StringCbAppendWackW
  1263. #define AppendWack AppendWackW
  1264. #define AppendDosWack AppendDosWackW
  1265. #define AppendUncWack AppendUncWackW
  1266. #define AppendPathWack AppendPathWackW
  1267. #define RemoveWackAtEnd RemoveWackAtEndW
  1268. #define JoinPathsEx JoinPathsExW
  1269. #define JoinPaths JoinPathsW
  1270. #define AllocPathString AllocPathStringW
  1271. #define SplitPath SplitPathW
  1272. #define GetFileNameFromPath GetFileNameFromPathW
  1273. #define GetFileExtensionFromPath GetFileExtensionFromPathW
  1274. #define GetDotExtensionFromPath GetDotExtensionFromPathW
  1275. #define DuplicatePathString DuplicatePathStringW
  1276. #define FreePathStringEx FreePathStringExW
  1277. #define FreePathString FreePathStringW
  1278. #define GetNextRuleChar GetNextRuleCharW
  1279. #define DecodeRuleChars DecodeRuleCharsW
  1280. #define DecodeRuleCharsAB DecodeRuleCharsABW
  1281. #define EncodeRuleChars EncodeRuleCharsW
  1282. #define SkipSpace SkipSpaceW
  1283. #define SkipSpaceR SkipSpaceRW
  1284. #define TruncateTrailingSpace TruncateTrailingSpaceW
  1285. #define IsPatternMatch IsPatternMatchW
  1286. #define IsPatternMatchAB IsPatternMatchABW
  1287. #define PPARSEDPATTERN PPARSEDPATTERNW
  1288. #define PARSEDPATTERN PARSEDPATTERNW
  1289. #define CreateParsedPattern CreateParsedPatternW
  1290. #define IsPatternMatchEx IsPatternMatchExW
  1291. #define TestParsedPattern TestParsedPatternW
  1292. #define TestParsedPatternAB TestParsedPatternABW
  1293. #define DestroyParsedPattern DestroyParsedPatternW
  1294. #define CountInstancesOfChar CountInstancesOfCharW
  1295. #define CountInstancesOfCharI CountInstancesOfCharIW
  1296. #define StringReplace StringReplaceW
  1297. #define CountInstancesOfSubString CountInstancesOfSubStringW
  1298. #define StringSearchAndReplace StringSearchAndReplaceW
  1299. #define MULTISZ_ENUM MULTISZ_ENUMW
  1300. #define EnumFirstMultiSz EnumFirstMultiSzW
  1301. #define EnumNextMultiSz EnumNextMultiSzW
  1302. #define ParseMessage ParseMessageW
  1303. #define ParseMessageEx ParseMessageExW
  1304. #define ParseMessageID ParseMessageIDW
  1305. #define ParseMessageIDEx ParseMessageIDExW
  1306. #define GetStringResource GetStringResourceW
  1307. #define GetStringResourceEx GetStringResourceExW
  1308. #define FreeStringResource FreeStringResourceW
  1309. #define ParseMessageInWnd ParseMessageInWndW
  1310. #define ResourceMessageBox ResourceMessageBoxW
  1311. #if 0
  1312. #define AddInfSectionToStringTable AddInfSectionToStringTableW
  1313. #endif
  1314. #define ADDINFSECTION_PROC ADDINFSECTION_PROCW
  1315. #define ReplaceWacks(f) ToggleWacksW(f,FALSE)
  1316. #define RestoreWacks(f) ToggleWacksW(f,TRUE)
  1317. #define SanitizePath SanitizePathW
  1318. #else
  1319. #define LcharCount LcharCountA
  1320. #define LcharCountToPointer LcharCountToPointerA
  1321. #define LcharCountAB LcharCountABA
  1322. #define LcharCountInByteRange LcharCountInByteRangeA
  1323. #define LcharCountToBytes LcharCountToBytesA
  1324. #define LcharCountToTchars LcharCountToTcharsA
  1325. #define ByteCount ByteCountA
  1326. #define SizeOfString SizeOfStringA
  1327. #define SizeOfMultiSz SizeOfMultiSzA
  1328. #define MultiSzSizeInChars MultiSzSizeInCharsA
  1329. #define ByteCountToPointer ByteCountToPointerA
  1330. #define ByteCountAB ByteCountABA
  1331. #define ByteCountToChars ByteCountToCharsA
  1332. #define ByteCountToTchars ByteCountToTcharsA
  1333. #define TcharCount TcharCountA
  1334. #define TcharCountToPointer TcharCountToPointerA
  1335. #define TcharCountAB TcharCountABA
  1336. #define TcharCountToChars TcharCountToCharsA
  1337. #define TcharCountToBytes TcharCountToBytesA
  1338. #define StackStringCopy StackStringCopyA
  1339. #define StringCompare StringCompareA
  1340. #define StringMatch StringMatchA
  1341. #define StringICompare StringICompareA
  1342. #define StringIMatch StringIMatchA
  1343. #define StringCompareByteCount StringCompareByteCountA
  1344. #define StringMatchByteCount StringMatchByteCountA
  1345. #define StringICompareByteCount StringICompareByteCountA
  1346. #define StringIMatchByteCount StringIMatchByteCountA
  1347. #define StringCompareLcharCount StringCompareLcharCountA
  1348. #define StringMatchLcharCount StringMatchLcharCountA
  1349. #define StringICompareLcharCount StringICompareLcharCountA
  1350. #define StringIMatchLcharCount StringIMatchLcharCountA
  1351. #define StringCompareTcharCount StringCompareTcharCountA
  1352. #define StringMatchTcharCount StringMatchTcharCountA
  1353. #define StringICompareTcharCount StringICompareTcharCountA
  1354. #define StringIMatchTcharCount StringIMatchTcharCountA
  1355. #define StringCompareAB StringCompareABA
  1356. #define StringMatchAB StringMatchABA
  1357. #define StringICompareAB StringICompareABA
  1358. #define StringIMatchAB StringIMatchABA
  1359. #define StringCopy StringCopyA
  1360. #define StringCopyByteCount StringCopyByteCountA
  1361. #define StringCopyLcharCount StringCopyLcharCountA
  1362. #define StringCopyTcharCount StringCopyTcharCountA
  1363. #define StringCopyAB StringCopyABA
  1364. #define StringCat StringCatA
  1365. #define GetEndOfString GetEndOfStringA
  1366. #define GetPrevChar GetPrevCharA
  1367. #define StringMemMatch StringMemMatchA
  1368. #define AllocTextEx AllocTextExA
  1369. #define AllocText AllocTextA
  1370. #define FreeTextEx FreeTextExA
  1371. #define FreeText FreeTextA
  1372. #define DuplicateText DuplicateTextA
  1373. #define DuplicateTextEx DuplicateTextExA
  1374. #define JoinTextEx JoinTextExA
  1375. #define JoinText JoinTextA
  1376. #define ExpandEnvironmentText ExpandEnvironmentTextA
  1377. #define ExpandEnvironmentTextEx ExpandEnvironmentTextExA
  1378. #define CommandLineToArgv CommandLineToArgvA
  1379. #define _tcsdec2 our_mbsdec
  1380. #define _copytchar _copymbchar
  1381. #define _settchar _setchar
  1382. #define _tcsgetc _mbsgetc
  1383. #define _tcssetc _mbssetc
  1384. #define _tcsnum _mbsnum
  1385. #define _tcsappend _mbsappend
  1386. #define _tcsistr _mbsistr
  1387. #define _tcsisprint _mbsisprint
  1388. #define _tcsnzcpy _mbsnzcpy
  1389. #define _tcssafecpy _mbssafecpy
  1390. #define _tcsnzcpyab _mbsnzcpyab
  1391. #define _tcssafecpyab _mbssafecpyab
  1392. #define StringPrefix StringPrefixA
  1393. #define StringIPrefix StringIPrefixA
  1394. #define _tcsctrim _mbsctrim
  1395. #define StringCbAppendWack StringCbAppendWackA
  1396. #define AppendWack AppendWackA
  1397. #define AppendDosWack AppendDosWackA
  1398. #define AppendUncWack AppendUncWackA
  1399. #define AppendPathWack AppendPathWackA
  1400. #define RemoveWackAtEnd RemoveWackAtEndA
  1401. #define JoinPathsEx JoinPathsExA
  1402. #define JoinPaths JoinPathsA
  1403. #define AllocPathString AllocPathStringA
  1404. #define SplitPath SplitPathA
  1405. #define GetFileNameFromPath GetFileNameFromPathA
  1406. #define GetFileExtensionFromPath GetFileExtensionFromPathA
  1407. #define GetDotExtensionFromPath GetDotExtensionFromPathA
  1408. #define DuplicatePathString DuplicatePathStringA
  1409. #define PATH_ENUM PATH_ENUMA
  1410. #define PPATH_ENUM PPATH_ENUMA
  1411. #define EnumFirstPathEx EnumFirstPathExA
  1412. #define EnumFirstPath EnumFirstPathA
  1413. #define EnumNextPath EnumNextPathA
  1414. #define EnumPathAbort EnumPathAbortA
  1415. #define FreePathStringEx FreePathStringExA
  1416. #define FreePathString FreePathStringA
  1417. #define GetNextRuleChar GetNextRuleCharA
  1418. #define DecodeRuleChars DecodeRuleCharsA
  1419. #define DecodeRuleCharsAB DecodeRuleCharsABA
  1420. #define EncodeRuleChars EncodeRuleCharsA
  1421. #define SkipSpace SkipSpaceA
  1422. #define SkipSpaceR SkipSpaceRA
  1423. #define TruncateTrailingSpace TruncateTrailingSpaceA
  1424. #define IsPatternMatch IsPatternMatchA
  1425. #define IsPatternMatchAB IsPatternMatchABA
  1426. #define PPARSEDPATTERN PPARSEDPATTERNA
  1427. #define PARSEDPATTERN PARSEDPATTERNA
  1428. #define CreateParsedPattern CreateParsedPatternA
  1429. #define IsPatternMatchEx IsPatternMatchExA
  1430. #define TestParsedPattern TestParsedPatternA
  1431. #define TestParsedPatternAB TestParsedPatternABA
  1432. #define DestroyParsedPattern DestroyParsedPatternA
  1433. #define CountInstancesOfChar CountInstancesOfCharA
  1434. #define CountInstancesOfCharI CountInstancesOfCharIA
  1435. #define StringReplace StringReplaceA
  1436. #define CountInstancesOfSubString CountInstancesOfSubStringA
  1437. #define StringSearchAndReplace StringSearchAndReplaceA
  1438. #define MULTISZ_ENUM MULTISZ_ENUMA
  1439. #define EnumFirstMultiSz EnumFirstMultiSzA
  1440. #define EnumNextMultiSz EnumNextMultiSzA
  1441. #define ParseMessage ParseMessageA
  1442. #define ParseMessageEx ParseMessageExA
  1443. #define ParseMessageID ParseMessageIDA
  1444. #define ParseMessageIDEx ParseMessageIDExA
  1445. #define GetStringResource GetStringResourceA
  1446. #define GetStringResourceEx GetStringResourceExA
  1447. #define FreeStringResource FreeStringResourceA
  1448. #define ParseMessageInWnd ParseMessageInWndA
  1449. #define ResourceMessageBox ResourceMessageBoxA
  1450. #if 0
  1451. #define AddInfSectionToStringTable AddInfSectionToStringTableA
  1452. #endif
  1453. #define ADDINFSECTION_PROC ADDINFSECTION_PROCA
  1454. #define ReplaceWacks(f) ToggleWacksA(f,FALSE)
  1455. #define RestoreWacks(f) ToggleWacksA(f,TRUE)
  1456. #define SanitizePath SanitizePathA
  1457. #endif
  1458. //
  1459. // MessageBox macros
  1460. //
  1461. #define YesNoBox(hwnd,ID) ResourceMessageBox(hwnd,ID,MB_YESNO|MB_ICONQUESTION|MB_SETFOREGROUND,NULL)
  1462. #define YesNoCancelBox(hwnd,ID) ResourceMessageBox(hwnd,ID,MB_YESNOCANCEL|MB_ICONQUESTION|MB_SETFOREGROUND,NULL)
  1463. #define OkBox(hwnd,ID) ResourceMessageBox(hwnd,ID,MB_OK|MB_ICONINFORMATION|MB_SETFOREGROUND,NULL)
  1464. #define OkCancelBox(hwnd,ID) ResourceMessageBox(hwnd,ID,MB_OKCANCEL|MB_ICONQUESTION|MB_SETFOREGROUND,NULL)
  1465. #define RetryCancelBox(hwnd,ID) ResourceMessageBox(hwnd,ID,MB_RETRYCANCEL|MB_ICONQUESTION|MB_SETFOREGROUND,NULL)