Source code of Windows XP (NT5)
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.

800 lines
29 KiB

  1. //////////////////////////////////////////////////////////////////////////
  2. //
  3. // This application will generate a localized binary given in input
  4. // a source binary and two token files.
  5. //
  6. // The format of the token file is:
  7. // [[TYPE ID|RES ID|Item ID|Flags|Status Flags|Item Name]]=
  8. // this is the standar format used by several token file tools in MS.
  9. //
  10. ///////////////////////////////////////////////////////////////////////////////
  11. //
  12. // Other DLL used: IODLL.DLL
  13. //
  14. ///////////////////////////////////////////////////////////////////////////////
  15. //
  16. // Author: Alessandro Muti
  17. // Date: 01-16-95
  18. //
  19. ///////////////////////////////////////////////////////////////////////////////
  20. #include <afx.h>
  21. #include "main.h"
  22. #include <iodll.h>
  23. #include <winuser.h>
  24. #include <ntverp.h>
  25. //////////////////////////////////////////////////////////////////////////
  26. #define BANNER "Microsoft (R) 32-bit RLTools Version 3.5 (Build %d)\r\n" \
  27. "Copyright (C) Microsoft Corp. 1991-1998. All Rights reserved.\r\n"\
  28. "\r\n" \
  29. "Binary file generator utility.\r\n\r\n"
  30. #ifdef _DEBUG
  31. #define BUILDSTAMP "Build: " __DATE__ " " __TIME__ " (" __TIMESTAMP__ ")\r\n\r\n"
  32. #endif
  33. // Need to split the help screen in two since it is too long.
  34. // The good thing to do would be to put this string in a message table
  35. // To be done...
  36. char strHelp0[] = \
  37. "BINGEN [-w|n] [-h|?] [-b|s|f] [-p cp] [-{i|o} Pri Sub] [-d char] \r\n"\
  38. " [-{t|u|r|a|x} files] \r\n"\
  39. " \r\n"\
  40. " -w (Show warning messages) \r\n"\
  41. " -? or -h (Show more complete help using winhelp) \r\n"\
  42. " -b (Extract bitmaps and icons) \r\n"\
  43. " -c (Extract embedded gifs, htmls, infs and other binaries) \r\n"\
  44. " -y (Extract Static Control alignment style) \r\n"\
  45. " -l (Lean mode and do not append redundant resources) \r\n"\
  46. " -s (Split Message table messages at \\n\\r) \r\n"\
  47. " -f (Add/Use font information field for dialogs) \r\n"\
  48. " -n (Nologo) \r\n"\
  49. " -v (Ignore selected version stamp information) \r\n"\
  50. " -p CodePage (Default code page of text in project token file) \r\n"\
  51. " -d Character (Default for unmappable characters) \r\n"\
  52. " \r\n"\
  53. "<<The commands -{t|r|a} are mutually exlusive>> \r\n"\
  54. " -t InputExeFile OutputTokenFile \r\n"\
  55. " (Extract token file) \r\n"\
  56. " -u InputExeFile InputUSTokFile InputLOCTokFile OutputExeFile \r\n"\
  57. " (Replace old lang resources with localized tokens) \r\n"\
  58. " -r InputExeFile InputLOCTokFile OutputExeFile \r\n"\
  59. " (Replace old lang resources with localized tokens) \r\n"\
  60. " (Doesn't perform any consistency check) \r\n"\
  61. " -a InputExeFile InputLOCTokFile OutputExeFile \r\n"\
  62. " (Append resources in localized tokens) \r\n"\
  63. " \r\n";
  64. char strHelp1[] = \
  65. "<<Default language is always NEUTRAL>> \r\n"\
  66. " -i PriLangId SecLangId (Primary- and Sub-Lang IDs, dec/hex, Input file) \r\n"\
  67. " -o PriLangId SecLangId (Primary- and Sub-Lang IDs, dec/hex, Output file) \r\n"\
  68. " \r\n"\
  69. " -x InputRuleFile (Pseudo translation options) \r\n"\
  70. " -m InputSymbolPath OutputSymbolPath \
  71. (Update symbol checksum if neccesory) \r\n";
  72. //////////////////////////////////////////////////////////////////////////
  73. CMainApp::CMainApp()
  74. {
  75. m_dwFlags = NO_OPTION;
  76. m_dwReturn = ERROR_NO_ERROR;
  77. m_StdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
  78. m_StdError = GetStdHandle(STD_ERROR_HANDLE);
  79. // Check if we have being piped to a file
  80. BY_HANDLE_FILE_INFORMATION HndlFileInfo;
  81. if(GetFileInformationByHandle(m_StdOutput, &HndlFileInfo) ||
  82. GetFileInformationByHandle(m_StdError, &HndlFileInfo))
  83. m_dwFlags |= PIPED;
  84. m_strBuffer1 = "";
  85. m_strBuffer2 = "";
  86. m_pBuf = new BYTE[MAX_BUF_SIZE];
  87. m_wIDNotFound = 0;
  88. m_wCntxChanged = 0;
  89. m_wResized = 0;
  90. //
  91. // Set default values for Language
  92. //
  93. m_usIPriLangId = -1;
  94. m_usISubLangId = -1;
  95. m_usOPriLangId = -1;
  96. m_usOSubLangId = -1;
  97. m_uiCodePage = GetACP();
  98. m_unmappedChar = '?';
  99. m_strSymPath = "";
  100. m_strOutputSymPath = "";
  101. }
  102. CMainApp::~CMainApp()
  103. {
  104. if(m_pBuf)
  105. delete m_pBuf;
  106. }
  107. //////////////////////////////////////////////////////////////////////////
  108. CMainApp::Error_Codes CMainApp::ParseCommandLine(int argc, char ** argv)
  109. {
  110. char * pArgument;
  111. int count = 0;
  112. if(argc==1)
  113. m_dwFlags |= HELP;
  114. while(++count<argc)
  115. {
  116. pArgument = argv[count];
  117. if(*pArgument=='/' || *pArgument=='-')
  118. {
  119. while(*(++pArgument))
  120. {
  121. switch(*pArgument)
  122. {
  123. case 'a': // Append resources
  124. case 'A':
  125. {
  126. //Make sure no other conflicting flags are specified
  127. if(IsFlag(REPLACE) | IsFlag(UPDATE) | IsFlag(EXTRACT))
  128. {
  129. Banner();
  130. WriteCon(CONERR, "Please use -a without the -r, -u or -t option!");
  131. return ERR_COMMAND_LINE;
  132. }
  133. // Make sure none of the next item is another option
  134. for(int c=1; c<=3; c++)
  135. if(argv[count+c]==NULL || *argv[count+c]=='/' || *argv[count+c]=='-')
  136. {
  137. Banner();
  138. WriteCon(CONERR, "Not enough parameters specified for the -a option\r\n"\
  139. " -a InputExeFile InputLOCTokFile OutputExeFile\r\n");
  140. return ERR_COMMAND_LINE;
  141. };
  142. m_dwFlags |= APPEND;
  143. // Get the input EXE file name
  144. m_strInExe = argv[++count];
  145. // Get the target token file name
  146. m_strTgtTok = argv[++count];
  147. // Get the output EXE file name
  148. m_strOutExe = argv[++count];
  149. }
  150. break;
  151. case 'b':
  152. case 'B':
  153. m_dwFlags |= BITMAPS;
  154. break;
  155. case 'd':
  156. case 'D': // Default for unmappable characters
  157. m_unmappedChar = argv[++count][0];
  158. break;
  159. case 'f':
  160. case 'F':
  161. m_dwFlags |= FONTS;
  162. break;
  163. case 'c':
  164. case 'C':
  165. m_dwFlags |= GIFHTMLINF;
  166. break;
  167. case '?': // Help
  168. case 'h':
  169. case 'H':
  170. m_dwFlags |= HELP;
  171. break;
  172. case 'i': // Input language/sublanguage
  173. case 'I':
  174. m_dwFlags |= INPUT_LANG;
  175. m_usIPriLangId = GetLangID(argv[++count]);
  176. m_usISubLangId = GetLangID(argv[++count]);
  177. break;
  178. case 'l':
  179. case 'L':
  180. {
  181. m_dwFlags |= LEANAPPEND;
  182. break;
  183. }
  184. case 'm':
  185. case 'M':
  186. {
  187. for(int c=1; c<=2; c++)
  188. {
  189. if(argv[count+c]==NULL || *argv[count+c]=='/' || *argv[count+c]=='-')
  190. {
  191. Banner();
  192. WriteCon(CONERR, "Please specify Input and Output Symbol Paths.\r\n");
  193. return ERR_COMMAND_LINE;
  194. }
  195. }
  196. m_strSymPath = argv[++count];
  197. m_strOutputSymPath = argv[++count];
  198. }
  199. break;
  200. case 'n':
  201. case 'N':
  202. m_dwFlags |= NOLOGO;
  203. break;
  204. case 'o': // Output language/sublanguage
  205. case 'O':
  206. m_dwFlags |= OUTPUT_LANG;
  207. m_usOPriLangId = GetLangID(argv[++count]);
  208. m_usOSubLangId = GetLangID(argv[++count]);
  209. break;
  210. case 'p': // Code page
  211. case 'P':
  212. m_uiCodePage = GetCodePage(argv[++count]);
  213. break;
  214. case 'r': // Replace resources
  215. case 'R':
  216. {
  217. //Make sure no other conflicting flags are specified
  218. if(IsFlag(APPEND) | IsFlag(EXTRACT) | IsFlag(UPDATE))
  219. {
  220. Banner();
  221. WriteCon(CONERR, "Please use -r without the -a, -u or -t option!");
  222. return ERR_COMMAND_LINE;
  223. }
  224. // Make sure none of the next item is another option
  225. for(int c=1; c<=3; c++)
  226. if(argv[count+c]==NULL || *argv[count+c]=='/' || *argv[count+c]=='-')
  227. {
  228. Banner();
  229. WriteCon(CONERR, "Not enough parameters specified for the -r option\r\n"\
  230. " -r InputExeFile InputLOCTokFile OutputExeFile\r\n");
  231. return ERR_COMMAND_LINE;
  232. };
  233. m_dwFlags |= REPLACE;
  234. // Get the input EXE file name
  235. m_strInExe = argv[++count];
  236. // Get the target token file name
  237. m_strTgtTok = argv[++count];
  238. // Get the output EXE file name
  239. m_strOutExe = argv[++count];
  240. }
  241. break;
  242. case 'u': // Update resources
  243. break;
  244. case 's':
  245. case 'S':
  246. m_dwFlags |= SPLIT;
  247. break;
  248. case 't': // Create token file
  249. case 'T':
  250. {
  251. //Make sure no other conflicting flags are specified
  252. if(IsFlag(APPEND) | IsFlag(REPLACE) | IsFlag(UPDATE))
  253. {
  254. Banner();
  255. WriteCon(CONERR, "Please use -t without the -a, -u, or -r option!");
  256. return ERR_COMMAND_LINE;
  257. }
  258. // Make sure none of the next item is another option
  259. for(int c=1; c<=2; c++)
  260. if(argv[count+c]==NULL || *argv[count+c]=='/' || *argv[count+c]=='-')
  261. {
  262. Banner();
  263. WriteCon(CONERR, "Not enough parameters specified for the -t option\r\n"\
  264. " -t InputExeFile OutputTokenFile\r\n");
  265. return ERR_COMMAND_LINE;
  266. };
  267. m_dwFlags |= EXTRACT;
  268. // Get the input EXE file name
  269. m_strInExe = argv[++count];
  270. // Get the target token file name
  271. m_strTgtTok = argv[++count];
  272. }
  273. break;
  274. case 'U':
  275. {
  276. //Make sure no other conflicting flags are specified
  277. if(IsFlag(APPEND) | IsFlag(EXTRACT) | IsFlag(REPLACE))
  278. {
  279. Banner();
  280. WriteCon(CONERR, "Please use -u without the -a, -r or -t option!");
  281. return ERR_COMMAND_LINE;
  282. }
  283. // Make sure none of the next item is another option
  284. for(int c=1; c<=4; c++)
  285. if(argv[count+c]==NULL || *argv[count+c]=='/' || *argv[count+c]=='-')
  286. {
  287. Banner();
  288. WriteCon(CONERR, "Not enough parameters specified for the -u option\r\n"\
  289. " -u InputExeFile InputUSTokFile InputLOCTokFile OutputExeFile\r\n");
  290. return ERR_COMMAND_LINE;
  291. };
  292. m_dwFlags |= UPDATE;
  293. // Get the input EXE file name
  294. m_strInExe = argv[++count];
  295. // Get the source token file name
  296. m_strSrcTok = argv[++count];
  297. // Get the target token file name
  298. m_strTgtTok = argv[++count];
  299. // Get the output EXE file name
  300. m_strOutExe = argv[++count];
  301. }
  302. break;
  303. case 'v': // Display warnings
  304. case 'V':
  305. m_dwFlags |= NOVERSION;
  306. break;
  307. case 'w': // Display warnings
  308. case 'W':
  309. m_dwFlags |= WARNING;
  310. break;
  311. case 'y':
  312. case 'Y':
  313. m_dwFlags |= ALIGNMENT;
  314. break;
  315. default:
  316. break;
  317. }
  318. }
  319. }
  320. }
  321. // Do we want the banner
  322. if(!IsFlag(NOLOGO))
  323. Banner();
  324. // Before exiting make sure we display the help screen if requested
  325. if(IsFlag(HELP))
  326. {
  327. Help();
  328. return ERR_HELP_CHOOSE;
  329. }
  330. // Check if the code page we have is installed in this system
  331. if(!IsValidCodePage(m_uiCodePage))
  332. {
  333. // Warn the user and get back the default CP
  334. m_uiCodePage = GetACP();
  335. WriteCon(CONERR, "The code page specified is not installed in the system or is invalid! Using system default!\r\n");
  336. }
  337. // Make sure the input file is there
  338. CFileStatus fs;
  339. if(!m_strInExe.IsEmpty())
  340. {
  341. if(!CFile::GetStatus(m_strInExe, fs))
  342. {
  343. WriteCon(CONERR, "File not found: %s\r\n", m_strInExe);
  344. return ERR_FILE_NOTFOUND;
  345. }
  346. }
  347. // Check if the tgt token file or exe are read only
  348. if(!m_strOutExe.IsEmpty())
  349. {
  350. if(CFile::GetStatus(m_strOutExe, fs))
  351. {
  352. if((fs.m_attribute & 0x1)==0x1)
  353. {
  354. WriteCon(CONERR, "File is read only: %s\r\n", m_strOutExe);
  355. return ERR_FILE_CREATE;
  356. }
  357. }
  358. }
  359. if(!m_strTgtTok.IsEmpty() && IsFlag(EXTRACT))
  360. {
  361. if(CFile::GetStatus(m_strTgtTok, fs))
  362. {
  363. if((fs.m_attribute & 0x1)==0x1)
  364. {
  365. WriteCon(CONERR, "File is read only: %s\r\n", m_strTgtTok);
  366. return ERR_FILE_CREATE;
  367. }
  368. }
  369. }
  370. //
  371. // Check the value specified for the output language.
  372. // If none has been specified, warn the user and default to neutral.
  373. //
  374. if(IsFlag(APPEND) | IsFlag(REPLACE))
  375. {
  376. if(m_usOPriLangId==-1)
  377. {
  378. m_usOPriLangId = LANG_NEUTRAL; // set the PRI language ID to neutral
  379. WriteCon(CONERR, "Output language ID not specified, default to neutral(%d)\r\n", m_usOPriLangId);
  380. }
  381. if(m_usOSubLangId==-1)
  382. {
  383. m_usOSubLangId = SUBLANG_NEUTRAL; // set the SEC language ID to neutral
  384. WriteCon(CONERR, "Output sub-language ID not specified, default to neutral(%d)\r\n", m_usOSubLangId);
  385. }
  386. }
  387. WriteCon(CONWRN, "Code Page : %d\r\n", m_uiCodePage);
  388. WriteCon(CONWRN, "In Primary Language : %d (%d)\r\n", m_usIPriLangId, MAKELANGID(m_usIPriLangId,m_usISubLangId));
  389. WriteCon(CONWRN, "In Secondary Language : %d (0x%x)\r\n", m_usISubLangId, MAKELANGID(m_usIPriLangId,m_usISubLangId));
  390. WriteCon(CONWRN, "Out Primary Language : %d (%d)\r\n", m_usOPriLangId, MAKELANGID(m_usOPriLangId,m_usOSubLangId));
  391. WriteCon(CONWRN, "Out Secondary Language : %d (0x%x)\r\n", m_usOSubLangId, MAKELANGID(m_usOPriLangId,m_usOSubLangId));
  392. WriteCon(CONWRN, "Default unmapped char : %c \r\n", m_unmappedChar);
  393. return ERR_NOERROR;
  394. }
  395. /////////////////////////////////////////////////////////////////////////////////////////////////////
  396. // Helper start
  397. void CMainApp::Banner()
  398. {
  399. WriteCon(CONOUT, BANNER, VER_PRODUCTBUILD);
  400. #ifdef _DEBUG
  401. WriteCon(CONOUT, BUILDSTAMP);
  402. #endif
  403. }
  404. void CMainApp::Help()
  405. {
  406. WriteCon(CONOUT, strHelp0);
  407. WriteCon(CONOUT, strHelp1);
  408. }
  409. CString CMainApp::CalcTab(CString str, int tablen, char ch)
  410. {
  411. for(int i = tablen-str.GetLength();i>0;i--)
  412. str += (char)ch;
  413. return str.GetBuffer(0);
  414. }
  415. int __cdecl CMainApp::WriteCon(int iFlags, const char * lpstr, ...)
  416. {
  417. DWORD dwWritten;
  418. va_list ptr;
  419. va_start(ptr, lpstr);
  420. _vsnprintf(m_strBuffer1.GetBuffer(MAX_STR_SIZE), MAX_STR_SIZE, lpstr, ptr);
  421. m_strBuffer1.ReleaseBuffer();
  422. // Check if we want to have the handle sent to both out and err
  423. if((iFlags==CONBOTH) && (IsFlag(PIPED)))
  424. {
  425. WriteFile(m_StdError, m_strBuffer1, m_strBuffer1.GetLength(), &dwWritten, NULL);
  426. WriteFile(m_StdOutput, m_strBuffer1, m_strBuffer1.GetLength(), &dwWritten, NULL);
  427. return dwWritten;
  428. }
  429. if((iFlags==CONWRN))
  430. {
  431. if(IsFlag(WARNING))
  432. WriteFile(m_StdError, m_strBuffer1, m_strBuffer1.GetLength(), &dwWritten, NULL);
  433. return dwWritten;
  434. }
  435. if(iFlags==CONERR)
  436. WriteFile(m_StdError, m_strBuffer1, m_strBuffer1.GetLength(), &dwWritten, NULL);
  437. else
  438. WriteFile(m_StdOutput, m_strBuffer1, m_strBuffer1.GetLength(), &dwWritten, NULL);
  439. return dwWritten;
  440. }
  441. int CMainApp::SetReturn(int rc)
  442. { return (m_dwReturn = rc); }
  443. ////////////////////////////////////////////////
  444. // Will convert the string strNum in to a short
  445. USHORT CMainApp::GetLangID(CString strNum)
  446. {
  447. strNum.MakeUpper();
  448. // If is there is any of this char "ABCDEFX" assume is an hex number
  449. return LOWORD(strtol(strNum, NULL, ((strNum.FindOneOf("ABCDEFX")!=-1) ? 16:10)));
  450. }
  451. UINT CMainApp::GetCodePage(CString strNum)
  452. {
  453. strNum.MakeUpper();
  454. // If is there is any of this char "ABCDEFX" assume is an hex number
  455. return strtol(strNum, NULL, ((strNum.FindOneOf("ABCDEFX")!=-1) ? 16:10));
  456. }
  457. #ifdef NOSLASH
  458. LPCSTR CMainApp::Format(CString strTmp)
  459. {
  460. int iPos;
  461. char * pStr = strTmp.GetBuffer(0);
  462. char * pStrStart = pStr;
  463. int i = 0;
  464. m_strBuffer2 = strTmp;
  465. while((pStr = strchr(pStr, '\\')))
  466. {
  467. iPos = pStr++ - pStrStart + i++;
  468. m_strBuffer2 = m_strBuffer2.Left(iPos) + "\\\\" + m_strBuffer2.Right(m_strBuffer2.GetLength()-iPos-1);
  469. }
  470. while((iPos = m_strBuffer2.Find('\t'))!=-1)
  471. m_strBuffer2 = m_strBuffer2.Left(iPos) + "\\t" + m_strBuffer2.Right(m_strBuffer2.GetLength()-iPos-1);
  472. while((iPos = m_strBuffer2.Find('\n'))!=-1)
  473. m_strBuffer2 = m_strBuffer2.Left(iPos) + "\\n" + m_strBuffer2.Right(m_strBuffer2.GetLength()-iPos-1);
  474. while((iPos = m_strBuffer2.Find('\r'))!=-1)
  475. m_strBuffer2 = m_strBuffer2.Left(iPos) + "\\r" + m_strBuffer2.Right(m_strBuffer2.GetLength()-iPos-1);
  476. return m_strBuffer2;
  477. }
  478. LPCSTR CMainApp::UnFormat(CString strTmp)
  479. {
  480. int iPos;
  481. char * pStr = strTmp.GetBuffer(0);
  482. char * pStrStart = pStr;
  483. int i = 0;
  484. m_strBuffer2 = strTmp;
  485. while((pStr = strstr(pStr, "\\\\")))
  486. {
  487. iPos = pStr - pStrStart - i++; pStr += 2;
  488. m_strBuffer2 = m_strBuffer2.Left(iPos) + "\\" + m_strBuffer2.Right(m_strBuffer2.GetLength()-iPos-2);
  489. }
  490. while((iPos = m_strBuffer2.Find("\\t"))!=-1)
  491. m_strBuffer2 = m_strBuffer2.Left(iPos) + "\t" + m_strBuffer2.Right(m_strBuffer2.GetLength()-iPos-2);
  492. while((iPos = m_strBuffer2.Find("\\n"))!=-1)
  493. m_strBuffer2 = m_strBuffer2.Left(iPos) + "\n" + m_strBuffer2.Right(m_strBuffer2.GetLength()-iPos-2);
  494. while((iPos = m_strBuffer2.Find("\\r"))!=-1)
  495. m_strBuffer2 = m_strBuffer2.Left(iPos) + "\r" + m_strBuffer2.Right(m_strBuffer2.GetLength()-iPos-2);
  496. return m_strBuffer2;
  497. }
  498. #endif
  499. LPCSTR CMainApp::Format(CString strTmp)
  500. {
  501. char * pStr = strTmp.GetBuffer(0);
  502. char * pDest = m_strBuffer2.GetBuffer(MAX_STR_SIZE);
  503. char * pNext;
  504. while(*pStr)
  505. {
  506. if(!IsDBCSLeadByteEx(m_uiCodePage, *pStr))
  507. {
  508. switch(*pStr)
  509. {
  510. case '\\':
  511. *pDest++ = '\\';
  512. *pDest++ = '\\';
  513. break;
  514. case '\t':
  515. *pDest++ = '\\';
  516. *pDest++ = 't';
  517. break;
  518. case '\r':
  519. *pDest++ = '\\';
  520. *pDest++ = 'r';
  521. break;
  522. case '\n':
  523. *pDest++ = '\\';
  524. *pDest++ = 'n';
  525. break;
  526. default:
  527. *pDest++ = *pStr;
  528. break;
  529. }
  530. }
  531. else {
  532. memcpy( pDest, pStr, 2 );
  533. pDest += 2;
  534. }
  535. pStr = CharNextExA((WORD)m_uiCodePage, pStr, 0);
  536. }
  537. *pDest = '\0';
  538. m_strBuffer2.ReleaseBuffer(-1);
  539. return m_strBuffer2;
  540. }
  541. LPCSTR CMainApp::UnFormat(CString strTmp)
  542. {
  543. m_strBuffer2 = strTmp;
  544. int i = m_strBuffer2.GetLength();
  545. char * pStr = m_strBuffer2.GetBuffer(0);
  546. char * pNext;
  547. while(*pStr)
  548. {
  549. if(*pStr=='\\' && !IsDBCSLeadByteEx(m_uiCodePage, *pStr))
  550. {
  551. pNext = CharNextExA((WORD)m_uiCodePage, pStr, 0);
  552. switch(*pNext)
  553. {
  554. case '\\':
  555. *pStr = '\\';
  556. break;
  557. case 't':
  558. *pStr = '\t';
  559. break;
  560. case 'n':
  561. *pStr = '\n';
  562. break;
  563. case 'r':
  564. *pStr = '\r';
  565. break;
  566. default:
  567. break;
  568. }
  569. pStr = pNext;
  570. pNext = CharNextExA((WORD)m_uiCodePage, pNext, 0);
  571. memmove(pStr, pNext, --i);
  572. }
  573. else
  574. {
  575. //DBCS shorten length by 2
  576. if (IsDBCSLeadByteEx(m_uiCodePage, *pStr))
  577. i-=2;
  578. else
  579. i--;
  580. pStr = CharNextExA((WORD)m_uiCodePage, pStr, 0);
  581. }
  582. }
  583. m_strBuffer2.ReleaseBuffer(-1);
  584. return m_strBuffer2;
  585. }
  586. int CMainApp::IoDllError(int iError)
  587. {
  588. CString str = "";
  589. switch (iError) {
  590. case 0: break;
  591. case ERROR_HANDLE_INVALID: str = "Invalid handle."; break;
  592. case ERROR_READING_INI: str = "Error reading WIN.INI file."; break;
  593. case ERROR_NEW_FAILED: str = "Running low on memory."; break;
  594. case ERROR_FILE_OPEN: str = "Error opening file."; break;
  595. case ERROR_FILE_CREATE: str = "Error creating file."; break;
  596. case ERROR_FILE_INVALID_OFFSET: str = "File corruption detected."; break;
  597. case ERROR_FILE_READ: str = "Error reading file."; break;
  598. case ERROR_DLL_LOAD: str = "Error loading R/W DLL."; break;
  599. case ERROR_DLL_PROC_ADDRESS: str = "Error loading R/W procedure."; break;
  600. case ERROR_RW_LOADIMAGE: str = "Error loading R/W image."; break;
  601. case ERROR_RW_PARSEIMAGE: str = "Error parsing R/W image."; break;
  602. case ERROR_RW_NOTREADY: str = "Error: R/W not ready?"; break;
  603. case ERROR_RW_BUFFER_TOO_SMALL: str = "Running low on memory?"; break;
  604. case ERROR_RW_INVALID_FILE: str = "Invalid R/W file."; break;
  605. case ERROR_RW_IMAGE_TOO_BIG: str = "Can't load HUGE image."; break;
  606. case ERROR_RW_TOO_MANY_LEVELS: str = "Resource directory too deep."; break;
  607. case ERROR_RW_NO_RESOURCES: str = "This file contains no resources.";
  608. break;
  609. case ERROR_IO_INVALIDITEM: str = "Invalid resource item."; break;
  610. case ERROR_IO_INVALIDID: str = "Invalid resource ID."; break;
  611. case ERROR_IO_INVALID_DLL: str = "Unrecognized file format."; break;
  612. case ERROR_IO_TYPE_NOT_SUPPORTED: str = "Type not supported."; break;
  613. case ERROR_IO_INVALIDMODULE: str = "Invalid module."; break;
  614. case ERROR_IO_RESINFO_NULL: str = "ResInfo is NULL?"; break;
  615. case ERROR_IO_UPDATEIMAGE: str = "Error updating image."; break;
  616. case ERROR_IO_FILE_NOT_SUPPORTED: str = "File not supported."; break;
  617. case ERROR_IO_CHECKSUM_MISMATCH: str = "Symbol file checksum mismatch.";
  618. break;
  619. case ERROR_IO_SYMBOLFILE_NOT_FOUND: str = "Symbol file not found.";
  620. break;
  621. case ERROR_FILE_SYMPATH_NOT_FOUND: str = "Output symbol path not found.";
  622. break;
  623. case ERROR_RW_VXD_MSGPAGE:
  624. str = "The specified VxD file contains a message page as its";
  625. str += " last page. This may cause the VxD not to work. Please";
  626. str += " inform the development team of the problem with this file.";
  627. break;
  628. case ERROR_OUT_OF_DISKSPACE: str = "Out of disk space."; break;
  629. case ERROR_RES_NOT_FOUND: str = "Resource not found."; break;
  630. default:
  631. if(iError-LAST_ERROR>0)
  632. {
  633. FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
  634. NULL,
  635. iError-LAST_ERROR,
  636. MAKELANGID(LANG_NEUTRAL,LANG_NEUTRAL),
  637. str.GetBuffer(1024),
  638. 1024,
  639. NULL);
  640. str.ReleaseBuffer();
  641. }
  642. break;
  643. }
  644. if (!str.IsEmpty())
  645. {
  646. WriteCon(CONERR, "%s: %s\r\n", (iError < LAST_WRN) ? "IODLL Warning" : "IODLL Error", str);
  647. SetReturn(iError);
  648. }
  649. return iError;
  650. }
  651. // Helper end
  652. /////////////////////////////////////////////////////////////////////////////////////////////////////
  653. CMainApp::Error_Codes CMainApp::GenerateFile()
  654. {
  655. Error_Codes bRet;
  656. // Before we procede let's give the global info to the IODLL
  657. SETTINGS settings;
  658. settings.cp = m_uiCodePage;
  659. settings.bAppend = IsFlag(APPEND);
  660. settings.bUpdOtherResLang = TRUE; //we save this option for future
  661. settings.szDefChar[0] = m_unmappedChar; settings.szDefChar[1] = '\0';
  662. RSSetGlobals(settings);
  663. // Here we decide what is the action we have to take
  664. if(IsFlag(EXTRACT))
  665. {
  666. // we want to generate a token file
  667. bRet = TokGen();
  668. }
  669. else if(IsFlag(APPEND) | IsFlag(REPLACE) | IsFlag(UPDATE) )
  670. {
  671. // we want to generate a binary
  672. bRet = BinGen();
  673. }
  674. return bRet;
  675. }
  676. // Main application
  677. CMainApp theApp;
  678. //////////////////////////////////////////////////////////////////////////
  679. int _cdecl main(int argc, char** argv)
  680. {
  681. if(theApp.ParseCommandLine(argc, argv)){
  682. return theApp.ReturnCode();
  683. }
  684. theApp.GenerateFile();
  685. return theApp.ReturnCode();
  686. }
  687. //////////////////////////////////////////////////////////////////////////