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.

945 lines
29 KiB

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <windows.h>
  4. #include "windefs.h"
  5. #include "restok.h"
  6. #include "exentres.h"
  7. #include "resread.h"
  8. #include "checksum.h"
  9. #define SAME 0 //... Used in string compares
  10. #define MAXLEVELS 3 //... Max # of levels in resource directory
  11. typedef struct tagResSectData {
  12. ULONG ulVirtualAddress; //... Virtual address of section .rsrc
  13. ULONG ulSizeOfResources; //... Size of resources in section .rsrc
  14. ULONG ulVirtualSize; //... Virtual Size of resources in .rsrc
  15. ULONG ulVirtualAddressX; //... Virtual address of section .rsrc1
  16. ULONG ulSizeOfResourcesX; //... Size of resources in section .rsrc1
  17. ULONG ulVirtualSizeX; //... Virtual Size of resources in .rsrc1
  18. } RESSECTDATA, *PRESSECTDATA;
  19. WORD gwFilter = 0;
  20. int InsertResourcesInExe( FILE *, HANDLE);
  21. LONG GetFileResources( FILE *, FILE *, ULONG);
  22. ULONG MoveFilePos( FILE *, ULONG);
  23. ULONG MyWrite( FILE *, PUCHAR, ULONG);
  24. ULONG MyRead( FILE *, PUCHAR, ULONG);
  25. WCHAR *GetDirNameU( WCHAR *, PIMAGE_RESOURCE_DIR_STRING_U);
  26. ULONG ReadResources( FILE *, ULONG, ULONG, PUCHAR);
  27. DWORD AddToLangIDList( DWORD);
  28. ULONG ProcessDirectory( FILE *,
  29. USHORT,
  30. PRESSECTDATA,
  31. PIMAGE_RESOURCE_DIRECTORY,
  32. PIMAGE_RESOURCE_DIRECTORY);
  33. ULONG ProcessDirEntry( FILE *,
  34. USHORT,
  35. PRESSECTDATA,
  36. PIMAGE_RESOURCE_DIRECTORY,
  37. PIMAGE_RESOURCE_DIRECTORY_ENTRY);
  38. ULONG ProcessSubDir( FILE *,
  39. USHORT,
  40. PRESSECTDATA,
  41. PIMAGE_RESOURCE_DIRECTORY,
  42. PIMAGE_RESOURCE_DIRECTORY_ENTRY);
  43. ULONG ProcessNamedEntry( FILE *,
  44. PRESSECTDATA,
  45. PIMAGE_RESOURCE_DIRECTORY,
  46. PIMAGE_RESOURCE_DIRECTORY_ENTRY);
  47. ULONG ProcessIdEntry( FILE *,
  48. PRESSECTDATA,
  49. PIMAGE_RESOURCE_DIRECTORY,
  50. PIMAGE_RESOURCE_DIRECTORY_ENTRY);
  51. ULONG ProcessDataEntry( FILE *,
  52. PRESSECTDATA,
  53. PIMAGE_RESOURCE_DIRECTORY,
  54. PIMAGE_RESOURCE_DATA_ENTRY);
  55. int FindNewExeHdr( FILE *, ULONG *);
  56. IMAGE_DOS_HEADER ExeDosHdr;//... Exe's DOS header
  57. IMAGE_NT_HEADERS NTHdrs; //... Exe's NT headers
  58. struct tagLevelData //... Holds ID or name for each directory level
  59. {
  60. //... level [0] is for resource type
  61. ULONG dwID; //... level [1] is for resource name
  62. WCHAR wszName[128]; //... level [2] is for resource language
  63. }
  64. LevelData[ MAXLEVELS] = { 0L, TEXT(""), 0L, TEXT(""), 0L, TEXT("")};
  65. BOOL fGetResLangIDs = FALSE;
  66. extern BOOL fInThirdPartyEditer;//.. Are we in a 3rd-party resource editor?
  67. extern MSTRDATA gMstr; //... Data from Master Project file (MPJ)
  68. extern PROJDATA gProj; //... Data from Language Project file (PRJ)
  69. extern UCHAR szDHW[];
  70. PLANGLIST pLangIDList = NULL;
  71. //..........................................................................
  72. void FreeLangIDList( void)
  73. {
  74. PLANGLIST pID = NULL;
  75. while ( pLangIDList ) {
  76. pID = pLangIDList->pNext;
  77. RLFREE( pLangIDList);
  78. pLangIDList = pID;
  79. }
  80. }
  81. //..........................................................................
  82. ULONG GetListOfResLangIDs( char *szExeName)
  83. {
  84. ULONG ulRC = SUCCESS;
  85. ULONG ulOffset = 0;
  86. static RESHEADER ResHeader; // Structure contain Resource Header info.
  87. if ( IsExe( szExeName) ) { //.. open the original exe file
  88. FILE *fpExe = FOPEN( szExeName, "rb");
  89. if ( fpExe != NULL ) {
  90. //... Get list of languages in exe file
  91. ulRC = (ULONG)FindNewExeHdr( fpExe, &ulOffset);
  92. if ( ulRC == SUCCESS ) {
  93. fGetResLangIDs = TRUE;
  94. ulRC = (ULONG)GetFileResources( fpExe, NULL, ulOffset);
  95. fGetResLangIDs = FALSE;
  96. }
  97. FCLOSE( fpExe);
  98. } else {
  99. ulRC = ERROR_OPEN_FAILED;
  100. }
  101. } else if ( IsWin32Res( szExeName) ) {
  102. FILE *fpRes = FOPEN( szExeName, "rb");
  103. if ( fpRes != NULL ) {
  104. LONG lEndOffset = 0L;
  105. //... How large is the res file?
  106. fseek( fpRes, 0L, SEEK_END);
  107. lEndOffset = ftell( fpRes);
  108. rewind( fpRes);
  109. //... Get list of languages in .RES file
  110. while ( ulRC == SUCCESS && ! feof( fpRes) ) {
  111. LONG lCurrOffset = 0L;
  112. lCurrOffset = (LONG)ftell( fpRes);
  113. if ( (lCurrOffset + (LONG)sizeof( RESHEADER)) >= lEndOffset ) {
  114. break;
  115. }
  116. if ( GetResHeader( fpRes, &ResHeader, NULL) == -1 ) {
  117. ulRC = 1L;
  118. break;
  119. }
  120. //... Is this the dummy, res32-identifying, res?
  121. if ( ResHeader.lSize == 0L ) {
  122. continue;
  123. }
  124. ulRC = AddToLangIDList( (DWORD)ResHeader.wLanguageId);
  125. SkipBytes( fpRes, (DWORD *)&ResHeader.lSize);
  126. ClearResHeader( ResHeader);
  127. DWordUpFilePointer( fpRes, MYREAD, ftell( fpRes), NULL);
  128. } // END while ( ! feof( InResFile)
  129. FCLOSE( fpRes);
  130. } else {
  131. ulRC = ERROR_OPEN_FAILED;
  132. }
  133. }
  134. if ( ulRC != SUCCESS ) {
  135. FreeLangIDList();
  136. }
  137. return ( ulRC);
  138. }
  139. //..........................................................................
  140. int ExtractResFromExe32A(
  141. char *szExeName,
  142. char *szResName,
  143. WORD wFilter)
  144. {
  145. FILE *fpExe = NULL; //... Handle of input .EXE file
  146. FILE *fpRes = NULL; //... Handle of output .RES file
  147. ULONG ulRC = 0;
  148. ULONG ulOffset = 0;
  149. int nRC = SUCCESS;
  150. gwFilter = wFilter;
  151. //.. open the original exe file
  152. fpExe = FOPEN( szExeName, "rb");
  153. if ( fpExe == NULL ) {
  154. return ( ERROR_OPEN_FAILED);
  155. }
  156. nRC = FindNewExeHdr( fpExe, &ulOffset);
  157. if ( nRC != SUCCESS ) {
  158. FCLOSE( fpExe);
  159. return ( nRC);
  160. }
  161. fpRes = FOPEN( (CHAR *)szResName, "wb");
  162. if ( fpRes != NULL ) {
  163. //... First, write the dummy 32bit identifier
  164. PutByte( fpRes, 0x00, NULL);
  165. PutByte( fpRes, 0x00, NULL);
  166. PutByte( fpRes, 0x00, NULL);
  167. PutByte( fpRes, 0x00, NULL);
  168. PutByte( fpRes, 0x20, NULL);
  169. PutByte( fpRes, 0x00, NULL);
  170. PutByte( fpRes, 0x00, NULL);
  171. PutByte( fpRes, 0x00, NULL);
  172. PutWord( fpRes, 0xffff, NULL);
  173. PutWord( fpRes, 0x00, NULL);
  174. PutWord( fpRes, 0xffff, NULL);
  175. PutWord( fpRes, 0x00, NULL);
  176. PutdWord( fpRes, 0L, NULL);
  177. PutdWord( fpRes, 0L, NULL);
  178. PutdWord( fpRes, 0L, NULL);
  179. PutdWord( fpRes, 0L, NULL);
  180. ulRC = (ULONG)GetFileResources( fpExe, fpRes, ulOffset);
  181. FCLOSE( fpRes);
  182. } else {
  183. ulRC = GetLastError();
  184. }
  185. FCLOSE( fpExe);
  186. return ( ulRC);
  187. }
  188. //..........................................................................
  189. int BuildExeFromRes32A(
  190. char * szOutExe, //... Output EXE file's name
  191. char * szRes, //... File of replacement resources
  192. char * szInExe ) //... Intput EXE file's name
  193. {
  194. HANDLE hExeFile = NULL;
  195. FILE *fpRes = NULL;
  196. DWORD dwRC = 0;
  197. WORD wRC = 0;
  198. //... Copy Input exe to out put exe
  199. if ( CopyFileA( szInExe, szOutExe, FALSE) == FALSE ) {
  200. QuitA( IDS_COPYFILE_FAILED, szInExe, szOutExe);
  201. }
  202. if ( (fpRes = FOPEN( szRes, "rb")) == NULL ) {
  203. return -2;
  204. }
  205. SetLastError(0);
  206. //if Source file was set attributes READ-ONLY, CopyFile sets temp file also.
  207. //And BeginUpdateResourceA returns ERROR.
  208. SetFileAttributesA(szOutExe, FILE_ATTRIBUTE_NORMAL);
  209. hExeFile = BeginUpdateResourceA( szOutExe, TRUE);
  210. dwRC = GetLastError();
  211. if ( ! hExeFile ) {
  212. FCLOSE( fpRes);
  213. return ( -3);
  214. }
  215. wRC = (WORD)InsertResourcesInExe( fpRes, hExeFile);
  216. FCLOSE( fpRes);
  217. if ( wRC != 1 ) {
  218. return ( wRC);
  219. }
  220. SetLastError(0); // needed only to see if EndUpdateResource
  221. // sets last error value.
  222. dwRC = EndUpdateResource( hExeFile, FALSE);
  223. if ( dwRC == FALSE ) {
  224. return ( -4);
  225. }
  226. MapFileAndFixCheckSumA( szOutExe); //... This func always calls QuitT or returns 0
  227. return (1);
  228. }
  229. //..........................................................................
  230. int FindNewExeHdr( FILE *fpExe, ULONG *ulOffset)
  231. {
  232. ULONG ulRC = 0;
  233. //... read the old format EXE header
  234. ulRC = MyRead( fpExe, (void *)&ExeDosHdr, sizeof( ExeDosHdr));
  235. if ( ulRC != 0L && ulRC != sizeof( ExeDosHdr) ) {
  236. return ( ERROR_READ_FAULT);
  237. }
  238. //... make sure its really an EXE file
  239. if ( ExeDosHdr.e_magic != IMAGE_DOS_SIGNATURE ) {
  240. return ( ERROR_INVALID_EXE_SIGNATURE);
  241. }
  242. //... make sure theres a new EXE header
  243. //... floating around somewhere
  244. if ( ! (*ulOffset = ExeDosHdr.e_lfanew) ) {
  245. return ( ERROR_BAD_EXE_FORMAT);
  246. }
  247. return ( SUCCESS);
  248. }
  249. //..........................................................................
  250. int InsertResourcesInExe(
  251. FILE *fpRes,
  252. HANDLE hExeFile )
  253. {
  254. PVOID pResData = NULL;
  255. LONG lEndOffset = 0L;
  256. BOOL bUpdRC = FALSE;
  257. LANGID wLangID = 0;
  258. int nResCnt = 0;
  259. int nResOut = 0;
  260. static RESHEADER ResHeader;
  261. //... How big is the .RES file?
  262. fseek( fpRes, 0L, SEEK_END);
  263. lEndOffset = ftell( fpRes);
  264. rewind( fpRes);
  265. //... Update all resources, found in the .RES,
  266. //... to the .EXE
  267. while ( ! feof( fpRes) ) {
  268. DWordUpFilePointer( fpRes, MYREAD, ftell( fpRes), NULL);
  269. RLFREE( pResData);
  270. if ( ftell( fpRes) >= lEndOffset ) {
  271. return (1);
  272. }
  273. ZeroMemory( &ResHeader, sizeof( ResHeader));
  274. // Read in the resource header
  275. if ( ( GetResHeader( fpRes, &ResHeader, (DWORD *) NULL) == -1 ) ) {
  276. return ( -1);
  277. }
  278. if ( ResHeader.lSize > 0L ) {
  279. wLangID = ResHeader.wLanguageId;
  280. // Allocate Memory to hold resource data
  281. pResData = (PVOID)FALLOC( ResHeader.lSize);
  282. // Read it into the buffer
  283. if ( ResReadBytes( fpRes,
  284. pResData,
  285. (size_t)ResHeader.lSize,
  286. NULL ) == FALSE ) {
  287. RLFREE( pResData);
  288. return (-1);
  289. }
  290. nResCnt++; // Increment # resources read
  291. DWordUpFilePointer( fpRes, MYREAD, ftell( fpRes), NULL);
  292. } else {
  293. continue;
  294. }
  295. // now write the data
  296. if ( ResHeader.bTypeFlag == IDFLAG ) {
  297. if ( ResHeader.bNameFlag == IDFLAG ) {
  298. SetLastError(0);
  299. bUpdRC = UpdateResource( hExeFile,
  300. MAKEINTRESOURCE( ResHeader.wTypeID),
  301. MAKEINTRESOURCE( ResHeader.wNameID),
  302. wLangID,
  303. pResData,
  304. ResHeader.lSize);
  305. if ( ! bUpdRC ) {
  306. RLFREE( pResData);
  307. return (-1);
  308. }
  309. } else {
  310. SetLastError(0);
  311. bUpdRC = UpdateResource( hExeFile,
  312. MAKEINTRESOURCE( ResHeader.wTypeID),
  313. ResHeader.pszName,
  314. wLangID,
  315. pResData,
  316. ResHeader.lSize);
  317. if ( ! bUpdRC ) {
  318. RLFREE( pResData);
  319. return (-1);
  320. }
  321. }
  322. } else {
  323. if (ResHeader.bNameFlag == IDFLAG) {
  324. SetLastError(0);//BUGUG
  325. bUpdRC = UpdateResource( hExeFile,
  326. ResHeader.pszType,
  327. MAKEINTRESOURCE( ResHeader.wNameID),
  328. wLangID,
  329. pResData,
  330. ResHeader.lSize);
  331. if ( ! bUpdRC ) {
  332. RLFREE( pResData);
  333. return (-1);
  334. }
  335. } else {
  336. SetLastError(0);
  337. bUpdRC = UpdateResource( hExeFile,
  338. ResHeader.pszType,
  339. ResHeader.pszName,
  340. wLangID,
  341. pResData,
  342. ResHeader.lSize);
  343. if ( ! bUpdRC ) {
  344. RLFREE( pResData);
  345. return (-1);
  346. }
  347. }
  348. }
  349. ClearResHeader( ResHeader);
  350. RLFREE( pResData);
  351. } //... END WHILE ( ! feof...
  352. return (1);
  353. }
  354. //............................................................
  355. LONG GetFileResources(
  356. FILE *fpExe,
  357. FILE *fpRes,
  358. ULONG ulHdrOffset)
  359. {
  360. ULONG ulOffsetToResources;
  361. ULONG ulOffsetToResourcesX;
  362. ULONG ulRead;
  363. ULONG ulToRead;
  364. ULONG ulRC = SUCCESS;
  365. PUCHAR pResources = NULL; //... Ptr to start of resource directory table
  366. PIMAGE_SECTION_HEADER pSectTbl = NULL;
  367. PIMAGE_SECTION_HEADER pSectTblLast = NULL;
  368. PIMAGE_SECTION_HEADER pSect = NULL;
  369. PIMAGE_SECTION_HEADER pResSect = NULL;
  370. PIMAGE_SECTION_HEADER pResSectX = NULL;
  371. static RESSECTDATA ResSectData;
  372. //... Read the NT image headers into memory
  373. ulRC = MoveFilePos( fpExe, ulHdrOffset);
  374. if ( ulRC != 0L ) {
  375. return ( -1L);
  376. }
  377. ulRead = MyRead( fpExe, (PUCHAR)&NTHdrs, sizeof( IMAGE_NT_HEADERS));
  378. if ( ulRead != 0L && ulRead != sizeof( IMAGE_NT_HEADERS) ) {
  379. return ( -1L);
  380. }
  381. //... Check for valid exe
  382. if ( *(PUSHORT)&NTHdrs.Signature != IMAGE_NT_SIGNATURE ) {
  383. return ( ERROR_INVALID_EXE_SIGNATURE);
  384. }
  385. if ((NTHdrs.FileHeader.Characteristics&IMAGE_FILE_EXECUTABLE_IMAGE) == 0 &&
  386. (NTHdrs.FileHeader.Characteristics&IMAGE_FILE_DLL) == 0) {
  387. return ( ERROR_EXE_MARKED_INVALID);
  388. }
  389. //... Where is resource section in file
  390. //... and how big is it?
  391. //... First, read section table
  392. ulToRead = NTHdrs.FileHeader.NumberOfSections
  393. * sizeof( IMAGE_SECTION_HEADER);
  394. pSectTbl = (PIMAGE_SECTION_HEADER)FALLOC( ulToRead);
  395. memset( (PVOID)pSectTbl, 0, ulToRead);
  396. ulHdrOffset += sizeof(ULONG) + sizeof(IMAGE_FILE_HEADER) +
  397. NTHdrs.FileHeader.SizeOfOptionalHeader;
  398. MoveFilePos( fpExe, ulHdrOffset);
  399. ulRead = MyRead( fpExe, (PUCHAR)pSectTbl, ulToRead);
  400. if ( ulRead != 0L && ulRead != ulToRead ) {
  401. SetLastError(ERROR_BAD_FORMAT);
  402. RLFREE( pSectTbl);
  403. return ( -1L);
  404. }
  405. pSectTblLast = pSectTbl + NTHdrs.FileHeader.NumberOfSections;
  406. for ( pSect = pSectTbl; pSect < pSectTblLast; ++pSect ) {
  407. if ( lstrcmpA( (CHAR *)pSect->Name, ".rsrc") == SAME && pResSect==NULL ) {
  408. pResSect = pSect;
  409. } else if ( lstrcmpA( (CHAR *)pSect->Name, ".rsrc1") == SAME && pResSectX==NULL ) {
  410. pResSectX = pSect;
  411. }
  412. }
  413. if ( pResSect == NULL ) {
  414. RLFREE( pSectTbl);
  415. QuitA( IDS_NO_RES_SECTION, gMstr.szSrc, NULL);
  416. }
  417. ulOffsetToResources = pResSect->PointerToRawData;
  418. ulOffsetToResourcesX = pResSectX ? pResSectX->PointerToRawData : 0L;
  419. ResSectData.ulVirtualAddress = pResSect->VirtualAddress;
  420. ResSectData.ulSizeOfResources = pResSect->SizeOfRawData;
  421. ResSectData.ulVirtualSize = pResSect->Misc.VirtualSize;
  422. ResSectData.ulVirtualAddressX = pResSectX ? pResSectX->VirtualAddress : 0L;
  423. ResSectData.ulSizeOfResourcesX = pResSectX ? pResSectX->SizeOfRawData : 0L;
  424. ResSectData.ulVirtualSizeX = pResSectX ? pResSectX->Misc.VirtualSize : 0L;
  425. //... Read resource section into memory
  426. pResources = (PUCHAR)FALLOC((ulToRead =
  427. (max(ResSectData.ulVirtualSize, ResSectData.ulSizeOfResources) +
  428. max(ResSectData.ulVirtualSizeX, ResSectData.ulSizeOfResourcesX))));
  429. memset( (PVOID)pResources, 0, ulToRead);
  430. ulRC = ReadResources( fpExe,
  431. ulOffsetToResources,
  432. ResSectData.ulSizeOfResources,
  433. pResources);
  434. if ( ulRC != 0L ) {
  435. RLFREE( pSectTbl);
  436. RLFREE( pResources);
  437. return ( ulRC);
  438. } else if ( ResSectData.ulSizeOfResourcesX > 0L ) {
  439. ulRC = ReadResources( fpExe,
  440. ulOffsetToResourcesX,
  441. ResSectData.ulSizeOfResourcesX,
  442. &pResources[ ResSectData.ulVirtualSize]);
  443. if ( ulRC != 0L ) {
  444. RLFREE( pSectTbl);
  445. RLFREE( pResources);
  446. return ( ulRC);
  447. }
  448. }
  449. //... Now process the resource table
  450. ulRC = ProcessDirectory( fpRes,
  451. 0,
  452. &ResSectData,
  453. (PIMAGE_RESOURCE_DIRECTORY)pResources,
  454. (PIMAGE_RESOURCE_DIRECTORY)pResources);
  455. RLFREE( pSectTbl);
  456. RLFREE( pResources);
  457. return ( (LONG)ulRC);
  458. }
  459. //......................................................................
  460. ULONG ProcessDirectory(
  461. FILE *fpRes,
  462. USHORT usLevel,
  463. PRESSECTDATA pResSectData,
  464. PIMAGE_RESOURCE_DIRECTORY pResStart,
  465. PIMAGE_RESOURCE_DIRECTORY pResDir)
  466. {
  467. ULONG ulRC = SUCCESS;
  468. PIMAGE_RESOURCE_DIRECTORY_ENTRY pResDirEntry;
  469. PIMAGE_RESOURCE_DIRECTORY_ENTRY pResDirStart;
  470. PIMAGE_RESOURCE_DIRECTORY_ENTRY pResDirEnd;
  471. pResDirStart = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)
  472. ((PBYTE)pResDir + sizeof( IMAGE_RESOURCE_DIRECTORY));
  473. pResDirEnd = pResDirStart
  474. + pResDir->NumberOfNamedEntries
  475. + pResDir->NumberOfIdEntries;
  476. for ( pResDirEntry = pResDirStart, ulRC = 0L;
  477. pResDirEntry < pResDirEnd && ulRC == 0L;
  478. ++pResDirEntry ) {
  479. ulRC = ProcessDirEntry( fpRes,
  480. usLevel,
  481. pResSectData,
  482. pResStart,
  483. pResDirEntry);
  484. }
  485. return ( ulRC);
  486. }
  487. //......................................................................
  488. ULONG ProcessDirEntry(
  489. FILE *fpRes,
  490. USHORT usLevel,
  491. PRESSECTDATA pResSectData,
  492. PIMAGE_RESOURCE_DIRECTORY pResStart,
  493. PIMAGE_RESOURCE_DIRECTORY_ENTRY pResDirEntry)
  494. {
  495. ULONG ulRC = SUCCESS;
  496. if ( pResDirEntry->Name & IMAGE_RESOURCE_NAME_IS_STRING ) {
  497. GetDirNameU( LevelData[ usLevel].wszName,
  498. (PIMAGE_RESOURCE_DIR_STRING_U)((PBYTE)pResStart
  499. + (pResDirEntry->Name & (~IMAGE_RESOURCE_NAME_IS_STRING))));
  500. LevelData[ usLevel].dwID = IMAGE_RESOURCE_NAME_IS_STRING;
  501. } else {
  502. LevelData[ usLevel].wszName[0] = TEXT('\0');
  503. LevelData[ usLevel].dwID = pResDirEntry->Name;
  504. }
  505. if ( pResDirEntry->OffsetToData & IMAGE_RESOURCE_DATA_IS_DIRECTORY ) {
  506. ulRC = ProcessSubDir( fpRes,
  507. usLevel,
  508. pResSectData,
  509. pResStart,
  510. pResDirEntry);
  511. } else if ( pResDirEntry->Name & IMAGE_RESOURCE_NAME_IS_STRING ) {
  512. ulRC = ProcessNamedEntry( fpRes, pResSectData, pResStart, pResDirEntry);
  513. } else {
  514. ulRC = ProcessIdEntry( fpRes, pResSectData, pResStart, pResDirEntry);
  515. }
  516. return ( ulRC);
  517. }
  518. //......................................................................
  519. ULONG ProcessSubDir(
  520. FILE *fpRes,
  521. USHORT usLevel,
  522. PRESSECTDATA pResSectData,
  523. PIMAGE_RESOURCE_DIRECTORY pResStart,
  524. PIMAGE_RESOURCE_DIRECTORY_ENTRY pResDirEntry)
  525. {
  526. PIMAGE_RESOURCE_DIRECTORY pResDir;
  527. pResDir = (PIMAGE_RESOURCE_DIRECTORY)((PBYTE)pResStart
  528. + (pResDirEntry->OffsetToData & (~IMAGE_RESOURCE_DATA_IS_DIRECTORY)));
  529. return ( ++usLevel < MAXLEVELS ? ProcessDirectory( fpRes,
  530. usLevel,
  531. pResSectData,
  532. pResStart,
  533. pResDir)
  534. : -1L);
  535. }
  536. //......................................................................
  537. ULONG ProcessIdEntry(
  538. FILE *fpRes,
  539. PRESSECTDATA pResSectData,
  540. PIMAGE_RESOURCE_DIRECTORY pResStart,
  541. PIMAGE_RESOURCE_DIRECTORY_ENTRY pResDirEntry)
  542. {
  543. return ( ProcessDataEntry( fpRes,
  544. pResSectData,
  545. pResStart,
  546. (PIMAGE_RESOURCE_DATA_ENTRY)((PBYTE)pResStart
  547. + pResDirEntry->OffsetToData)));
  548. }
  549. //......................................................................
  550. ULONG ProcessNamedEntry(
  551. FILE *fpRes,
  552. PRESSECTDATA pResSectData,
  553. PIMAGE_RESOURCE_DIRECTORY pResStart,
  554. PIMAGE_RESOURCE_DIRECTORY_ENTRY pResDirEntry)
  555. {
  556. return ( ProcessDataEntry( fpRes,
  557. pResSectData,
  558. pResStart,
  559. (PIMAGE_RESOURCE_DATA_ENTRY)((PBYTE)pResStart
  560. + pResDirEntry->OffsetToData)));
  561. }
  562. //......................................................................
  563. ULONG ProcessDataEntry(
  564. FILE *fpRes,
  565. PRESSECTDATA pResSectData,
  566. PIMAGE_RESOURCE_DIRECTORY pResStart,
  567. PIMAGE_RESOURCE_DATA_ENTRY pResData)
  568. {
  569. ULONG ulOffset;
  570. ULONG ulCopied;
  571. DWORD dwHdrSize = 0L;
  572. fpos_t HdrSizePos;
  573. if ( fGetResLangIDs ) { //... Are we just looking for LANG IDs?
  574. return ( AddToLangIDList( (WORD)(LevelData[2].dwID)));
  575. }
  576. if ( gwFilter != 0 ) { //... Filtering turned on?
  577. //... Yes, is this a resource we want?
  578. if ( LevelData[0].dwID == IMAGE_RESOURCE_NAME_IS_STRING
  579. || LevelData[0].dwID != (DWORD)gwFilter ) {
  580. return ( 0L); //... Not a resource we want
  581. }
  582. }
  583. //... Are we in the dialog editor?
  584. if ( fInThirdPartyEditer ) { //... Is the language we want?
  585. if ( LevelData[2].dwID != gMstr.wLanguageID ) {
  586. return ( 0L); //... Not the language we want
  587. }
  588. }
  589. ulOffset = pResData->OffsetToData - pResSectData->ulVirtualAddress;
  590. if ( ulOffset >= pResSectData->ulVirtualSize ) {
  591. if ( pResSectData->ulVirtualSizeX > 0L ) {
  592. ulOffset = pResData->OffsetToData
  593. + pResSectData->ulVirtualSize
  594. - pResSectData->ulVirtualAddressX;
  595. if ( ulOffset >= pResSectData->ulVirtualSize
  596. + pResSectData->ulSizeOfResourcesX ) {
  597. return ( (ULONG)-1L);
  598. }
  599. } else {
  600. return ( (ULONG)-1L);
  601. }
  602. }
  603. //... write out the resource header info
  604. //... First, write the resource's size
  605. PutdWord( fpRes, pResData->Size, &dwHdrSize);
  606. //... Remember where to write real hdr size and
  607. //... write out bogus hdr size, fix up later
  608. fgetpos( fpRes, &HdrSizePos);
  609. PutdWord( fpRes, 0, &dwHdrSize);
  610. //... Write resource type
  611. if ( LevelData[0].dwID == IMAGE_RESOURCE_NAME_IS_STRING ) {
  612. PutString( fpRes, (TCHAR *)LevelData[0].wszName, &dwHdrSize);
  613. } else {
  614. PutWord( fpRes, IDFLAG, &dwHdrSize);
  615. PutWord( fpRes, LOWORD( LevelData[0].dwID), &dwHdrSize);
  616. }
  617. //... Write resource name
  618. //... dbl-null-terminated if string
  619. if ( LevelData[1].dwID == IMAGE_RESOURCE_NAME_IS_STRING ) {
  620. PutString( fpRes, (TCHAR *)LevelData[1].wszName, &dwHdrSize);
  621. } else {
  622. PutWord( fpRes, IDFLAG, &dwHdrSize);
  623. PutWord( fpRes, LOWORD( LevelData[1].dwID), &dwHdrSize);
  624. }
  625. DWordUpFilePointer( fpRes, MYWRITE, ftell( fpRes), &dwHdrSize);
  626. //... More Win32 header stuff
  627. PutdWord( fpRes, 0, &dwHdrSize); //... Data version
  628. PutWord( fpRes, 0x1030, &dwHdrSize); //... MemoryFlags (WORD)
  629. //... language is always a number (WORD)
  630. PutWord( fpRes, LOWORD( LevelData[2].dwID), &dwHdrSize);
  631. //... More Win32 header stuff
  632. PutdWord( fpRes, 0, &dwHdrSize); //... Version
  633. PutdWord( fpRes, 0, &dwHdrSize); //... Characteristics
  634. //... Now, fix up the resource header size
  635. UpdateResSize( fpRes, &HdrSizePos, dwHdrSize);
  636. //... Copy the resource data to the res file
  637. ulCopied = MyWrite( fpRes, (PUCHAR)pResStart + ulOffset, pResData->Size);
  638. if ( ulCopied != 0L && ulCopied != pResData->Size ) {
  639. return ( (ULONG)-1);
  640. }
  641. DWordUpFilePointer( fpRes, MYWRITE, ftell( fpRes), NULL);
  642. return ( 0L);
  643. }
  644. //......................................................................
  645. /*
  646. * Utility routines
  647. */
  648. ULONG ReadResources(
  649. FILE *fpExe,
  650. ULONG ulOffsetToResources,
  651. ULONG ulSizeOfResources,
  652. PUCHAR pResources)
  653. {
  654. ULONG ulRC = SUCCESS;
  655. ULONG ulRead;
  656. ulRC = MoveFilePos( fpExe, ulOffsetToResources);
  657. if ( ulRC != 0L ) {
  658. return ( (ULONG)-1L);
  659. }
  660. ulRead = MyRead( fpExe, pResources, ulSizeOfResources);
  661. if ( ulRead != 0L && ulRead != ulSizeOfResources ) {
  662. return ( (ULONG)-1L);
  663. }
  664. return ( 0L);
  665. }
  666. //......................................................................
  667. WCHAR * GetDirNameU(
  668. WCHAR *pszDest,
  669. PIMAGE_RESOURCE_DIR_STRING_U pDirStr)
  670. {
  671. CopyMemory( pszDest, pDirStr->NameString, MEMSIZE( pDirStr->Length));
  672. pszDest[ pDirStr->Length] = L'\0';
  673. return ( pszDest);
  674. }
  675. //......................................................................
  676. ULONG MoveFilePos( FILE *fp, ULONG pos)
  677. {
  678. return ( fseek( fp, pos, SEEK_SET));
  679. }
  680. //......................................................................
  681. ULONG MyWrite( FILE *fp, UCHAR *p, ULONG ulToWrite)
  682. {
  683. size_t cWritten;
  684. cWritten = fwrite( p, 1, (size_t)ulToWrite, fp);
  685. return ( (ULONG)(cWritten == ulToWrite ? 0L : cWritten));
  686. }
  687. //......................................................................
  688. ULONG MyRead( FILE *fp, UCHAR*p, ULONG ulRequested )
  689. {
  690. size_t cRead;
  691. cRead = fread( p, 1, (size_t)ulRequested, fp);
  692. return ( (ULONG)(cRead == ulRequested ? 0L : cRead));
  693. }
  694. //......................................................................
  695. DWORD AddToLangIDList( DWORD dwLangID)
  696. {
  697. WORD wLangID = (WORD)dwLangID;
  698. if ( pLangIDList ) {
  699. PLANGLIST pID;
  700. for ( pID = pLangIDList; pID; pID = pID->pNext ) {
  701. if ( pID->wLang == wLangID ) {
  702. break; //... LANGID already in list
  703. } else if ( pID->pNext == NULL ) {
  704. pID->pNext = (PLANGLIST)FALLOC( sizeof( LANGLIST));
  705. pID = pID->pNext;
  706. pID->pNext = NULL;
  707. pID->wLang = wLangID;
  708. //... LANGID now added to list
  709. }
  710. }
  711. } else {
  712. pLangIDList = (PLANGLIST)FALLOC( sizeof( LANGLIST));
  713. pLangIDList->pNext = NULL;
  714. pLangIDList->wLang = wLangID;
  715. }
  716. return ( SUCCESS);
  717. }