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.

648 lines
18 KiB

  1. /*++
  2. Copyright (c) 1999-2000 Microsoft Corporation
  3. Module Name:
  4. efistrutil.cxx
  5. --*/
  6. #include "efiwintypes.hxx"
  7. #include "pch.cxx"
  8. void *memmove( void *dest, const void *src, size_t count )
  9. {
  10. // quick workaround for lack of memmove in EFI library
  11. VOID * temp = AllocatePool(count);
  12. memcpy( temp, src, count);
  13. memcpy( dest, temp, count);
  14. FreePool(temp);
  15. return dest;
  16. }
  17. char *strcpy( char *strDestination, const char *strSource )
  18. {
  19. INT32 i;
  20. i=0;
  21. while(strSource[i] != NULL) {
  22. strDestination[i] = strSource[i];
  23. i++;
  24. }
  25. strDestination[i] = NULL; // null terminate.
  26. return strDestination;
  27. }
  28. int iswspace( WCHAR c )
  29. {
  30. // BUGBUG this isn't a proper wide char test
  31. // but will do for now.
  32. if( ((0x09 <= c) && (c <= 0x0d)) || (c == 0x20) ) {
  33. return TRUE;
  34. } else {
  35. return FALSE;
  36. }
  37. }
  38. int isspace( CHAR c )
  39. {
  40. // BUGBUG this isn't a proper wide char test
  41. // but will do for now.
  42. if( ((0x09 <= c) && (c <= 0x0d)) || (c == 0x20) ) {
  43. return TRUE;
  44. } else {
  45. return FALSE;
  46. }
  47. }
  48. int isdigit( int c )
  49. {
  50. // BUGBUG again, this isn't a proper wide char test
  51. // but it will do for now.
  52. if( c >= '0' && c <= '9' ) {
  53. return TRUE;
  54. } else {
  55. return FALSE;
  56. }
  57. }
  58. int towupper( WCHAR c )
  59. {
  60. // BUGBUG, this is wrong too, but for now it must do.
  61. return c;
  62. }
  63. int wcsncmp( const WCHAR *string1, const WCHAR *string2, size_t count )
  64. {
  65. for( unsigned int i=0; i<count; i++ ) {
  66. if(string1[i] != string2[i] || string1[i] == UNICODE_NULL || string2[i] == UNICODE_NULL) {
  67. break;
  68. }
  69. }
  70. return string2[i]-string1[i];
  71. }
  72. long atol(const char *nptr) {
  73. int c; /* current char */
  74. long total; /* current total */
  75. int sign; /* if '-', then negative, otherwise positive */
  76. while (isspace((int)(unsigned char)*nptr))
  77. nptr++;
  78. c = (int)(unsigned char)*nptr++;
  79. sign = c; /* save sign indication */
  80. if (c == '-' || c == '+')
  81. c = (int)(unsigned char)*nptr++; /* skip sign */
  82. total = 0;
  83. while ((c >= '0') && (c <= '9')) {
  84. total = 10 * total + (c - '0'); /* accumulate digit */
  85. c = (int)(unsigned char)*nptr++; /* get next char */
  86. }
  87. if (sign == '-')
  88. return -total;
  89. else
  90. return total;
  91. }
  92. int atoi(const char *nptr) {
  93. return (int)atol(nptr);
  94. }
  95. STATIC char *sprintf_buf;
  96. STATIC count;
  97. VOID
  98. bzero(char *cp, int len)
  99. {
  100. while (len--) {
  101. *(cp + len) = 0;
  102. }
  103. }
  104. VOID
  105. __cdecl
  106. putbuf(char c)
  107. {
  108. *sprintf_buf++ = c;
  109. count++;
  110. }
  111. VOID
  112. __cdecl
  113. doprnt(VOID (*func)(char c), const char *fmt, va_list args);
  114. //
  115. // BUGBUG this is a semi-sprintf hacked together just to get it to work
  116. //
  117. int
  118. __cdecl
  119. sprintf(char *buf, const char *fmt, ...)
  120. {
  121. va_list args;
  122. sprintf_buf = buf;
  123. va_start(args, fmt);
  124. doprnt(putbuf, fmt, args);
  125. va_end(args);
  126. putbuf('\0');
  127. return count--;
  128. }
  129. void
  130. __cdecl
  131. printbase(VOID (*func)(char), ULONG x, int base, int width)
  132. {
  133. static char itoa[] = "0123456789abcdef";
  134. ULONG j;
  135. LONG k;
  136. char buf[32], *s = buf;
  137. bzero(buf, 16);
  138. while (x) {
  139. j = x % base;
  140. *s++ = itoa[j];
  141. x -= j;
  142. x /= base;
  143. }
  144. if( s-buf < width ) {
  145. for( k = 0; k < width - (s-buf); k++ ) {
  146. func('0');
  147. }
  148. }
  149. for (--s; s >= buf; --s) {
  150. func(*s);
  151. }
  152. }
  153. void
  154. __cdecl
  155. doprnt(VOID (*func)( char c), const char *fmt, va_list args)
  156. {
  157. ULONG x;
  158. LONG l;
  159. LONG width;
  160. char c, *s;
  161. count = 0;
  162. while (c = *fmt++) {
  163. if (c != '%') {
  164. func(c);
  165. continue;
  166. }
  167. width=0;
  168. c=*fmt++;
  169. if(c == '0') {
  170. while( c = *fmt++) {
  171. if (!isdigit(c)) {
  172. break;
  173. }
  174. width = width*10;
  175. width = width+(c-48);
  176. }
  177. }
  178. fmt--; // back it up one char
  179. switch (c = *fmt++) {
  180. case 'x':
  181. x = va_arg(args, ULONG);
  182. printbase(func, x, 16, width);
  183. break;
  184. case 'o':
  185. x = va_arg(args, ULONG);
  186. printbase(func, x, 8, width);
  187. break;
  188. case 'd':
  189. l = va_arg(args, LONG);
  190. if (l < 0) {
  191. func('-');
  192. l = -l;
  193. }
  194. printbase(func, (ULONG) l, 10, width);
  195. break;
  196. case 'u':
  197. l = va_arg(args, ULONG);
  198. printbase(func, (ULONG) l, 10, width);
  199. break;
  200. case 'c':
  201. c = va_arg(args, char);
  202. func(c);
  203. break;
  204. case 's':
  205. s = va_arg(args, char *);
  206. while (*s) {
  207. func(*s++);
  208. }
  209. break;
  210. default:
  211. func(c);
  212. break;
  213. }
  214. }
  215. }
  216. #define MAX_INSERTS 200
  217. NTSTATUS
  218. RtlFormatMessage(
  219. IN PWSTR MessageFormat,
  220. IN ULONG MaximumWidth OPTIONAL,
  221. IN BOOLEAN IgnoreInserts,
  222. IN BOOLEAN ArgumentsAreAnsi,
  223. IN BOOLEAN ArgumentsAreAnArray,
  224. IN va_list *Arguments,
  225. OUT PWSTR Buffer,
  226. IN ULONG Length,
  227. OUT PULONG ReturnLength OPTIONAL
  228. )
  229. {
  230. ULONG Column;
  231. int cchRemaining, cchWritten;
  232. PULONG_PTR ArgumentsArray = (PULONG_PTR)Arguments;
  233. ULONG_PTR rgInserts[ MAX_INSERTS ];
  234. ULONG cSpaces;
  235. ULONG MaxInsert, CurInsert;
  236. ULONG PrintParameterCount;
  237. ULONG_PTR PrintParameter1;
  238. ULONG_PTR PrintParameter2;
  239. WCHAR PrintFormatString[ 32 ];
  240. BOOLEAN DefaultedFormatString;
  241. WCHAR c;
  242. PWSTR s, s1;
  243. PWSTR lpDst, lpDstBeg, lpDstLastSpace;
  244. cchRemaining = Length / sizeof( WCHAR );
  245. lpDst = Buffer;
  246. MaxInsert = 0;
  247. lpDstLastSpace = NULL;
  248. Column = 0;
  249. s = MessageFormat;
  250. while (*s != UNICODE_NULL) {
  251. if (*s == L'%') {
  252. s++;
  253. lpDstBeg = lpDst;
  254. if (*s >= L'1' && *s <= L'9') {
  255. CurInsert = *s++ - L'0';
  256. if (*s >= L'0' && *s <= L'9') {
  257. CurInsert = (CurInsert * 10) + (*s++ - L'0');
  258. if (*s >= L'0' && *s <= L'9') {
  259. CurInsert = (CurInsert * 10) + (*s++ - L'0');
  260. if (*s >= L'0' && *s <= L'9') {
  261. return( STATUS_INVALID_PARAMETER );
  262. }
  263. }
  264. }
  265. CurInsert -= 1;
  266. PrintParameterCount = 0;
  267. if (*s == L'!') {
  268. DefaultedFormatString = FALSE;
  269. s1 = PrintFormatString;
  270. *s1++ = L'%';
  271. s++;
  272. while (*s != L'!') {
  273. if (*s != UNICODE_NULL) {
  274. if (s1 >= &PrintFormatString[ 31 ]) {
  275. return( STATUS_INVALID_PARAMETER );
  276. }
  277. if (*s == L'*') {
  278. if (PrintParameterCount++ > 1) {
  279. return( STATUS_INVALID_PARAMETER );
  280. }
  281. }
  282. *s1++ = *s++;
  283. }
  284. else {
  285. return( STATUS_INVALID_PARAMETER );
  286. }
  287. }
  288. s++;
  289. *s1 = UNICODE_NULL;
  290. }
  291. else {
  292. DefaultedFormatString = TRUE;
  293. wcscpy( PrintFormatString, TEXT("%s") );
  294. s1 = PrintFormatString + wcslen( PrintFormatString );
  295. }
  296. if (IgnoreInserts) {
  297. if (!wcscmp( PrintFormatString, TEXT("%s") )) {
  298. cchWritten = (int)SPrint( lpDst,
  299. cchRemaining,
  300. TEXT("%%%u"),
  301. CurInsert+1
  302. );
  303. }
  304. else {
  305. cchWritten = (int)SPrint( lpDst,
  306. cchRemaining,
  307. TEXT("%%%u!%s!"),
  308. CurInsert+1,
  309. &PrintFormatString[ 1 ]
  310. );
  311. }
  312. if (cchWritten == -1) {
  313. return(STATUS_BUFFER_OVERFLOW);
  314. }
  315. }
  316. else
  317. if (ARGUMENT_PRESENT( Arguments )) {
  318. if ((CurInsert+PrintParameterCount) >= MAX_INSERTS) {
  319. return( STATUS_INVALID_PARAMETER );
  320. }
  321. if (ArgumentsAreAnsi) {
  322. if (s1[ -1 ] == L'c' && s1[ -2 ] != L'h'
  323. && s1[ -2 ] != L'w' && s1[ -2 ] != L'l') {
  324. wcscpy( &s1[ -1 ], TEXT("hc") );
  325. }
  326. else
  327. if (s1[ -1 ] == L's' && s1[ -2 ] != L'h'
  328. && s1[ -2 ] != L'w' && s1[ -2 ] != L'l') {
  329. wcscpy( &s1[ -1 ], TEXT("hs") );
  330. }
  331. else if (s1[ -1 ] == L'S') {
  332. s1[ -1 ] = L's';
  333. }
  334. else if (s1[ -1 ] == L'C') {
  335. s1[ -1 ] = L'c';
  336. }
  337. }
  338. while (CurInsert >= MaxInsert) {
  339. if (ArgumentsAreAnArray) {
  340. PULONG_PTR aaa;
  341. aaa = (PULONG_PTR)Arguments++;
  342. PrintParameter2 = rgInserts[ MaxInsert++ ] = *(aaa);
  343. }
  344. else {
  345. rgInserts[ MaxInsert++ ] = va_arg(*Arguments, ULONG_PTR);
  346. }
  347. }
  348. s1 = (PWSTR)rgInserts[ CurInsert ];
  349. PrintParameter1 = 0;
  350. PrintParameter2 = 0;
  351. if (PrintParameterCount > 0) {
  352. if (ArgumentsAreAnArray) {
  353. PULONG_PTR aaa;
  354. aaa = (PULONG_PTR)Arguments;
  355. PrintParameter2 = rgInserts[ MaxInsert++ ] = *(aaa)++;
  356. }
  357. else {
  358. PrintParameter1 = rgInserts[ MaxInsert++ ] = va_arg( *Arguments, ULONG_PTR );
  359. }
  360. if (PrintParameterCount > 1) {
  361. if (ArgumentsAreAnArray) {
  362. PULONG_PTR aaa;
  363. aaa = (PULONG_PTR)Arguments;
  364. PrintParameter2 = rgInserts[ MaxInsert++ ] = *(aaa)++;
  365. }
  366. else {
  367. PrintParameter2 = rgInserts[ MaxInsert++ ] = va_arg( *Arguments, ULONG_PTR );
  368. }
  369. }
  370. }
  371. cchWritten = (int)SPrint( lpDst,
  372. cchRemaining,
  373. PrintFormatString,
  374. s1,
  375. PrintParameter1,
  376. PrintParameter2
  377. );
  378. if (cchWritten == -1) {
  379. return(STATUS_BUFFER_OVERFLOW);
  380. }
  381. }
  382. else {
  383. return( STATUS_INVALID_PARAMETER );
  384. }
  385. if ((cchRemaining -= cchWritten) <= 0) {
  386. return STATUS_BUFFER_OVERFLOW;
  387. }
  388. lpDst += cchWritten;
  389. }
  390. else
  391. if (*s == L'0') {
  392. if ((cchRemaining -= 1) <= 0) {
  393. return STATUS_BUFFER_OVERFLOW;
  394. }
  395. *lpDst++ = L'\0';
  396. break;
  397. }
  398. else
  399. if (!*s) {
  400. return( STATUS_INVALID_PARAMETER );
  401. }
  402. else
  403. if (*s == L'r') {
  404. if ((cchRemaining -= 1) <= 0) {
  405. return STATUS_BUFFER_OVERFLOW;
  406. }
  407. *lpDst++ = L'\r';
  408. s++;
  409. lpDstBeg = NULL;
  410. }
  411. else
  412. if (*s == L'n') {
  413. if ((cchRemaining -= 2) <= 0) {
  414. return STATUS_BUFFER_OVERFLOW;
  415. }
  416. *lpDst++ = L'\r';
  417. *lpDst++ = L'\n';
  418. s++;
  419. lpDstBeg = NULL;
  420. }
  421. else
  422. if (*s == L't') {
  423. if ((cchRemaining -= 1) <= 0) {
  424. return STATUS_BUFFER_OVERFLOW;
  425. }
  426. if (Column % 8) {
  427. Column = (Column + 7) & ~7;
  428. }
  429. else {
  430. Column += 8;
  431. }
  432. lpDstLastSpace = lpDst;
  433. *lpDst++ = L'\t';
  434. s++;
  435. }
  436. else
  437. if (*s == L'b') {
  438. if ((cchRemaining -= 1) <= 0) {
  439. return STATUS_BUFFER_OVERFLOW;
  440. }
  441. lpDstLastSpace = lpDst;
  442. *lpDst++ = L' ';
  443. s++;
  444. }
  445. else
  446. if (IgnoreInserts) {
  447. if ((cchRemaining -= 2) <= 0) {
  448. return STATUS_BUFFER_OVERFLOW;
  449. }
  450. *lpDst++ = L'%';
  451. *lpDst++ = *s++;
  452. }
  453. else {
  454. if ((cchRemaining -= 1) <= 0) {
  455. return STATUS_BUFFER_OVERFLOW;
  456. }
  457. *lpDst++ = *s++;
  458. }
  459. if (lpDstBeg == NULL) {
  460. lpDstLastSpace = NULL;
  461. Column = 0;
  462. }
  463. else {
  464. Column += (ULONG)(lpDst - lpDstBeg);
  465. }
  466. }
  467. else {
  468. c = *s++;
  469. if (c == L'\r' || c == L'\n') {
  470. if ((c == L'\n' && *s == L'\r') ||
  471. (c == L'\r' && *s == L'\n')
  472. ) {
  473. s++;
  474. }
  475. if (MaximumWidth != 0) {
  476. lpDstLastSpace = lpDst;
  477. c = L' ';
  478. }
  479. else {
  480. c = L'\n';
  481. }
  482. }
  483. if (c == L'\n') {
  484. if ((cchRemaining -= 2) <= 0) {
  485. return STATUS_BUFFER_OVERFLOW;
  486. }
  487. *lpDst++ = L'\r';
  488. *lpDst++ = L'\n';
  489. lpDstLastSpace = NULL;
  490. Column = 0;
  491. }
  492. else {
  493. if ((cchRemaining -= 1) <= 0) {
  494. return STATUS_BUFFER_OVERFLOW;
  495. }
  496. if (c == L' ') {
  497. lpDstLastSpace = lpDst;
  498. }
  499. *lpDst++ = c;
  500. Column += 1;
  501. }
  502. }
  503. if (MaximumWidth != 0 &&
  504. MaximumWidth != 0xFFFFFFFF &&
  505. Column >= MaximumWidth
  506. ) {
  507. if (lpDstLastSpace != NULL) {
  508. lpDstBeg = lpDstLastSpace;
  509. while (*lpDstBeg == L' ' || *lpDstBeg == L'\t') {
  510. lpDstBeg += 1;
  511. if (lpDstBeg == lpDst) {
  512. break;
  513. }
  514. }
  515. while (lpDstLastSpace > Buffer) {
  516. if (lpDstLastSpace[ -1 ] == L' ' || lpDstLastSpace[ -1 ] == L'\t') {
  517. lpDstLastSpace -= 1;
  518. }
  519. else {
  520. break;
  521. }
  522. }
  523. cSpaces = (ULONG)(lpDstBeg - lpDstLastSpace);
  524. if (cSpaces == 1) {
  525. if ((cchRemaining -= 1) <= 0) {
  526. return STATUS_BUFFER_OVERFLOW;
  527. }
  528. }
  529. else
  530. if (cSpaces > 2) {
  531. cchRemaining += (cSpaces - 2);
  532. }
  533. memmove( lpDstLastSpace + 2,
  534. lpDstBeg,
  535. (ULONG) ((lpDst - lpDstBeg) * sizeof( WCHAR ))
  536. );
  537. *lpDstLastSpace++ = L'\r';
  538. *lpDstLastSpace++ = L'\n';
  539. Column = (ULONG)(lpDst - lpDstBeg);
  540. lpDst = lpDstLastSpace + Column;
  541. lpDstLastSpace = NULL;
  542. }
  543. else {
  544. if ((cchRemaining -= 2) <= 0) {
  545. return STATUS_BUFFER_OVERFLOW;
  546. }
  547. *lpDst++ = L'\r';
  548. *lpDst++ = L'\n';
  549. lpDstLastSpace = NULL;
  550. Column = 0;
  551. }
  552. }
  553. }
  554. if ((cchRemaining -= 2) <= 0) {
  555. return STATUS_BUFFER_OVERFLOW;
  556. }
  557. *lpDst++ = '\r';
  558. *lpDst++ = '\n';
  559. if ((cchRemaining -= 1) <= 0) {
  560. return STATUS_BUFFER_OVERFLOW;
  561. }
  562. *lpDst++ = '\0';
  563. if ( ARGUMENT_PRESENT(ReturnLength) ) {
  564. *ReturnLength = (ULONG)(lpDst - Buffer) * sizeof( WCHAR );
  565. }
  566. return( STATUS_SUCCESS );
  567. }