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.

533 lines
13 KiB

  1. #include <ctype.h>
  2. #include <malloc.h>
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include <tchar.h>
  7. #ifdef RLDOS
  8. #include "dosdefs.h"
  9. #else
  10. #include <windows.h>
  11. #include "windefs.h"
  12. #endif
  13. #include "restok.h"
  14. #include "commbase.h"
  15. #include "resread.h"
  16. extern UCHAR szDHW[];
  17. //
  18. // The syssetup.dll, that has been contained Windows NT 4.00, has the largest
  19. // message strings than ever. So, we have to expand buffer size(to 20480).
  20. //
  21. #define MAX_OUT_BUFFER 20480
  22. CHAR gt_szTextBuffer[ MAX_OUT_BUFFER];
  23. TCHAR pt_szOutBuffer[MAX_OUT_BUFFER];
  24. /**
  25. *
  26. *
  27. * Function:
  28. *
  29. *
  30. * Arguments:
  31. *
  32. * Returns:
  33. *
  34. * Errors Codes:
  35. *
  36. * History:
  37. *
  38. *
  39. **/
  40. /*---------------------------------------------------------
  41. * Function: GetToken
  42. * Input: fpInFile File pointer, points to the token to be read.
  43. * tToken Pointer to a token.
  44. *
  45. *
  46. * Output: fpInFile File pointer after read operation.
  47. * points to the next token in the file.
  48. * tToken The token read in from the file. Memory will have been
  49. * allocated for the token text, unless no token was read in.
  50. *
  51. * Return code:
  52. * 0 = Read token, every thing OK
  53. * 1 = Empty line or line started with # (Comment)
  54. * -1 = End of FILE
  55. * -2 = Error reading from file.
  56. *
  57. * History:
  58. * 01/93 Re-written to read in long token text strings. MHotchin
  59. *
  60. *----------------------------------------------------------*/
  61. int GetToken(
  62. FILE *fpInFile, //... File to get token from.
  63. TOKEN *pToken) //... Buffer for token.
  64. {
  65. int chNextChar = 0;
  66. int cTextLen = 0;
  67. int rc = 0;
  68. // Read token from file.
  69. // we will want to use MyGetStr, when
  70. // tokens are in UNICODE
  71. // Strip off leading whitespace, and check
  72. // for blank lines.
  73. chNextChar = fgetc( fpInFile);
  74. while ( (chNextChar == ' ') || (chNextChar == '\t') ) {
  75. chNextChar = fgetc( fpInFile);
  76. }
  77. if ( chNextChar == EOF ) {
  78. return ( -1);
  79. } else if ( chNextChar == '\n' ) {
  80. return ( 1);
  81. }
  82. // Now we have the first non-white space
  83. // character.
  84. // Check for a comment line, and strip out the
  85. // remainder of the line if it is.
  86. else if ( chNextChar == '#' ) {
  87. fscanf( fpInFile, "%*[^\n]");
  88. chNextChar = fgetc( fpInFile);
  89. if ( chNextChar == EOF ) {
  90. return ( -1);
  91. } else {
  92. return ( 1);
  93. }
  94. }
  95. // Now we are positioned at the first
  96. // non-whitespace character. Check it, and
  97. // read in the numbers...
  98. else if ( chNextChar != '[' ) {
  99. // Bad format?
  100. return ( -2);
  101. }
  102. if ( fscanf( fpInFile,
  103. "[%hu|%hu|%hu|%hu|%hu",
  104. &pToken->wType,
  105. &pToken->wName,
  106. &pToken->wID,
  107. &pToken->wFlag,
  108. &pToken->wReserved) != 5 ) {
  109. QuitA( IDS_ENGERR_12, (LPSTR)IDS_BADTOKID, NULL);
  110. }
  111. // Now that we have all the numbers, we can
  112. // look for the name of the token.
  113. if ( (pToken->wName == IDFLAG) || (pToken->wType == ID_RT_ERRTABLE) ) {
  114. static char szName[ TOKENSTRINGBUFFER];
  115. int nRC = 0;
  116. nRC = fscanf( fpInFile, "|\"%[^\"]", szName);
  117. if ( nRC == EOF ) {
  118. QuitT( IDS_ENGERR_05, (LPTSTR)IDS_INVTOKNAME, NULL);
  119. }
  120. #ifndef UNITOK
  121. #ifdef RLRES32
  122. if (nRC)
  123. _MBSTOWCS( (TCHAR *)pToken->szName,
  124. szName,
  125. TOKENSTRINGBUFFER,
  126. lstrlenA( szName) + 1);
  127. else
  128. _MBSTOWCS( (TCHAR *)pToken->szName,
  129. "",
  130. TOKENSTRINGBUFFER,
  131. lstrlenA( szName) + 1);
  132. #else
  133. if (nRC)
  134. strcpy( pToken->szName, szName);
  135. else
  136. *pToken->szName = '\0';
  137. #endif
  138. #else
  139. if (nRC)
  140. strcpy( pToken->szName, szName);
  141. else
  142. *pToken->szName = '\0';
  143. #endif
  144. } else {
  145. if ( fscanf( fpInFile, "|\"%*[^\"]") != 0 ) {
  146. QuitT( IDS_ENGERR_05, (LPTSTR)IDS_NOSKIPNAME, NULL);
  147. }
  148. pToken->szName[0] = '\0';
  149. }
  150. // Now the name has been read, and we are
  151. // positioned at the last '"' in the text
  152. // stream. Allocate memory for the token
  153. // text, and read it in.
  154. fgets( gt_szTextBuffer, sizeof(gt_szTextBuffer), fpInFile);
  155. // Now that the token text is read in,
  156. // convert it to whatever character type
  157. // we are expecting. First strip the newline!
  158. StripNewLineA( gt_szTextBuffer);
  159. cTextLen = lstrlenA( gt_szTextBuffer);
  160. if ( cTextLen < 4 ) { // Must be more than "\"]]=" in szTextBuffer
  161. return ( -2);
  162. }
  163. pToken->szText = (TCHAR *)FALLOC( MEMSIZE( cTextLen - 3));
  164. #ifndef UNITOK
  165. #ifdef RLRES32
  166. _MBSTOWCS( pToken->szText, gt_szTextBuffer+4, cTextLen - 3, cTextLen - 3);
  167. #else
  168. strcpy( pToken->szText, gt_szTextBuffer+4);
  169. #endif // RLRES32
  170. #else // UNITOK
  171. strcpy( pToken->szText, gt_szTextBuffer+4);
  172. #endif // UNITOK
  173. return ( 0);
  174. }
  175. /**
  176. *
  177. *
  178. * Function:
  179. *
  180. *
  181. * Arguments:
  182. *
  183. * Returns:
  184. *
  185. * Errors Codes:
  186. *
  187. * History:
  188. * 01/93 Added new character count field. MHotchin
  189. *
  190. **/
  191. int PutToken(
  192. FILE *fpOutFile, //... Token file to write to
  193. TOKEN *tToken) //... Token to be writen to the token file
  194. {
  195. WORD rc = 0;
  196. PCHAR pszBuf = NULL;
  197. ParseTokToBuf( pt_szOutBuffer, tToken);
  198. // RLFREE( tToken->szText);
  199. #ifdef RLRES32
  200. if ( ! _WCSTOMBS( szDHW, pt_szOutBuffer, DHWSIZE, lstrlen( pt_szOutBuffer) + 1) ) {
  201. QuitT( IDS_ENGERR_26, pt_szOutBuffer, NULL);
  202. }
  203. pszBuf = szDHW;
  204. #else
  205. pszBuf = pt_szOutBuffer;
  206. #endif
  207. return fprintf( fpOutFile, "%s\n", pszBuf);
  208. }
  209. /**
  210. * Function: FindToken
  211. * Finds a token whose status bits match only where the mask is set.
  212. *
  213. * Arguments:
  214. * fpSearchFile -- search file
  215. * psTok -- pointer to the token
  216. * uMask -- status bit mask
  217. *
  218. * Returns:
  219. * string and status of found token
  220. *
  221. * Errors Codes:
  222. * 0 - token not found
  223. * 1 - token found
  224. *
  225. * History:
  226. * 01/93 Added support for var length token text strings. Previous token text
  227. * is de-allocated! MHotchin
  228. *
  229. **/
  230. int FindToken( FILE *fpSearchFile, TOKEN *psTok, WORD wMask)
  231. {
  232. BOOL fFound = FALSE;
  233. BOOL fStartOver = TRUE;
  234. int error;
  235. int nTokensRead = 0;
  236. long lStartFilePos, lFilePos;
  237. TOKEN cTok;
  238. //... Remember where we are starting
  239. lFilePos = lStartFilePos = ftell(fpSearchFile);
  240. do {
  241. long lType11Pos = 0;
  242. do {
  243. lType11Pos = ftell( fpSearchFile);
  244. error = GetToken( fpSearchFile, &cTok);
  245. if ( error == 0 ) {
  246. //... Is this the token we are looking for?
  247. fFound = ((cTok.wType == psTok->wType)
  248. && (cTok.wName == psTok->wName)
  249. && (cTok.wID == psTok->wID)
  250. && (cTok.wFlag == psTok->wFlag)
  251. && ((WORD)(cTok.wReserved & wMask) == psTok->wReserved)
  252. && (_tcscmp( (TCHAR *)cTok.szName,
  253. (TCHAR *)psTok->szName) == 0));
  254. }
  255. if ( ! fFound ) {
  256. //... If we were looking for another segment to
  257. //... an NT Msg Table entry, move back to the
  258. //... token we just read and quit (speedup).
  259. if ( psTok->wType == ID_RT_ERRTABLE
  260. && psTok->wFlag > 0
  261. && error == 0 ) {
  262. if ( cTok.wType != psTok->wType
  263. || cTok.wName != psTok->wName
  264. || cTok.wID != psTok->wID
  265. || cTok.wFlag > psTok->wFlag ) {
  266. fseek( fpSearchFile, lType11Pos, SEEK_SET);
  267. RLFREE( cTok.szText);
  268. return ( FALSE);
  269. }
  270. } else if ( error >= 0 ) {
  271. lFilePos = ftell(fpSearchFile);
  272. if (error == 0) {
  273. RLFREE(cTok.szText);
  274. }
  275. } else if (error == -2) {
  276. return ( FALSE);
  277. }
  278. }
  279. } while ( ! fFound
  280. && (error >= 0)
  281. && (fStartOver || (lFilePos < lStartFilePos)) );
  282. if ( ! fFound && (error == -1) && fStartOver ) {
  283. rewind(fpSearchFile);
  284. lFilePos = 0L;
  285. fStartOver = FALSE;
  286. }
  287. } while ( ! fFound && (lFilePos < lStartFilePos) );
  288. //... Did we find the desired token?
  289. if ( fFound ) { //... Yes, we found it
  290. psTok->wReserved = cTok.wReserved;
  291. RLFREE( psTok->szText);
  292. psTok->szText = cTok.szText;
  293. }
  294. return ( fFound);
  295. }
  296. /**
  297. *
  298. *
  299. * Function:
  300. *
  301. *
  302. * Arguments:
  303. *
  304. * Returns:
  305. *
  306. * Errors Codes:
  307. *
  308. * History:
  309. * 01/93 Added support for new token text count. MHotchin
  310. *
  311. **/
  312. void ParseBufToTok( TCHAR *szToken, TOKEN *pTok )
  313. {
  314. TCHAR *pos;
  315. WORD bChars;
  316. if ( _stscanf( szToken,
  317. TEXT("[[%hu|%hu|%hu|%hu|%hu"),
  318. &pTok->wType,
  319. &pTok->wName,
  320. &pTok->wID,
  321. &pTok->wFlag,
  322. &pTok->wReserved) != 5 ) {
  323. QuitT( IDS_BADTOK, szToken, NULL);
  324. }
  325. if ( pTok->wName == IDFLAG || pTok->wType == ID_RT_ERRTABLE ) {
  326. //... Find Names's first char and get it's len
  327. if ( pos = _tcschr( (TCHAR *)szToken, TEXT('"')) ) {
  328. TCHAR *pStart;
  329. pStart = ++pos;
  330. bChars = 0;
  331. while ( *pos && *pos != TEXT('"')
  332. && bChars < TOKENSTRINGBUFFER - 1 ) {
  333. bChars++;
  334. pos++;
  335. } // while
  336. CopyMemory( pTok->szName, pStart, min( TOKENSTRINGBUFFER, bChars) * sizeof( TCHAR));
  337. pTok->szName[ bChars ] = TEXT('\0');
  338. } else {
  339. //... No token ID found
  340. QuitT( IDS_ENGERR_05, (LPTSTR)IDS_INVTOKNAME, NULL);
  341. }
  342. } else {
  343. // Don't forget the zero termination
  344. pTok->szName[0] = TEXT('\0');
  345. }
  346. // now do the token text
  347. pos = _tcschr ((TCHAR *)szToken, TEXT(']'));
  348. if ( pos ) {
  349. // This can be written better now that we know the text length.
  350. bChars = (WORD)lstrlen( pos);
  351. if ( bChars > 3 ) {
  352. pos += 3;
  353. bChars -= 3;
  354. pTok->szText = (TCHAR *)FALLOC( MEMSIZE( bChars + 1));
  355. CopyMemory( pTok->szText, pos, MEMSIZE( bChars + 1));
  356. // Don't forget the zero termination
  357. pTok->szText[ bChars] = TEXT('\0');
  358. } else if ( bChars == 3 ) {
  359. //... Empty token text
  360. pTok->szText = (TCHAR *) FALLOC( 0);
  361. } else {
  362. //... No token ID found
  363. QuitT( IDS_ENGERR_05, (LPTSTR)IDS_INVTOKID, NULL);
  364. }
  365. } else {
  366. //... No token ID found
  367. QuitT( IDS_ENGERR_05, (LPTSTR)IDS_NOTOKID, NULL);
  368. }
  369. }
  370. /**
  371. *
  372. *
  373. * Function:
  374. *
  375. *
  376. * Arguments:
  377. *
  378. * Returns:
  379. *
  380. * Errors Codes:
  381. *
  382. * History:
  383. *
  384. **/
  385. void ParseTokToBuf( TCHAR *szToken, TOKEN *pTok )
  386. {
  387. *szToken = TEXT('\0');
  388. if ( pTok != NULL) {
  389. wsprintf( szToken,
  390. TEXT("[[%hu|%hu|%hu|%hu|%hu|\"%s\"]]="),
  391. pTok->wType,
  392. pTok->wName,
  393. pTok->wID,
  394. pTok->wFlag,
  395. pTok->wReserved,
  396. pTok->szName);
  397. if (pTok->szText)
  398. lstrcat(szToken, pTok->szText);
  399. }
  400. }
  401. /**
  402. *
  403. *
  404. * Function: TokenToTextSize
  405. * This calculates the number of characters needed to hold
  406. * the text representation of a token.
  407. *
  408. * Arguments:
  409. * pTok The token to measure.
  410. *
  411. * Returns:
  412. * int The number of characters needed to hold the token, not
  413. * including a null terminator. [[%hu|%hu|%hu|%hu|%hu|\"%s\"]]=%s
  414. *
  415. * Errors Codes:
  416. * None.
  417. *
  418. * History:
  419. * 01/18/93 MHotchin Created.
  420. *
  421. **/
  422. int TokenToTextSize( TOKEN *pTok)
  423. {
  424. int cTextLen;
  425. cTextLen = (14 + // Separators and terminator ( + 1 extra)
  426. 30); // Space for 5 numeric fields (65,535 = 6 chars)
  427. if ( pTok->szText != NULL ) {
  428. // Add space for the Token text
  429. cTextLen += MEMSIZE( lstrlen( pTok->szText) );
  430. }
  431. cTextLen += lstrlen( pTok->szName);
  432. return ( cTextLen);
  433. }