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.

727 lines
29 KiB

  1. //////////////////////////////////////////////////////////////////////////
  2. //
  3. // The format of the token file is:
  4. // [[TYPE ID|RES ID|Item ID|Flags|Status Flags|Item Name]]=
  5. // this is the standar format used by several token file tools in MS.
  6. //
  7. ///////////////////////////////////////////////////////////////////////////////
  8. //
  9. // Author: Alessandro Muti
  10. // Date: 12/02/94
  11. //
  12. ///////////////////////////////////////////////////////////////////////////////
  13. #include <afx.h>
  14. #include "iodll.h"
  15. #include "main.h"
  16. #include "vktbl.h"
  17. extern CMainApp theApp;
  18. #define RECURSIVE 0x10
  19. #define WARNINGS 0x20
  20. ///////////////////////////////////////////////////////////////////////////////
  21. CString CreateName(CString & strTokenName, CString strExt, int iID)
  22. {
  23. CString strOutputName = strTokenName;
  24. int iNamePos = strTokenName.ReverseFind('\\');
  25. if(iNamePos!=-1) {
  26. strOutputName = strTokenName.Right(strTokenName.GetLength()-iNamePos-1);
  27. } else if(iNamePos = strTokenName.ReverseFind(':')!=-1){
  28. strOutputName = strTokenName.Right(strTokenName.GetLength()-iNamePos-1);
  29. }
  30. CString strID = "";
  31. // subst with ID name
  32. _itoa(iID++, strID.GetBuffer(10), 10);
  33. strID.ReleaseBuffer(-1);
  34. // Check the length of the name
  35. iNamePos = strOutputName.Find('.');
  36. if(iNamePos!=-1)
  37. strOutputName.SetAt(iNamePos, '_');
  38. strOutputName = strOutputName + "_" + strID + strExt;
  39. return strOutputName;
  40. }
  41. CString CreateName(CString & strTokenName, CString strExt, CString strIdName)
  42. {
  43. CString strOutputName = strTokenName;
  44. int iNamePos = strTokenName.ReverseFind('\\');
  45. if(iNamePos!=-1) {
  46. strOutputName = strTokenName.Right(strTokenName.GetLength()-iNamePos-1);
  47. } else if(iNamePos = strTokenName.ReverseFind(':')!=-1){
  48. strOutputName = strTokenName.Right(strTokenName.GetLength()-iNamePos-1);
  49. }
  50. iNamePos = strOutputName.Find('.');
  51. if(iNamePos!=-1)
  52. strOutputName.SetAt(iNamePos, '_');
  53. iNamePos = strIdName.Find(':');
  54. if (iNamePos!=-1)
  55. strIdName.SetAt(iNamePos, '_');
  56. iNamePos = strIdName.Find('\\');
  57. if (iNamePos!=-1)
  58. strIdName.SetAt(iNamePos, '_');
  59. strOutputName = strOutputName + "_" + strIdName + strExt;
  60. return strOutputName;
  61. }
  62. ///////////////////////////////////////////////////////////////////////////////
  63. // This function will parse the source file and create the token file
  64. CMainApp::Error_Codes CMainApp::TokGen()
  65. {
  66. Error_Codes ReturnErr = ERR_NOERROR;
  67. WriteCon(CONERR, "%s\r\n", CalcTab("", 79, '-'));
  68. // Open the iodll.dll using the first file name
  69. HANDLE hModule = RSOpenModule(m_strInExe, NULL);
  70. if ((int)(INT_PTR)hModule < LAST_ERROR) {
  71. // error or warning
  72. WriteCon(CONERR, "%s", CalcTab(m_strInExe, m_strInExe.GetLength()+5, ' '));
  73. IoDllError((int)(INT_PTR)hModule);
  74. return ERR_FILE_NOTSUPP;
  75. } else {
  76. // before we do anything else we have to check how many languages we have in the file
  77. CString strLang;
  78. char szLang[8];
  79. BOOL b_multi_lang = FALSE;
  80. USHORT usInputLang = MAKELANGID(m_usIPriLangId, m_usISubLangId);
  81. if((b_multi_lang = RSLanguages(hModule, strLang.GetBuffer(1024))) && !IsFlag(INPUT_LANG))
  82. {
  83. // this is a multiple language file but we don't have an input language specified
  84. // Fail, but warn the user that he has to set the input language to continue.
  85. strLang.ReleaseBuffer();
  86. WriteCon(CONERR, "Multiple language file. Please specify an input language %s.\r\n", strLang);
  87. theApp.SetReturn(ERROR_FILE_MULTILANG);
  88. goto exit;
  89. }
  90. // Convert the language in to the hex value
  91. sprintf(szLang,"0x%3.3X", usInputLang);
  92. // Check if the input language that we got is a valid one
  93. if(IsFlag(INPUT_LANG) && strLang.Find(szLang)==-1)
  94. {
  95. WriteCon(CONERR, "The language %s in not a valid language for this file.\r\n", szLang);
  96. WriteCon(CONERR, "Valid languages are: %s.\r\n", strLang);
  97. theApp.SetReturn(ERROR_RES_NOT_FOUND);
  98. goto exit;
  99. }
  100. // Check if the user is extracting the neutral language
  101. if(!usInputLang)
  102. usInputLang = 0xFFFF;
  103. // Open the output file
  104. CStdioFile fileOut;
  105. if(!fileOut.Open(m_strTgtTok, CFile::modeCreate | CFile::modeReadWrite)) {
  106. WriteCon(CONERR, "Cannot create file: %s\r\n", CalcTab(m_strTgtTok, m_strTgtTok.GetLength()+5, ' '));
  107. return ERR_FILE_CREATE;
  108. }
  109. CString strOutputDir = "";
  110. CString strFileName = m_strInExe;
  111. int pos = m_strInExe.ReverseFind('\\');
  112. if(pos!=-1)
  113. {
  114. strFileName = m_strInExe.Right(m_strInExe.GetLength()-pos-1);
  115. }
  116. else
  117. if((pos = m_strInExe.ReverseFind(':'))!=-1)
  118. {
  119. strFileName = m_strInExe.Right(m_strInExe.GetLength()-pos-1);
  120. }
  121. pos = m_strTgtTok.ReverseFind('\\');
  122. if(pos!=-1)
  123. {
  124. strOutputDir = m_strTgtTok.Left(pos+1);
  125. }
  126. else
  127. if((pos = m_strTgtTok.ReverseFind(':'))!=-1)
  128. {
  129. strOutputDir = m_strTgtTok.Left(pos+1);
  130. }
  131. // inform the user ...
  132. WriteCon(CONOUT, "Processing\t");
  133. WriteCon(CONBOTH, "%s", CalcTab(strFileName, strFileName.GetLength()+5, ' '));
  134. if (IsFlag(WARNING))
  135. WriteCon(CONOUT, "\r\n");
  136. LPCSTR lpszType = 0L;
  137. LPCSTR lpszRes = 0L;
  138. DWORD dwLang = 0L;
  139. DWORD dwItem = 0L;
  140. DWORD dwItemID = 0L;
  141. LPRESITEM lpResItem = NULL;
  142. CString strToken;
  143. CString strResName;
  144. CString strCaption;
  145. WORD wFlag;
  146. BOOL bSkip = FALSE;
  147. BOOL bSkipEmpty = FALSE;
  148. BOOL bSkipLang = FALSE;
  149. WORD wCount = 0;
  150. WORD wMsgCount = 0;
  151. int iPos = 1;
  152. int iBmpIdCount = 0;
  153. BOOL bVersionStampOnly = TRUE;
  154. BOOL bCustomResource = FALSE;
  155. while ((lpszType = RSEnumResType(hModule, lpszType))) {
  156. // Check if is one of the type we care about
  157. if(HIWORD(lpszType)==0)
  158. {
  159. switch(LOWORD(lpszType))
  160. {
  161. case 2:
  162. case 3:
  163. if(theApp.IsFlag(CMainApp::BITMAPS))
  164. bSkip = FALSE;
  165. else bSkip = TRUE;
  166. break;
  167. case 4:
  168. case 5:
  169. case 6:
  170. case 11:
  171. bVersionStampOnly = FALSE;
  172. case 9:
  173. case 10:
  174. case 16:
  175. bSkip = FALSE;
  176. break;
  177. case 23:
  178. case 240:
  179. case 1024:
  180. case 2110:
  181. if(theApp.IsFlag(CMainApp::GIFHTMLINF))
  182. bSkip = FALSE;
  183. else
  184. bSkip = TRUE;
  185. bVersionStampOnly = FALSE;
  186. bCustomResource = TRUE;
  187. break;
  188. default:
  189. bSkip = TRUE;
  190. }
  191. }
  192. else
  193. {
  194. if (lstrcmp (lpszType, "REGINST") == 0)
  195. {
  196. if(theApp.IsFlag(CMainApp::GIFHTMLINF))
  197. bSkip = FALSE;
  198. else
  199. bSkip = TRUE;
  200. bCustomResource = TRUE;
  201. }
  202. else
  203. {
  204. bSkip = FALSE;
  205. }
  206. bVersionStampOnly = FALSE;
  207. }
  208. lpszRes = 0L;
  209. dwLang = 0L;
  210. dwItem = 0L;
  211. while ((!bSkip) && (lpszRes = RSEnumResId(hModule, lpszType, lpszRes))) {
  212. while ((dwLang = RSEnumResLang(hModule, lpszType, lpszRes, dwLang))) {
  213. // Check if we have to skip this language
  214. if(b_multi_lang && (LOWORD(dwLang)!=usInputLang))
  215. bSkipLang = TRUE;
  216. else
  217. bSkipLang = FALSE;
  218. while ((!bSkipLang) && (dwItem = RSEnumResItemId(hModule, lpszType, lpszRes, dwLang, dwItem))) {
  219. // Now Get the Data
  220. DWORD dwImageSize = RSGetResItemData( hModule,
  221. lpszType,
  222. lpszRes,
  223. dwLang,
  224. dwItem,
  225. m_pBuf,
  226. MAX_BUF_SIZE );
  227. lpResItem = (LPRESITEM)m_pBuf;
  228. if((wCount++ % 50)==0 && !(IsFlag(WARNING)))
  229. WriteCon(CONOUT, ".");
  230. if (HIWORD(lpszType))
  231. {
  232. if (lstrcmp (lpszType,"REGINST") == 0)
  233. {
  234. //
  235. // Currently there is no id for REGINST defined
  236. // in nt. We just use this 2200 for now.
  237. //
  238. lpResItem->dwTypeID = 2200;
  239. }
  240. }
  241. // Check if we want or not empty strings
  242. // Allow empty strings for Dialog resources
  243. switch(lpResItem->dwTypeID)
  244. {
  245. case 4:
  246. case 16:
  247. bSkipEmpty = TRUE;
  248. break;
  249. default:
  250. bSkipEmpty = FALSE;
  251. break;
  252. }
  253. // Version stamp use class name as res id
  254. if(lpResItem->lpszResID)
  255. strResName = lpResItem->lpszResID;
  256. else strResName = "";
  257. dwItemID = lpResItem->dwItemID;
  258. if(lpResItem->dwTypeID==5 &&
  259. dwItemID==0 &&
  260. lpResItem->dwExtStyle){
  261. sprintf(strToken.GetBuffer(MAX_STR_SIZE),
  262. TEXT("[[%u|%u|%u|%u|%u|\"%s\"]]=0x%08x\n"),
  263. lpResItem->dwTypeID,
  264. lpResItem->dwResID,
  265. dwItemID,
  266. ISEXTSTYLE,
  267. ST_TRANSLATED,
  268. strResName.GetBuffer(0),
  269. lpResItem->dwExtStyle);
  270. fileOut.WriteString(strToken);
  271. }
  272. // Add font info for dialogs
  273. if((theApp.IsFlag(CMainApp::FONTS)
  274. && (lpResItem->dwTypeID==5) && (dwItemID==0)))
  275. {
  276. if( (lpResItem->dwStyle & DS_SETFONT)!=DS_SETFONT ){
  277. sprintf(strToken.GetBuffer(MAX_STR_SIZE),
  278. TEXT("[[%u|%u|%u|%u|%u|\"%s\"]]"),
  279. lpResItem->dwTypeID,
  280. lpResItem->dwResID,
  281. dwItemID,
  282. ISDLGFONTNAME | ISDLGFONTSIZE,
  283. ST_TRANSLATED,
  284. strResName.GetBuffer(0));
  285. WriteCon(CONWRN, "Dialog ID %s is missing the DS_SETFONT bit. Cannot extract font information!\r\n", strToken);
  286. }else{
  287. // Add font information
  288. if (lpResItem->bCharSet != DEFAULT_CHARSET){
  289. sprintf(strToken.GetBuffer(MAX_STR_SIZE),
  290. TEXT("[[%u|%u|%u|%u|%u|\"%s\"]]=%s:%hd:%d\n"),
  291. lpResItem->dwTypeID,
  292. lpResItem->dwResID,
  293. dwItemID,
  294. ISDLGFONTNAME | ISDLGFONTSIZE|ISDLGFONTCHARSET,
  295. ST_TRANSLATED,
  296. strResName.GetBuffer(0),
  297. Format(lpResItem->lpszFaceName),
  298. lpResItem->wPointSize,
  299. lpResItem->bCharSet);
  300. }else{
  301. sprintf(strToken.GetBuffer(MAX_STR_SIZE),
  302. TEXT("[[%u|%u|%u|%u|%u|\"%s\"]]=%s:%hd\n"),
  303. lpResItem->dwTypeID,
  304. lpResItem->dwResID,
  305. dwItemID,
  306. ISDLGFONTNAME | ISDLGFONTSIZE ,
  307. ST_TRANSLATED,
  308. strResName.GetBuffer(0),
  309. Format(lpResItem->lpszFaceName),
  310. lpResItem->wPointSize);
  311. }
  312. fileOut.WriteString(strToken);
  313. }
  314. }
  315. strCaption = lpResItem->lpszCaption;
  316. // Set the flag
  317. wFlag = 0;
  318. if(!(bSkipEmpty && strCaption.IsEmpty()))
  319. {
  320. CString strExt;
  321. switch(lpResItem->dwTypeID)
  322. {
  323. case 2:
  324. case 3:
  325. case 23:
  326. case 240:
  327. case 1024:
  328. case 2110:
  329. case 2200:
  330. {
  331. switch(lpResItem->dwTypeID)
  332. {
  333. case 2:
  334. strExt = ".bmp";
  335. break;
  336. case 3:
  337. strExt = ".ico";
  338. break;
  339. case 240:
  340. case 1024:
  341. strExt = ".bin";
  342. break;
  343. case 23:
  344. case 2110:
  345. strExt = "";
  346. break;
  347. case 2200:
  348. strExt = ".inf";
  349. break;
  350. }
  351. // create the output name
  352. CString strOutputName;
  353. if(lpResItem->dwResID)
  354. {
  355. strOutputName = CreateName(
  356. strFileName,
  357. strExt,
  358. lpResItem->dwResID);
  359. }
  360. else
  361. {
  362. strOutputName = CreateName(
  363. strFileName,
  364. strExt,
  365. lpResItem->lpszResID);
  366. }
  367. // Get the image from the file
  368. DWORD dwBufSize = RSGetResImage( hModule,
  369. lpszType,
  370. lpszRes,
  371. dwLang,
  372. NULL,
  373. 0 );
  374. BYTE * pBuf = (BYTE*)(new BYTE[dwBufSize]);
  375. if(pBuf==NULL)
  376. {
  377. WriteCon(CONERR,
  378. "Warning: Failed to allocate buffer for image! (%d, %d, %s, Size: %d)\r\n",
  379. lpResItem->dwTypeID,
  380. lpResItem->dwResID,
  381. lpResItem->lpszResID,
  382. dwBufSize);
  383. break;
  384. }
  385. dwBufSize = RSGetResImage( hModule,
  386. lpszType,
  387. lpszRes,
  388. dwLang,
  389. pBuf,
  390. dwBufSize );
  391. // write the data in to a file
  392. CFile OutputFile;
  393. if(!OutputFile.Open(strOutputDir+strOutputName, CFile::modeCreate | CFile::modeWrite))
  394. {
  395. WriteCon(CONERR, "Cannot create file: %s\r\n",
  396. CalcTab(strOutputDir+strOutputName, strOutputName.GetLength()+strOutputDir.GetLength()+5, ' '));
  397. delete pBuf;
  398. break;
  399. }
  400. switch(lpResItem->dwTypeID)
  401. {
  402. case 2:
  403. {
  404. BITMAPFILEHEADER bmpFileHeader;
  405. BITMAPINFO * pbmpInfo = (BITMAPINFO *)pBuf;
  406. DWORD dwNumColor = 0;
  407. if(pbmpInfo->bmiHeader.biBitCount!=24)
  408. dwNumColor = ( 1L << pbmpInfo->bmiHeader.biBitCount);
  409. bmpFileHeader.bfType = 0x4d42;
  410. bmpFileHeader.bfSize = (dwBufSize+sizeof(BITMAPFILEHEADER))/4;
  411. bmpFileHeader.bfReserved1 = 0;
  412. bmpFileHeader.bfReserved2 = 0;
  413. bmpFileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + pbmpInfo->bmiHeader.biSize + dwNumColor*sizeof(RGBQUAD);
  414. OutputFile.Write(&bmpFileHeader, sizeof(BITMAPFILEHEADER));
  415. }
  416. break;
  417. case 3:
  418. {
  419. ICONHEADER icoHeader;
  420. BITMAPINFOHEADER * pbmpInfoH = (BITMAPINFOHEADER*)pBuf;
  421. icoHeader.idReserved = 0;
  422. icoHeader.idType = 1;
  423. icoHeader.idCount = 1;
  424. icoHeader.bWidth = LOBYTE(pbmpInfoH->biWidth);
  425. icoHeader.bHeight = LOBYTE(pbmpInfoH->biWidth);
  426. icoHeader.bColorCount = 16;
  427. icoHeader.bReserved = 0;
  428. icoHeader.wPlanes = 0;
  429. icoHeader.wBitCount = 0;
  430. icoHeader.dwBytesInRes = dwBufSize;
  431. icoHeader.dwImageOffset = sizeof(ICONHEADER);
  432. OutputFile.Write(&icoHeader, sizeof(ICONHEADER));
  433. }
  434. case 23:
  435. case 240:
  436. case 1024:
  437. case 2110:
  438. case 2200:
  439. {
  440. //
  441. // No header for html stuff.
  442. //
  443. break;
  444. }
  445. break;
  446. default:
  447. break;
  448. }
  449. OutputFile.Write(pBuf, dwBufSize);
  450. OutputFile.Close();
  451. delete pBuf;
  452. strCaption = strOutputName;
  453. }
  454. break;
  455. case 4:
  456. if(lpResItem->dwFlags & MF_POPUP) {
  457. wFlag = ISPOPUP;
  458. // check if this popup has a valid ID
  459. if (LOWORD(dwItemID)==0xffff)
  460. wFlag |= OLD_POPUP_ID;
  461. dwItemID = (LOWORD(dwItemID)==0xffff ? HIWORD(dwItemID) : dwItemID);
  462. }
  463. else if (LOWORD(dwItemID)==0xffff)
  464. {
  465. dwItemID = HIWORD(dwItemID);
  466. WriteCon (CONWRN, TEXT("Token [[%u|%u|%u|%u|%u|\"%s\"]] is generated with a suspicious ID. Please check the resource file for invalid ID's.\n"),
  467. lpResItem->dwTypeID,
  468. lpResItem->dwResID,
  469. dwItemID,
  470. wFlag,
  471. ST_TRANSLATED,
  472. strResName.GetBuffer(0));
  473. }
  474. break;
  475. case 5:
  476. if(dwItemID==0) {
  477. wFlag = ISCAP;
  478. }
  479. // check if this is a duplicated id
  480. if (LOWORD(dwItemID)==0xffff)
  481. wFlag |= ISDUP;
  482. dwItemID = (LOWORD(dwItemID)==0xffff ? HIWORD(dwItemID) : dwItemID);
  483. break;
  484. case 9:
  485. {
  486. CAccel accel(lpResItem->dwFlags, lpResItem->dwStyle);
  487. strCaption = accel.GetText();
  488. // check if this is a duplicated ID
  489. if(HIWORD(dwItemID))
  490. {
  491. wFlag |= ISDUP;
  492. }
  493. }
  494. break;
  495. case 11:
  496. dwItemID = LOWORD(dwItemID);
  497. break;
  498. case 16:
  499. strResName = lpResItem->lpszClassName;
  500. break;
  501. default:
  502. break;
  503. }
  504. // Create the token file
  505. if(lpResItem->dwTypeID==11 && theApp.IsFlag(CMainApp::SPLIT))
  506. {
  507. // Search for the \r\n and replace them
  508. while((iPos = strCaption.Find("\r\n"))!=-1)
  509. {
  510. sprintf(strToken.GetBuffer(MAX_STR_SIZE),
  511. TEXT("[[%u|%u|%u|%u|%u|\"%s\"]]=%s\\r\\n\n"),
  512. lpResItem->dwTypeID,
  513. lpResItem->dwResID,
  514. dwItemID,
  515. wFlag | wMsgCount++,
  516. ST_TRANSLATED,
  517. strResName.GetBuffer(0),
  518. Format(strCaption.Left(iPos)));
  519. strCaption = strCaption.Right(strCaption.GetLength()-2-iPos);
  520. fileOut.WriteString(strToken);
  521. }
  522. wMsgCount = 0;
  523. }
  524. else
  525. {
  526. if(lpResItem->dwTypeID==16 &&
  527. theApp.IsFlag(CMainApp::NOVERSION) &&
  528. (strResName==TEXT("FileVersion") ||
  529. strResName==TEXT("ProductVersion") ||
  530. strResName==TEXT("Platform"))){
  531. //
  532. // do not generate token for these resources
  533. //
  534. }else{
  535. sprintf(strToken.GetBuffer(MAX_STR_SIZE),
  536. TEXT("[[%u|%u|%u|%u|%u|\"%s\"]]=%s\n"),
  537. lpResItem->dwTypeID,
  538. lpResItem->dwResID,
  539. dwItemID, /*(LOWORD(dwItemID)==0xffff ? HIWORD(dwItemID) : dwItemID),*/
  540. wFlag,
  541. ST_TRANSLATED,
  542. strResName.GetBuffer(0),
  543. Format(strCaption));
  544. fileOut.WriteString(strToken);
  545. }
  546. }
  547. // If this is a dialog box add the coordinates
  548. if(lpResItem->dwTypeID==5)
  549. {
  550. sprintf(strToken.GetBuffer(MAX_STR_SIZE),
  551. TEXT("[[%u|%u|%u|%u|%u|\"%s\"]]=%hu %hu %hu %hu\n"),
  552. lpResItem->dwTypeID,
  553. lpResItem->dwResID,
  554. (LOWORD(dwItemID)==0xffff ? HIWORD(dwItemID) : dwItemID),
  555. wFlag | ISCOR,
  556. ST_TRANSLATED,
  557. strResName.GetBuffer(0),
  558. lpResItem->wX,
  559. lpResItem->wY,
  560. lpResItem->wcX,
  561. lpResItem->wcY);
  562. fileOut.WriteString(strToken);
  563. //Extract STATIC control alignment style info
  564. if (LOBYTE(lpResItem->wClassName) == 0x82 &&
  565. theApp.IsFlag(CMainApp::ALIGNMENT))
  566. {
  567. CHAR szBuf[20]="SS_LEFT";
  568. if ((lpResItem->dwStyle & SS_CENTER) == SS_CENTER)
  569. lstrcpy(szBuf, "SS_CENTER");
  570. else if ((lpResItem->dwStyle & SS_RIGHT)==SS_RIGHT)
  571. lstrcpy(szBuf, "SS_RIGHT");
  572. sprintf(strToken.GetBuffer(MAX_STR_SIZE),
  573. TEXT("[[%u|%u|%u|%u|%u|\"%s\"]]=%s\n"),
  574. lpResItem->dwTypeID,
  575. lpResItem->dwResID,
  576. (LOWORD(dwItemID)==0xffff ? HIWORD(dwItemID) : dwItemID),
  577. wFlag | ISALIGN,
  578. ST_TRANSLATED,
  579. strResName.GetBuffer(0),
  580. szBuf);
  581. fileOut.WriteString(strToken);
  582. }
  583. }
  584. }
  585. else
  586. {
  587. // If this is a dialog box add the coordinates
  588. if(lpResItem->dwTypeID==5) {
  589. sprintf(strToken.GetBuffer(MAX_STR_SIZE),
  590. TEXT("[[%u|%u|%u|%u|%u|\"%s\"]]=%hu %hu %hu %hu\n"),
  591. lpResItem->dwTypeID,
  592. lpResItem->dwResID,
  593. (LOWORD(dwItemID)==0xffff ? HIWORD(dwItemID) : dwItemID),
  594. wFlag | ISCOR,
  595. ST_TRANSLATED,
  596. strResName.GetBuffer(0),
  597. lpResItem->wX,
  598. lpResItem->wY,
  599. lpResItem->wcX,
  600. lpResItem->wcY);
  601. fileOut.WriteString(strToken);
  602. }
  603. }
  604. } // end while
  605. }
  606. }
  607. }
  608. fileOut.Close();
  609. // Check the size of the new file and remove it if empty...
  610. CFileStatus fstat;
  611. if(CFile::GetStatus(m_strTgtTok, fstat))
  612. if(fstat.m_size==0)
  613. CFile::Remove(m_strTgtTok);
  614. WriteCon(CONBOTH, " %hu Items\r\n", wCount);
  615. if(bVersionStampOnly) {
  616. ReturnErr = ERR_FILE_VERSTAMPONLY;
  617. theApp.SetReturn(ERROR_FILE_VERSTAMPONLY);
  618. WriteCon(CONWRN, "%s : Version Stamping only!\r\n", strFileName);
  619. }
  620. if(bCustomResource) {
  621. SetReturn(ERROR_FILE_CUSTOMRES);
  622. WriteCon(CONWRN, "%s : Custom resource!\r\n", strFileName);
  623. }
  624. }
  625. exit:
  626. RSCloseModule(hModule);
  627. return ReturnErr;
  628. }