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.

715 lines
20 KiB

  1. #include "pch.hxx"
  2. #include <BadStrFunctions.h>
  3. UINT AthGetTempFileNameW( LPCWSTR pwszPathName, // pointer to directory name for temporary file
  4. LPCWSTR pwszPrefixString, // pointer to filename prefix
  5. UINT uUnique, // number used to create temporary filename
  6. LPWSTR wszTempFileName) // pointer to buffer that receives the new filename
  7. {
  8. UINT uRetValue = 0;
  9. LPSTR pszPathName = NULL,
  10. pszPrefixString = NULL;
  11. CHAR szTempFileName[MAX_PATH];
  12. LPWSTR pwszTempFileName = NULL;
  13. Assert(pwszPathName && pwszPrefixString && wszTempFileName);
  14. if (S_OK == IsPlatformWinNT())
  15. return GetTempFileNameW(pwszPathName, pwszPrefixString, uUnique, wszTempFileName);
  16. pszPathName = PszToANSI(CP_ACP, pwszPathName);
  17. if (!pszPathName)
  18. goto exit;
  19. pszPrefixString = PszToANSI(CP_ACP, pwszPrefixString);
  20. if (!pszPrefixString)
  21. goto exit;
  22. uRetValue = GetTempFileNameA(pszPathName, pszPrefixString, uUnique, szTempFileName);
  23. if ( uRetValue != 0 )
  24. {
  25. pwszTempFileName = PszToUnicode(CP_ACP, szTempFileName);
  26. if (!pwszTempFileName)
  27. {
  28. uRetValue = 0;
  29. goto exit;
  30. }
  31. CopyMemory(wszTempFileName, pwszTempFileName, (lstrlenW(pwszTempFileName)+1)*sizeof(WCHAR));
  32. }
  33. exit:
  34. MemFree(pwszTempFileName);
  35. MemFree(pszPathName);
  36. MemFree(pszPrefixString);
  37. return uRetValue;
  38. }
  39. DWORD AthGetTempPathW( DWORD nBufferLength, // size, in characters, of the buffer
  40. LPWSTR pwszBuffer ) // pointer to buffer for temp. path
  41. {
  42. DWORD nRequired = 0;
  43. CHAR szBuffer[MAX_PATH];
  44. LPWSTR pwszBufferToFree = NULL;
  45. Assert(pwszBuffer);
  46. if (S_OK == IsPlatformWinNT())
  47. return GetTempPathW(nBufferLength, pwszBuffer);
  48. nRequired = GetTempPathA(MAX_PATH, szBuffer);
  49. if (nRequired == 0 || nRequired > MAX_PATH)
  50. {
  51. *pwszBuffer = 0;
  52. }
  53. else
  54. {
  55. pwszBufferToFree = PszToUnicode(CP_ACP, szBuffer);
  56. if (pwszBufferToFree)
  57. {
  58. nRequired = lstrlenW(pwszBufferToFree);
  59. if ( nRequired < nBufferLength)
  60. CopyMemory(pwszBuffer, pwszBufferToFree, (nRequired+1)*sizeof(WCHAR) );
  61. else
  62. {
  63. nRequired = 0;
  64. *pwszBuffer = 0;
  65. }
  66. }
  67. else
  68. *pwszBuffer = 0;
  69. MemFree(pwszBufferToFree);
  70. }
  71. return nRequired;
  72. }
  73. HANDLE AthCreateFileW(LPCWSTR lpFileName, // pointer to name of the file
  74. DWORD dwDesiredAccess, // access (read-write) mode
  75. DWORD dwShareMode, // share mode
  76. LPSECURITY_ATTRIBUTES lpSecurityAttributes,
  77. // pointer to security attributes
  78. DWORD dwCreationDisposition, // how to create
  79. DWORD dwFlagsAndAttributes, // file attributes
  80. HANDLE hTemplateFile ) // handle to file with attributes to copy
  81. {
  82. LPSTR lpFileA = NULL;
  83. HANDLE hFile = NULL;
  84. if (S_OK == IsPlatformWinNT())
  85. return CreateFileW( lpFileName,
  86. dwDesiredAccess,
  87. dwShareMode,
  88. lpSecurityAttributes,
  89. dwCreationDisposition,
  90. dwFlagsAndAttributes,
  91. hTemplateFile);
  92. lpFileA = PszToANSI(CP_ACP, lpFileName);
  93. if (lpFileA)
  94. hFile = CreateFileA(lpFileA,
  95. dwDesiredAccess,
  96. dwShareMode,
  97. lpSecurityAttributes,
  98. dwCreationDisposition,
  99. dwFlagsAndAttributes,
  100. hTemplateFile);
  101. MemFree(lpFileA);
  102. return (hFile);
  103. }
  104. LONG_PTR SetWindowLongPtrAthW(HWND hWnd, int nIndex, LONG_PTR dwNewLong)
  105. {
  106. if (S_OK == IsPlatformWinNT())
  107. return SetWindowLongPtrW(hWnd, nIndex, dwNewLong);
  108. return SetWindowLongPtrA(hWnd, nIndex, dwNewLong);
  109. }
  110. /**********************************************************************************\
  111. * bobn 6/23/99
  112. *
  113. * The following code was ported from ShlWapi. There were problems with
  114. * our implementation on Win95 and it seemed prudent to have a solution
  115. * without a bunch of special cases.
  116. *
  117. *
  118. \**********************************************************************************/
  119. #define DBCS_CHARSIZE (2)
  120. int Ath_MBToWCS(LPSTR pszIn, int cchIn, LPWSTR *ppwszOut)
  121. {
  122. int cch = 0;
  123. int cbAlloc;
  124. if ((0 != cchIn) && (NULL != ppwszOut))
  125. {
  126. cchIn++;
  127. cbAlloc = cchIn * sizeof(WCHAR);
  128. *ppwszOut = (LPWSTR)LocalAlloc(LMEM_FIXED, cbAlloc);
  129. if (NULL != *ppwszOut)
  130. {
  131. cch = MultiByteToWideChar(CP_ACP, 0, pszIn, cchIn, *ppwszOut, cchIn);
  132. if (!cch)
  133. {
  134. LocalFree(*ppwszOut);
  135. *ppwszOut = NULL;
  136. }
  137. else
  138. {
  139. cch--; // Just return the number of characters
  140. }
  141. }
  142. }
  143. return cch;
  144. }
  145. int Ath_WCSToMB(LPCWSTR pwszIn, int cchIn, LPSTR *ppszOut)
  146. {
  147. int cch = 0;
  148. int cbAlloc;
  149. if ((0 != cchIn) && (NULL != ppszOut))
  150. {
  151. cchIn++;
  152. cbAlloc = cchIn * DBCS_CHARSIZE;
  153. *ppszOut = (LPSTR)LocalAlloc(LMEM_FIXED, cbAlloc);
  154. if (NULL != *ppszOut)
  155. {
  156. cch = WideCharToMultiByte(CP_ACP, 0, pwszIn, cchIn,
  157. *ppszOut, cbAlloc, NULL, NULL);
  158. if (!cch)
  159. {
  160. LocalFree(*ppszOut);
  161. *ppszOut = NULL;
  162. }
  163. else
  164. {
  165. cch--; // Just return the number of characters
  166. }
  167. }
  168. }
  169. return cch;
  170. }
  171. /****************************** Module Header ******************************\
  172. * Module Name: wsprintf.c
  173. *
  174. * Copyright (c) 1985-91, Microsoft Corporation
  175. * sprintf.c
  176. *
  177. * Implements Windows friendly versions of sprintf and vsprintf
  178. *
  179. * History:
  180. * 2-15-89 craigc Initial
  181. * 11-12-90 MikeHar Ported from windows 3
  182. \***************************************************************************/
  183. /* Max number of characters. Doesn't include termination character */
  184. #define out(c) if (cchLimit) {*lpOut++=(c); cchLimit--;} else goto errorout
  185. /***************************************************************************\
  186. * AthSP_GetFmtValueW
  187. *
  188. * reads a width or precision value from the format string
  189. *
  190. * History:
  191. * 11-12-90 MikeHar Ported from windows 3
  192. * 07-27-92 GregoryW Created Unicode version (copied from AthSP_GetFmtValue)
  193. \***************************************************************************/
  194. LPCWSTR AthSP_GetFmtValueW(
  195. LPCWSTR lpch,
  196. int *lpw)
  197. {
  198. int ii = 0;
  199. /* It might not work for some locales or digit sets */
  200. while (*lpch >= L'0' && *lpch <= L'9') {
  201. ii *= 10;
  202. ii += (int)(*lpch - L'0');
  203. lpch++;
  204. }
  205. *lpw = ii;
  206. /*
  207. * return the address of the first non-digit character
  208. */
  209. return lpch;
  210. }
  211. /***************************************************************************\
  212. * AthSP_PutNumberW
  213. *
  214. * Takes an unsigned long integer and places it into a buffer, respecting
  215. * a buffer limit, a radix, and a case select (upper or lower, for hex).
  216. *
  217. *
  218. * History:
  219. * 11-12-90 MikeHar Ported from windows 3 asm --> C
  220. * 12-11-90 GregoryW need to increment lpstr after assignment of mod
  221. * 02-11-92 GregoryW temporary version until we have C runtime support
  222. \***************************************************************************/
  223. int AthSP_PutNumberW(
  224. LPWSTR lpstr,
  225. DWORD n,
  226. int limit,
  227. DWORD radix,
  228. int uppercase,
  229. int *pcch)
  230. {
  231. DWORD mod;
  232. *pcch = 0;
  233. /* It might not work for some locales or digit sets */
  234. if(uppercase)
  235. uppercase = 'A'-'0'-10;
  236. else
  237. uppercase = 'a'-'0'-10;
  238. if (limit) {
  239. do {
  240. mod = n % radix;
  241. n /= radix;
  242. mod += '0';
  243. if (mod > '9')
  244. mod += uppercase;
  245. *lpstr++ = (WCHAR)mod;
  246. (*pcch)++;
  247. } while((*pcch < limit) && n);
  248. }
  249. return (n == 0) && (*pcch > 0);
  250. }
  251. /***************************************************************************\
  252. * AthSP_ReverseW
  253. *
  254. * reverses a string in place
  255. *
  256. * History:
  257. * 11-12-90 MikeHar Ported from windows 3 asm --> C
  258. * 12-11-90 GregoryW fixed boundary conditions; removed count
  259. * 02-11-92 GregoryW temporary version until we have C runtime support
  260. \***************************************************************************/
  261. void AthSP_ReverseW(
  262. LPWSTR lpFirst,
  263. LPWSTR lpLast)
  264. {
  265. WCHAR ch;
  266. while(lpLast > lpFirst){
  267. ch = *lpFirst;
  268. *lpFirst++ = *lpLast;
  269. *lpLast-- = ch;
  270. }
  271. }
  272. /***************************************************************************\
  273. * wvsprintfW (API)
  274. *
  275. * wsprintfW() calls this function.
  276. *
  277. * History:
  278. * 11-Feb-1992 GregoryW copied xwvsprintf
  279. * Temporary hack until we have C runtime support
  280. * 1-22-97 tnoonan Converted to wvnsprintfW
  281. \***************************************************************************/
  282. OESTDAPI_(int) AthwvnsprintfW(
  283. LPWSTR lpOut,
  284. int cchLimitIn,
  285. LPCWSTR lpFmt,
  286. va_list arglist)
  287. {
  288. BOOL fAllocateMem = FALSE;
  289. WCHAR prefix, fillch;
  290. int left, width, prec, size, sign, radix, upper, hprefix;
  291. int cchLimit = --cchLimitIn, cch, cchAvailable;
  292. LPWSTR lpT, lpTWC;
  293. LPSTR psz;
  294. va_list varglist = arglist;
  295. union {
  296. long l;
  297. unsigned long ul;
  298. CHAR sz[2];
  299. WCHAR wsz[2];
  300. } val;
  301. if (cchLimit < 0)
  302. return 0;
  303. while (*lpFmt != 0) {
  304. if (*lpFmt == L'%') {
  305. /*
  306. * read the flags. These can be in any order
  307. */
  308. left = 0;
  309. prefix = 0;
  310. while (*++lpFmt) {
  311. if (*lpFmt == L'-')
  312. left++;
  313. else if (*lpFmt == L'#')
  314. prefix++;
  315. else
  316. break;
  317. }
  318. /*
  319. * find fill character
  320. */
  321. if (*lpFmt == L'0') {
  322. fillch = L'0';
  323. lpFmt++;
  324. } else
  325. fillch = L' ';
  326. /*
  327. * read the width specification
  328. */
  329. lpFmt = AthSP_GetFmtValueW(lpFmt, &cch);
  330. width = cch;
  331. /*
  332. * read the precision
  333. */
  334. if (*lpFmt == L'.') {
  335. lpFmt = AthSP_GetFmtValueW(++lpFmt, &cch);
  336. prec = cch;
  337. } else
  338. prec = -1;
  339. /*
  340. * get the operand size
  341. * default size: size == 0
  342. * long number: size == 1
  343. * wide chars: size == 2
  344. * It may be a good idea to check the value of size when it
  345. * is tested for non-zero below (IanJa)
  346. */
  347. hprefix = 0;
  348. if ((*lpFmt == L'w') || (*lpFmt == L't')) {
  349. size = 2;
  350. lpFmt++;
  351. } else if (*lpFmt == L'l') {
  352. size = 1;
  353. lpFmt++;
  354. } else {
  355. size = 0;
  356. if (*lpFmt == L'h') {
  357. lpFmt++;
  358. hprefix = 1;
  359. }
  360. }
  361. upper = 0;
  362. sign = 0;
  363. radix = 10;
  364. switch (*lpFmt) {
  365. case 0:
  366. goto errorout;
  367. case L'i':
  368. case L'd':
  369. size=1;
  370. sign++;
  371. /*** FALL THROUGH to case 'u' ***/
  372. case L'u':
  373. /* turn off prefix if decimal */
  374. prefix = 0;
  375. donumeric:
  376. /* special cases to act like MSC v5.10 */
  377. if (left || prec >= 0)
  378. fillch = L' ';
  379. /*
  380. * if size == 1, "%lu" was specified (good);
  381. * if size == 2, "%wu" was specified (bad)
  382. */
  383. if (size) {
  384. val.l = va_arg(varglist, LONG);
  385. } else if (sign) {
  386. val.l = va_arg(varglist, SHORT);
  387. } else {
  388. val.ul = va_arg(varglist, unsigned);
  389. }
  390. if (sign && val.l < 0L)
  391. val.l = -val.l;
  392. else
  393. sign = 0;
  394. lpT = lpOut;
  395. /*
  396. * blast the number backwards into the user buffer
  397. * AthSP_PutNumberW returns FALSE if it runs out of space
  398. */
  399. if (!AthSP_PutNumberW(lpOut, val.l, cchLimit, radix, upper, &cch))
  400. {
  401. break;
  402. }
  403. // Now we have the number backwards, calculate how much
  404. // more buffer space we'll need for this number to
  405. // format correctly.
  406. cchAvailable = cchLimit - cch;
  407. width -= cch;
  408. prec -= cch;
  409. if (prec > 0)
  410. {
  411. width -= prec;
  412. cchAvailable -= prec;
  413. }
  414. if (width > 0)
  415. {
  416. cchAvailable -= width - (sign ? 1 : 0);
  417. }
  418. if (sign)
  419. {
  420. cchAvailable--;
  421. }
  422. if (cchAvailable < 0)
  423. {
  424. break;
  425. }
  426. // We have enough space to format the buffer as requested
  427. // without overflowing.
  428. lpOut += cch;
  429. cchLimit -= cch;
  430. /*
  431. * fill to the field precision
  432. */
  433. while (prec-- > 0)
  434. out(L'0');
  435. if (width > 0 && !left) {
  436. /*
  437. * if we're filling with spaces, put sign first
  438. */
  439. if (fillch != L'0') {
  440. if (sign) {
  441. sign = 0;
  442. out(L'-');
  443. width--;
  444. }
  445. if (prefix) {
  446. out(prefix);
  447. out(L'0');
  448. prefix = 0;
  449. }
  450. }
  451. if (sign)
  452. width--;
  453. /*
  454. * fill to the field width
  455. */
  456. while (width-- > 0)
  457. out(fillch);
  458. /*
  459. * still have a sign?
  460. */
  461. if (sign)
  462. out(L'-');
  463. if (prefix) {
  464. out(prefix);
  465. out(L'0');
  466. }
  467. /*
  468. * now reverse the string in place
  469. */
  470. AthSP_ReverseW(lpT, lpOut - 1);
  471. } else {
  472. /*
  473. * add the sign character
  474. */
  475. if (sign) {
  476. out(L'-');
  477. width--;
  478. }
  479. if (prefix) {
  480. out(prefix);
  481. out(L'0');
  482. }
  483. /*
  484. * reverse the string in place
  485. */
  486. AthSP_ReverseW(lpT, lpOut - 1);
  487. /*
  488. * pad to the right of the string in case left aligned
  489. */
  490. while (width-- > 0)
  491. out(fillch);
  492. }
  493. break;
  494. case L'X':
  495. upper++;
  496. /*** FALL THROUGH to case 'x' ***/
  497. case L'x':
  498. radix = 16;
  499. if (prefix)
  500. if (upper)
  501. prefix = L'X';
  502. else
  503. prefix = L'x';
  504. goto donumeric;
  505. case L'c':
  506. if (!size && !hprefix) {
  507. size = 1; // force WCHAR
  508. }
  509. /*** FALL THROUGH to case 'C' ***/
  510. case L'C':
  511. /*
  512. * if size == 0, "%C" or "%hc" was specified (CHAR);
  513. * if size == 1, "%c" or "%lc" was specified (WCHAR);
  514. * if size == 2, "%wc" or "%tc" was specified (WCHAR)
  515. */
  516. cch = 1; /* One character must be copied to the output buffer */
  517. if (size) {
  518. val.wsz[0] = va_arg(varglist, WCHAR);
  519. val.wsz[1] = 0;
  520. lpT = val.wsz;
  521. goto putwstring;
  522. } else {
  523. val.sz[0] = va_arg(varglist, CHAR);
  524. val.sz[1] = 0;
  525. psz = (LPSTR)(val.sz);
  526. goto putstring;
  527. }
  528. case L's':
  529. if (!size && !hprefix) {
  530. size = 1; // force LPWSTR
  531. }
  532. /*** FALL THROUGH to case 'S' ***/
  533. case L'S':
  534. /*
  535. * if size == 0, "%S" or "%hs" was specified (LPSTR)
  536. * if size == 1, "%s" or "%ls" was specified (LPWSTR);
  537. * if size == 2, "%ws" or "%ts" was specified (LPWSTR)
  538. */
  539. if (size) {
  540. lpT = va_arg(varglist, LPWSTR);
  541. cch = lstrlenW(lpT);
  542. } else {
  543. psz = va_arg(varglist, LPSTR);
  544. cch = lstrlen((LPCSTR)psz);
  545. putstring:
  546. cch = Ath_MBToWCS(psz, cch, &lpTWC);
  547. fAllocateMem = (BOOL) cch;
  548. lpT = lpTWC;
  549. }
  550. putwstring:
  551. if (prec >= 0 && cch > prec)
  552. cch = prec;
  553. width -= cch;
  554. if (left) {
  555. while (cch--)
  556. out(*lpT++);
  557. while (width-- > 0)
  558. out(fillch);
  559. } else {
  560. while (width-- > 0)
  561. out(fillch);
  562. while (cch--)
  563. out(*lpT++);
  564. }
  565. if (fAllocateMem) {
  566. LocalFree(lpTWC);
  567. fAllocateMem = FALSE;
  568. }
  569. break;
  570. default:
  571. normalch:
  572. out((WCHAR)*lpFmt);
  573. break;
  574. } /* END OF SWITCH(*lpFmt) */
  575. } /* END OF IF(%) */ else
  576. goto normalch; /* character not a '%', just do it */
  577. /*
  578. * advance to next format string character
  579. */
  580. lpFmt++;
  581. } /* END OF OUTER WHILE LOOP */
  582. errorout:
  583. *lpOut = 0;
  584. if (fAllocateMem)
  585. {
  586. LocalFree(lpTWC);
  587. }
  588. return cchLimitIn - cchLimit;
  589. }
  590. OESTDAPI_(int) AthwsprintfW( LPWSTR lpOut, int cchLimitIn, LPCWSTR lpFmt, ... )
  591. {
  592. va_list arglist;
  593. int ret;
  594. Assert(lpOut);
  595. Assert(lpFmt);
  596. lpOut[0] = 0;
  597. va_start(arglist, lpFmt);
  598. ret = AthwvnsprintfW(lpOut, cchLimitIn, lpFmt, arglist);
  599. va_end(arglist);
  600. return ret;
  601. }