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.

587 lines
15 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. win95api.c
  5. Abstract:
  6. Contains some thunking for Unicode KERNEL32 and USER32 APIs
  7. Author:
  8. Danilo Almeida (t-danal) 01-Jul-1996
  9. Revision History:
  10. --*/
  11. #include <windows.h>
  12. #include "charset.h"
  13. #include "win95api.h"
  14. UINT
  15. WINAPI
  16. GetProfileIntW(
  17. LPCWSTR lpAppName,
  18. LPCWSTR lpKeyName,
  19. INT nDefault
  20. )
  21. {
  22. LPSTR alpAppName;
  23. LPSTR alpKeyName;
  24. UINT err;
  25. err = AllocAnsi(lpAppName, &alpAppName);
  26. if (err)
  27. return nDefault;
  28. err = AllocAnsi(lpKeyName, &alpKeyName);
  29. if (err) {
  30. FreeAnsi(alpAppName);
  31. return nDefault;
  32. }
  33. err = GetProfileIntA((LPCSTR)alpAppName, (LPCSTR)alpKeyName, nDefault);
  34. FreeAnsi(alpAppName);
  35. FreeAnsi(alpKeyName);
  36. return err;
  37. }
  38. HANDLE
  39. WINAPI
  40. CreateSemaphoreW(
  41. LPSECURITY_ATTRIBUTES lpSemaphoreAttributes,
  42. LONG lInitialCount,
  43. LONG lMaximumCount,
  44. LPCWSTR lpName
  45. )
  46. {
  47. LPSTR alpName;
  48. UINT err;
  49. HANDLE hSemaphore;
  50. err = AllocAnsi(lpName, &alpName);
  51. if (err) {
  52. SetLastError(err);
  53. return NULL;
  54. }
  55. hSemaphore = CreateSemaphoreA(lpSemaphoreAttributes,
  56. lInitialCount,
  57. lMaximumCount,
  58. alpName);
  59. FreeAnsi(alpName);
  60. return hSemaphore;
  61. }
  62. HMODULE
  63. WINAPI
  64. LoadLibraryW(
  65. LPCWSTR lpLibFileName
  66. )
  67. {
  68. LPSTR alpLibFileName;
  69. UINT err;
  70. HMODULE hLibrary;
  71. err = AllocAnsi(lpLibFileName, &alpLibFileName);
  72. if (err) {
  73. SetLastError(err);
  74. return NULL;
  75. }
  76. hLibrary = LoadLibraryA(alpLibFileName);
  77. FreeAnsi(alpLibFileName);
  78. return hLibrary;
  79. }
  80. BOOL
  81. WINAPI
  82. SystemTimeToTzSpecificLocalTime(
  83. LPTIME_ZONE_INFORMATION lpTimeZoneInformation,
  84. LPSYSTEMTIME lpUniversalTime,
  85. LPSYSTEMTIME lpLocalTime
  86. )
  87. {
  88. FILETIME UniversalFileTime;
  89. FILETIME LocalFileTime;
  90. if (!SystemTimeToFileTime(lpUniversalTime, &UniversalFileTime))
  91. return FALSE;
  92. if(!FileTimeToLocalFileTime(&UniversalFileTime, &LocalFileTime))
  93. return FALSE;
  94. if(!FileTimeToSystemTime(&LocalFileTime, lpLocalTime))
  95. return FALSE;
  96. return TRUE;
  97. }
  98. /****************************** Module Header ******************************\
  99. * Module Name: wsprintf.c
  100. *
  101. * Copyright (c) 1985-91, Microsoft Corporation
  102. * sprintf.c
  103. *
  104. * Implements Windows friendly versions of sprintf and vsprintf
  105. *
  106. * History:
  107. * 2-15-89 craigc Initial
  108. * 11-12-90 MikeHar Ported from windows 3
  109. \***************************************************************************/
  110. /* Max number of characters. Doesn't include termination character */
  111. #define WSPRINTF_LIMIT 1024
  112. #define out(c) if (cchLimit) {*lpOut++=(c); cchLimit--;} else goto errorout
  113. /***************************************************************************\
  114. * SP_GetFmtValueW
  115. *
  116. * reads a width or precision value from the format string
  117. *
  118. * History:
  119. * 11-12-90 MikeHar Ported from windows 3
  120. * 07-27-92 GregoryW Created Unicode version (copied from SP_GetFmtValue)
  121. \***************************************************************************/
  122. LPCWSTR SP_GetFmtValueW(
  123. LPCWSTR lpch,
  124. int *lpw)
  125. {
  126. int ii = 0;
  127. /* It might not work for some locales or digit sets */
  128. while (*lpch >= L'0' && *lpch <= L'9') {
  129. ii *= 10;
  130. ii += (int)(*lpch - L'0');
  131. lpch++;
  132. }
  133. *lpw = ii;
  134. /*
  135. * return the address of the first non-digit character
  136. */
  137. return lpch;
  138. }
  139. /***************************************************************************\
  140. * SP_PutNumberW
  141. *
  142. * Takes an unsigned long integer and places it into a buffer, respecting
  143. * a buffer limit, a radix, and a case select (upper or lower, for hex).
  144. *
  145. *
  146. * History:
  147. * 11-12-90 MikeHar Ported from windows 3 asm --> C
  148. * 12-11-90 GregoryW need to increment lpstr after assignment of mod
  149. * 02-11-92 GregoryW temporary version until we have C runtime support
  150. \***************************************************************************/
  151. int SP_PutNumberW(
  152. LPWSTR lpstr,
  153. DWORD n,
  154. int limit,
  155. DWORD radix,
  156. int uppercase)
  157. {
  158. DWORD mod;
  159. int count = 0;
  160. /* It might not work for some locales or digit sets */
  161. if(uppercase)
  162. uppercase = 'A'-'0'-10;
  163. else
  164. uppercase = 'a'-'0'-10;
  165. if (count < limit) {
  166. do {
  167. mod = n % radix;
  168. n /= radix;
  169. mod += '0';
  170. if (mod > '9')
  171. mod += uppercase;
  172. *lpstr++ = (WCHAR)mod;
  173. count++;
  174. } while((count < limit) && n);
  175. }
  176. return count;
  177. }
  178. /***************************************************************************\
  179. * SP_ReverseW
  180. *
  181. * reverses a string in place
  182. *
  183. * History:
  184. * 11-12-90 MikeHar Ported from windows 3 asm --> C
  185. * 12-11-90 GregoryW fixed boundary conditions; removed count
  186. * 02-11-92 GregoryW temporary version until we have C runtime support
  187. \***************************************************************************/
  188. void SP_ReverseW(
  189. LPWSTR lpFirst,
  190. LPWSTR lpLast)
  191. {
  192. WCHAR ch;
  193. while(lpLast > lpFirst){
  194. ch = *lpFirst;
  195. *lpFirst++ = *lpLast;
  196. *lpLast-- = ch;
  197. }
  198. }
  199. /***************************************************************************\
  200. * wvsprintfW (API)
  201. *
  202. * wsprintfW() calls this function.
  203. *
  204. * History:
  205. * 11-Feb-1992 GregoryW copied xwvsprintf
  206. * Temporary hack until we have C runtime support
  207. \***************************************************************************/
  208. int WINAPI wvsprintfW(
  209. LPWSTR lpOut,
  210. LPCWSTR lpFmt,
  211. va_list arglist)
  212. {
  213. BOOL fAllocateMem;
  214. WCHAR prefix, fillch;
  215. int left, width, prec, size, sign, radix, upper, hprefix;
  216. int cchLimit = WSPRINTF_LIMIT, cch;
  217. LPWSTR lpT, lpTWC;
  218. LPBYTE psz;
  219. va_list varglist = arglist;
  220. union {
  221. long l;
  222. unsigned long ul;
  223. char sz[2];
  224. WCHAR wsz[2];
  225. } val;
  226. while (*lpFmt != 0) {
  227. if (*lpFmt == L'%') {
  228. /*
  229. * read the flags. These can be in any order
  230. */
  231. left = 0;
  232. prefix = 0;
  233. while (*++lpFmt) {
  234. if (*lpFmt == L'-')
  235. left++;
  236. else if (*lpFmt == L'#')
  237. prefix++;
  238. else
  239. break;
  240. }
  241. /*
  242. * find fill character
  243. */
  244. if (*lpFmt == L'0') {
  245. fillch = L'0';
  246. lpFmt++;
  247. } else
  248. fillch = L' ';
  249. /*
  250. * read the width specification
  251. */
  252. lpFmt = SP_GetFmtValueW(lpFmt, &cch);
  253. width = cch;
  254. /*
  255. * read the precision
  256. */
  257. if (*lpFmt == L'.') {
  258. lpFmt = SP_GetFmtValueW(++lpFmt, &cch);
  259. prec = cch;
  260. } else
  261. prec = -1;
  262. /*
  263. * get the operand size
  264. * default size: size == 0
  265. * long number: size == 1
  266. * wide chars: size == 2
  267. * It may be a good idea to check the value of size when it
  268. * is tested for non-zero below (IanJa)
  269. */
  270. hprefix = 0;
  271. if ((*lpFmt == L'w') || (*lpFmt == L't')) {
  272. size = 2;
  273. lpFmt++;
  274. } else if (*lpFmt == L'l') {
  275. size = 1;
  276. lpFmt++;
  277. } else {
  278. size = 0;
  279. if (*lpFmt == L'h') {
  280. lpFmt++;
  281. hprefix = 1;
  282. }
  283. }
  284. upper = 0;
  285. sign = 0;
  286. radix = 10;
  287. switch (*lpFmt) {
  288. case 0:
  289. goto errorout;
  290. case L'i':
  291. case L'd':
  292. size=1;
  293. sign++;
  294. /*** FALL THROUGH to case 'u' ***/
  295. case L'u':
  296. /* turn off prefix if decimal */
  297. prefix = 0;
  298. donumeric:
  299. /* special cases to act like MSC v5.10 */
  300. if (left || prec >= 0)
  301. fillch = L' ';
  302. /*
  303. * if size == 1, "%lu" was specified (good);
  304. * if size == 2, "%wu" was specified (bad)
  305. */
  306. if (size) {
  307. val.l = va_arg(varglist, LONG);
  308. } else if (sign) {
  309. val.l = va_arg(varglist, SHORT);
  310. } else {
  311. val.ul = va_arg(varglist, unsigned);
  312. }
  313. if (sign && val.l < 0L)
  314. val.l = -val.l;
  315. else
  316. sign = 0;
  317. lpT = lpOut;
  318. /*
  319. * blast the number backwards into the user buffer
  320. */
  321. cch = SP_PutNumberW(lpOut, val.l, cchLimit, radix, upper);
  322. if (!(cchLimit -= cch))
  323. goto errorout;
  324. lpOut += cch;
  325. width -= cch;
  326. prec -= cch;
  327. if (prec > 0)
  328. width -= prec;
  329. /*
  330. * fill to the field precision
  331. */
  332. while (prec-- > 0)
  333. out(L'0');
  334. if (width > 0 && !left) {
  335. /*
  336. * if we're filling with spaces, put sign first
  337. */
  338. if (fillch != L'0') {
  339. if (sign) {
  340. sign = 0;
  341. out(L'-');
  342. width--;
  343. }
  344. if (prefix) {
  345. out(prefix);
  346. out(L'0');
  347. prefix = 0;
  348. }
  349. }
  350. if (sign)
  351. width--;
  352. /*
  353. * fill to the field width
  354. */
  355. while (width-- > 0)
  356. out(fillch);
  357. /*
  358. * still have a sign?
  359. */
  360. if (sign)
  361. out(L'-');
  362. if (prefix) {
  363. out(prefix);
  364. out(L'0');
  365. }
  366. /*
  367. * now reverse the string in place
  368. */
  369. SP_ReverseW(lpT, lpOut - 1);
  370. } else {
  371. /*
  372. * add the sign character
  373. */
  374. if (sign) {
  375. out(L'-');
  376. width--;
  377. }
  378. if (prefix) {
  379. out(prefix);
  380. out(L'0');
  381. }
  382. /*
  383. * reverse the string in place
  384. */
  385. SP_ReverseW(lpT, lpOut - 1);
  386. /*
  387. * pad to the right of the string in case left aligned
  388. */
  389. while (width-- > 0)
  390. out(fillch);
  391. }
  392. break;
  393. case L'X':
  394. upper++;
  395. /*** FALL THROUGH to case 'x' ***/
  396. case L'x':
  397. radix = 16;
  398. if (prefix)
  399. if (upper)
  400. prefix = L'X';
  401. else
  402. prefix = L'x';
  403. goto donumeric;
  404. case L'c':
  405. if (!size && !hprefix) {
  406. size = 1; // force WCHAR
  407. }
  408. /*** FALL THROUGH to case 'C' ***/
  409. case L'C':
  410. /*
  411. * if size == 0, "%C" or "%hc" was specified (CHAR);
  412. * if size == 1, "%c" or "%lc" was specified (WCHAR);
  413. * if size == 2, "%wc" or "%tc" was specified (WCHAR)
  414. */
  415. cch = 1; /* One character must be copied to the output buffer */
  416. if (size) {
  417. val.wsz[0] = va_arg(varglist, WCHAR);
  418. val.wsz[1] = 0;
  419. lpT = val.wsz;
  420. goto putwstring;
  421. } else {
  422. val.sz[0] = va_arg(varglist, CHAR);
  423. val.sz[1] = 0;
  424. psz = val.sz;
  425. goto putstring;
  426. }
  427. case L's':
  428. if (!size && !hprefix) {
  429. size = 1; // force LPWSTR
  430. }
  431. /*** FALL THROUGH to case 'S' ***/
  432. case L'S':
  433. /*
  434. * if size == 0, "%S" or "%hs" was specified (LPSTR)
  435. * if size == 1, "%s" or "%ls" was specified (LPWSTR);
  436. * if size == 2, "%ws" or "%ts" was specified (LPWSTR)
  437. */
  438. if (size) {
  439. lpT = va_arg(varglist, LPWSTR);
  440. cch = wcslen(lpT);
  441. putwstring:
  442. fAllocateMem = FALSE;
  443. } else {
  444. psz = va_arg(varglist, LPBYTE);
  445. cch = strlen(psz);
  446. putstring:
  447. cch = AllocUnicode2(psz, cch, &lpTWC);
  448. fAllocateMem = (BOOL) cch;
  449. lpT = lpTWC;
  450. }
  451. if (prec >= 0 && cch > prec)
  452. cch = prec;
  453. width -= cch;
  454. if (fAllocateMem) {
  455. if (cch + (width < 0 ? 0 : width) >= cchLimit) {
  456. FreeUnicode(lpTWC);
  457. goto errorout;
  458. }
  459. }
  460. if (left) {
  461. while (cch--)
  462. out(*lpT++);
  463. while (width-- > 0)
  464. out(fillch);
  465. } else {
  466. while (width-- > 0)
  467. out(fillch);
  468. while (cch--)
  469. out(*lpT++);
  470. }
  471. if (fAllocateMem) {
  472. FreeUnicode(lpTWC);
  473. }
  474. break;
  475. default:
  476. normalch:
  477. out((WCHAR)*lpFmt);
  478. break;
  479. } /* END OF SWITCH(*lpFmt) */
  480. } /* END OF IF(%) */ else
  481. goto normalch; /* character not a '%', just do it */
  482. /*
  483. * advance to next format string character
  484. */
  485. lpFmt++;
  486. } /* END OF OUTER WHILE LOOP */
  487. errorout:
  488. *lpOut = 0;
  489. return WSPRINTF_LIMIT - cchLimit;
  490. }
  491. int WINAPIV wsprintfW(
  492. LPWSTR lpOut,
  493. LPCWSTR lpFmt,
  494. ...)
  495. {
  496. va_list arglist;
  497. int ret;
  498. va_start(arglist, lpFmt);
  499. ret = wvsprintfW(lpOut, lpFmt, arglist);
  500. va_end(arglist);
  501. return ret;
  502. }