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.

4646 lines
164 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // File: win16.cpp
  4. //
  5. // Contents: Implementation for the Windows 16 Read/Write module
  6. //
  7. // Classes: one
  8. //
  9. // History: 26-July-93 alessanm created
  10. //
  11. //----------------------------------------------------------------------------
  12. #include <afxwin.h>
  13. #include "..\common\rwdll.h"
  14. #include "newexe.h"
  15. #include <stdio.h>
  16. #include <limits.h>
  17. /////////////////////////////////////////////////////////////////////////////
  18. // Initialization of MFC Extension DLL
  19. #include "afxdllx.h" // standard MFC Extension DLL routines
  20. static AFX_EXTENSION_MODULE NEAR extensionDLL = { NULL, NULL};
  21. /////////////////////////////////////////////////////////////////////////////
  22. // General Declarations
  23. #define MODULENAME "RWWin16.dll"
  24. #define RWTAG "WIN16"
  25. #define LPNULL 0L
  26. #define Pad16(x) ((((x+15)>>4)<<4)-x)
  27. #define Pad4(x) ((((x+3)>>2)<<2)-x)
  28. #define MAXSTR 300
  29. #define MAXID 128
  30. #define IMAGE_DOS_SIGNATURE 0x5A4D // MZ
  31. #define IMAGE_WIN_SIGNATURE 0x454E // NE
  32. #define VB // RCDATA process for VB only - WB
  33. #ifdef VB
  34. static const RES_SIGNATURE = 0xA5; // identifier for VB entry
  35. #endif
  36. // Code pages
  37. #define CP_ASCII7 0 // 7-bit ASCII
  38. #define CP_JIS 932 // Japan (Shift - JIS X-0208)
  39. #define CP_KSC 949 // Korea (Shift - KSC 5601)
  40. #define CP_GB5 950 // Taiwan (GB5)
  41. #define CP_UNI 1200 // Unicode
  42. #define CP_EE 1250 // Latin-2 (Eastern Europe)
  43. #define CP_CYR 1251 // Cyrillic
  44. #define CP_MULTI 1252 // Multilingual
  45. #define CP_GREEK 1253 // Greek
  46. #define CP_TURK 1254 // Turkish
  47. #define CP_HEBR 1255 // Hebrew
  48. #define CP_ARAB 1256 // Arabic
  49. /////////////////////////////////////////////////////////////////////////////
  50. // General type Declarations
  51. typedef unsigned char UCHAR;
  52. typedef UCHAR * PUCHAR;
  53. typedef struct ver_block {
  54. WORD wBlockLen;
  55. WORD wValueLen;
  56. WORD wType;
  57. WORD wHead;
  58. BYTE far * pValue;
  59. char szKey[100];
  60. char szValue[300];
  61. } VER_BLOCK;
  62. /////////////////////////////////////////////////////////////////////////////
  63. // Function Declarations
  64. static UINT GetResInfo(
  65. CFile*,
  66. WORD* wTypeId, LPSTR lplpszTypeId, BYTE bMaxTypeLen,
  67. WORD* wNameId, LPSTR lplpszNameId, BYTE bMaxNameLen,
  68. WORD* pwFlags,
  69. DWORD* dwSize, DWORD* dwFileOffset );
  70. static UINT WriteHeader(
  71. CFile*,
  72. WORD wTypeId, LPSTR lpszTypeId,
  73. WORD wNameId, LPSTR lpszNameId,
  74. WORD wFlags );
  75. static UINT WriteImage(
  76. CFile*,
  77. LPVOID lpImage, DWORD dwSize );
  78. static UINT GetUpdatedRes(
  79. LPVOID far * lplpBuffer,
  80. UINT* uiSize,
  81. WORD* wTypeId, LPSTR lplpszTypeId,
  82. WORD* wNameId, LPSTR lplpszNameId,
  83. DWORD* dwlang, DWORD* dwSize );
  84. static UINT GetUpdatedItem(
  85. LPVOID far * lplpBuffer,
  86. LONG* dwSize,
  87. WORD* wX, WORD* wY,
  88. WORD* wcX, WORD* wcY,
  89. DWORD* dwPosId,
  90. DWORD* dwStyle, DWORD* dwExtStyle,
  91. LPSTR lpszText);
  92. static int GetVSBlock( BYTE far * far * lplpImage, LONG* pdwSize, VER_BLOCK* pverBlock);
  93. static int PutVSBlock( BYTE far * far * lplpImage, LONG* pdwSize, VER_BLOCK verBlock,
  94. LPSTR lpStr, BYTE far * far * lplpBlockSize, WORD* pwPad);
  95. /////////////////////////////////////////////////////////////////////////////
  96. // Helper Function Declarations
  97. static UINT CopyFile( CFile* filein, CFile* fileout );
  98. static UINT GetNameOrOrdFile( CFile* pfile, WORD* pwId, LPSTR lpszId, BYTE bMaxStrLen );
  99. static UINT ParseMenu( LPVOID lpImageBuf, DWORD dwImageSize, LPVOID lpBuffer, DWORD dwSize );
  100. static UINT ParseString( LPVOID lpImageBuf, DWORD dwImageSize, LPVOID lpBuffer, DWORD dwSize );
  101. static UINT ParseDialog( LPVOID lpImageBuf, DWORD dwImageSize, LPVOID lpBuffer, DWORD dwSize );
  102. static UINT ParseCursor( LPVOID lpImageBuf, DWORD dwImageSize, LPVOID lpBuffer, DWORD dwSize );
  103. static UINT ParseIcon( LPVOID lpImageBuf, DWORD dwImageSize, LPVOID lpBuffer, DWORD dwSize );
  104. static UINT ParseBitmap( LPVOID lpImageBuf, DWORD dwImageSize, LPVOID lpBuffer, DWORD dwSize );
  105. static UINT ParseAccel( LPVOID lpImageBuf, DWORD dwImageSize, LPVOID lpBuffer, DWORD dwSize );
  106. #ifdef VB
  107. static UINT ParseVBData( LPVOID lpImageBuf, DWORD dwImageSize, LPVOID lpBuffer, DWORD dwSize );
  108. #endif
  109. static UINT ParseVerst( LPVOID lpImageBuf, DWORD dwImageSize, LPVOID lpBuffer, DWORD dwSize );
  110. static UINT GenerateFile( LPCSTR lpszTgtFilename,
  111. HANDLE hResFileModule,
  112. LPVOID lpBuffer,
  113. UINT uiSize,
  114. HINSTANCE hDllInst
  115. );
  116. static UINT UpdateMenu( LPVOID lpNewBuf, LONG dwNewSize,
  117. LPVOID lpOldImage, LONG dwOldImageSize,
  118. LPVOID lpNewImage, DWORD* pdwNewImageSize );
  119. static UINT GenerateMenu( LPVOID lpNewBuf, LONG dwNewSize,
  120. LPVOID lpNewImage, DWORD* pdwNewImageSize );
  121. static UINT UpdateString( LPVOID lpNewBuf, LONG dwNewSize,
  122. LPVOID lpOldI, LONG dwOldImageSize,
  123. LPVOID lpNewI, DWORD* pdwNewImageSize );
  124. static UINT GenerateString( LPVOID lpNewBuf, LONG dwNewSize,
  125. LPVOID lpNewImage, DWORD* pdwNewImageSize );
  126. static UINT UpdateDialog( LPVOID lpNewBuf, LONG dwNewSize,
  127. LPVOID lpOldI, LONG dwOldImageSize,
  128. LPVOID lpNewI, DWORD* pdwNewImageSize );
  129. static UINT GenerateDialog( LPVOID lpNewBuf, LONG dwNewSize,
  130. LPVOID lpNewImage, DWORD* pdwNewImageSize );
  131. static UINT UpdateAccel(LPVOID lpNewBuf, LONG dwNewSize,
  132. LPVOID lpOldImage, LONG dwOldImageSize,
  133. LPVOID lpNewImage, DWORD* pdwNewImageSize );
  134. #ifdef VB
  135. static UINT UpdateVBData( LPVOID lpNewBuf, LONG dwNewSize,
  136. LPVOID lpOldI, LONG dwOldImageSize,
  137. LPVOID lpNewI, DWORD* pdwNewImageSize );
  138. #endif
  139. static UINT UpdateVerst( LPVOID lpNewBuf, LONG dwNewSize,
  140. LPVOID lpOldI, LONG dwOldImageSize,
  141. LPVOID lpNewI, DWORD* pdwNewImageSize );
  142. static BYTE SkipByte( BYTE far * far * lplpBuf, UINT uiSkip, LONG* pdwRead );
  143. static BYTE PutDWord( BYTE far * far* lplpBuf, DWORD dwValue, LONG* pdwSize );
  144. static BYTE PutWord( BYTE far * far* lplpBuf, WORD wValue, LONG* pdwSize );
  145. static BYTE PutByte( BYTE far * far* lplpBuf, BYTE bValue, LONG* pdwSize );
  146. static UINT PutString( BYTE far * far* lplpBuf, LPSTR lpszText, LONG* pdwSize );
  147. static UINT PutPascalString( BYTE far * far* lplpBuf, LPSTR lpszText, BYTE bLen, LONG* pdwSize );
  148. static UINT PutNameOrOrd( BYTE far * far* lplpBuf, WORD wOrd, LPSTR lpszText, LONG* pdwSize );
  149. static UINT PutCaptionOrOrd( BYTE far * far* lplpBuf, WORD wOrd, LPSTR lpszText, LONG* pdwSize,
  150. BYTE bClass, DWORD dwStyle );
  151. static UINT PutClassName( BYTE far * far* lplpBuf, BYTE bClass, LPSTR lpszText, LONG* pdwSize );
  152. static UINT PutControlClassName( BYTE far * far* lplpBuf, BYTE bClass, LPSTR lpszText, LONG* pdwSize );
  153. static BYTE GetDWord( BYTE far * far* lplpBuf, DWORD* dwValue, LONG* pdwSize );
  154. static BYTE GetWord( BYTE far * far* lplpBuf, WORD* wValue, LONG* pdwSize );
  155. static BYTE GetByte( BYTE far * far* lplpBuf, BYTE* bValue, LONG* pdwSize );
  156. static UINT GetNameOrOrd( BYTE far * far* lplpBuf, WORD* wOrd, LPSTR lpszText, LONG* pdwSize );
  157. static UINT GetCaptionOrOrd( BYTE far * far* lplpBuf, WORD* wOrd, LPSTR lpszText, LONG* pdwSize,
  158. BYTE wClass, DWORD dwStyle );
  159. static UINT GetString( BYTE far * far* lplpBuf, LPSTR lpszText, LONG* pdwSize );
  160. static UINT GetClassName( BYTE far * far* lplpBuf, BYTE* bClass, LPSTR lpszText, LONG* pdwSize );
  161. static UINT GetControlClassName( BYTE far * far* lplpBuf, BYTE* bClass, LPSTR lpszText, LONG* pdwSize );
  162. static UINT CopyText( BYTE far * far * lplpTgt, BYTE far * far * lplpSrc, LONG* pdwTgtSize, LONG* pdwSrcSize);
  163. static int GetVSString( BYTE far * far* lplpBuf, LPSTR lpszText, LONG* pdwSize, int cMaxLen );
  164. static LPRESITEM GetItem( BYTE far * lpBuf, LONG dwNewSize, LPSTR lpStr );
  165. static DWORD CalcID( WORD wId, BOOL bFlag );
  166. static DWORD GenerateTransField( WORD wLang, BOOL bReverse );
  167. static void GenerateTransField( WORD wLang, VER_BLOCK * pVer );
  168. static void ChangeLanguage( LPVOID, UINT );
  169. // Allignment helpers
  170. static LONG Allign( BYTE * * lplpBuf, LONG* plBufSize, LONG lSize );
  171. /////////////////////////////////////////////////////////////////////////////
  172. // Global variables
  173. static BYTE sizeofByte = sizeof(BYTE);
  174. static BYTE sizeofWord = sizeof(WORD);
  175. static BYTE sizeofDWord = sizeof(DWORD);
  176. static CWordArray wIDArray;
  177. static DWORD gLang = 0;
  178. /////////////////////////////////////////////////////////////////////////////
  179. // Public C interface implementation
  180. //[registration]
  181. extern "C"
  182. BOOL FAR PASCAL RWGetTypeString(LPSTR lpszTypeName)
  183. {
  184. strcpy( lpszTypeName, RWTAG );
  185. return FALSE;
  186. }
  187. extern "C"
  188. BOOL FAR PASCAL RWValidateFileType (LPCSTR lpszFilename)
  189. {
  190. UINT uiError = ERROR_NO_ERROR;
  191. CFile file;
  192. WORD w;
  193. // we Open the file to see if it is a file we can handle
  194. if (!file.Open( lpszFilename, CFile::shareDenyNone | CFile::typeBinary | CFile::modeRead ))
  195. return FALSE;
  196. // Read the file signature
  197. file.Read((WORD*)&w, sizeof(WORD));
  198. if (w==IMAGE_DOS_SIGNATURE) {
  199. file.Seek( 0x18, CFile::begin );
  200. file.Read((WORD*)&w, sizeof(WORD));
  201. if (w<0x0040) {
  202. // this is not a Windows Executable
  203. file.Close();
  204. return FALSE;
  205. }
  206. // get offset to header
  207. file.Seek( 0x3c, CFile::begin );
  208. file.Read((WORD*)&w, sizeof(WORD));
  209. // Read header
  210. new_exe ne;
  211. file.Seek( w, CFile::begin );
  212. file.Read(&ne, sizeof(new_exe));
  213. if (NE_MAGIC(ne)==LOWORD(IMAGE_WIN_SIGNATURE)) {
  214. // this is a Windows Executable
  215. // we can handle the situation
  216. file.Close();
  217. return TRUE;
  218. }
  219. }
  220. file.Close();
  221. return FALSE;
  222. }
  223. extern "C"
  224. UINT
  225. APIENTRY
  226. RWReadTypeInfo(
  227. LPCSTR lpszFilename,
  228. LPVOID lpBuffer,
  229. UINT* puiSize
  230. )
  231. {
  232. UINT uiError = ERROR_NO_ERROR;
  233. BYTE far * lpBuf = (BYTE far *)lpBuffer;
  234. DWORD uiBufSize = *puiSize;
  235. // we can consider the use of a CMemFile so we get the same speed as memory access.
  236. CFile file;
  237. WORD i;
  238. WORD wAlignShift;
  239. WORD w, wResCount;
  240. WORD wWinHeaderOffset, wResTableOffset;
  241. WORD wCurTypeOffset, wCurNameOffset;
  242. BYTE nCount;
  243. WORD wTypeId; DWORD dwTypeId;
  244. static char szTypeId[128];
  245. WORD wNameId;
  246. static char szNameId[128];
  247. WORD wSize, wFileOffset;
  248. DWORD dwSize,dwFileOffset;
  249. WORD wResidentOffset;
  250. DWORD dwVerStampOffset = 0xffffffff;
  251. DWORD dwVerStampSize = 0;
  252. UINT uiOverAllSize = 0;
  253. if (!RWValidateFileType(lpszFilename))
  254. return ERROR_RW_INVALID_FILE;
  255. // Open the file and try to read the information on the resource in it.
  256. if (!file.Open(lpszFilename, CFile::shareDenyNone | CFile::modeRead | CFile::typeBinary))
  257. return ERROR_FILE_OPEN;
  258. // we try to read as much information as we can
  259. // Because this is a exe file we can read all the information we need.
  260. file.Read((WORD*)&w, sizeof(WORD));
  261. if (w!=IMAGE_DOS_SIGNATURE) return ERROR_RW_INVALID_FILE;
  262. file.Seek( 0x18, CFile::begin );
  263. file.Read((WORD*)&w, sizeof(WORD));
  264. if (w<0x0040) {
  265. // this is not a Windows Executable
  266. file.Close();
  267. return ERROR_RW_INVALID_FILE;
  268. }
  269. // Get offset to Windows new header
  270. file.Seek( 0x3c, CFile::begin );
  271. file.Read((WORD*)&wWinHeaderOffset, sizeof(WORD));
  272. // Read and save Windows header Offset
  273. file.Seek( wWinHeaderOffset, CFile::begin );
  274. // Read header
  275. new_exe ne;
  276. file.Read(&ne, sizeof(new_exe));
  277. if (NE_MAGIC(ne)!=LOWORD(IMAGE_WIN_SIGNATURE)) {
  278. // this is not a Windows Executable
  279. file.Close();
  280. return ERROR_RW_INVALID_FILE;
  281. }
  282. // this is a Windows 16 Executable
  283. // we can handle the situation
  284. // Later we want to check for the file type
  285. // Location 24H inside of the Windows header has the relative offset from
  286. // the beginning of the Windows header to the beginning of the resource table
  287. file.Seek (wWinHeaderOffset+0x24, CFile::begin);
  288. file.Read ((WORD*)&wResTableOffset, sizeof(WORD));
  289. file.Read ((WORD*)&wResidentOffset, sizeof(WORD));
  290. // Check if there are resources
  291. if (wResTableOffset == wResidentOffset) {
  292. file.Close ();
  293. return ERROR_RW_NO_RESOURCES;
  294. }
  295. // Read the resurce table
  296. new_rsrc rsrc;
  297. file.Seek (wWinHeaderOffset+NE_RSRCTAB(ne), CFile::begin);
  298. file.Read (&rsrc, sizeof(new_rsrc));
  299. WORD rsrc_size = NE_RESTAB(ne)-NE_RSRCTAB(ne);
  300. // Read and save alignment shift count
  301. file.Seek (wWinHeaderOffset+wResTableOffset, CFile::begin);
  302. file.Read ((WORD*)&wAlignShift, sizeof(WORD));
  303. // Read the first type ID
  304. file.Read ((WORD*)&wTypeId, sizeof(WORD));
  305. // Save the Offset of the current TypeInfo record
  306. wCurTypeOffset = wWinHeaderOffset + wResTableOffset + 2;
  307. // reset the global language
  308. gLang = 0;
  309. // Process TypeInfo records while there are TypeInfo record left
  310. while (wTypeId) {
  311. // Get Name of ord
  312. if (!(wTypeId & 0x8000)) {
  313. // It is a Offset to a string
  314. dwTypeId = (MAKELONG(wTypeId, 0)); //<<wAlignShift;
  315. file.Seek (wWinHeaderOffset+wResTableOffset+dwTypeId, CFile::begin);
  316. // Get the character count for the ID string
  317. file.Read ((BYTE*)&nCount, sizeof(BYTE));
  318. // Read the ID string
  319. file.Read (szTypeId, nCount);
  320. // Put null at the end of the string
  321. szTypeId[nCount] = 0;
  322. if (0 == strlen(szTypeId))
  323. return ERROR_RW_INVALID_FILE;
  324. // Set wTypeId to zero
  325. wTypeId = 0;
  326. } else {
  327. // It is an ID
  328. // Turn off the high bit
  329. wTypeId = wTypeId & 0x7FFF;
  330. if (0 == wTypeId)
  331. return ERROR_RW_INVALID_FILE;
  332. // Set the ID string to null
  333. szTypeId[0] = 0;
  334. }
  335. // Restore the file read point
  336. file.Seek (wCurTypeOffset+2, CFile::begin);
  337. // Get the count for this type of resource
  338. file.Read ((WORD*)&wResCount, sizeof(WORD));
  339. // Pass the reserved DWORD
  340. file.Seek (4, CFile::current);
  341. // Save the Offset of the current NameInfo record
  342. wCurNameOffset = wCurTypeOffset + 8;
  343. // Process NameInfo records
  344. for (i = 0; i < wResCount; i++) {
  345. file.Read ((WORD*)&wFileOffset, sizeof(WORD));
  346. file.Read ((WORD*)&wSize, sizeof(WORD));
  347. // Pass the flags
  348. file.Seek (2, CFile::current);
  349. file.Read ((WORD*)&wNameId, sizeof(WORD));
  350. // Get name of ord
  351. if (!(wNameId & 0x8000)) {
  352. // It is a Offset to a string
  353. file.Seek (wWinHeaderOffset+wResTableOffset+wNameId, CFile::begin);
  354. // Get the character count for the string
  355. file.Read ((BYTE*)&nCount, sizeof(BYTE));
  356. // Read the string
  357. file.Read (szNameId, nCount);
  358. // Put null at the end of the string
  359. szNameId[nCount] = 0;
  360. // Set wNameId to zero
  361. wNameId = 0;
  362. } else {
  363. // It is an ID
  364. // Turn off the high bit
  365. wNameId = wNameId & 0x7FFF;
  366. if (0 == wNameId)
  367. return ERROR_RW_INVALID_FILE;
  368. // Set the string to null
  369. szNameId[0] = 0;
  370. }
  371. dwSize = (MAKELONG (wSize, 0))<<wAlignShift;
  372. // dwSize = MAKELONG (wSize, 0);
  373. dwFileOffset = (MAKELONG (wFileOffset, 0))<<wAlignShift;
  374. // Put the data into the buffer
  375. uiOverAllSize += PutWord( &lpBuf, wTypeId, (LONG*)&uiBufSize );
  376. uiOverAllSize += PutString( &lpBuf, szTypeId, (LONG*)&uiBufSize );
  377. // Check if it is alligned
  378. uiOverAllSize += Allign( &lpBuf, (LONG*)&uiBufSize, (LONG)uiOverAllSize);
  379. uiOverAllSize += PutWord( &lpBuf, wNameId, (LONG*)&uiBufSize );
  380. uiOverAllSize += PutString( &lpBuf, szNameId, (LONG*)&uiBufSize );
  381. // Check if it is alligned
  382. uiOverAllSize += Allign( &lpBuf, (LONG*)&uiBufSize, (LONG)uiOverAllSize);
  383. uiOverAllSize += PutDWord( &lpBuf, gLang, (LONG*)&uiBufSize );
  384. uiOverAllSize += PutDWord( &lpBuf, dwSize, (LONG*)&uiBufSize );
  385. uiOverAllSize += PutDWord( &lpBuf, dwFileOffset, (LONG*)&uiBufSize );
  386. TRACE("WIN16: Type: %hd\tName: %hd\tOffset: %lX\n", wTypeId, wNameId, dwFileOffset);
  387. // Check if this is the Version stamp block and save the offset to it
  388. if (wTypeId==16) {
  389. dwVerStampOffset = dwFileOffset;
  390. dwVerStampSize = dwSize;
  391. }
  392. // Update the current NameInfo record offset
  393. wCurNameOffset = wCurNameOffset + 12;
  394. // Move file pointer to the next NameInfo record
  395. file.Seek (wCurNameOffset, CFile::begin);
  396. }
  397. // Update the current TypeInfo record offset
  398. wCurTypeOffset = wCurTypeOffset + 8 + wResCount * 12;
  399. // Move file pointer to the next TypeInfo record
  400. file.Seek (wCurTypeOffset, CFile::begin);
  401. // Read the next TypeId
  402. file.Read ((WORD*)&wTypeId, sizeof(WORD));
  403. }
  404. // Now do we have a VerStamp Offset
  405. if (dwVerStampOffset!=0xffffffff) {
  406. // Let's get the language ID and touch the buffer with the new information
  407. file.Seek (dwVerStampOffset, CFile::begin);
  408. DWORD dwBuffSize = dwVerStampSize;
  409. char * pBuff = new char[dwVerStampSize+1];
  410. char * pTrans = pBuff;
  411. char * pTrans2;
  412. file.Read(pBuff, dwVerStampSize);
  413. while ( pTrans2 = (LPSTR)memchr(pTrans, 'T', dwBuffSize) ) {
  414. dwBuffSize -= (DWORD)(pTrans2 - pTrans);
  415. pTrans = pTrans2;
  416. if (!memcmp( pTrans, "Translation", 11)) {
  417. pTrans = pTrans + 12;
  418. gLang = (WORD)*((WORD*)pTrans);
  419. break;
  420. }
  421. ++pTrans;
  422. dwBuffSize--;
  423. }
  424. delete pBuff;
  425. if (gLang!=0) {
  426. // walk the buffer and change the language id
  427. ChangeLanguage(lpBuffer, uiOverAllSize);
  428. }
  429. }
  430. file.Close();
  431. *puiSize = uiOverAllSize;
  432. return uiError;
  433. }
  434. extern "C"
  435. DWORD
  436. APIENTRY
  437. RWGetImage(
  438. LPCSTR lpszFilename,
  439. DWORD dwImageOffset,
  440. LPVOID lpBuffer,
  441. DWORD dwSize
  442. )
  443. {
  444. UINT uiError = ERROR_NO_ERROR;
  445. BYTE far * lpBuf = (BYTE far *)lpBuffer;
  446. DWORD dwBufSize = dwSize;
  447. // we can consider the use of a CMemFile so we get the same speed as memory access.
  448. CFile file;
  449. // Open the file and try to read the information on the resource in it.
  450. if (!file.Open(lpszFilename, CFile::shareDenyNone | CFile::modeRead | CFile::typeBinary)) {
  451. return (DWORD)ERROR_FILE_OPEN;
  452. }
  453. if ( dwImageOffset!=(DWORD)file.Seek( dwImageOffset, CFile::begin) )
  454. return (DWORD)ERROR_FILE_INVALID_OFFSET;
  455. if (dwSize>UINT_MAX) {
  456. // we have to read the image in different steps
  457. return (DWORD)0L;
  458. } else uiError = file.Read( lpBuf, (UINT)dwSize);
  459. file.Close();
  460. return (DWORD)uiError;
  461. }
  462. extern "C"
  463. UINT
  464. APIENTRY
  465. RWParseImage(
  466. LPCSTR lpszType,
  467. LPVOID lpImageBuf,
  468. DWORD dwImageSize,
  469. LPVOID lpBuffer,
  470. DWORD dwSize
  471. )
  472. {
  473. UINT uiError = ERROR_NO_ERROR;
  474. BYTE far * lpBuf = (BYTE far *)lpBuffer;
  475. DWORD dwBufSize = dwSize;
  476. // The Type we can parse are only the standard ones
  477. // This function should fill the lpBuffer with an array of ResItem structure
  478. switch ((UINT)LOWORD(lpszType)) {
  479. case 1:
  480. uiError = ParseCursor( lpImageBuf, dwImageSize, lpBuffer, dwSize );
  481. break;
  482. case 2:
  483. uiError = ParseBitmap( lpImageBuf, dwImageSize, lpBuffer, dwSize );
  484. break;
  485. case 3:
  486. uiError = ParseIcon( lpImageBuf, dwImageSize, lpBuffer, dwSize );
  487. break;
  488. case 4:
  489. uiError = ParseMenu( lpImageBuf, dwImageSize, lpBuffer, dwSize );
  490. break;
  491. case 5:
  492. uiError = ParseDialog( lpImageBuf, dwImageSize, lpBuffer, dwSize );
  493. break;
  494. case 6:
  495. uiError = ParseString( lpImageBuf, dwImageSize, lpBuffer, dwSize );
  496. break;
  497. case 9:
  498. uiError = ParseAccel( lpImageBuf, dwImageSize, lpBuffer, dwSize );
  499. break;
  500. #ifdef VB
  501. case 10:
  502. uiError = ParseVBData( lpImageBuf, dwImageSize, lpBuffer, dwSize );
  503. break;
  504. #endif
  505. case 16:
  506. uiError = ParseVerst( lpImageBuf, dwImageSize, lpBuffer, dwSize );
  507. break;
  508. default:
  509. break;
  510. }
  511. return uiError;
  512. }
  513. extern"C"
  514. UINT
  515. APIENTRY
  516. RWWriteFile(
  517. LPCSTR lpszSrcFilename,
  518. LPCSTR lpszTgtFilename,
  519. HANDLE hResFileModule,
  520. LPVOID lpBuffer,
  521. UINT uiSize,
  522. HINSTANCE hDllInst,
  523. LPCSTR lpszSymbol
  524. )
  525. {
  526. UINT uiError = ERROR_NO_ERROR;
  527. BYTE far * lpBuf = LPNULL;
  528. UINT uiBufSize = uiSize;
  529. // we can consider the use of a CMemFile so we get the same speed as memory access.
  530. CFile fileIn;
  531. CFile fileOut;
  532. BOOL bfileIn = TRUE;
  533. WORD wTypeId; DWORD dwTypeId;
  534. char szTypeId[128];
  535. WORD wNameId;
  536. char szNameId[128];
  537. DWORD dwSize;
  538. DWORD dwFileOffset;
  539. WORD wUpdTypeId = 0;
  540. static char szUpdTypeId[128];
  541. static char szUpdNameId[128];
  542. UINT uiBufStartSize = uiBufSize;
  543. DWORD dwImageBufSize = 0L;
  544. BYTE far * lpImageBuf = 0L;
  545. WORD wWinHeaderOffset = 0;
  546. WORD wResTableOffset = 0;
  547. WORD wCurTypeOffset = 0;
  548. WORD wFileOffset = 0;
  549. WORD wSize = 0;
  550. WORD wCurNameOffset = 0;
  551. WORD wAlignShift = 0;
  552. WORD wResDataOffset = 0;
  553. WORD wResDataBegin = 0;
  554. WORD wCurResDataBegin = 0;
  555. DWORD dwResDataBegin = 0L;
  556. DWORD dwCurResDataBegin = 0L;
  557. WORD i = 0; short j = 0L; WORD wResCount = 0L;
  558. BYTE nCharCount = 0;
  559. short delta = 0;
  560. WORD wFlags = 0; WORD wLoadOnCallResDataBegin = 0;
  561. WORD wNumOfSegments = 0;
  562. WORD wSegmentTableOffset = 0;
  563. WORD wOffset = 0;
  564. WORD wLoadOnCallCodeBegin = 0;
  565. DWORD dwLoadOnCallCodeBegin = 0L;
  566. DWORD (FAR PASCAL * lpfnGetImage)(HANDLE, LPCSTR, LPCSTR, DWORD, LPVOID, DWORD);
  567. // Open the file and try to read the information on the resource in it.
  568. CFileStatus status;
  569. if (CFile::GetStatus( lpszSrcFilename, status )) {
  570. // check if the size of the file is not null
  571. if (!status.m_size)
  572. CFile::Remove(lpszSrcFilename);
  573. }
  574. if (!fileIn.Open(lpszSrcFilename, CFile::shareDenyNone | CFile::modeRead | CFile::typeBinary))
  575. return GenerateFile(lpszTgtFilename,
  576. hResFileModule,
  577. lpBuffer,
  578. uiSize,
  579. hDllInst
  580. );
  581. if (!fileOut.Open(lpszTgtFilename, CFile::shareDenyNone | CFile::modeWrite | CFile::modeCreate | CFile::typeBinary))
  582. return ERROR_FILE_CREATE;
  583. // Get the handle to the IODLL
  584. hDllInst = LoadLibrary("iodll.dll");
  585. if (!hDllInst)
  586. return ERROR_DLL_LOAD;
  587. // Get the pointer to the function to extract the resources image
  588. lpfnGetImage = (DWORD (FAR PASCAL *)(HANDLE, LPCSTR, LPCSTR, DWORD, LPVOID, DWORD))
  589. GetProcAddress( hDllInst, "RSGetResImage" );
  590. if (lpfnGetImage==NULL) {
  591. FreeLibrary(hDllInst);
  592. return ERROR_DLL_PROC_ADDRESS;
  593. }
  594. // We read the resources from the file and then we check if the resource has been updated
  595. // or if we can just copy it
  596. // Get offset to Windows new header
  597. fileIn.Seek( 0x3c, CFile::begin );
  598. fileIn.Read((WORD*)&wWinHeaderOffset, sizeof(WORD));
  599. // Read and save resource table Offset
  600. fileIn.Seek( wWinHeaderOffset+0x24, CFile::begin );
  601. fileIn.Read ((WORD*)&wResTableOffset, sizeof(WORD));
  602. // Read AlignShift
  603. fileIn.Seek (wWinHeaderOffset+wResTableOffset, CFile::begin);
  604. fileIn.Read ((WORD*)&wAlignShift, sizeof(WORD));
  605. // Get the beginning of the resource data
  606. wResDataBegin = 0xffff;
  607. wLoadOnCallResDataBegin = 0xffff;
  608. fileIn.Read((WORD*)&wTypeId, sizeof(WORD));
  609. while (wTypeId) {
  610. fileIn.Read ((WORD*)&wResCount, sizeof(WORD));
  611. // Pass the reserved DWORD
  612. fileIn.Seek (4, CFile::current);
  613. for (i=0; i<wResCount; i++) {
  614. fileIn.Read ((WORD*)&wResDataOffset, sizeof(WORD));
  615. fileIn.Seek (2, CFile::current);
  616. fileIn.Read ((WORD*)&wFlags, sizeof(WORD));
  617. if (wResDataOffset>0) {
  618. if (wFlags & 0x0040)
  619. wResDataBegin = (wResDataOffset < wResDataBegin) ? wResDataOffset:wResDataBegin;
  620. else
  621. wLoadOnCallResDataBegin = (wResDataOffset < wLoadOnCallResDataBegin) ? wResDataOffset:wLoadOnCallResDataBegin;
  622. }
  623. // Get to next NameInfo record
  624. fileIn.Seek (6, CFile::current);
  625. }
  626. fileIn.Read ((WORD*)&wTypeId, sizeof(WORD));
  627. }
  628. // Copy data before resource data
  629. fileIn.SeekToBegin ();
  630. fileOut.SeekToBegin ();
  631. CopyFile (&fileIn, &fileOut);
  632. if (wResDataBegin != 0xffff) { // If there are PreLoad resources
  633. dwResDataBegin = (MAKELONG (wResDataBegin, 0))<<wAlignShift;
  634. // Read the first type ID
  635. fileIn.Seek (wWinHeaderOffset+wResTableOffset+2, CFile::begin);
  636. fileIn.Read ((WORD*)&wTypeId, sizeof(WORD));
  637. // Save the Offset of the current TypeInfo record
  638. wCurTypeOffset = wWinHeaderOffset + wResTableOffset + 2;
  639. // Save the beginning of current resource data
  640. dwCurResDataBegin = dwResDataBegin;
  641. // Loop through the TypeInfo table to write PreLoad resources
  642. while (wTypeId) {
  643. // Get Name of ord
  644. if (!(wTypeId & 0x8000)) {
  645. // It is a Offset to a string
  646. dwTypeId = (MAKELONG(wTypeId, 0)); //<<wAlignShift;
  647. fileIn.Seek (wWinHeaderOffset+wResTableOffset+dwTypeId, CFile::begin);
  648. // Get the character count for the ID string
  649. fileIn.Read ((BYTE*)&nCharCount, sizeof(BYTE));
  650. // Read the ID string
  651. fileIn.Read (szTypeId, nCharCount);
  652. // Put null at the end of the string
  653. szTypeId[nCharCount] = 0;
  654. // Set wTypeId to zero
  655. wTypeId = 0;
  656. } else {
  657. // It is an ID
  658. // Turn off the high bit
  659. wTypeId = wTypeId & 0x7FFF;
  660. if (0 == wTypeId)
  661. return ERROR_RW_INVALID_FILE;
  662. // Set the ID string to null
  663. szTypeId[0] = 0;
  664. }
  665. // Restore the file read point
  666. fileIn.Seek (wCurTypeOffset+2, CFile::begin);
  667. // Get the count for this type of resource
  668. fileIn.Read ((WORD*)&wResCount, sizeof(WORD));
  669. // Pass the reserved DWORD
  670. fileIn.Seek (4, CFile::current);
  671. // Save the Offset of the current NameInfo record
  672. wCurNameOffset = wCurTypeOffset + 8;
  673. // Loop through NameInfo records
  674. for (i = 0; i < wResCount; i++) {
  675. // Read resource offset
  676. fileIn.Read ((WORD*)&wFileOffset, sizeof(WORD));
  677. // Read resource length
  678. fileIn.Read ((WORD*)&wSize, sizeof(WORD));
  679. // Read the flags
  680. fileIn.Read ((WORD*)&wFlags, sizeof(WORD));
  681. // Read resource ID
  682. fileIn.Read ((WORD*)&wNameId, sizeof(WORD));
  683. if (wFlags & 0x0040) {
  684. // Get name of ord
  685. if (!(wNameId & 0x8000)) {
  686. // It is a Offset to a string
  687. fileIn.Seek (wWinHeaderOffset+wResTableOffset+wNameId, CFile::begin);
  688. // Get the character count for the string
  689. fileIn.Read ((BYTE*)&nCharCount, sizeof(BYTE));
  690. // Read the string
  691. fileIn.Read (szNameId, nCharCount);
  692. // Put null at the end of the string
  693. szNameId[nCharCount] = 0;
  694. // Set wNameId to zero
  695. wNameId = 0;
  696. } else {
  697. // It is an ID
  698. // Turn off the high bit
  699. wNameId = wNameId & 0x7FFF;
  700. if ( 0 == wNameId)
  701. return ERROR_RW_INVALID_FILE;
  702. // Set the string to null
  703. szNameId[0] = 0;
  704. }
  705. dwSize = (MAKELONG (wSize, 0))<<wAlignShift;
  706. dwFileOffset = (MAKELONG (wFileOffset, 0))<<wAlignShift;
  707. // Now we got the Type and Name here and size
  708. // Get the image from the IODLL
  709. if (dwSize)
  710. lpImageBuf = new BYTE[dwSize];
  711. else lpImageBuf = LPNULL;
  712. LPSTR lpType = LPNULL;
  713. LPSTR lpRes = LPNULL;
  714. if (wTypeId)
  715. lpType = (LPSTR)((WORD)wTypeId);
  716. else
  717. lpType = &szTypeId[0];
  718. if (wNameId)
  719. lpRes = (LPSTR)((WORD)wNameId);
  720. else
  721. lpRes = &szNameId[0];
  722. dwImageBufSize = (*lpfnGetImage)( hResFileModule,
  723. lpType,
  724. lpRes,
  725. (DWORD)-1,
  726. lpImageBuf,
  727. dwSize
  728. );
  729. if (dwImageBufSize>dwSize ) {
  730. // The buffer is too small
  731. delete []lpImageBuf;
  732. lpImageBuf = new BYTE[dwImageBufSize];
  733. dwSize = (*lpfnGetImage)( hResFileModule,
  734. lpType,
  735. lpRes,
  736. (DWORD)-1,
  737. lpImageBuf,
  738. dwImageBufSize
  739. );
  740. if ((dwSize-dwImageBufSize)!=0 ) {
  741. delete []lpImageBuf;
  742. lpImageBuf = LPNULL;
  743. }
  744. }
  745. // Try to see if we have to set the memory to 0
  746. if ((int)(dwSize-dwImageBufSize)>0)
  747. memset(lpImageBuf+dwImageBufSize, 0, (size_t)(dwSize-dwImageBufSize));
  748. // Write the image
  749. fileOut.Seek (dwCurResDataBegin, CFile::begin);
  750. WriteImage( &fileOut, lpImageBuf, dwSize);
  751. // Fix the alignment for resource data
  752. delta = (short)((((dwSize+(1<<wAlignShift)-1)>>wAlignShift)<<wAlignShift)-dwSize);
  753. BYTE nByte = 0;
  754. fileOut.Seek (dwCurResDataBegin+dwSize, CFile::begin);
  755. for (j=0; j<delta; j++)
  756. fileOut.Write ((BYTE*)&nByte, sizeof(BYTE));
  757. dwSize = dwSize + MAKELONG(delta, 0);
  758. // Fixup the resource table
  759. fileOut.Seek (wCurNameOffset, CFile::begin);
  760. wCurResDataBegin = LOWORD(dwCurResDataBegin>>wAlignShift);
  761. fileOut.Write ((WORD*)&wCurResDataBegin, sizeof(WORD));
  762. wSize = LOWORD (dwSize>>wAlignShift);
  763. fileOut.Write ((WORD*)&wSize, sizeof(WORD));
  764. if (lpImageBuf) delete []lpImageBuf;
  765. // Update the current resource data beginning
  766. dwCurResDataBegin = dwCurResDataBegin + dwSize;
  767. }
  768. // Update the current NameInfo record offset
  769. wCurNameOffset = wCurNameOffset + 12;
  770. // Move file pointer to the next NameInfo record
  771. fileIn.Seek (wCurNameOffset, CFile::begin);
  772. }
  773. // Update the current TypeInfo record offset
  774. wCurTypeOffset = wCurTypeOffset + 8 + wResCount * 12;
  775. // Move file pointer to the next TypeInfo record
  776. fileIn.Seek (wCurTypeOffset, CFile::begin);
  777. // Read the next TypeId
  778. fileIn.Read ((WORD*)&wTypeId, sizeof(WORD));
  779. }
  780. }
  781. // Get segment table offset
  782. fileIn.Seek (wWinHeaderOffset+0x001c, CFile::begin);
  783. fileIn.Read ((WORD*)&wNumOfSegments, sizeof(WORD));
  784. fileIn.Seek (wWinHeaderOffset+0x0022, CFile::begin);
  785. fileIn.Read ((WORD*)&wSegmentTableOffset, sizeof(WORD));
  786. // Find the beginning of the LoadOnCall code segments in the src exe file
  787. wLoadOnCallCodeBegin = 0xffff;
  788. for (i=0; i<wNumOfSegments; i++) {
  789. fileIn.Seek (wWinHeaderOffset+wSegmentTableOffset+8*i+4, CFile::begin);
  790. fileIn.Read ((WORD*)&wFlags, sizeof(WORD));
  791. if (!(wFlags & 0x0040)) {
  792. fileIn.Seek (wWinHeaderOffset+wSegmentTableOffset+8*i, CFile::begin);
  793. fileIn.Read ((WORD*)&wOffset, sizeof(WORD));
  794. // In the file winoa386.mod we have a LoadOnCall segment that doesn't exist.
  795. // We have to check for this before go on
  796. if (wOffset)
  797. wLoadOnCallCodeBegin = (wOffset < wLoadOnCallCodeBegin) ? wOffset:wLoadOnCallCodeBegin;
  798. }
  799. }
  800. // Calculate the delta between the new beginning and the old beginnning
  801. // of the LoadOnCall code segments
  802. if (wResDataBegin != 0xffff && wLoadOnCallCodeBegin != 0xffff) { // Both LoadOnCall code and FastLoad
  803. wCurResDataBegin = LOWORD(dwCurResDataBegin>>wAlignShift);
  804. delta = wCurResDataBegin - wLoadOnCallCodeBegin;
  805. } else if (wResDataBegin != 0xffff && wLoadOnCallResDataBegin != 0xffff) { // Both LoadOnCall and FastLoad Resources
  806. wCurResDataBegin = LOWORD(dwCurResDataBegin>>wAlignShift);
  807. delta = wCurResDataBegin - wLoadOnCallResDataBegin;
  808. } else if (wResDataBegin != 0xffff) { // Only FastLoad Resources
  809. wCurResDataBegin = LOWORD((dwCurResDataBegin-dwSize)>>wAlignShift);
  810. delta = wCurResDataBegin - wResDataBegin;
  811. } else delta = 0;
  812. dwLoadOnCallCodeBegin = MAKELONG (wLoadOnCallCodeBegin, 0) << wAlignShift;
  813. // Change the length for preload area
  814. if (wResDataBegin != 0xffff) {
  815. fileIn.Seek (wWinHeaderOffset+0x003a, CFile::begin);
  816. fileIn.Read ((WORD*)&wOffset, sizeof(WORD));
  817. wOffset += delta;
  818. fileOut.Seek (wWinHeaderOffset+0x003a, CFile::begin);
  819. fileOut.Write ((WORD*)&wOffset, sizeof(WORD));
  820. }
  821. if (wLoadOnCallCodeBegin != 0xffff && delta) {
  822. // Write LoadOnCall segments
  823. fileIn.Seek (dwLoadOnCallCodeBegin, CFile::begin);
  824. fileOut.Seek (dwCurResDataBegin, CFile::begin);
  825. LONG lLeft;
  826. if (wLoadOnCallResDataBegin != 0xffff)
  827. lLeft = MAKELONG (wLoadOnCallResDataBegin - wLoadOnCallCodeBegin, 0) << wAlignShift;
  828. else
  829. lLeft = (fileIn.GetLength () - (MAKELONG (wLoadOnCallCodeBegin, 0))) << wAlignShift;
  830. WORD wRead = 0;
  831. BYTE far * pBuf = (BYTE far *) new BYTE[32739];
  832. if (!pBuf) {
  833. FreeLibrary(hDllInst);
  834. return ERROR_NEW_FAILED;
  835. }
  836. while (lLeft>0) {
  837. wRead =(WORD) (32738ul < lLeft ? 32738: lLeft);
  838. if (wRead!= fileIn.Read( pBuf, wRead)) {
  839. delete []pBuf;
  840. FreeLibrary(hDllInst);
  841. return ERROR_FILE_READ;
  842. }
  843. fileOut.Write( pBuf, wRead );
  844. lLeft -= wRead;
  845. }
  846. delete []pBuf;
  847. // Fixup the segment table
  848. for (i=0; i<wNumOfSegments; i++) {
  849. fileIn.Seek (wWinHeaderOffset+wSegmentTableOffset+8*i+4, CFile::begin);
  850. fileIn.Read ((WORD*)&wFlags, sizeof(WORD));
  851. if (!(wFlags & 0x0040)) {
  852. fileIn.Seek (wWinHeaderOffset+wSegmentTableOffset+8*i, CFile::begin);
  853. fileIn.Read ((WORD*)&wOffset, sizeof(WORD));
  854. wOffset = wOffset + delta;
  855. fileOut.Seek (wWinHeaderOffset+wSegmentTableOffset+8*i, CFile::begin);
  856. fileOut.Write ((WORD*)&wOffset, sizeof(WORD));
  857. }
  858. }
  859. }
  860. if (wLoadOnCallResDataBegin != 0xffff) {
  861. // Read the first type ID again
  862. fileIn.Seek (wWinHeaderOffset+wResTableOffset+2, CFile::begin);
  863. fileIn.Read ((WORD*)&wTypeId, sizeof(WORD));
  864. // Save the Offset of the current TypeInfo record
  865. wCurTypeOffset = wWinHeaderOffset + wResTableOffset + 2;
  866. // Calc the beginning of the LoadOnCall resources
  867. dwCurResDataBegin = (MAKELONG (wLoadOnCallResDataBegin + delta, 0))<<wAlignShift;
  868. // Loop through the TypeInfo table again to write LoadOnCall resources
  869. while (wTypeId) {
  870. // Get Name of ord
  871. if (!(wTypeId & 0x8000)) {
  872. // It is a Offset to a string
  873. dwTypeId = (MAKELONG(wTypeId, 0)); //<<wAlignShift;
  874. fileIn.Seek (wWinHeaderOffset+wResTableOffset+dwTypeId, CFile::begin);
  875. // Get the character count for the ID string
  876. fileIn.Read ((BYTE*)&nCharCount, sizeof(BYTE));
  877. // Read the ID string
  878. fileIn.Read (szTypeId, nCharCount);
  879. // Put null at the end of the string
  880. szTypeId[nCharCount] = 0;
  881. // Set wTypeId to zero
  882. wTypeId = 0;
  883. } else {
  884. // It is an ID
  885. // Turn off the high bit
  886. wTypeId = wTypeId & 0x7FFF;
  887. if ( 0 == wTypeId)
  888. return ERROR_RW_INVALID_FILE;
  889. // Set the ID string to null
  890. szTypeId[0] = 0;
  891. }
  892. // Restore the file read point
  893. fileIn.Seek (wCurTypeOffset+2, CFile::begin);
  894. // Get the count for this type of resource
  895. fileIn.Read ((WORD*)&wResCount, sizeof(WORD));
  896. // Pass the reserved DWORD
  897. fileIn.Seek (4, CFile::current);
  898. // Save the Offset of the current NameInfo record
  899. wCurNameOffset = wCurTypeOffset + 8;
  900. // Loop through NameInfo records
  901. for (i = 0; i < wResCount; i++) {
  902. // Read resource offset
  903. fileIn.Read ((WORD*)&wFileOffset, sizeof(WORD));
  904. // Read resource length
  905. fileIn.Read ((WORD*)&wSize, sizeof(WORD));
  906. // Read the flags
  907. fileIn.Read ((WORD*)&wFlags, sizeof(WORD));
  908. // Read resource ID
  909. fileIn.Read ((WORD*)&wNameId, sizeof(WORD));
  910. if (!(wFlags & 0x0040)) {
  911. // Get name of ord
  912. if (!(wNameId & 0x8000)) {
  913. // It is a Offset to a string
  914. fileIn.Seek (wWinHeaderOffset+wResTableOffset+wNameId, CFile::begin);
  915. // Get the character count for the string
  916. fileIn.Read ((BYTE*)&nCharCount, sizeof(BYTE));
  917. // Read the string
  918. fileIn.Read (szNameId, nCharCount);
  919. // Put null at the end of the string
  920. szNameId[nCharCount] = 0;
  921. // Set wNameId to zero
  922. wNameId = 0;
  923. } else {
  924. // It is an ID
  925. // Turn off the high bit
  926. wNameId = wNameId & 0x7FFF;
  927. if (0 == wNameId)
  928. return ERROR_RW_INVALID_FILE;
  929. // Set the string to null
  930. szNameId[0] = 0;
  931. }
  932. dwSize = (MAKELONG (wSize, 0))<<wAlignShift;
  933. dwFileOffset = (MAKELONG (wFileOffset, 0))<<wAlignShift;
  934. // Now we got the Type and Name here and size
  935. // Get the image from the IODLL
  936. if (dwSize)
  937. lpImageBuf = new BYTE[dwSize];
  938. else lpImageBuf = LPNULL;
  939. LPSTR lpType = LPNULL;
  940. LPSTR lpRes = LPNULL;
  941. if (wTypeId)
  942. lpType = (LPSTR)((WORD)wTypeId);
  943. else
  944. lpType = &szTypeId[0];
  945. if (wNameId)
  946. lpRes = (LPSTR)((WORD)wNameId);
  947. else
  948. lpRes = &szNameId[0];
  949. dwImageBufSize = (*lpfnGetImage)( hResFileModule,
  950. lpType,
  951. lpRes,
  952. (DWORD)-1,
  953. lpImageBuf,
  954. dwSize
  955. );
  956. if (dwImageBufSize>dwSize ) {
  957. // The buffer is too small
  958. delete []lpImageBuf;
  959. lpImageBuf = new BYTE[dwImageBufSize];
  960. dwSize = (*lpfnGetImage)( hResFileModule,
  961. lpType,
  962. lpRes,
  963. (DWORD)-1,
  964. lpImageBuf,
  965. dwImageBufSize
  966. );
  967. if ((dwSize-dwImageBufSize)!=0 ) {
  968. delete []lpImageBuf;
  969. lpImageBuf = LPNULL;
  970. }
  971. }
  972. // Try to see if we have to set the memory to 0
  973. if ((int)(dwSize-dwImageBufSize)>0)
  974. memset(lpImageBuf+dwImageBufSize, 0, (size_t)(dwSize-dwImageBufSize));
  975. // Write the image
  976. fileOut.Seek (dwCurResDataBegin, CFile::begin);
  977. WriteImage( &fileOut, lpImageBuf, dwSize);
  978. // Fix the alignment for resource data
  979. DWORD dwTmp = 1;
  980. delta = (short)((((dwSize+(dwTmp<<wAlignShift)-1)>>wAlignShift)<<wAlignShift)-dwSize);
  981. BYTE nByte = 0;
  982. fileOut.Seek (dwCurResDataBegin+dwSize, CFile::begin);
  983. for (j=0; j<delta; j++)
  984. fileOut.Write ((BYTE*)&nByte, sizeof(BYTE));
  985. dwSize = dwSize + MAKELONG(delta, 0);
  986. // Fixup the resource table
  987. fileOut.Seek (wCurNameOffset, CFile::begin);
  988. wCurResDataBegin = LOWORD(dwCurResDataBegin>>wAlignShift);
  989. fileOut.Write ((WORD*)&wCurResDataBegin, sizeof(WORD));
  990. wSize = LOWORD (dwSize>>wAlignShift);
  991. fileOut.Write ((WORD*)&wSize, sizeof(WORD));
  992. if (lpImageBuf) delete []lpImageBuf;
  993. // Update the current resource data beginning
  994. dwCurResDataBegin = dwCurResDataBegin + dwSize;
  995. }
  996. // Update the current NameInfo record offset
  997. wCurNameOffset = wCurNameOffset + 12;
  998. // Move file pointer to the next NameInfo record
  999. fileIn.Seek (wCurNameOffset, CFile::begin);
  1000. }
  1001. // Update the current TypeInfo record offset
  1002. wCurTypeOffset = wCurTypeOffset + 8 + wResCount * 12;
  1003. // Move file pointer to the next TypeInfo record
  1004. fileIn.Seek (wCurTypeOffset, CFile::begin);
  1005. // Read the next TypeId
  1006. fileIn.Read ((WORD*)&wTypeId, sizeof(WORD));
  1007. }
  1008. }
  1009. fileIn.Close();
  1010. fileOut.Close();
  1011. FreeLibrary(hDllInst);
  1012. return uiError;
  1013. }
  1014. extern "C"
  1015. UINT
  1016. APIENTRY
  1017. RWUpdateImage(
  1018. LPCSTR lpszType,
  1019. LPVOID lpNewBuf,
  1020. DWORD dwNewSize,
  1021. LPVOID lpOldImage,
  1022. DWORD dwOldImageSize,
  1023. LPVOID lpNewImage,
  1024. DWORD* pdwNewImageSize
  1025. )
  1026. {
  1027. UINT uiError = ERROR_NO_ERROR;
  1028. // The Type we can parse are only the standard ones
  1029. switch ((UINT)LOWORD(lpszType)) {
  1030. case 4:
  1031. if (lpOldImage)
  1032. uiError = UpdateMenu( lpNewBuf, dwNewSize,
  1033. lpOldImage, dwOldImageSize,
  1034. lpNewImage, pdwNewImageSize );
  1035. else uiError = GenerateMenu( lpNewBuf, dwNewSize,
  1036. lpNewImage, pdwNewImageSize );
  1037. break;
  1038. case 5:
  1039. if (lpOldImage)
  1040. uiError = UpdateDialog( lpNewBuf, dwNewSize,
  1041. lpOldImage, dwOldImageSize,
  1042. lpNewImage, pdwNewImageSize );
  1043. else uiError = GenerateDialog( lpNewBuf, dwNewSize,
  1044. lpNewImage, pdwNewImageSize );
  1045. break;
  1046. case 6:
  1047. if (lpOldImage)
  1048. uiError = UpdateString( lpNewBuf, dwNewSize,
  1049. lpOldImage, dwOldImageSize,
  1050. lpNewImage, pdwNewImageSize );
  1051. else uiError = GenerateString( lpNewBuf, dwNewSize,
  1052. lpNewImage, pdwNewImageSize );
  1053. break;
  1054. case 9:
  1055. if (lpOldImage)
  1056. uiError = UpdateAccel( lpNewBuf, dwNewSize,
  1057. lpOldImage, dwOldImageSize,
  1058. lpNewImage, pdwNewImageSize );
  1059. else {
  1060. *pdwNewImageSize = 0L;
  1061. uiError = ERROR_RW_NOTREADY;
  1062. }
  1063. break;
  1064. #ifdef VB
  1065. case 10:
  1066. if (lpOldImage)
  1067. uiError = UpdateVBData( lpNewBuf, dwNewSize,
  1068. lpOldImage, dwOldImageSize,
  1069. lpNewImage, pdwNewImageSize );
  1070. else {
  1071. *pdwNewImageSize = 0L;
  1072. uiError = ERROR_RW_NOTREADY;
  1073. }
  1074. break;
  1075. #endif
  1076. case 16:
  1077. if (lpOldImage)
  1078. uiError = UpdateVerst( lpNewBuf, dwNewSize,
  1079. lpOldImage, dwOldImageSize,
  1080. lpNewImage, pdwNewImageSize );
  1081. else {
  1082. *pdwNewImageSize = 0L;
  1083. uiError = ERROR_RW_NOTREADY;
  1084. }
  1085. break;
  1086. default:
  1087. *pdwNewImageSize = 0L;
  1088. uiError = ERROR_RW_NOTREADY;
  1089. break;
  1090. }
  1091. return uiError;
  1092. }
  1093. ///////////////////////////////////////////////////////////////////////////
  1094. // Functions implementation
  1095. static UINT GenerateFile( LPCSTR lpszTgtFilename,
  1096. HANDLE hResFileModule,
  1097. LPVOID lpBuffer,
  1098. UINT uiSize,
  1099. HINSTANCE hDllInst
  1100. )
  1101. {
  1102. UINT uiError = ERROR_NO_ERROR;
  1103. BYTE far * lpBuf = LPNULL;
  1104. UINT uiBufSize = uiSize;
  1105. // we can consider the use of a CMemFile so we get the same speed as memory access.
  1106. CFile fileOut;
  1107. if (!fileOut.Open(lpszTgtFilename, CFile::shareDenyNone | CFile::modeWrite | CFile::modeCreate | CFile::typeBinary))
  1108. return ERROR_FILE_CREATE;
  1109. // Get the pointer to the function
  1110. if (!hDllInst)
  1111. return ERROR_DLL_LOAD;
  1112. DWORD (FAR PASCAL * lpfnGetImage)(HANDLE, LPCSTR, LPCSTR, DWORD, LPVOID, DWORD);
  1113. // Get the pointer to the function to extract the resources image
  1114. lpfnGetImage = (DWORD (FAR PASCAL *)(HANDLE, LPCSTR, LPCSTR, DWORD, LPVOID, DWORD))
  1115. GetProcAddress( hDllInst, "RSGetResImage" );
  1116. if (lpfnGetImage==NULL) {
  1117. return ERROR_DLL_PROC_ADDRESS;
  1118. }
  1119. WORD wUpdTypeId = 0;
  1120. static char szUpdTypeId[128];
  1121. WORD wUpdNameId;
  1122. static char szUpdNameId[128];
  1123. DWORD dwUpdLang;
  1124. DWORD dwUpdSize;
  1125. UINT uiBufStartSize = uiBufSize;
  1126. DWORD dwImageBufSize;
  1127. BYTE far * lpImageBuf;
  1128. while (uiBufSize>0) {
  1129. if ((!wUpdTypeId) && (uiBufSize))
  1130. GetUpdatedRes( &lpBuffer,
  1131. &uiBufSize,
  1132. &wUpdTypeId, &szUpdTypeId[0],
  1133. &wUpdNameId, &szUpdNameId[0],
  1134. &dwUpdLang,
  1135. &dwUpdSize
  1136. );
  1137. // The resource has been updated get the image from the IODLL
  1138. if (dwUpdSize) {
  1139. lpImageBuf = new BYTE[dwUpdSize];
  1140. LPSTR lpType = LPNULL;
  1141. LPSTR lpRes = LPNULL;
  1142. if (wUpdTypeId) {
  1143. lpType = (LPSTR)((WORD)wUpdTypeId);
  1144. } else {
  1145. lpType = &szUpdTypeId[0];
  1146. }
  1147. if (wUpdNameId) {
  1148. lpRes = (LPSTR)((WORD)wUpdNameId);
  1149. } else {
  1150. lpRes = &szUpdNameId[0];
  1151. }
  1152. dwImageBufSize = (*lpfnGetImage)( hResFileModule,
  1153. lpType,
  1154. lpRes,
  1155. dwUpdLang,
  1156. lpImageBuf,
  1157. dwUpdSize
  1158. );
  1159. if (dwImageBufSize>dwUpdSize ) {
  1160. // The buffer is too small
  1161. delete []lpImageBuf;
  1162. lpImageBuf = new BYTE[dwImageBufSize];
  1163. dwUpdSize = (*lpfnGetImage)( hResFileModule,
  1164. lpType,
  1165. lpRes,
  1166. dwUpdLang,
  1167. lpImageBuf,
  1168. dwImageBufSize
  1169. );
  1170. if ((dwUpdSize-dwImageBufSize)!=0 ) {
  1171. delete []lpImageBuf;
  1172. lpImageBuf = LPNULL;
  1173. }
  1174. }
  1175. WriteHeader(&fileOut,
  1176. wUpdTypeId, &szUpdTypeId[0],
  1177. wUpdNameId, &szUpdNameId[0],
  1178. 0l);
  1179. WriteImage( &fileOut,
  1180. lpImageBuf, dwImageBufSize);
  1181. if (lpImageBuf) delete []lpImageBuf;
  1182. wUpdTypeId = 0;
  1183. } else wUpdTypeId = 0;
  1184. }
  1185. fileOut.Close();
  1186. return uiError;
  1187. }
  1188. static UINT CopyFile( CFile* pfilein, CFile* pfileout )
  1189. {
  1190. LONG lLeft = pfilein->GetLength();
  1191. WORD wRead = 0;
  1192. DWORD dwOffset = 0;
  1193. BYTE far * pBuf = (BYTE far *) new BYTE[32739];
  1194. if (!pBuf)
  1195. return ERROR_NEW_FAILED;
  1196. while (lLeft>0) {
  1197. wRead =(WORD) (32738ul < lLeft ? 32738: lLeft);
  1198. if (wRead!= pfilein->Read( pBuf, wRead)) {
  1199. delete []pBuf;
  1200. return ERROR_FILE_READ;
  1201. }
  1202. pfileout->Write( pBuf, wRead );
  1203. lLeft -= wRead;
  1204. dwOffset += wRead;
  1205. }
  1206. delete []pBuf;
  1207. return ERROR_NO_ERROR;
  1208. }
  1209. static UINT GetUpdatedRes(
  1210. LPVOID far * lplpBuffer,
  1211. UINT* uiSize,
  1212. WORD* wTypeId, LPSTR lplpszTypeId,
  1213. WORD* wNameId, LPSTR lplpszNameId,
  1214. DWORD* dwLang, DWORD* dwSize )
  1215. {
  1216. BYTE far * lpBuf = (BYTE far *)*lplpBuffer;
  1217. *wTypeId = *((WORD*)lpBuf);
  1218. lpBuf += sizeofWord;
  1219. strcpy( lplpszTypeId, (char *)lpBuf);
  1220. lpBuf += strlen(lplpszTypeId)+1;
  1221. *wNameId = *((WORD*)lpBuf);
  1222. lpBuf += sizeofWord;
  1223. strcpy( lplpszNameId, (char *)lpBuf);
  1224. lpBuf += strlen(lplpszNameId)+1;
  1225. *dwLang = *((DWORD*)lpBuf);
  1226. lpBuf += sizeofDWord;
  1227. *dwSize = *((DWORD*)lpBuf);
  1228. lpBuf += sizeofDWord;
  1229. *uiSize -= (UINT)((lpBuf-(BYTE far *)*lplpBuffer));
  1230. *lplpBuffer = (LPVOID)lpBuf;
  1231. return 0;
  1232. }
  1233. static
  1234. UINT
  1235. GetUpdatedItem(
  1236. LPVOID far * lplpBuffer,
  1237. LONG* dwSize,
  1238. WORD* wX, WORD* wY,
  1239. WORD* wcX, WORD* wcY,
  1240. DWORD* dwPosId,
  1241. DWORD* dwStyle, DWORD* dwExtStyle,
  1242. LPSTR lpszText)
  1243. {
  1244. BYTE far * far * lplpBuf = (BYTE far * far *)lplpBuffer;
  1245. UINT uiSize = GetWord( lplpBuf, wX, dwSize );
  1246. uiSize += GetWord( lplpBuf, wY, dwSize );
  1247. uiSize += GetWord( lplpBuf, wcX, dwSize );
  1248. uiSize += GetWord( lplpBuf, wcY, dwSize );
  1249. uiSize += GetDWord( lplpBuf, dwPosId, dwSize );
  1250. uiSize += GetDWord( lplpBuf, dwStyle, dwSize );
  1251. uiSize += GetDWord( lplpBuf, dwExtStyle, dwSize );
  1252. uiSize += GetString( lplpBuf, lpszText, dwSize );
  1253. return uiSize;
  1254. /*
  1255. *wX = *((WORD*)lpBuf);
  1256. lpBuf += sizeofWord;
  1257. *wY = *((WORD*)lpBuf);
  1258. lpBuf += sizeofWord;
  1259. *wcX = *((WORD*)lpBuf);
  1260. lpBuf += sizeofWord;
  1261. *wcY = *((WORD*)lpBuf);
  1262. lpBuf += sizeofWord;
  1263. *dwPosId = *((DWORD*)lpBuf);
  1264. lpBuf += sizeofDWord;
  1265. *dwStyle = *((DWORD*)lpBuf);
  1266. lpBuf += sizeofDWord;
  1267. *dwExtStyle = *((DWORD*)lpBuf);
  1268. lpBuf += sizeofDWord;
  1269. strcpy( lpszText, (char *)lpBuf);
  1270. lpBuf += strlen(lpszText)+1;
  1271. *dwSize -= (lpBuf-(BYTE far *)*lplpBuffer);
  1272. *lplpBuffer = lpBuf;
  1273. return 0;*/
  1274. }
  1275. static UINT
  1276. GetResInfo( CFile* pfile,
  1277. WORD* pwTypeId, LPSTR lpszTypeId, BYTE bMaxTypeLen,
  1278. WORD* pwNameId, LPSTR lpszNameId, BYTE bMaxNameLen,
  1279. WORD* pwFlags,
  1280. DWORD* pdwSize, DWORD* pdwFileOffset )
  1281. {
  1282. static UINT uiSize;
  1283. static LONG lOfsCheck;
  1284. // get the Type info
  1285. uiSize = GetNameOrOrdFile( pfile, pwTypeId, lpszTypeId, bMaxTypeLen);
  1286. if (!uiSize)
  1287. return 0;
  1288. // get the Name info
  1289. uiSize = GetNameOrOrdFile( pfile, pwNameId, lpszNameId, bMaxNameLen);
  1290. if (!uiSize)
  1291. return 0;
  1292. // Skip the Flag
  1293. pfile->Read( pwFlags, 2 );
  1294. // get the size
  1295. pfile->Read( pdwSize, 4 );
  1296. if (*pdwSize==0)
  1297. // size id 0 the resource file is corrupted or is not a res file
  1298. return 0;
  1299. *pdwFileOffset = pfile->GetPosition();
  1300. // check if the size is valid
  1301. TRY {
  1302. lOfsCheck = pfile->Seek(*pdwSize, CFile::current);
  1303. } CATCH(CFileException, e) {
  1304. // Check is the right exception
  1305. return 0;
  1306. } END_CATCH
  1307. if (lOfsCheck!=(LONG)(*pdwFileOffset+*pdwSize))
  1308. return 0;
  1309. return 1;
  1310. }
  1311. static UINT WriteHeader(
  1312. CFile* pFile,
  1313. WORD wTypeId, LPSTR lpszTypeId,
  1314. WORD wNameId, LPSTR lpszNameId,
  1315. WORD wFlags )
  1316. {
  1317. UINT uiError = ERROR_NO_ERROR;
  1318. BYTE bFF = 0xFF;
  1319. if (wTypeId) {
  1320. // It is an ordinal
  1321. pFile->Write( &bFF, 1 );
  1322. pFile->Write( &wTypeId, 2 );
  1323. } else {
  1324. pFile->Write( lpszTypeId, strlen(lpszTypeId)+1 );
  1325. }
  1326. if (wNameId) {
  1327. // It is an ordinal
  1328. pFile->Write( &bFF, 1 );
  1329. pFile->Write( &wNameId, 2 );
  1330. } else {
  1331. pFile->Write( lpszNameId, strlen(lpszNameId)+1 );
  1332. }
  1333. pFile->Write( &wFlags, 2 );
  1334. return uiError;
  1335. }
  1336. static UINT WriteImage(
  1337. CFile* pFile,
  1338. LPVOID lpImage, DWORD dwSize )
  1339. {
  1340. UINT uiError = ERROR_NO_ERROR;
  1341. if (lpImage) {
  1342. // pFile->Write( &dwSize, sizeofDWord );
  1343. pFile->Write( lpImage, (UINT)dwSize );
  1344. }
  1345. return uiError;
  1346. }
  1347. ////////////////////////////////////////////////////////////////////////////
  1348. // Helper Function Implementation
  1349. static UINT GetNameOrOrdFile( CFile* pfile, WORD* pwId, LPSTR lpszId, BYTE bMaxStrLen )
  1350. {
  1351. UINT uiSize = 0;
  1352. *pwId = 0;
  1353. // read the first BYTE to see if it is a string or an ordinal
  1354. pfile->Read( pwId, sizeof(BYTE) );
  1355. if (LOBYTE(*pwId)==0xFF) {
  1356. // This is an Ordinal
  1357. pfile->Read( pwId, sizeofWord );
  1358. *lpszId = '\0';
  1359. uiSize = 2;
  1360. } else {
  1361. uiSize++;
  1362. *lpszId = LOBYTE(*pwId);
  1363. while ((*lpszId++) && (bMaxStrLen-2)) {
  1364. pfile->Read( pwId, sizeof(BYTE) );
  1365. *lpszId = LOBYTE(*pwId);
  1366. uiSize++;
  1367. bMaxStrLen--;
  1368. }
  1369. if ( (!(bMaxStrLen-2)) && (*pwId) ) {
  1370. // Failed
  1371. return 0;
  1372. }
  1373. }
  1374. return uiSize;
  1375. }
  1376. static
  1377. UINT
  1378. ParseCursor( LPVOID lpImageBuf, DWORD dwISize, LPVOID lpBuffer, DWORD dwSize )
  1379. {
  1380. // Should be almost impossible for a Cursor to be Huge
  1381. BYTE far * lpImage = (BYTE far *)lpImageBuf;
  1382. LONG dwImageSize = dwISize;
  1383. BYTE far * lpBuf = (BYTE far *)lpBuffer;
  1384. LONG dwBufSize = dwSize;
  1385. BYTE far * lpItem = (BYTE far *)lpBuffer;
  1386. UINT uiOffset = 0;
  1387. LONG dwOverAllSize = 0L;
  1388. // Cursor Items
  1389. WORD wWidth = 0;
  1390. WORD wHeight = 0;
  1391. WORD wPlanes = 0;
  1392. WORD wBitCount = 0;
  1393. DWORD dwBytesInRes = 0;
  1394. WORD wImageIndex = 0;
  1395. // Get the CURSOR DIR ENTRY
  1396. GetWord( &lpImage, &wWidth, &dwImageSize );
  1397. GetWord( &lpImage, &wHeight, &dwImageSize );
  1398. GetWord( &lpImage, &wPlanes, &dwImageSize );
  1399. GetWord( &lpImage, &wBitCount, &dwImageSize );
  1400. GetDWord( &lpImage, &dwBytesInRes, &dwImageSize );
  1401. GetWord( &lpImage, &wImageIndex, &dwImageSize );
  1402. //SkipByte( &lpImage, 4, &dwImageSize );
  1403. //BITMAPINFO
  1404. BITMAPINFOHEADER* pBmpInfHead = (BITMAPINFOHEADER*) lpImage;
  1405. UINT uiSize = sizeof(BITMAPINFOHEADER);
  1406. SkipByte( &lpImage, uiSize, &dwImageSize );
  1407. /*
  1408. // Get the Width
  1409. SkipByte( &lpImage, 4, &dwImageSize );
  1410. // Menu Items
  1411. WORD fItemFlags;
  1412. WORD wMenuId;
  1413. CString szCaption;
  1414. while(dwImageSize>0) {
  1415. // Fixed field
  1416. dwOverAllSize += PutDWord( &lpBuf, 0, &dwBufSize);
  1417. // We don't have the size and pos in a menu
  1418. dwOverAllSize += PutWord( &lpBuf, -1, &dwBufSize);
  1419. dwOverAllSize += PutWord( &lpBuf, -1, &dwBufSize);
  1420. dwOverAllSize += PutWord( &lpBuf, -1, &dwBufSize);
  1421. dwOverAllSize += PutWord( &lpBuf, -1, &dwBufSize);
  1422. // we don't have checksum and style
  1423. dwOverAllSize += PutDWord( &lpBuf, -1, &dwBufSize);
  1424. dwOverAllSize += PutDWord( &lpBuf, -1, &dwBufSize);
  1425. dwOverAllSize += PutDWord( &lpBuf, -1, &dwBufSize);
  1426. // Let's get the Menu flags
  1427. GetWord( &lpImage, &fItemFlags, &dwImageSize );
  1428. if ( !(fItemFlags & MF_POPUP) )
  1429. // Get the menu Id
  1430. GetWord( &lpImage, &wMenuId, &dwImageSize );
  1431. else wMenuId = -1;
  1432. //Put the Flag
  1433. dwOverAllSize += PutDWord( &lpBuf, (DWORD)fItemFlags, &dwBufSize);
  1434. //Put the MenuId
  1435. dwOverAllSize += PutDWord( &lpBuf, (DWORD)wMenuId, &dwBufSize);
  1436. // we don't have the resID, and the Type Id
  1437. dwOverAllSize += PutDWord( &lpBuf, -1, &dwBufSize);
  1438. dwOverAllSize += PutDWord( &lpBuf, -1, &dwBufSize);
  1439. // we don't have the language
  1440. dwOverAllSize += PutDWord( &lpBuf, -1, &dwBufSize);
  1441. // we don't have the codepage or the font name
  1442. dwOverAllSize += PutDWord( &lpBuf, -1, &dwBufSize);
  1443. dwOverAllSize += PutWord( &lpBuf, -1, &dwBufSize);
  1444. dwOverAllSize += PutWord( &lpBuf, -1, &dwBufSize);
  1445. dwOverAllSize += PutWord( &lpBuf, (WORD)-1, &dwBufSize);
  1446. dwOverAllSize += PutByte( &lpBuf, (BYTE)-1, &dwBufSize);
  1447. dwOverAllSize += PutByte( &lpBuf, (BYTE)-1, &dwBufSize);
  1448. // Let's put null were we don;t have the strings
  1449. uiOffset = sizeof(RESITEM);
  1450. dwOverAllSize += PutDWord( &lpBuf, 0, &dwBufSize);
  1451. dwOverAllSize += PutDWord( &lpBuf, 0, &dwBufSize);
  1452. dwOverAllSize += PutDWord( &lpBuf, (DWORD)(lpItem+uiOffset), &dwBufSize);
  1453. dwOverAllSize += PutDWord( &lpBuf, 0, &dwBufSize);
  1454. dwOverAllSize += PutDWord( &lpBuf, 0, &dwBufSize);
  1455. // Get the text
  1456. // calculate were the string is going to be
  1457. // Will be the fixed header+the pointer
  1458. dwOverAllSize += CopyText( &lpBuf, &lpImage, &dwBufSize, &dwImageSize );
  1459. // Put the size of the resource
  1460. if (dwBufSize>=0) {
  1461. uiOffset += strlen((LPSTR)(lpItem+uiOffset))+1;
  1462. lDummy = 8;
  1463. PutDWord( &lpItem, (DWORD)uiOffset, &lDummy);
  1464. }
  1465. // Move to the next position
  1466. lpItem = lpBuf;
  1467. if (dwImageSize<=16) {
  1468. // Check if we are at the end and this is just padding
  1469. BYTE bPad = (BYTE)Pad16((DWORD)(dwISize-dwImageSize));
  1470. //TRACE3(" dwRead: %lu\t dwImageSize: %lu\t Pad: %hd\n", dwRead, dwImageSize, bPad );
  1471. if (bPad==(dwImageSize))
  1472. dwImageSize = -1;
  1473. }
  1474. }
  1475. */
  1476. return (UINT)(dwOverAllSize);
  1477. }
  1478. static
  1479. UINT
  1480. ParseBitmap( LPVOID lpImageBuf, DWORD dwISize, LPVOID lpBuffer, DWORD dwSize )
  1481. {
  1482. // we will return just one item so the iodll will handle this resource as
  1483. // something valid. We will not bother doing anything else. The only thing
  1484. // we are interesed is the raw data in the immage, but if we don't return at
  1485. // least one item IODLL will consider the resource empty.
  1486. BYTE far * lpBuf = (BYTE far *)lpBuffer;
  1487. LONG dwBufSize = dwSize;
  1488. LONG dwOverAllSize = 0;
  1489. TRACE1("ParseBitmap: dwISize=%ld\n", dwISize);
  1490. dwOverAllSize += PutDWord( &lpBuf, sizeof(RESITEM), &dwBufSize);
  1491. // We have the size and pos in a cursor but we are not interested now
  1492. dwOverAllSize += PutWord( &lpBuf, (WORD)-1, &dwBufSize);
  1493. dwOverAllSize += PutWord( &lpBuf, (WORD)-1, &dwBufSize);
  1494. dwOverAllSize += PutWord( &lpBuf, (WORD)-1, &dwBufSize);
  1495. dwOverAllSize += PutWord( &lpBuf, (WORD)-1, &dwBufSize);
  1496. // we don't have checksum and style
  1497. dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);
  1498. dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);
  1499. dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);
  1500. //Put the Flag
  1501. dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);
  1502. // The ID will be just 1
  1503. dwOverAllSize += PutDWord( &lpBuf, 1, &dwBufSize);
  1504. // we don't have the resID, and the Type Id
  1505. dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);
  1506. dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);
  1507. // we don't have the language
  1508. dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);
  1509. // we don't have the codepage or the font name
  1510. dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);
  1511. dwOverAllSize += PutWord( &lpBuf, (WORD)-1, &dwBufSize);
  1512. dwOverAllSize += PutWord( &lpBuf, (WORD)-1, &dwBufSize);
  1513. dwOverAllSize += PutWord( &lpBuf, (WORD)-1, &dwBufSize);
  1514. dwOverAllSize += PutByte( &lpBuf, (BYTE)-1, &dwBufSize);
  1515. dwOverAllSize += PutByte( &lpBuf, (BYTE)-1, &dwBufSize);
  1516. // Let's put null were we don;t have the strings
  1517. dwOverAllSize += PutDWord( &lpBuf, 0, &dwBufSize);
  1518. dwOverAllSize += PutDWord( &lpBuf, 0, &dwBufSize);
  1519. dwOverAllSize += PutDWord( &lpBuf, 0, &dwBufSize);
  1520. dwOverAllSize += PutDWord( &lpBuf, 0, &dwBufSize);
  1521. dwOverAllSize += PutDWord( &lpBuf, 0, &dwBufSize);
  1522. // we just return. This is enough for IODLL
  1523. return (UINT)(dwOverAllSize);
  1524. }
  1525. static
  1526. UINT
  1527. ParseIcon( LPVOID lpImageBuf, DWORD dwISize, LPVOID lpBuffer, DWORD dwSize )
  1528. {
  1529. // Should be almost impossible for an Icon to be Huge
  1530. BYTE far * lpImage = (BYTE far *)lpImageBuf;
  1531. LONG dwImageSize = dwISize;
  1532. BYTE far * lpBuf = (BYTE far *)lpBuffer;
  1533. LONG dwBufSize = dwSize;
  1534. BYTE far * lpItem = (BYTE far *)lpBuffer;
  1535. UINT uiOffset = 0;
  1536. LONG lDummy;
  1537. LONG dwOverAllSize = 0L;
  1538. BITMAPINFOHEADER* pBmpInfo = (BITMAPINFOHEADER*) lpImage;
  1539. // difficult it will be bigger than UINT_MAX
  1540. SkipByte( &lpImage, (UINT)pBmpInfo->biSize, &dwImageSize );
  1541. RGBQUAD* pRgbQuad = (RGBQUAD*) lpImage;
  1542. SkipByte( &lpImage, sizeof(RGBQUAD), &dwImageSize );
  1543. // Calculate CheckSum on the image
  1544. DWORD dwCheckSum = 0l;
  1545. BYTE * hp = (BYTE *) lpImage;
  1546. for ( DWORD dwLen = pBmpInfo->biSizeImage; dwLen; dwLen--)
  1547. dwCheckSum = (dwCheckSum << 8) | *hp++;
  1548. // Fixed field
  1549. dwOverAllSize += PutDWord( &lpBuf, 0, &dwBufSize);
  1550. // We don't have the size and pos in a menu
  1551. dwOverAllSize += PutWord( &lpBuf, (WORD)-1, &dwBufSize);
  1552. dwOverAllSize += PutWord( &lpBuf, (WORD)-1, &dwBufSize);
  1553. dwOverAllSize += PutWord( &lpBuf, (WORD)pBmpInfo->biWidth, &dwBufSize);
  1554. dwOverAllSize += PutWord( &lpBuf, (WORD)pBmpInfo->biHeight, &dwBufSize);
  1555. // we don't have checksum and style
  1556. dwOverAllSize += PutDWord( &lpBuf, dwCheckSum, &dwBufSize);
  1557. dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);
  1558. dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);
  1559. dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);
  1560. dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);
  1561. // we don't have the resID, and the Type Id
  1562. dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);
  1563. dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);
  1564. // we don't have the language
  1565. dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);
  1566. // we don't have the codepage or the font name
  1567. dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);
  1568. dwOverAllSize += PutWord( &lpBuf, (WORD)-1, &dwBufSize);
  1569. dwOverAllSize += PutWord( &lpBuf, (WORD)-1, &dwBufSize);
  1570. dwOverAllSize += PutWord( &lpBuf, (WORD)-1, &dwBufSize);
  1571. dwOverAllSize += PutByte( &lpBuf, (BYTE)-1, &dwBufSize);
  1572. dwOverAllSize += PutByte( &lpBuf, (BYTE)-1, &dwBufSize);
  1573. // Let's put null were we don;t have the strings
  1574. uiOffset = sizeof(RESITEM);
  1575. dwOverAllSize += PutDWord( &lpBuf, 0, &dwBufSize);
  1576. dwOverAllSize += PutDWord( &lpBuf, 0, &dwBufSize);
  1577. dwOverAllSize += PutDWord( &lpBuf, 0, &dwBufSize);
  1578. dwOverAllSize += PutDWord( &lpBuf, 0, &dwBufSize);
  1579. dwOverAllSize += PutDWord( &lpBuf, 0, &dwBufSize);
  1580. // Put the size of the resource
  1581. if (dwBufSize>=0) {
  1582. lDummy = 8;
  1583. PutDWord( &lpItem, (DWORD)uiOffset, &lDummy);
  1584. }
  1585. return (UINT)(dwOverAllSize);
  1586. }
  1587. static int
  1588. GetVSBlock( BYTE far * far * lplpImage, LONG* pdwSize, VER_BLOCK* pver)
  1589. {
  1590. // We have to hard code the language filed because otherwise, due to some
  1591. // inconsistent RC compiler, the Image are not following any standard.
  1592. // We assume that all the block but the one hard-coded here are binary and
  1593. // we just skip them
  1594. WORD wHead = 0;
  1595. WORD wPad = 0;
  1596. WORD wValue = 0;
  1597. pver->pValue = *lplpImage;
  1598. // Read the header of the block
  1599. wHead = GetWord( lplpImage, &pver->wBlockLen, pdwSize );
  1600. wHead += GetWord( lplpImage, &pver->wValueLen, pdwSize );
  1601. // The Key name is all the time a NULL terminated string
  1602. wHead += (WORD)GetString( lplpImage, &pver->szKey[0], pdwSize );
  1603. pver->wHead = wHead;
  1604. // See if we have padding after the header. We can check on wHead because
  1605. // we need an allignment on a DWORD boundary and we have 2 WORD+the string.
  1606. wPad = SkipByte( lplpImage, Pad4(wHead), pdwSize );
  1607. // Fix the pointer to the value
  1608. pver->pValue = (pver->pValue+wHead+wPad);
  1609. if ((int)pver->wValueLen>*pdwSize) {
  1610. // There is an error
  1611. wPad += SkipByte( lplpImage, (UINT)*pdwSize, pdwSize );
  1612. return wHead+wPad;
  1613. }
  1614. // Now we check the key name and if is one of the one we accept as good
  1615. // we read the string. Otherwise we just skip the value field
  1616. if ( !strcmp(pver->szKey,"Comments") ||
  1617. !strcmp(pver->szKey,"CompanyName") ||
  1618. !strcmp(pver->szKey,"FileDescription") ||
  1619. !strcmp(pver->szKey,"FileVersion") ||
  1620. !strcmp(pver->szKey,"InternalName") ||
  1621. !strcmp(pver->szKey,"LegalCopyright") ||
  1622. !strcmp(pver->szKey,"LegalTrademarks") ||
  1623. !strcmp(pver->szKey,"OriginalFilename") ||
  1624. !strcmp(pver->szKey,"PrivateBuild") ||
  1625. !strcmp(pver->szKey,"ProductName") ||
  1626. !strcmp(pver->szKey,"ProductVersion") ||
  1627. !strcmp(pver->szKey,"SpecialBuild") ||
  1628. !strcmp(pver->szKey,"StringFileInfo") // found in a Borland Version resource
  1629. ) {
  1630. if (!strcmp(pver->szKey,"StringFileInfo") && !pver->wValueLen) {
  1631. pver->wType = 0;
  1632. wValue=0;
  1633. } else {
  1634. // It is a standard key name read the string.
  1635. // Set the flag to show it is a string
  1636. pver->wType = 1;
  1637. wValue = (WORD)GetVSString( lplpImage, &pver->szValue[0], pdwSize, pver->wValueLen );
  1638. }
  1639. // check if this is the LegalCopyright block.
  1640. // If it is then there might be a null in the middle of the string
  1641. if (!strcmp(pver->szKey,"LegalCopyright")) {
  1642. // we just skip the rest. This need to be fixed in the RC, not here
  1643. if ((int)(pver->wValueLen-wValue)>0)
  1644. wValue += SkipByte( lplpImage, pver->wValueLen-wValue, pdwSize );
  1645. }
  1646. } else {
  1647. // It isn't a string, or if is is not a standard key name, skip it
  1648. pver->wType = 0;
  1649. *pver->szValue = '\0';
  1650. wValue = SkipByte( lplpImage, pver->wValueLen, pdwSize );
  1651. }
  1652. // Check the padding
  1653. wPad += SkipByte( lplpImage, Pad4(wValue), pdwSize );
  1654. // Even if it look what we have done should be enough we have to walk the image
  1655. // skiping the NULL char that sometimes the comipler place there.
  1656. // Do this only if it is not the translation field.
  1657. // The translation field is the last so we might have some image padding
  1658. if (strcmp(pver->szKey, "Translation")) {
  1659. WORD wSkip = 0;
  1660. BYTE far * lpTmp = *lplpImage;
  1661. if (*lplpImage)
  1662. while (!**lplpImage && *pdwSize) {
  1663. wSkip += SkipByte(lplpImage, 1, pdwSize);
  1664. }
  1665. if (Pad4(wSkip)) {
  1666. *lplpImage = lpTmp;
  1667. *pdwSize += wSkip;
  1668. } else wPad += wSkip;
  1669. }
  1670. return wHead+wValue+wPad;
  1671. }
  1672. static int
  1673. GetVSBlockOld( BYTE far * far * lplpImage, LONG* pdwSize, VER_BLOCK* pver)
  1674. {
  1675. WORD wHead = 0;
  1676. WORD wPad = 0;
  1677. WORD wValue = 0;
  1678. LONG lValueLen = 0;
  1679. pver->pValue = *lplpImage;
  1680. wHead = GetWord( lplpImage, &pver->wBlockLen, pdwSize );
  1681. wHead += GetWord( lplpImage, &pver->wValueLen, pdwSize );
  1682. wHead += (WORD)GetString( lplpImage, &pver->szKey[0], pdwSize );
  1683. pver->wHead = wHead;
  1684. wPad = SkipByte( lplpImage, Pad4(wHead), pdwSize );
  1685. lValueLen = pver->wValueLen;
  1686. if (lValueLen>*pdwSize) {
  1687. // There is an error
  1688. wPad += SkipByte( lplpImage, (UINT)*pdwSize, pdwSize );
  1689. return wHead+wPad;
  1690. }
  1691. pver->wType = 0;
  1692. pver->pValue = (pver->pValue+wHead+wPad);
  1693. if (pver->wValueLen) {
  1694. wValue = (WORD)GetString( lplpImage, &pver->szValue[0], &lValueLen );
  1695. *pdwSize -= wValue;
  1696. pver->wType = 1;
  1697. }
  1698. if (wValue!=pver->wValueLen) {
  1699. // Just skip the value. It isn't a string, is a value
  1700. if (pver->wValueLen-wValue!=1) {
  1701. *pver->szValue = '\0';
  1702. pver->wType = 0;
  1703. }
  1704. wPad += SkipByte( lplpImage, pver->wValueLen-wValue, pdwSize );
  1705. }
  1706. wPad += SkipByte( lplpImage, Pad4(pver->wValueLen), pdwSize );
  1707. return wHead+wPad+wValue;
  1708. }
  1709. static int
  1710. PutVSBlock( BYTE far * far * lplpImage, LONG* pdwSize, VER_BLOCK ver,
  1711. LPSTR lpStr, BYTE far * far * lplpBlockSize, WORD* pwTrash)
  1712. {
  1713. // We have to write the info in the VER_BLOCK in the new image
  1714. // We want to remember were the block size field is so we can update it later
  1715. WORD wHead = 0;
  1716. WORD wValue = 0;
  1717. WORD wPad = Pad4(ver.wHead);
  1718. *pwTrash = 0;
  1719. // Get the pointer to the header of the block
  1720. BYTE far * pHead = ver.pValue-ver.wHead-wPad;
  1721. BYTE far * lpNewImage = *lplpImage;
  1722. // Copy the header of the block to the new image
  1723. wHead = ver.wHead;
  1724. if (*pdwSize>=(int)ver.wHead) {
  1725. memcpy( *lplpImage, pHead, ver.wHead );
  1726. *pdwSize -= ver.wHead;
  1727. lpNewImage += ver.wHead;
  1728. } else *pdwSize = -1;
  1729. // Check if padding is needed
  1730. if (*pdwSize>=(int)wPad) {
  1731. memset( *lplpImage+ver.wHead, 0, wPad );
  1732. *pdwSize -= wPad;
  1733. lpNewImage += wPad;
  1734. } else *pdwSize = -1;
  1735. // Store the pointer to the block size WORD
  1736. BYTE far * pBlockSize = *lplpImage;
  1737. // Check if the value is a string or a BYTE array
  1738. if (ver.wType) {
  1739. // it is a string, copy the updated item
  1740. wValue = strlen(lpStr)+1;
  1741. if (*pdwSize>=(int)wValue) {
  1742. memcpy(*lplpImage+wHead+wPad, lpStr, wValue);
  1743. *pdwSize -= wValue;
  1744. lpNewImage += wValue;
  1745. } else *pdwSize = -1;
  1746. // Check if padding is needed
  1747. int wPad1 = Pad4(wValue);
  1748. if (*pdwSize>=wPad1) {
  1749. memset( *lplpImage+ver.wHead+wValue+wPad, 0, wPad1 );
  1750. *pdwSize -= wPad1;
  1751. lpNewImage += wPad1;
  1752. } else *pdwSize = -1;
  1753. *pwTrash = Pad4(ver.wValueLen);
  1754. wValue += (WORD)wPad1;
  1755. // Fix to the strange behaviour of the ver.dll
  1756. if ((wPad1) && (wPad1>=(int)*pwTrash)) {
  1757. wValue -= *pwTrash;
  1758. } else *pwTrash = 0;
  1759. // Fix up the Value len field. We will put the len of the value + padding
  1760. if (*pdwSize>=0)
  1761. memcpy( pBlockSize+2, &wValue, 2);
  1762. } else {
  1763. // it is an array, just copy it in the new image buffer
  1764. wValue = ver.wValueLen;
  1765. if (*pdwSize>=(int)ver.wValueLen) {
  1766. memcpy(*lplpImage+wHead+wPad, ver.pValue, ver.wValueLen);
  1767. *pdwSize -= ver.wValueLen;
  1768. lpNewImage += ver.wValueLen;
  1769. } else *pdwSize = -1;
  1770. // Check if padding is needed
  1771. if (*pdwSize>=(int)Pad4(ver.wValueLen)) {
  1772. memset( *lplpImage+ver.wHead+ver.wValueLen+wPad, 0, Pad4(ver.wValueLen) );
  1773. *pdwSize -= Pad4(ver.wValueLen);
  1774. lpNewImage += Pad4(ver.wValueLen);
  1775. } else *pdwSize = -1;
  1776. wPad += Pad4(ver.wValueLen);
  1777. }
  1778. *lplpBlockSize = pBlockSize;
  1779. *lplpImage = lpNewImage;
  1780. return wPad+wValue+wHead;
  1781. }
  1782. static
  1783. UINT ParseVerst( LPVOID lpImageBuf, DWORD dwISize, LPVOID lpBuffer, DWORD dwSize )
  1784. {
  1785. TRACE("ParseVersion Stamp: \n");
  1786. BYTE far * lpImage = (BYTE far *)lpImageBuf;
  1787. LONG dwImageSize = dwISize;
  1788. BYTE far * lpBuf = (BYTE far *)lpBuffer;
  1789. LONG dwBufSize = dwSize;
  1790. BYTE far * lpItem = (BYTE far *)lpBuffer;
  1791. UINT uiOffset = 0;
  1792. LPRESITEM lpResItem = (LPRESITEM)lpBuffer;
  1793. char far * lpStrBuf = (char far *)(lpBuf+sizeof(RESITEM));
  1794. LONG dwOverAllSize = 0L;
  1795. WORD wPos = 0;
  1796. static VER_BLOCK verBlock;
  1797. while (dwImageSize>0) {
  1798. wPos++;
  1799. GetVSBlock( &lpImage, &dwImageSize, &verBlock);
  1800. // check if this is the translation block
  1801. if (!strcmp(verBlock.szKey, "Translation" )) {
  1802. // This is the translation block let the localizer have it for now
  1803. DWORD dwCodeLang = 0;
  1804. LONG lDummy = 4;
  1805. GetDWord( &verBlock.pValue, &dwCodeLang, &lDummy);
  1806. // Put the value in the string value
  1807. wsprintf( &verBlock.szValue[0], "%#08lX", dwCodeLang );
  1808. }
  1809. // Fixed field
  1810. dwOverAllSize += PutDWord( &lpBuf, 0, &dwBufSize);
  1811. // We don't have the size and pos in an accelerator
  1812. dwOverAllSize += PutWord( &lpBuf, (WORD)-1, &dwBufSize);
  1813. dwOverAllSize += PutWord( &lpBuf, (WORD)-1, &dwBufSize);
  1814. dwOverAllSize += PutWord( &lpBuf, (WORD)-1, &dwBufSize);
  1815. dwOverAllSize += PutWord( &lpBuf, (WORD)-1, &dwBufSize);
  1816. // we don't have checksum and style
  1817. dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);
  1818. dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);
  1819. dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);
  1820. //Put the Flag
  1821. dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);
  1822. // we will need to calculate the correct ID for mike
  1823. //Put the Id
  1824. dwOverAllSize += PutDWord( &lpBuf, wPos, &dwBufSize);
  1825. // we don't have the resID, and the Type Id
  1826. dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);
  1827. dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);
  1828. // we don't have the language
  1829. dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);
  1830. // we don't have the codepage or the font name
  1831. dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);
  1832. dwOverAllSize += PutWord( &lpBuf, (WORD)-1, &dwBufSize);
  1833. dwOverAllSize += PutWord( &lpBuf, (WORD)-1, &dwBufSize);
  1834. dwOverAllSize += PutWord( &lpBuf, (WORD)-1, &dwBufSize);
  1835. dwOverAllSize += PutByte( &lpBuf, (BYTE)-1, &dwBufSize);
  1836. dwOverAllSize += PutByte( &lpBuf, (BYTE)-1, &dwBufSize);
  1837. // Let's put null were we don;t have the strings
  1838. uiOffset = sizeof(RESITEM);
  1839. dwOverAllSize += PutDWord( &lpBuf, 0, &dwBufSize);
  1840. dwOverAllSize += PutDWord( &lpBuf, 0, &dwBufSize);
  1841. dwOverAllSize += PutDWord( &lpBuf, 0, &dwBufSize);
  1842. dwOverAllSize += PutDWord( &lpBuf, 0, &dwBufSize);
  1843. dwOverAllSize += PutDWord( &lpBuf, 0, &dwBufSize);
  1844. lpResItem->lpszClassName = strcpy( lpStrBuf, verBlock.szKey );
  1845. lpStrBuf += strlen(lpResItem->lpszClassName)+1;
  1846. lpResItem->lpszCaption = strcpy( lpStrBuf, verBlock.szValue );
  1847. lpStrBuf += strlen(lpResItem->lpszCaption)+1;
  1848. // Put the size of the resource
  1849. if (dwBufSize>0) {
  1850. uiOffset += strlen((LPSTR)(lpResItem->lpszClassName))+1;
  1851. uiOffset += strlen((LPSTR)(lpResItem->lpszCaption))+1;
  1852. }
  1853. // Check if we are alligned
  1854. uiOffset += Allign( (BYTE**)&lpStrBuf, &dwBufSize, (LONG)uiOffset);
  1855. dwOverAllSize += uiOffset-sizeof(RESITEM);
  1856. lpResItem->dwSize = (DWORD)uiOffset;
  1857. // Move to the next position
  1858. lpResItem = (LPRESITEM) lpStrBuf;
  1859. lpBuf = (BYTE far *)lpStrBuf;
  1860. lpStrBuf = (char far *)(lpBuf+sizeof(RESITEM));
  1861. if (dwImageSize<=16) {
  1862. // Check if we are at the end and this is just padding
  1863. BYTE bPad = (BYTE)Pad16((DWORD)(dwISize-dwImageSize));
  1864. //TRACE3(" dwRead: %lu\t dwImageSize: %lu\t Pad: %hd\n", dwRead, dwImageSize, bPad );
  1865. if (bPad==(dwImageSize))
  1866. dwImageSize = -1;
  1867. }
  1868. }
  1869. return (UINT)(dwOverAllSize);
  1870. }
  1871. static void GenerateTransField( WORD wLang, VER_BLOCK * pVer )
  1872. {
  1873. // Get the DWORD value
  1874. DWORD dwValue = GenerateTransField( wLang, TRUE );
  1875. char buf[9];
  1876. // Put the value in the string value
  1877. wsprintf( &buf[0], "%08lX", dwValue );
  1878. // Just check if we are in the right place. Should never have problem
  1879. if (strlen(pVer->szKey)==8) {
  1880. //strcpy( pVer->szKey, buf );
  1881. // We have to change the header in the image, not just the
  1882. // szKey field
  1883. // Get the pointer to he begin of the filed
  1884. WORD wPad = Pad4(pVer->wHead);
  1885. BYTE far * pHead = pVer->pValue-pVer->wHead-wPad;
  1886. pHead += 4; // Move at the begin of the string
  1887. strcpy( (char*)pHead, buf );
  1888. }
  1889. }
  1890. static DWORD GenerateTransField(WORD wLang, BOOL bReverse)
  1891. {
  1892. // we have to generate a table to connect
  1893. // the language with the correct code page
  1894. WORD wCP = 0;
  1895. DWORD dwRet = 0;
  1896. switch (wLang) {
  1897. // Just have a big switch to assign the codepage
  1898. case 0x1401: wCP = 1256; break; // Algeria
  1899. case 0x1801: wCP = 1256; break; // Morocco
  1900. case 0x1C01: wCP = 1256; break; // Tunisia
  1901. case 0x2001: wCP = 1256; break; // Oman
  1902. case 0x2401: wCP = 1256; break; // Yemen
  1903. case 0x2801: wCP = 1256; break; // Syria
  1904. case 0x2C01: wCP = 1256; break; // Jordan
  1905. case 0x3001: wCP = 1256; break; // Lebanon
  1906. case 0x3401: wCP = 1256; break; // Kuwait
  1907. case 0x3801: wCP = 1256; break; // U.A.E.
  1908. case 0x3C01: wCP = 1256; break; // Bahrain
  1909. case 0x4001: wCP = 1256; break; // Qatar
  1910. case 0x0423: wCP = 1251; break; // Byelorussia
  1911. case 0x0402: wCP = 1251; break; // Bulgaria
  1912. case 0x0403: wCP = 1252; break; // Catalan
  1913. case 0x0404: wCP = 950; break; // Taiwan
  1914. case 0x0804: wCP = 936; break; // PRC
  1915. case 0x0C04: wCP = 950; break; // Hong Kong
  1916. case 0x1004: wCP = 936; break; // Singapore
  1917. case 0x0405: wCP = 1250; break; // Czech
  1918. case 0x0406: wCP = 1252; break; // Danish
  1919. case 0x0413: wCP = 1252; break; // Dutch (Standard)
  1920. case 0x0813: wCP = 1252; break; // Dutch (Belgian)
  1921. case 0x0409: wCP = 1252; break; // English (American)
  1922. case 0x0809: wCP = 1252; break; // English (British)
  1923. case 0x1009: wCP = 1252; break; // English (Canadian)
  1924. case 0x1409: wCP = 1252; break; // English (New Zealand)
  1925. case 0x0c09: wCP = 1252; break; // English (Australian)
  1926. case 0x1809: wCP = 1252; break; // English (Ireland)
  1927. case 0x0425: wCP = 1257; break; // Estonia
  1928. //case 0x0429: wCP = Farsi
  1929. case 0x040b: wCP = 1252; break; // Finnish
  1930. case 0x040c: wCP = 1252; break; // French (Standard)
  1931. case 0x080c: wCP = 1252; break; // French (Belgian)
  1932. case 0x100c: wCP = 1252; break; // French (Swiss)
  1933. case 0x0c0c: wCP = 1252; break; // French (Canadian)
  1934. case 0x0407: wCP = 1252; break; // German (Standard)
  1935. case 0x0807: wCP = 1252; break; // German (Swiss)
  1936. case 0x0c07: wCP = 1252; break; // German (Austrian)
  1937. case 0x0408: wCP = 1253; break; // Greek
  1938. case 0x040D: wCP = 1255; break; // Israel
  1939. case 0x040e: wCP = 1250; break; // Hungarian
  1940. case 0x040f: wCP = 1252; break; // Icelandic
  1941. case 0x0421: wCP = 1252; break; // Indonesia
  1942. case 0x0410: wCP = 1252; break; // Italian (Standard)
  1943. case 0x0810: wCP = 1252; break; // Italian (Swiss)
  1944. case 0x0411: wCP = 932; break; // Japanese
  1945. case 0x0412: wCP = 949; break; // Korea
  1946. case 0x0426: wCP = 1257; break; // Latvia
  1947. case 0x0427: wCP = 1257; break; // Lithuania
  1948. case 0x0414: wCP = 1252; break; // Norwegian (Bokmal)
  1949. case 0x0814: wCP = 1252; break; // Norwegian (Nynorsk)
  1950. case 0x0415: wCP = 1250; break; // Polish
  1951. case 0x0816: wCP = 1252; break; // Portuguese (Standard)
  1952. case 0x0416: wCP = 1252; break; // Portuguese (Brazilian)
  1953. case 0x0417: wCP = 1252; break; // Rhaeto-Romanic
  1954. case 0x0818: wCP = 1250; break; // Moldavia
  1955. case 0x0418: wCP = 1250; break; // Romanian
  1956. case 0x0419: wCP = 1251; break; // Russian
  1957. case 0x041b: wCP = 1250; break; // Slovak
  1958. case 0x0424: wCP = 1250; break; // Slovenian
  1959. case 0x042e: wCP = 1250; break; // Germany
  1960. case 0x080a: wCP = 1252; break; // Spanish (Mexican)
  1961. case 0x040a: wCP = 1252; break; // Spanish (Castilian)
  1962. case 0x0c0a: wCP = 1252; break; // Spanish (Modern)
  1963. case 0x041d: wCP = 1252; break; // Swedish
  1964. case 0x041E: wCP = 874; break; // Thailand
  1965. case 0x041f: wCP = 1254; break; // Turkish
  1966. case 0x0422: wCP = 1251; break; // Ukraine
  1967. default: wCP = 1252; break; // Return standard US English CP.
  1968. }
  1969. if (bReverse)
  1970. dwRet = MAKELONG( wCP, wLang );
  1971. else dwRet = MAKELONG( wLang, wCP );
  1972. return dwRet;
  1973. }
  1974. #ifdef VB
  1975. static
  1976. UINT
  1977. UpdateVBData( LPVOID lpNewBuf, LONG dwNewSize,
  1978. LPVOID lpOldI, LONG dwOldImageSize,
  1979. LPVOID lpNewI, DWORD* pdwNewImageSize )
  1980. {
  1981. // The following special format is used by VB for international messages
  1982. // The code here is mostly copied from the UpdateMenu routine
  1983. UINT uiError = ERROR_NO_ERROR;
  1984. BYTE far * lpNewImage = (BYTE far *) lpNewI;
  1985. LONG dwNewImageSize = *pdwNewImageSize;
  1986. BYTE far * lpOldImage = (BYTE far *) lpOldI;
  1987. DWORD dwOriginalOldSize = dwOldImageSize;
  1988. BYTE far * lpBuf = (BYTE far *) lpNewBuf;
  1989. LPRESITEM lpResItem = LPNULL;
  1990. // We have to read the information from the lpNewBuf
  1991. // Data Items
  1992. WORD wDataId;
  1993. char szTxt[256];
  1994. WORD wPos = 0;
  1995. // Updated items
  1996. WORD wUpdPos = 0;
  1997. WORD wUpdDataId;
  1998. char szUpdTxt[256];
  1999. LONG dwOverAllSize = 0l;
  2000. // Copy the language specifier
  2001. dwOldImageSize -= PutDWord( &lpNewImage, *((DWORD*)lpOldImage), &dwNewImageSize);
  2002. lpOldImage += sizeofDWord;
  2003. dwOverAllSize += sizeofDWord;
  2004. GetString( &lpOldImage, &szTxt[0], &dwOldImageSize );
  2005. dwOverAllSize += PutString( &lpNewImage, &szTxt[0], &dwNewImageSize);
  2006. // Now copy the strings
  2007. while (dwOldImageSize>0) {
  2008. wPos++;
  2009. // Check for only padding remaining and exit
  2010. if ( *(WORD *)lpOldImage != RES_SIGNATURE )
  2011. if ( dwOldImageSize < 16 && *(BYTE *)lpOldImage == 0 )
  2012. break;
  2013. else
  2014. return ERROR_RW_INVALID_FILE;
  2015. // This copies signature and ID
  2016. wDataId = *(WORD *)(lpOldImage + sizeof(WORD));
  2017. dwOldImageSize -= PutDWord( &lpNewImage, *((DWORD*)lpOldImage), &dwNewImageSize);
  2018. lpOldImage += sizeofDWord;
  2019. dwOverAllSize += sizeofDWord;
  2020. // Get the untranslated string
  2021. GetString( &lpOldImage, &szTxt[0], &dwOldImageSize );
  2022. if ((!wUpdPos) && dwNewSize ) {
  2023. lpResItem = (LPRESITEM) lpBuf;
  2024. wUpdPos = HIWORD(lpResItem->dwItemID);
  2025. wUpdDataId = LOWORD(lpResItem->dwItemID);
  2026. strcpy( szUpdTxt, lpResItem->lpszCaption );
  2027. lpBuf += lpResItem->dwSize;
  2028. dwNewSize -= lpResItem->dwSize;
  2029. }
  2030. if ((wPos==wUpdPos) && (wUpdDataId==wDataId)) {
  2031. strcpy(szTxt, szUpdTxt);
  2032. wUpdPos = 0;
  2033. }
  2034. // Write the text
  2035. dwOverAllSize += PutString( &lpNewImage, &szTxt[0], &dwNewImageSize);
  2036. // Check for padding
  2037. if (dwOldImageSize<=16) {
  2038. // Check if we are at the end and this is just padding
  2039. BYTE bPad = (BYTE)Pad16((dwOriginalOldSize-dwOldImageSize));
  2040. //TRACE3(" dwRead: %lu\t dwImageSize: %lu\t Pad: %hd\n", dwRead, dwOldImageSize, bPad );
  2041. if (bPad==dwOldImageSize) {
  2042. BYTE far * lpBuf = lpOldImage;
  2043. while (bPad) {
  2044. if (*lpBuf++!=0x00)
  2045. break;
  2046. bPad--;
  2047. }
  2048. if (bPad==0)
  2049. dwOldImageSize = -1;
  2050. }
  2051. }
  2052. }
  2053. if (dwOverAllSize>(LONG)*pdwNewImageSize) {
  2054. // calc the padding as well
  2055. dwOverAllSize += (BYTE)Pad4((DWORD)(dwOverAllSize));
  2056. *pdwNewImageSize = dwOverAllSize;
  2057. return uiError;
  2058. }
  2059. *pdwNewImageSize = *pdwNewImageSize-dwNewImageSize;
  2060. if (*pdwNewImageSize>0) {
  2061. // calculate padding
  2062. BYTE bPad = (BYTE)Pad4((DWORD)(*pdwNewImageSize));
  2063. if (bPad>dwNewImageSize) {
  2064. *pdwNewImageSize += bPad;
  2065. return uiError;
  2066. }
  2067. memset(lpNewImage, 0x00, bPad);
  2068. *pdwNewImageSize += bPad;
  2069. }
  2070. return uiError;
  2071. }
  2072. #endif
  2073. static
  2074. UINT
  2075. UpdateVerst( LPVOID lpNewBuf, LONG dwNewSize,
  2076. LPVOID lpOldI, LONG dwOldImageSize,
  2077. LPVOID lpNewI, DWORD* pdwNewImageSize )
  2078. {
  2079. /*
  2080. * This Function is a big mess. It is like this because the RC compiler generate
  2081. * some inconsistent code so we have to do a lot of hacking to get the VS working
  2082. * In future, if ever ver.dll and the RC compiler will be fixed will be possible
  2083. * fix some of the bad thing we have to do to get the updated VS as consistent as
  2084. * possible with the old one
  2085. */
  2086. UINT uiError = ERROR_NO_ERROR;
  2087. LONG dwNewImageSize = *pdwNewImageSize;
  2088. BYTE far * lpNewImage = (BYTE far *) lpNewI;
  2089. BYTE far * lpOldImage = (BYTE far *) lpOldI;
  2090. BYTE far * lpBuf = (BYTE far *) lpNewBuf;
  2091. LPRESITEM lpResItem = LPNULL;
  2092. WORD wPos = 0;
  2093. // Updated info
  2094. WORD wUpdPos = 0;
  2095. static char szCaption[300];
  2096. static char szUpdCaption[300];
  2097. static char szUpdKey[100];
  2098. DWORD dwOriginalOldSize = dwOldImageSize;
  2099. LONG dwOverAllSize = 0l;
  2100. WORD wPad = 0;
  2101. // Pointer to the block size to fix up later
  2102. BYTE far * lpVerBlockSize = LPNULL;
  2103. BYTE far * lpSFIBlockSize = LPNULL;
  2104. BYTE far * lpTrnBlockSize = LPNULL;
  2105. BYTE far * lpStrBlockSize = LPNULL;
  2106. BYTE far * lpDummy = LPNULL;
  2107. WORD wVerBlockSize = 0;
  2108. WORD wSFIBlockSize = 0;
  2109. WORD wTrnBlockSize = 0;
  2110. WORD wStrBlockSize = 0;
  2111. WORD wTrash = 0; // we need this to fix a bug in the RC compiler
  2112. // StringFileInfo
  2113. static VER_BLOCK SFI; // StringFileInfo
  2114. LONG lSFILen = 0;
  2115. // Translation blocks
  2116. static VER_BLOCK Trn;
  2117. LONG lTrnLen = 0;
  2118. static VER_BLOCK Str; // Strings
  2119. // we read first of all the information from the VS_VERSION_INFO block
  2120. static VER_BLOCK VS_INFO; // VS_VERSION_INFO
  2121. int iHeadLen = GetVSBlock( &lpOldImage, &dwOldImageSize, &VS_INFO );
  2122. // Write the block in the new image
  2123. wVerBlockSize = (WORD)PutVSBlock( &lpNewImage, &dwNewImageSize, VS_INFO, &VS_INFO.szValue[0], &lpVerBlockSize, &wTrash );
  2124. dwOverAllSize = wVerBlockSize+wTrash;
  2125. // we have to check the len of the full block for padding.
  2126. // For some wild reasons the RC compiler place a wrong value there
  2127. LONG lVS_INFOLen = VS_INFO.wBlockLen - iHeadLen - Pad4(VS_INFO.wBlockLen);
  2128. while (dwOldImageSize>0 && lVS_INFOLen>0) {
  2129. //Get the StringFileInfo
  2130. iHeadLen = GetVSBlock( &lpOldImage, &dwOldImageSize, &SFI );
  2131. // Check if this is the StringFileInfo field
  2132. if (!strcmp(SFI.szKey, "StringFileInfo")) {
  2133. // Read all the translation blocks
  2134. lSFILen = SFI.wBlockLen-iHeadLen-Pad4(SFI.wBlockLen);
  2135. // Write the block in the new image
  2136. wSFIBlockSize = (WORD)PutVSBlock( &lpNewImage, &dwNewImageSize, SFI, &SFI.szValue[0], &lpSFIBlockSize, &wTrash );
  2137. dwOverAllSize += wSFIBlockSize+wTrash;
  2138. while (lSFILen>0) {
  2139. // Read the Translation block
  2140. iHeadLen = GetVSBlock( &lpOldImage, &dwOldImageSize, &Trn );
  2141. // Calculate the right key name
  2142. if ((lpResItem = GetItem( lpBuf, dwNewSize, Trn.szKey))) {
  2143. // Find the Translation ResItem
  2144. LPRESITEM lpTrans = GetItem( lpBuf, dwNewSize, "Translation");
  2145. WORD wLang = (lpTrans ? LOWORD(lpTrans->dwLanguage) : 0xFFFF);
  2146. GenerateTransField( wLang, &Trn );
  2147. }
  2148. // Write the block in the new image
  2149. wTrnBlockSize = (WORD) PutVSBlock( &lpNewImage, &dwNewImageSize, Trn, &Trn.szValue[0], &lpTrnBlockSize, &wTrash );
  2150. dwOverAllSize += wTrnBlockSize+wTrash;
  2151. lTrnLen = Trn.wBlockLen-iHeadLen-Pad4(Trn.wBlockLen);
  2152. while (lTrnLen>0) {
  2153. // Read the Strings in the block
  2154. iHeadLen = GetVSBlock( &lpOldImage, &dwOldImageSize, &Str );
  2155. lTrnLen -= iHeadLen;
  2156. TRACE2("Key: %s\tValue: %s\n", Str.szKey, Str.szValue );
  2157. TRACE3("Len: %hd\tValLen: %hd\tType: %hd\n", Str.wBlockLen, Str.wValueLen, Str.wType );
  2158. strcpy(szCaption, Str.szValue);
  2159. // Check if this Item has been updated
  2160. if ((lpResItem = GetItem( lpBuf, dwNewSize, Str.szKey))) {
  2161. strcpy( szUpdCaption, lpResItem->lpszCaption );
  2162. strcpy( szUpdKey, lpResItem->lpszClassName );
  2163. }
  2164. if (!strcmp( szUpdKey, Str.szKey)) {
  2165. strcpy( szCaption, szUpdCaption );
  2166. wUpdPos = 0;
  2167. }
  2168. // Write the block in the new image
  2169. wStrBlockSize = (WORD) PutVSBlock( &lpNewImage, &dwNewImageSize, Str, szCaption, &lpStrBlockSize, &wTrash );
  2170. dwOverAllSize += wStrBlockSize+wTrash;
  2171. // Fix up the size of the block
  2172. if (dwNewImageSize>=0)
  2173. memcpy( lpStrBlockSize, &wStrBlockSize, 2);
  2174. wTrnBlockSize += wStrBlockSize + wTrash;
  2175. }
  2176. lSFILen -= Trn.wBlockLen;
  2177. // Fix up the size of the block
  2178. if (dwNewImageSize>=0)
  2179. memcpy( lpTrnBlockSize, &wTrnBlockSize, 2);
  2180. wSFIBlockSize += wTrnBlockSize;
  2181. }
  2182. lVS_INFOLen -= SFI.wBlockLen;
  2183. // Fix up the size of the block
  2184. if (dwNewImageSize>=0)
  2185. memcpy( lpSFIBlockSize, &wSFIBlockSize, 2);
  2186. wVerBlockSize += wSFIBlockSize;
  2187. } else {
  2188. // this is another block skip it all
  2189. lVS_INFOLen -= SFI.wValueLen+iHeadLen;
  2190. // Check if this block is the translation field
  2191. if (!strcmp(SFI.szKey, "Translation")) {
  2192. // it is calculate the right value to place in the value field
  2193. // We calculate automatically the value to have the correct
  2194. // localized language in the translation field
  2195. //wVerBlockSize += PutTranslation( &lpNewImage, &dwNewImageSize, SFI );
  2196. // check if this is the translation block
  2197. // This is the translation block let the localizer have it for now
  2198. /*
  2199. if ((lpResItem = GetItem( lpBuf, dwNewSize, SFI.szKey)))
  2200. strcpy( szUpdCaption, lpResItem->lpszCaption );
  2201. // Convert the value back in numbers
  2202. DWORD dwCodeLang = strtol( szUpdCaption, '\0', 16);
  2203. */
  2204. //
  2205. // We do generate the Tranlsation filed from the language
  2206. // We will have to update the block name as well
  2207. //
  2208. DWORD dwCodeLang = 0;
  2209. if ((lpResItem = GetItem( lpBuf, dwNewSize, SFI.szKey)))
  2210. dwCodeLang = GenerateTransField((WORD)LOWORD(lpResItem->dwLanguage), FALSE);
  2211. else {
  2212. // Place the original value here
  2213. dwCodeLang =(DWORD)*(SFI.pValue);
  2214. }
  2215. LONG lDummy = 4;
  2216. SFI.pValue -= PutDWord( &SFI.pValue, dwCodeLang, &lDummy );
  2217. }
  2218. // Write the block in the new image
  2219. wVerBlockSize += (WORD) PutVSBlock( &lpNewImage, &dwNewImageSize, SFI, &SFI.szValue[0], &lpDummy, &wTrash );
  2220. if (dwNewImageSize>=0)
  2221. memcpy( lpVerBlockSize, &wVerBlockSize, 2);
  2222. dwOverAllSize = wVerBlockSize+wTrash;
  2223. }
  2224. }
  2225. // fix up the block size
  2226. if (dwNewImageSize>=0)
  2227. memcpy( lpVerBlockSize, &wVerBlockSize, 2);
  2228. if (dwOverAllSize>(LONG)*pdwNewImageSize) {
  2229. // calc the padding as well
  2230. dwOverAllSize += (BYTE)Pad4((DWORD)(dwOverAllSize));
  2231. *pdwNewImageSize = dwOverAllSize;
  2232. return uiError;
  2233. }
  2234. *pdwNewImageSize = *pdwNewImageSize-dwNewImageSize;
  2235. if (*pdwNewImageSize>0) {
  2236. // calculate padding
  2237. BYTE bPad = (BYTE)Pad4((DWORD)(*pdwNewImageSize));
  2238. if (bPad>dwNewImageSize) {
  2239. *pdwNewImageSize += bPad;
  2240. return uiError;
  2241. }
  2242. memset(lpNewImage, 0x00, bPad);
  2243. *pdwNewImageSize += bPad;
  2244. }
  2245. return uiError;
  2246. }
  2247. static
  2248. UINT ParseAccel( LPVOID lpImageBuf, DWORD dwISize, LPVOID lpBuffer, DWORD dwSize )
  2249. {
  2250. TRACE("ParseAccelerator: \n");
  2251. BYTE far * lpImage = (BYTE far *)lpImageBuf;
  2252. LONG dwImageSize = dwISize;
  2253. BYTE far * lpBuf = (BYTE far *)lpBuffer;
  2254. LONG dwBufSize = dwSize;
  2255. BYTE far * lpItem = (BYTE far *)lpBuffer;
  2256. UINT uiOffset = 0;
  2257. LONG lDummy;
  2258. LONG dwOverAllSize = 0L;
  2259. WORD wPos = 0;
  2260. BYTE fFlags = 0;
  2261. WORD wEvent = 0;
  2262. WORD wId = 0;
  2263. // Reset the IDArray
  2264. CalcID(0, FALSE);
  2265. while (dwImageSize>0) {
  2266. wPos++;
  2267. GetByte( &lpImage, &fFlags, &dwImageSize );
  2268. GetWord( &lpImage, &wEvent, &dwImageSize );
  2269. GetWord( &lpImage, &wId, &dwImageSize );
  2270. if (fFlags & 0x80)
  2271. dwImageSize = 0;
  2272. // Fixed field
  2273. dwOverAllSize += PutDWord( &lpBuf, 0, &dwBufSize);
  2274. // We don't have the size and pos in an accelerator
  2275. dwOverAllSize += PutWord( &lpBuf, (WORD)-1, &dwBufSize);
  2276. dwOverAllSize += PutWord( &lpBuf, (WORD)-1, &dwBufSize);
  2277. dwOverAllSize += PutWord( &lpBuf, (WORD)-1, &dwBufSize);
  2278. dwOverAllSize += PutWord( &lpBuf, (WORD)-1, &dwBufSize);
  2279. // we don't have checksum and style
  2280. dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);
  2281. dwOverAllSize += PutDWord( &lpBuf, (DWORD)wEvent, &dwBufSize);
  2282. dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);
  2283. //Put the Flag
  2284. dwOverAllSize += PutDWord( &lpBuf, (DWORD)fFlags, &dwBufSize);
  2285. // we will need to calculate the correct ID for mike
  2286. //Put the Id
  2287. dwOverAllSize += PutDWord( &lpBuf, CalcID(wId, TRUE), &dwBufSize);
  2288. // we don't have the resID, and the Type Id
  2289. dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);
  2290. dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);
  2291. // we don't have the language
  2292. dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);
  2293. // we don't have the codepage or the font name
  2294. dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);
  2295. dwOverAllSize += PutWord( &lpBuf, (WORD)-1, &dwBufSize);
  2296. dwOverAllSize += PutWord( &lpBuf, (WORD)-1, &dwBufSize);
  2297. dwOverAllSize += PutWord( &lpBuf, (WORD)-1, &dwBufSize);
  2298. dwOverAllSize += PutByte( &lpBuf, (BYTE)-1, &dwBufSize);
  2299. dwOverAllSize += PutByte( &lpBuf, (BYTE)-1, &dwBufSize);
  2300. // Let's put null were we don;t have the strings
  2301. uiOffset = sizeof(RESITEM);
  2302. dwOverAllSize += PutDWord( &lpBuf, 0, &dwBufSize);
  2303. dwOverAllSize += PutDWord( &lpBuf, 0, &dwBufSize);
  2304. dwOverAllSize += PutDWord( &lpBuf, 0, &dwBufSize);
  2305. dwOverAllSize += PutDWord( &lpBuf, 0, &dwBufSize);
  2306. dwOverAllSize += PutDWord( &lpBuf, 0, &dwBufSize);
  2307. // Put the size of the resource
  2308. if (dwBufSize>=0) {
  2309. lDummy = 8;
  2310. PutDWord( &lpItem, (DWORD)uiOffset, &lDummy);
  2311. }
  2312. // Move to the next position
  2313. lpItem = lpBuf;
  2314. /*
  2315. if (dwImageSize<=16) {
  2316. // Check if we are at the end and this is just padding
  2317. BYTE bPad = (BYTE)Pad16((DWORD)(dwISize-dwImageSize));
  2318. //TRACE3(" dwRead: %lu\t dwImageSize: %lu\t Pad: %hd\n", dwRead, dwImageSize, bPad );
  2319. if (bPad==(dwImageSize))
  2320. dwImageSize = -1;
  2321. }
  2322. */
  2323. }
  2324. return (UINT)(dwOverAllSize);
  2325. }
  2326. #ifdef VB
  2327. static
  2328. UINT ParseVBData( LPVOID lpImageBuf, DWORD dwISize, LPVOID lpBuffer, DWORD dwSize )
  2329. {
  2330. // The following special format is used by VB for international messages
  2331. // The code here is mostly copied from the ParseMenu routine
  2332. // UGLY!! The following values are taken from GLOBALS.C in TMSB.
  2333. // I have added a couple not in use by VB in hopes not to re-build
  2334. // when they decide to add additionals
  2335. enum LOCALE {
  2336. FRENCH = 0x040C,
  2337. GERMAN = 0x0407,
  2338. SPANISH = 0X040A,
  2339. DANISH = 0X0406,
  2340. ITALIAN = 0X0410,
  2341. RUSSIAN = 0X0419,
  2342. JAPANESE = 0X0411,
  2343. PORTUGUESE = 0X0816,
  2344. DUTCH = 0X0413};
  2345. // {3,0x041D,850,"Swedish",""},
  2346. // {4,0x0414,850,"Norwegian Bokm�l","NOB"},
  2347. // {5,0x0814,850,"Norwegian Nynorsk","NON"},
  2348. // {6,0x040B,850,"Finnish","FIN"},
  2349. // {7,0x0C0C,863,"French Canadian","FRC"},
  2350. // {9,0x0416,850,"Portuguese (Brazilian)","BPO"},
  2351. // {10,0x0816,850,"Portuguese (Portugal)","PPO"},
  2352. // {17,0x0415,850,"Polish","POL"},
  2353. // {18,0x040E,850,"Hungarian","HUN"},
  2354. // {19,0x0405,850,"Czech","CZE"},
  2355. // {20,0x0401,864,"Arabic","ARA"},
  2356. // {21,0x040D,862,"Hebrew","HBR"},
  2357. // {23,0x0412,934,"Korean","KOR"},
  2358. // {24,0x041E,938,"Thai","THA"},
  2359. // {25,0x0404,936,"Chinese (Traditional)","CHI (Tra)"},
  2360. // {26,0x0404,936,"Chinese (Simplified)","CHI (Sim)"},
  2361. WORD wSig, wID;
  2362. LONG dwImageSize = dwISize;
  2363. LONG dwOverAllSize = 0L;
  2364. LONG lDummy;
  2365. BYTE far * lpImage = (BYTE far *)lpImageBuf;
  2366. static char szWork[MAXSTR];
  2367. BYTE far * lpBuf = (BYTE far *)lpBuffer;
  2368. LONG dwBufSize = dwSize;
  2369. BYTE far * lpItem = (BYTE far *)lpBuffer;
  2370. UINT uiOffset = 0;
  2371. GetWord( &lpImage, &wSig, &dwImageSize);
  2372. if ( wSig != RES_SIGNATURE ) // Not a VB resource
  2373. return 0;
  2374. GetWord( &lpImage, &wSig, &dwImageSize);
  2375. if ( wSig != 0 ) // Header should have zero ID
  2376. return 0;
  2377. GetString( &lpImage, &szWork[0], &dwImageSize );
  2378. LOCALE locale = (LOCALE)GetPrivateProfileInt("AUTOTRANS","Locale", 0, "ESPRESSO.INI");
  2379. if (( lstrcmp(szWork, "VBINTLSZ_FRENCH") == 0 && locale == FRENCH) ||
  2380. ( lstrcmp(szWork, "VBINTLSZ_GERMAN") == 0 && locale == GERMAN) ||
  2381. ( lstrcmp(szWork, "VBINTLSZ_ITALIAN") == 0 && locale == ITALIAN) ||
  2382. ( lstrcmp(szWork, "VBINTLSZ_JAPANESE") == 0 && locale == JAPANESE) ||
  2383. ( lstrcmp(szWork, "VBINTLSZ_SPANISH") == 0 && locale == SPANISH) ||
  2384. ( lstrcmp(szWork, "VBINTLSZ_DANISH") == 0 && locale == DANISH) ||
  2385. ( lstrcmp(szWork, "VBINTLSZ_DUTCH") == 0 && locale == DUTCH) ||
  2386. ( lstrcmp(szWork, "VBINTLSZ_PORTUGUESE") == 0 && locale == PORTUGUESE)
  2387. ) {
  2388. while ( dwImageSize > 0 ) {
  2389. GetWord( &lpImage, &wSig, &dwImageSize);
  2390. // Check for only padding remaining and exit
  2391. if ( wSig != RES_SIGNATURE )
  2392. if ( dwImageSize < 16 && *(BYTE *)lpImage == 0 )
  2393. break;
  2394. else
  2395. return ERROR_RW_INVALID_FILE;
  2396. GetWord( &lpImage, &wID, &dwImageSize); // ID
  2397. // Fixed field
  2398. dwOverAllSize += PutDWord( &lpBuf, 0, &dwBufSize);
  2399. // We don't have the size and pos in a string
  2400. dwOverAllSize += PutWord( &lpBuf, (WORD)-1, &dwBufSize);
  2401. dwOverAllSize += PutWord( &lpBuf, (WORD)-1, &dwBufSize);
  2402. dwOverAllSize += PutWord( &lpBuf, (WORD)-1, &dwBufSize);
  2403. dwOverAllSize += PutWord( &lpBuf, (WORD)-1, &dwBufSize);
  2404. // we don't have checksum and style
  2405. dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);
  2406. dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);
  2407. dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);
  2408. dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);
  2409. // We'll save the string's "resource" ID as an Item ID
  2410. dwOverAllSize += PutDWord( &lpBuf, wID, &dwBufSize);
  2411. // Don't save a resource ID or Type Id
  2412. dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);
  2413. dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);
  2414. // we don't display the language
  2415. dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);
  2416. // we don't have the codepage or the font name
  2417. dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);
  2418. dwOverAllSize += PutWord( &lpBuf, (WORD)-1, &dwBufSize);
  2419. dwOverAllSize += PutWord( &lpBuf, (WORD)-1, &dwBufSize);
  2420. dwOverAllSize += PutWord( &lpBuf, (WORD)-1, &dwBufSize);
  2421. dwOverAllSize += PutByte( &lpBuf, (BYTE)-1, &dwBufSize);
  2422. dwOverAllSize += PutByte( &lpBuf, (BYTE)-1, &dwBufSize);
  2423. // Let's put null were we don;t have the strings
  2424. uiOffset = sizeof(RESITEM);
  2425. dwOverAllSize += PutDWord( &lpBuf, 0, &dwBufSize); // ClassName
  2426. dwOverAllSize += PutDWord( &lpBuf, 0, &dwBufSize); // FaceName
  2427. dwOverAllSize += PutDWord( &lpBuf, (DWORD)(DWORD_PTR)(lpItem+uiOffset), &dwBufSize); // Caption
  2428. dwOverAllSize += PutDWord( &lpBuf, 0, &dwBufSize); // ResItem
  2429. dwOverAllSize += PutDWord( &lpBuf, 0, &dwBufSize); // TypeItem
  2430. // Get the text
  2431. GetString( &lpImage, &szWork[0], &dwImageSize ); // Text string
  2432. dwOverAllSize += PutString( & lpBuf, &szWork[0], &dwBufSize);
  2433. // Put the size of the resource
  2434. if (dwBufSize>=0) {
  2435. uiOffset += strlen((LPSTR)(lpItem+uiOffset))+1;
  2436. lDummy = 8;
  2437. PutDWord( &lpItem, (DWORD)uiOffset, &lDummy);
  2438. }
  2439. // Move to the next position
  2440. lpItem = lpBuf;
  2441. if (dwImageSize<=16) {
  2442. // Check if we are at the end and this is just padding
  2443. BYTE bPad = (BYTE)Pad16((DWORD)(dwISize-dwImageSize));
  2444. //TRACE3(" dwRead: %lu\t dwImageSize: %lu\t Pad: %hd\n", dwRead, dwImageSize, bPad );
  2445. if (bPad==(dwImageSize))
  2446. dwImageSize = -1;
  2447. }
  2448. }
  2449. return (UINT)(dwOverAllSize);
  2450. }
  2451. return 0;
  2452. }
  2453. #endif
  2454. static
  2455. UINT
  2456. UpdateAccel( LPVOID lpNewBuf, LONG dwNewSize,
  2457. LPVOID lpOldI, LONG dwOldImageSize,
  2458. LPVOID lpNewI, DWORD* pdwNewImageSize )
  2459. {
  2460. TRACE("UpdateAccel\n");
  2461. UINT uiError = ERROR_NO_ERROR;
  2462. BYTE far * lpNewImage = (BYTE far *) lpNewI;
  2463. LONG dwNewImageSize = *pdwNewImageSize;
  2464. BYTE far * lpOldImage = (BYTE far *) lpOldI;
  2465. DWORD dwOriginalOldSize = dwOldImageSize;
  2466. BYTE far * lpBuf = (BYTE far *) lpNewBuf;
  2467. LPRESITEM lpResItem = LPNULL;
  2468. //Old Items
  2469. BYTE fFlags = 0;
  2470. WORD wEvent = 0;
  2471. WORD wId = 0;
  2472. WORD wPos = 0;
  2473. // Updated items
  2474. BYTE fUpdFlags = 0;
  2475. WORD wUpdEvent = 0;
  2476. WORD wUpdId = 0;
  2477. WORD wUpdPos = 0;
  2478. LONG dwOverAllSize = 0l;
  2479. while (dwOldImageSize>0) {
  2480. wPos++;
  2481. // Get the information from the old image
  2482. GetByte( &lpOldImage, &fFlags, &dwOldImageSize );
  2483. GetWord( &lpOldImage, &wEvent, &dwOldImageSize );
  2484. GetWord( &lpOldImage, &wId, &dwOldImageSize );
  2485. if (fFlags & 0x80)
  2486. dwOldImageSize = 0;
  2487. if ((!wUpdPos) && dwNewSize ) {
  2488. lpResItem = (LPRESITEM) lpBuf;
  2489. wUpdId = LOWORD(lpResItem->dwItemID);
  2490. wUpdPos = HIWORD(lpResItem->dwItemID);
  2491. fUpdFlags = (BYTE)lpResItem->dwFlags;
  2492. wUpdEvent = (WORD)lpResItem->dwStyle;
  2493. lpBuf += lpResItem->dwSize;
  2494. dwNewSize -= lpResItem->dwSize;
  2495. }
  2496. TRACE3("Old Accel: wID: %hd\t wEvent: %hd\t wFlag: %hd\n", wId, wEvent, fFlags);
  2497. TRACE3("New Accel: wID: %hd\t wEvent: %hd\t wFlag: %hd\n", wUpdId, wUpdEvent, fUpdFlags);
  2498. if ((wPos==wUpdPos) && (wUpdId==wId)) {
  2499. if (fFlags & 0x80)
  2500. fFlags = fUpdFlags | 0x80;
  2501. else fFlags = fUpdFlags;
  2502. wEvent = wUpdEvent;
  2503. wUpdPos = 0;
  2504. }
  2505. dwOverAllSize += PutByte( &lpNewImage, fFlags, &dwNewImageSize);
  2506. dwOverAllSize += PutWord( &lpNewImage, wEvent, &dwNewImageSize);
  2507. dwOverAllSize += PutWord( &lpNewImage, wId, &dwNewImageSize);
  2508. /*
  2509. if (dwOldImageSize<=16) {
  2510. // Check if we are at the end and this is just padding
  2511. BYTE bPad = (BYTE)Pad16((DWORD)(dwOriginalOldSize-dwOldImageSize));
  2512. if (bPad==dwOldImageSize)
  2513. dwOldImageSize = 0;
  2514. }
  2515. */
  2516. }
  2517. if (dwOverAllSize>(LONG)*pdwNewImageSize) {
  2518. // calc the padding as well
  2519. dwOverAllSize += (BYTE)Pad4((DWORD)(dwOverAllSize));
  2520. *pdwNewImageSize = dwOverAllSize;
  2521. return uiError;
  2522. }
  2523. *pdwNewImageSize = *pdwNewImageSize-dwNewImageSize;
  2524. if (*pdwNewImageSize>0) {
  2525. // calculate padding
  2526. BYTE bPad = (BYTE)Pad4((DWORD)(*pdwNewImageSize));
  2527. if (bPad>dwNewImageSize) {
  2528. *pdwNewImageSize += bPad;
  2529. return uiError;
  2530. }
  2531. memset(lpNewImage, 0x00, bPad);
  2532. *pdwNewImageSize += bPad;
  2533. }
  2534. return uiError;
  2535. }
  2536. static
  2537. UINT
  2538. ParseMenu( LPVOID lpImageBuf, DWORD dwISize, LPVOID lpBuffer, DWORD dwSize )
  2539. {
  2540. // Should be almost impossible for a Menu to be Huge
  2541. BYTE far * lpImage = (BYTE far *)lpImageBuf;
  2542. LONG dwImageSize = dwISize;
  2543. BYTE far * lpBuf = (BYTE far *)lpBuffer;
  2544. LONG dwBufSize = dwSize;
  2545. BYTE far * lpItem = (BYTE far *)lpBuffer;
  2546. UINT uiOffset = 0;
  2547. LONG lDummy;
  2548. LONG dwOverAllSize = 0L;
  2549. // skip the menu header
  2550. SkipByte( &lpImage, 4, &dwImageSize );
  2551. // Menu Items
  2552. WORD fItemFlags;
  2553. WORD wMenuId;
  2554. static char szCaption[MAXSTR];
  2555. int iter = 1;
  2556. while (dwImageSize>0) {
  2557. // Let's get the Menu flags
  2558. GetWord( &lpImage, &fItemFlags, &dwImageSize );
  2559. if ( !(fItemFlags & MF_POPUP) )
  2560. // Get the menu Id
  2561. GetWord( &lpImage, &wMenuId, &dwImageSize );
  2562. else wMenuId = (WORD)-1;
  2563. // Get the text
  2564. GetString( &lpImage, &szCaption[0], &dwImageSize );
  2565. // Check if is not a separator or padding
  2566. // Fixed field
  2567. dwOverAllSize += PutDWord( &lpBuf, 0, &dwBufSize);
  2568. // We don't have the size and pos in a menu
  2569. dwOverAllSize += PutWord( &lpBuf, (WORD)-1, &dwBufSize);
  2570. dwOverAllSize += PutWord( &lpBuf, (WORD)-1, &dwBufSize);
  2571. dwOverAllSize += PutWord( &lpBuf, (WORD)-1, &dwBufSize);
  2572. dwOverAllSize += PutWord( &lpBuf, (WORD)-1, &dwBufSize);
  2573. // we don't have checksum and style
  2574. dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);
  2575. dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);
  2576. dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);
  2577. //Put the Flag
  2578. dwOverAllSize += PutDWord( &lpBuf, (DWORD)fItemFlags, &dwBufSize);
  2579. //Put the MenuId
  2580. dwOverAllSize += PutDWord( &lpBuf, (DWORD)wMenuId, &dwBufSize);
  2581. // we don't have the resID, and the Type Id
  2582. dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);
  2583. dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);
  2584. // we don't have the language
  2585. dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);
  2586. // we don't have the codepage or the font name
  2587. dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);
  2588. dwOverAllSize += PutWord( &lpBuf, (WORD)-1, &dwBufSize);
  2589. dwOverAllSize += PutWord( &lpBuf, (WORD)-1, &dwBufSize);
  2590. dwOverAllSize += PutWord( &lpBuf, (WORD)-1, &dwBufSize);
  2591. dwOverAllSize += PutByte( &lpBuf, (BYTE)-1, &dwBufSize);
  2592. dwOverAllSize += PutByte( &lpBuf, (BYTE)-1, &dwBufSize);
  2593. // Let's put null were we don;t have the strings
  2594. uiOffset = sizeof(RESITEM);
  2595. dwOverAllSize += PutDWord( &lpBuf, 0, &dwBufSize);
  2596. dwOverAllSize += PutDWord( &lpBuf, 0, &dwBufSize);
  2597. dwOverAllSize += PutDWord( &lpBuf, (DWORD)(DWORD_PTR)(lpItem+uiOffset), &dwBufSize);
  2598. dwOverAllSize += PutDWord( &lpBuf, 0, &dwBufSize);
  2599. dwOverAllSize += PutDWord( &lpBuf, 0, &dwBufSize);
  2600. // Get the text
  2601. // calculate were the string is going to be
  2602. // Will be the fixed header+the pointer
  2603. dwOverAllSize += PutString( &lpBuf, &szCaption[0], &dwBufSize);
  2604. TRACE("Menu: Iteration %d size %d\n", iter++, dwOverAllSize);
  2605. // Put the size of the resource
  2606. uiOffset += strlen(szCaption)+1;
  2607. // Check if we are alligned
  2608. lDummy = Allign( &lpBuf, &dwBufSize, (LONG)uiOffset);
  2609. dwOverAllSize += lDummy;
  2610. uiOffset += lDummy;
  2611. lDummy = 4;
  2612. if (dwBufSize>=0)
  2613. PutDWord( &lpItem, (DWORD)uiOffset, &lDummy);
  2614. // Move to the next position
  2615. lpItem = lpBuf;
  2616. if (dwImageSize<=16) {
  2617. // Check if we are at the end and this is just padding
  2618. BYTE bPad = (BYTE)Pad16((DWORD)(dwISize-dwImageSize));
  2619. //TRACE3(" dwRead: %lu\t dwImageSize: %lu\t Pad: %hd\n", dwRead, dwImageSize, bPad );
  2620. if (bPad==dwImageSize) {
  2621. BYTE far * lpBuf = lpImage;
  2622. while (bPad) {
  2623. if (*lpBuf++!=0x00)
  2624. break;
  2625. bPad--;
  2626. }
  2627. if (bPad==0)
  2628. dwImageSize = -1;
  2629. }
  2630. }
  2631. }
  2632. return (UINT)(dwOverAllSize);
  2633. }
  2634. static
  2635. UINT
  2636. UpdateMenu( LPVOID lpNewBuf, LONG dwNewSize,
  2637. LPVOID lpOldI, LONG dwOldImageSize,
  2638. LPVOID lpNewI, DWORD* pdwNewImageSize )
  2639. {
  2640. UINT uiError = ERROR_NO_ERROR;
  2641. BYTE far * lpNewImage = (BYTE far *) lpNewI;
  2642. LONG dwNewImageSize = *pdwNewImageSize;
  2643. BYTE far * lpOldImage = (BYTE far *) lpOldI;
  2644. DWORD dwOriginalOldSize = dwOldImageSize;
  2645. BYTE far * lpBuf = (BYTE far *) lpNewBuf;
  2646. LPRESITEM lpResItem = LPNULL;
  2647. // We have to read the information from the lpNewBuf
  2648. // Menu Items
  2649. WORD fItemFlags;
  2650. WORD wMenuId;
  2651. char szTxt[256];
  2652. WORD wPos = 0;
  2653. // Updated items
  2654. WORD wUpdPos = 0;
  2655. WORD fUpdItemFlags;
  2656. WORD wUpdMenuId;
  2657. char szUpdTxt[256];
  2658. LONG dwOverAllSize = 0l;
  2659. // Copy the menu flags
  2660. dwOldImageSize -= PutDWord( &lpNewImage, *((DWORD*)lpOldImage), &dwNewImageSize);
  2661. lpOldImage += sizeofDWord;
  2662. dwOverAllSize += sizeofDWord;
  2663. while (dwOldImageSize>0) {
  2664. wPos++;
  2665. // Get the information from the old image
  2666. // Get the menu flag
  2667. GetWord( &lpOldImage, &fItemFlags, &dwOldImageSize );
  2668. if ( !(fItemFlags & MF_POPUP) )
  2669. GetWord( &lpOldImage, &wMenuId, &dwOldImageSize );
  2670. else wMenuId = (WORD)-1;
  2671. // Get the text
  2672. GetString( &lpOldImage, &szTxt[0], &dwOldImageSize );
  2673. if ((!wUpdPos) && dwNewSize ) {
  2674. lpResItem = (LPRESITEM) lpBuf;
  2675. wUpdPos = HIWORD(lpResItem->dwItemID);
  2676. wUpdMenuId = LOWORD(lpResItem->dwItemID);
  2677. fUpdItemFlags = (WORD)lpResItem->dwFlags;
  2678. strcpy( szUpdTxt, lpResItem->lpszCaption );
  2679. lpBuf += lpResItem->dwSize;
  2680. dwNewSize -= lpResItem->dwSize;
  2681. }
  2682. if ((wPos==wUpdPos) && (wUpdMenuId==wMenuId)) {
  2683. // check if it is not the last item in the menu
  2684. if (fItemFlags & MF_END)
  2685. fItemFlags = fUpdItemFlags | (WORD)MF_END;
  2686. else fItemFlags = fUpdItemFlags;
  2687. wMenuId = wUpdMenuId;
  2688. // check it is not a separator
  2689. if ((fItemFlags==0) && (wMenuId==0))
  2690. strcpy(szTxt, "");
  2691. else strcpy(szTxt, szUpdTxt);
  2692. wUpdPos = 0;
  2693. }
  2694. dwOverAllSize += PutWord( &lpNewImage, fItemFlags, &dwNewImageSize);
  2695. if ( !(fItemFlags & MF_POPUP) ) {
  2696. dwOverAllSize += PutWord( &lpNewImage, wMenuId, &dwNewImageSize);
  2697. }
  2698. // Write the text
  2699. dwOverAllSize += PutString( &lpNewImage, &szTxt[0], &dwNewImageSize);
  2700. // Check for padding
  2701. if (dwOldImageSize<=16) {
  2702. // Check if we are at the end and this is just padding
  2703. BYTE bPad = (BYTE)Pad16((dwOriginalOldSize-dwOldImageSize));
  2704. //TRACE3(" dwRead: %lu\t dwImageSize: %lu\t Pad: %hd\n", dwRead, dwOldImageSize, bPad );
  2705. if (bPad==dwOldImageSize) {
  2706. BYTE far * lpBuf = lpOldImage;
  2707. while (bPad) {
  2708. if (*lpBuf++!=0x00)
  2709. break;
  2710. bPad--;
  2711. }
  2712. if (bPad==0)
  2713. dwOldImageSize = -1;
  2714. }
  2715. }
  2716. }
  2717. if (dwOverAllSize>(LONG)*pdwNewImageSize) {
  2718. // calc the padding as well
  2719. dwOverAllSize += (BYTE)Pad4((DWORD)(dwOverAllSize));
  2720. *pdwNewImageSize = dwOverAllSize;
  2721. return uiError;
  2722. }
  2723. *pdwNewImageSize = *pdwNewImageSize-dwNewImageSize;
  2724. if (*pdwNewImageSize>0) {
  2725. // calculate padding
  2726. BYTE bPad = (BYTE)Pad4((DWORD)(*pdwNewImageSize));
  2727. if (bPad>dwNewImageSize) {
  2728. *pdwNewImageSize += bPad;
  2729. return uiError;
  2730. }
  2731. memset(lpNewImage, 0x00, bPad);
  2732. *pdwNewImageSize += bPad;
  2733. }
  2734. return uiError;
  2735. }
  2736. static UINT GenerateMenu( LPVOID lpNewBuf, LONG dwNewSize,
  2737. LPVOID lpNewI, DWORD* pdwNewImageSize )
  2738. {
  2739. UINT uiError = ERROR_NO_ERROR;
  2740. BYTE far * lpNewImage = (BYTE far *) lpNewI;
  2741. LONG dwNewImageSize = *pdwNewImageSize;
  2742. BYTE far * lpBuf = (BYTE far *) lpNewBuf;
  2743. LPRESITEM lpResItem = LPNULL;
  2744. // We have to read the information from the lpNewBuf
  2745. // Updated items
  2746. WORD wUpdPos = 0;
  2747. WORD fUpdItemFlags;
  2748. WORD wUpdMenuId;
  2749. char szUpdTxt[256];
  2750. LONG dwOverAllSize = 0l;
  2751. // invent the menu flags
  2752. dwOverAllSize += PutDWord( &lpNewImage, 0L, &dwNewImageSize);
  2753. while (dwNewSize>0) {
  2754. if (dwNewSize ) {
  2755. lpResItem = (LPRESITEM) lpBuf;
  2756. wUpdMenuId = LOWORD(lpResItem->dwItemID);
  2757. fUpdItemFlags = (WORD)lpResItem->dwFlags;
  2758. strcpy( szUpdTxt, lpResItem->lpszCaption );
  2759. lpBuf += lpResItem->dwSize;
  2760. dwNewSize -= lpResItem->dwSize;
  2761. }
  2762. dwOverAllSize += PutWord( &lpNewImage, fUpdItemFlags, &dwNewImageSize);
  2763. if ( !(fUpdItemFlags & MF_POPUP) )
  2764. dwOverAllSize += PutWord( &lpNewImage, wUpdMenuId, &dwNewImageSize);
  2765. // Write the text
  2766. // check if it is a separator
  2767. if ( !(fUpdItemFlags) && !(wUpdMenuId) )
  2768. szUpdTxt[0] = 0x00;
  2769. dwOverAllSize += PutString( &lpNewImage, &szUpdTxt[0], &dwNewImageSize);
  2770. }
  2771. if (dwOverAllSize>(LONG)*pdwNewImageSize) {
  2772. // calc the padding as well
  2773. dwOverAllSize += (BYTE)Pad4((DWORD)(dwOverAllSize));
  2774. *pdwNewImageSize = dwOverAllSize;
  2775. return uiError;
  2776. }
  2777. *pdwNewImageSize = *pdwNewImageSize-dwNewImageSize;
  2778. if (*pdwNewImageSize>0) {
  2779. // calculate padding
  2780. BYTE bPad = (BYTE)Pad4((DWORD)(*pdwNewImageSize));
  2781. if (bPad>dwNewImageSize) {
  2782. *pdwNewImageSize += bPad;
  2783. return uiError;
  2784. }
  2785. memset(lpNewImage, 0x00, bPad);
  2786. *pdwNewImageSize += bPad;
  2787. }
  2788. return uiError;
  2789. }
  2790. static
  2791. UINT
  2792. ParseString( LPVOID lpImageBuf, DWORD dwISize, LPVOID lpBuffer, DWORD dwSize )
  2793. {
  2794. // Should be almost impossible for a String to be Huge
  2795. BYTE far * lpImage = (BYTE far *)lpImageBuf;
  2796. LONG dwImageSize = dwISize;
  2797. BYTE far * lpBuf = (BYTE far *)lpBuffer;
  2798. LONG dwBufSize = dwSize;
  2799. BYTE far * lpItem = (BYTE far *)lpBuffer;
  2800. UINT uiOffset = 0;
  2801. LONG lDummy;
  2802. LONG dwOverAllSize = 0L;
  2803. LONG dwRead = 0L;
  2804. BYTE bIdCount = 0;
  2805. while ( (dwImageSize>0) && (bIdCount<16) ) {
  2806. // Fixed field
  2807. dwOverAllSize += PutDWord( &lpBuf, 0, &dwBufSize);
  2808. // We don't have the size and pos in a string
  2809. dwOverAllSize += PutWord( &lpBuf, (WORD)-1, &dwBufSize);
  2810. dwOverAllSize += PutWord( &lpBuf, (WORD)-1, &dwBufSize);
  2811. dwOverAllSize += PutWord( &lpBuf, (WORD)-1, &dwBufSize);
  2812. dwOverAllSize += PutWord( &lpBuf, (WORD)-1, &dwBufSize);
  2813. // we don't have checksum and style
  2814. dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);
  2815. dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);
  2816. dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);
  2817. dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);
  2818. //Put the StringId
  2819. dwOverAllSize += PutDWord( &lpBuf, bIdCount++, &dwBufSize);
  2820. // we don't have the resID, and the Type Id
  2821. dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);
  2822. dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);
  2823. // we don't have the language
  2824. dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);
  2825. // we don't have the codepage or the font name
  2826. dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);
  2827. dwOverAllSize += PutWord( &lpBuf, (WORD)-1, &dwBufSize);
  2828. dwOverAllSize += PutWord( &lpBuf, (WORD)-1, &dwBufSize);
  2829. dwOverAllSize += PutWord( &lpBuf, (WORD)-1, &dwBufSize);
  2830. dwOverAllSize += PutByte( &lpBuf, (BYTE)-1, &dwBufSize);
  2831. dwOverAllSize += PutByte( &lpBuf, (BYTE)-1, &dwBufSize);
  2832. // Let's put null were we don;t have the strings
  2833. uiOffset = sizeof(RESITEM);
  2834. dwOverAllSize += PutDWord( &lpBuf, 0, &dwBufSize); // ClassName
  2835. dwOverAllSize += PutDWord( &lpBuf, 0, &dwBufSize); // FaceName
  2836. dwOverAllSize += PutDWord( &lpBuf, (DWORD)(DWORD_PTR)(lpItem+uiOffset), &dwBufSize); // Caption
  2837. dwOverAllSize += PutDWord( &lpBuf, 0, &dwBufSize); // ResItem
  2838. dwOverAllSize += PutDWord( &lpBuf, 0, &dwBufSize); // TypeItem
  2839. // Get the text
  2840. BYTE bstrlen = *lpImage++;
  2841. dwImageSize -= 1;
  2842. TRACE1("StrLen: %hd\t", bstrlen);
  2843. if ((bstrlen+1)>dwBufSize) {
  2844. dwOverAllSize += bstrlen+1;
  2845. dwImageSize -= bstrlen;
  2846. lpImage += bstrlen;
  2847. dwBufSize -= bstrlen+1;
  2848. TRACE1("BufferSize: %ld\n", dwBufSize);
  2849. } else {
  2850. if (bstrlen)
  2851. memcpy( (char*)lpBuf, (char*)lpImage, bstrlen );
  2852. *(lpBuf+(bstrlen)) = 0;
  2853. TRACE1("Caption: %Fs\n", lpBuf);
  2854. lpImage += bstrlen;
  2855. lpBuf += bstrlen+1;
  2856. dwImageSize -= bstrlen;
  2857. dwBufSize -= bstrlen+1;
  2858. dwOverAllSize += bstrlen+1;
  2859. }
  2860. // Put the size of the resource
  2861. uiOffset += bstrlen+1;
  2862. // Check if we are alligned
  2863. lDummy = Allign( &lpBuf, &dwBufSize, (LONG)uiOffset);
  2864. dwOverAllSize += lDummy;
  2865. uiOffset += lDummy;
  2866. lDummy = 4;
  2867. if (dwBufSize>=0)
  2868. PutDWord( &lpItem, (DWORD)uiOffset, &lDummy);
  2869. // Move to the next position
  2870. lpItem = lpBuf;
  2871. if ((dwImageSize<=16) && (bIdCount==16)) {
  2872. // Check if we are at the end and this is just padding
  2873. BYTE bPad = (BYTE)Pad16((DWORD)(dwISize-dwImageSize));
  2874. //TRACE3(" dwRead: %lu\t dwImageSize: %lu\t Pad: %hd\n", dwRead, dwImageSize, bPad );
  2875. if (bPad==dwImageSize)
  2876. dwImageSize = -1;
  2877. }
  2878. }
  2879. return (UINT)(dwOverAllSize);
  2880. }
  2881. static
  2882. UINT
  2883. UpdateString( LPVOID lpNewBuf, LONG dwNewSize,
  2884. LPVOID lpOldI, LONG dwOldImageSize,
  2885. LPVOID lpNewI, DWORD* pdwNewImageSize )
  2886. {
  2887. UINT uiError = ERROR_NO_ERROR;
  2888. LONG dwNewImageSize = *pdwNewImageSize;
  2889. BYTE far * lpNewImage = (BYTE far *) lpNewI;
  2890. BYTE far * lpOldImage = (BYTE far *) lpOldI;
  2891. BYTE far * lpBuf = (BYTE far *) lpNewBuf;
  2892. LPRESITEM lpResItem = LPNULL;
  2893. // We have to read the information from the lpNewBuf
  2894. BYTE bLen;
  2895. char szTxt[MAXSTR];
  2896. WORD wPos = 0;
  2897. // Updated info
  2898. WORD wUpdPos = 0;
  2899. char szUpdTxt[MAXSTR];
  2900. DWORD dwOriginalOldSize = dwOldImageSize;
  2901. LONG dwOverAllSize = 0l;
  2902. while (dwOldImageSize>0) {
  2903. wPos++;
  2904. // Get the information from the old image
  2905. GetByte( &lpOldImage, &bLen, &dwOldImageSize );
  2906. // Copy the text
  2907. if (bLen>MAXSTR) {
  2908. } else {
  2909. memcpy( szTxt, (char*)lpOldImage, bLen );
  2910. lpOldImage += bLen;
  2911. dwOldImageSize -= bLen;
  2912. szTxt[bLen]='\0';
  2913. }
  2914. if ((!wUpdPos) && dwNewSize ) {
  2915. /*
  2916. GetUpdatedItem(
  2917. &lpNewBuf, &dwNewSize,
  2918. &wDummy, &wDummy,
  2919. &wDummy, &wDummy,
  2920. &dwPosId,
  2921. &dwDummy, &dwDummy,
  2922. &szUpdTxt[0]);
  2923. wUpdPos = HIWORD(dwPosId);
  2924. */
  2925. lpResItem = (LPRESITEM) lpBuf;
  2926. wUpdPos = HIWORD(lpResItem->dwItemID);
  2927. strcpy( szUpdTxt, lpResItem->lpszCaption );
  2928. lpBuf += lpResItem->dwSize;
  2929. dwNewSize -= lpResItem->dwSize;
  2930. }
  2931. if ((wPos==wUpdPos)) {
  2932. strcpy(szTxt, szUpdTxt);
  2933. wUpdPos = 0;
  2934. }
  2935. bLen = strlen(szTxt);
  2936. //dwOverAllSize += PutByte( &lpNewImage, (BYTE)bLen, &dwNewImageSize);
  2937. // Write the text
  2938. dwOverAllSize += PutPascalString( &lpNewImage, &szTxt[0], bLen, &dwNewImageSize );
  2939. if ((dwOldImageSize<=16) && (wPos==16)) {
  2940. // Check if we are at the end and this is just padding
  2941. BYTE bPad = (BYTE)Pad16((DWORD)(dwOriginalOldSize-dwOldImageSize));
  2942. //TRACE3(" dwRead: %lu\t dwImageSize: %lu\t Pad: %hd\n", dwRead, dwImageSize, bPad );
  2943. if (bPad==dwOldImageSize)
  2944. dwOldImageSize = -1;
  2945. }
  2946. }
  2947. if (dwOverAllSize>(LONG)*pdwNewImageSize) {
  2948. // calc the padding as well
  2949. dwOverAllSize += (BYTE)Pad4((DWORD)(dwOverAllSize));
  2950. *pdwNewImageSize = dwOverAllSize;
  2951. return uiError;
  2952. }
  2953. *pdwNewImageSize = *pdwNewImageSize-dwNewImageSize;
  2954. if (*pdwNewImageSize>0) {
  2955. // calculate padding
  2956. BYTE bPad = (BYTE)Pad4((DWORD)(*pdwNewImageSize));
  2957. if (bPad>dwNewImageSize) {
  2958. *pdwNewImageSize += bPad;
  2959. return uiError;
  2960. }
  2961. memset(lpNewImage, 0x00, bPad);
  2962. *pdwNewImageSize += bPad;
  2963. }
  2964. return uiError;
  2965. }
  2966. static
  2967. UINT
  2968. GenerateString( LPVOID lpNewBuf, LONG dwNewSize,
  2969. LPVOID lpNewI, DWORD* pdwNewImageSize )
  2970. {
  2971. UINT uiError = ERROR_NO_ERROR;
  2972. LONG dwNewImageSize = *pdwNewImageSize;
  2973. BYTE far * lpNewImage = (BYTE far *) lpNewI;
  2974. BYTE far * lpBuf = (BYTE far *) lpNewBuf;
  2975. LPRESITEM lpResItem = LPNULL;
  2976. // We have to read the information from the lpNewBuf
  2977. BYTE bLen;
  2978. static char szTxt[MAXSTR];
  2979. WORD wPos = 0;
  2980. LONG dwOverAllSize = 0l;
  2981. while (dwNewSize>0) {
  2982. if ( dwNewSize ) {
  2983. lpResItem = (LPRESITEM) lpBuf;
  2984. strcpy( szTxt, lpResItem->lpszCaption );
  2985. lpBuf += lpResItem->dwSize;
  2986. dwNewSize -= lpResItem->dwSize;
  2987. }
  2988. bLen = strlen(szTxt);
  2989. // Write the text
  2990. dwOverAllSize += PutPascalString( &lpNewImage, &szTxt[0], bLen, &dwNewImageSize );
  2991. }
  2992. if (dwOverAllSize>(LONG)*pdwNewImageSize) {
  2993. // calc the padding as well
  2994. dwOverAllSize += (BYTE)Pad4((DWORD)(dwOverAllSize));
  2995. *pdwNewImageSize = dwOverAllSize;
  2996. return uiError;
  2997. }
  2998. *pdwNewImageSize = *pdwNewImageSize-dwNewImageSize;
  2999. if (*pdwNewImageSize>0) {
  3000. // calculate padding
  3001. BYTE bPad = (BYTE)Pad4((DWORD)(*pdwNewImageSize));
  3002. if (bPad>dwNewImageSize) {
  3003. *pdwNewImageSize += bPad;
  3004. return uiError;
  3005. }
  3006. memset(lpNewImage, 0x00, bPad);
  3007. *pdwNewImageSize += bPad;
  3008. }
  3009. return uiError;
  3010. }
  3011. static
  3012. UINT
  3013. ParseDialog( LPVOID lpImageBuf, DWORD dwISize, LPVOID lpBuffer, DWORD dwSize )
  3014. {
  3015. // Should be almost impossible for a Dialog to be Huge
  3016. BYTE far * lpImage = (BYTE far *)lpImageBuf;
  3017. LONG dwImageSize = dwISize;
  3018. BYTE far * lpBuf = (BYTE far *)lpBuffer;
  3019. LONG dwBufSize = dwSize;
  3020. LPRESITEM lpResItem = (LPRESITEM)lpBuffer;
  3021. UINT uiOffset = 0;
  3022. char far * lpStrBuf = (char far *)(lpBuf+sizeof(RESITEM));
  3023. LONG dwOverAllSize = 0L;
  3024. BYTE bIdCount = 0;
  3025. // Dialog Elements
  3026. DWORD dwStyle = 0L;
  3027. BYTE bNumOfElem = 0;
  3028. WORD wX = 0;
  3029. WORD wY = 0;
  3030. WORD wcX = 0;
  3031. WORD wcY = 0;
  3032. WORD wId = 0;
  3033. static char szMenuName[MAXID];
  3034. WORD wMenuName;
  3035. static char szClassName[MAXID];
  3036. BYTE bClassName, bControlClassName;
  3037. static char szCaption[MAXSTR];
  3038. WORD wOrd;
  3039. WORD wPointSize = 0;
  3040. static char szFaceName[MAXID];
  3041. // read the dialog header
  3042. GetDWord( &lpImage, &dwStyle, &dwImageSize );
  3043. GetByte( &lpImage, &bNumOfElem, &dwImageSize );
  3044. GetWord( &lpImage, &wX, &dwImageSize );
  3045. GetWord( &lpImage, &wY, &dwImageSize );
  3046. GetWord( &lpImage, &wcX, &dwImageSize );
  3047. GetWord( &lpImage, &wcY, &dwImageSize );
  3048. GetNameOrOrd( &lpImage, &wMenuName, &szMenuName[0], &dwImageSize );
  3049. GetClassName( &lpImage, &bClassName, &szClassName[0], &dwImageSize );
  3050. GetCaptionOrOrd( &lpImage, &wOrd, &szCaption[0], &dwImageSize,
  3051. bClassName, dwStyle );
  3052. if ( dwStyle & DS_SETFONT ) {
  3053. GetWord( &lpImage, &wPointSize, &dwImageSize );
  3054. GetString( &lpImage, &szFaceName[0], &dwImageSize );
  3055. }
  3056. TRACE("Win16.DLL ParseDialog\t");
  3057. TRACE1("NumElem: %hd\t", bNumOfElem);
  3058. TRACE1("X %hd\t", wX);
  3059. TRACE1("Y: %hd\t", wY);
  3060. TRACE1("CX: %hd\t", wcX);
  3061. TRACE1("CY: %hd\t", wcY);
  3062. TRACE1("Id: %hd\t", wId);
  3063. TRACE1("Style: %lu\n", dwStyle);
  3064. TRACE1("Caption: %s\n", szCaption);
  3065. TRACE2("ClassName: %s\tClassId: %hd\n", szClassName, bClassName );
  3066. TRACE2("MenuName: %s\tMenuId: %hd\n", szMenuName, wMenuName );
  3067. TRACE2("FontName: %s\tPoint: %hd\n", szFaceName, wPointSize );
  3068. // Fixed field
  3069. dwOverAllSize += PutDWord( &lpBuf, 0, &dwBufSize);
  3070. dwOverAllSize += PutWord( &lpBuf, wX, &dwBufSize);
  3071. dwOverAllSize += PutWord( &lpBuf, wY, &dwBufSize);
  3072. dwOverAllSize += PutWord( &lpBuf, wcX, &dwBufSize);
  3073. dwOverAllSize += PutWord( &lpBuf, wcY, &dwBufSize);
  3074. // we don't have checksum and extended style
  3075. dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);
  3076. dwOverAllSize += PutDWord( &lpBuf, dwStyle, &dwBufSize);
  3077. dwOverAllSize += PutDWord( &lpBuf, 0, &dwBufSize);
  3078. dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);
  3079. //Put the Id 0 for the main dialog
  3080. dwOverAllSize += PutDWord( &lpBuf, bIdCount++, &dwBufSize);
  3081. // we don't have the resID, and the Type Id
  3082. dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);
  3083. dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);
  3084. // we don't have the language
  3085. dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);
  3086. // we don't have the codepage
  3087. dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);
  3088. dwOverAllSize += PutWord( &lpBuf, bClassName, &dwBufSize);
  3089. dwOverAllSize += PutWord( &lpBuf, wPointSize, &dwBufSize);
  3090. dwOverAllSize += PutWord( &lpBuf, (WORD)-1, &dwBufSize);
  3091. dwOverAllSize += PutByte( &lpBuf, (BYTE)-1, &dwBufSize);
  3092. dwOverAllSize += PutByte( &lpBuf, (BYTE)DEFAULT_CHARSET, &dwBufSize);
  3093. // Let's put null were we don;t have the strings
  3094. uiOffset = sizeof(RESITEM);
  3095. dwOverAllSize += PutDWord( &lpBuf, 0, &dwBufSize); // ClassName
  3096. dwOverAllSize += PutDWord( &lpBuf, 0, &dwBufSize); // FaceName
  3097. dwOverAllSize += PutDWord( &lpBuf, 0, &dwBufSize); // Caption
  3098. dwOverAllSize += PutDWord( &lpBuf, 0, &dwBufSize); // ResItem
  3099. dwOverAllSize += PutDWord( &lpBuf, 0, &dwBufSize); // TypeItem
  3100. lpResItem->lpszClassName = strcpy( lpStrBuf, szClassName );
  3101. lpStrBuf += strlen(lpResItem->lpszClassName)+1;
  3102. lpResItem->lpszFaceName = strcpy( lpStrBuf, szFaceName );
  3103. lpStrBuf += strlen(lpResItem->lpszFaceName)+1;
  3104. lpResItem->lpszCaption = strcpy( lpStrBuf, szCaption );
  3105. lpStrBuf += strlen(lpResItem->lpszCaption)+1;
  3106. // Put the size of the resource
  3107. if (dwBufSize>0) {
  3108. uiOffset += strlen((LPSTR)(lpResItem->lpszClassName))+1;
  3109. uiOffset += strlen((LPSTR)(lpResItem->lpszFaceName))+1;
  3110. uiOffset += strlen((LPSTR)(lpResItem->lpszCaption))+1;
  3111. }
  3112. // Check if we are alligned
  3113. uiOffset += Allign( (BYTE**)&lpStrBuf, &dwBufSize, (LONG)uiOffset);
  3114. dwOverAllSize += uiOffset-sizeof(RESITEM);
  3115. lpResItem->dwSize = (DWORD)uiOffset;
  3116. // Move to the next position
  3117. lpResItem = (LPRESITEM) lpStrBuf;
  3118. lpBuf = (BYTE far *)lpStrBuf;
  3119. lpStrBuf = (char far *)(lpBuf+sizeof(RESITEM));
  3120. while ( (dwImageSize>0) && (bNumOfElem>0) ) {
  3121. // Read the COntrols
  3122. GetWord( &lpImage, &wX, &dwImageSize );
  3123. GetWord( &lpImage, &wY, &dwImageSize );
  3124. GetWord( &lpImage, &wcX, &dwImageSize );
  3125. GetWord( &lpImage, &wcY, &dwImageSize );
  3126. GetWord( &lpImage, &wId, &dwImageSize );
  3127. GetDWord( &lpImage, &dwStyle, &dwImageSize );
  3128. GetControlClassName( &lpImage, &bControlClassName, &szClassName[0], &dwImageSize );
  3129. GetCaptionOrOrd( &lpImage, &wOrd, &szCaption[0], &dwImageSize,
  3130. bControlClassName, dwStyle );
  3131. SkipByte( &lpImage, 1, &dwImageSize );
  3132. bNumOfElem--;
  3133. // Fixed field
  3134. dwOverAllSize += PutDWord( &lpBuf, 0, &dwBufSize);
  3135. dwOverAllSize += PutWord( &lpBuf, wX, &dwBufSize);
  3136. dwOverAllSize += PutWord( &lpBuf, wY, &dwBufSize);
  3137. dwOverAllSize += PutWord( &lpBuf, wcX, &dwBufSize);
  3138. dwOverAllSize += PutWord( &lpBuf, wcY, &dwBufSize);
  3139. // we don't have checksum and extended style
  3140. dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);
  3141. dwOverAllSize += PutDWord( &lpBuf, dwStyle, &dwBufSize);
  3142. dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);
  3143. dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);
  3144. //Put the Id
  3145. dwOverAllSize += PutDWord( &lpBuf, wId, &dwBufSize);
  3146. // we don't have the resID, and the Type Id
  3147. dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);
  3148. dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);
  3149. // we don't have the language
  3150. dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);
  3151. // we don't have the codepage
  3152. dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);
  3153. dwOverAllSize += PutWord( &lpBuf, bControlClassName, &dwBufSize);
  3154. dwOverAllSize += PutWord( &lpBuf, wPointSize, &dwBufSize);
  3155. dwOverAllSize += PutByte( &lpBuf, (BYTE)-1, &dwBufSize);
  3156. dwOverAllSize += PutByte( &lpBuf, DEFAULT_CHARSET, &dwBufSize);
  3157. // Let's put null were we don;t have the strings
  3158. uiOffset = sizeof(RESITEM);
  3159. dwOverAllSize += PutDWord( &lpBuf, 0, &dwBufSize); // ClassName
  3160. dwOverAllSize += PutDWord( &lpBuf, 0, &dwBufSize); // FaceName
  3161. dwOverAllSize += PutDWord( &lpBuf, 0, &dwBufSize); // Caption
  3162. dwOverAllSize += PutDWord( &lpBuf, 0, &dwBufSize); // ResItem
  3163. dwOverAllSize += PutDWord( &lpBuf, 0, &dwBufSize); // TypeItem
  3164. lpResItem->lpszClassName = strcpy( lpStrBuf, szClassName );
  3165. lpStrBuf += strlen(lpResItem->lpszClassName)+1;
  3166. lpResItem->lpszFaceName = strcpy( lpStrBuf, szFaceName );
  3167. lpStrBuf += strlen(lpResItem->lpszFaceName)+1;
  3168. lpResItem->lpszCaption = strcpy( lpStrBuf, szCaption );
  3169. lpStrBuf += strlen(lpResItem->lpszCaption)+1;
  3170. // Put the size of the resource
  3171. if (dwBufSize>0) {
  3172. uiOffset += strlen((LPSTR)(lpResItem->lpszClassName))+1;
  3173. uiOffset += strlen((LPSTR)(lpResItem->lpszFaceName))+1;
  3174. uiOffset += strlen((LPSTR)(lpResItem->lpszCaption))+1;
  3175. }
  3176. // Check if we are alligned
  3177. uiOffset += Allign( (BYTE**)&lpStrBuf, &dwBufSize, (LONG)uiOffset);
  3178. dwOverAllSize += uiOffset-sizeof(RESITEM);
  3179. lpResItem->dwSize = (DWORD)uiOffset;
  3180. // Move to the next position
  3181. lpResItem = (LPRESITEM) lpStrBuf;
  3182. lpBuf = (BYTE far *)lpStrBuf;
  3183. lpStrBuf = (char far *)(lpBuf+sizeof(RESITEM));
  3184. TRACE1("\tControl: X: %hd\t", wX);
  3185. TRACE1("Y: %hd\t", wY);
  3186. TRACE1("CX: %hd\t", wcX);
  3187. TRACE1("CY: %hd\t", wcY);
  3188. TRACE1("Id: %hd\t", wId);
  3189. TRACE1("Style: %lu\n", dwStyle);
  3190. TRACE1("Caption: %s\n", szCaption);
  3191. if (dwImageSize<=16) {
  3192. // Check if we are at the end and this is just padding
  3193. BYTE bPad = (BYTE)Pad16((DWORD)(dwISize-dwImageSize));
  3194. //TRACE3(" dwRead: %lu\t dwImageSize: %lu\t Pad: %hd\n", dwRead, dwImageSize, bPad );
  3195. if (bPad==dwImageSize)
  3196. dwImageSize = -1;
  3197. }
  3198. }
  3199. return (UINT)(dwOverAllSize);
  3200. }
  3201. static
  3202. UINT
  3203. UpdateDialog( LPVOID lpNewBuf, LONG dwNewSize,
  3204. LPVOID lpOldI, LONG dwOldImageSize,
  3205. LPVOID lpNewI, DWORD* pdwNewImageSize )
  3206. {
  3207. // Should be almost impossible for a Dialog to be Huge
  3208. UINT uiError = ERROR_NO_ERROR;
  3209. BYTE far * lpNewImage = (BYTE far *) lpNewI;
  3210. LONG dwNewImageSize = *pdwNewImageSize;
  3211. BYTE far * lpOldImage = (BYTE far *) lpOldI;
  3212. DWORD dwOriginalOldSize = dwOldImageSize;
  3213. BYTE far * lpBuf = (BYTE far *) lpNewBuf;
  3214. LPRESITEM lpResItem = LPNULL;
  3215. LONG dwOverAllSize = 0L;
  3216. BYTE bIdCount = 0;
  3217. // Dialog Elements
  3218. DWORD dwStyle = 0L;
  3219. BYTE bNumOfElem = 0;
  3220. WORD wX = 0;
  3221. WORD wY = 0;
  3222. WORD wcX = 0;
  3223. WORD wcY = 0;
  3224. WORD wId = 0;
  3225. static char szMenuName[MAXID];
  3226. WORD wMenuName;
  3227. static char szClassName[MAXID];
  3228. BYTE bClassName, bControlClassName;
  3229. static char szCaption[MAXSTR];
  3230. WORD wOrd = 0;
  3231. WORD wPointSize = 0;
  3232. static char szFaceName[MAXID];
  3233. WORD wPos = 1;
  3234. // Updated elements
  3235. WORD wUpdX = 0;
  3236. WORD wUpdY = 0;
  3237. WORD wUpdcX = 0;
  3238. WORD wUpdcY = 0;
  3239. DWORD dwUpdStyle = 0l;
  3240. DWORD dwPosId = 0l;
  3241. static char szUpdCaption[MAXSTR];
  3242. static char szUpdFaceName[MAXID];
  3243. WORD wUpdPointSize = 0;
  3244. WORD wUpdPos = 0;
  3245. // read the dialog header
  3246. GetDWord( &lpOldImage, &dwStyle, &dwOldImageSize );
  3247. GetByte( &lpOldImage, &bNumOfElem, &dwOldImageSize );
  3248. GetWord( &lpOldImage, &wX, &dwOldImageSize );
  3249. GetWord( &lpOldImage, &wY, &dwOldImageSize );
  3250. GetWord( &lpOldImage, &wcX, &dwOldImageSize );
  3251. GetWord( &lpOldImage, &wcY, &dwOldImageSize );
  3252. GetNameOrOrd( &lpOldImage, &wMenuName, &szMenuName[0], &dwOldImageSize );
  3253. GetClassName( &lpOldImage, &bClassName, &szClassName[0], &dwOldImageSize );
  3254. GetCaptionOrOrd( &lpOldImage, &wOrd, &szCaption[0], &dwOldImageSize,
  3255. bClassName, dwStyle );
  3256. if ( dwStyle & DS_SETFONT ) {
  3257. GetWord( &lpOldImage, &wPointSize, &dwOldImageSize );
  3258. GetString( &lpOldImage, &szFaceName[0], &dwOldImageSize );
  3259. }
  3260. // Get the infrmation from the updated resource
  3261. if ((!wUpdPos) && dwNewSize ) {
  3262. lpResItem = (LPRESITEM) lpBuf;
  3263. wUpdX = lpResItem->wX;
  3264. wUpdY = lpResItem->wY;
  3265. wUpdcX = lpResItem->wcX;
  3266. wUpdcY = lpResItem->wcY;
  3267. wUpdPointSize = lpResItem->wPointSize;
  3268. dwUpdStyle = lpResItem->dwStyle;
  3269. dwPosId = lpResItem->dwItemID;
  3270. strcpy( szUpdCaption, lpResItem->lpszCaption );
  3271. strcpy( szUpdFaceName, lpResItem->lpszFaceName );
  3272. lpBuf += lpResItem->dwSize;
  3273. dwNewSize -= lpResItem->dwSize;
  3274. }
  3275. // check if we have to update the header
  3276. if ((HIWORD(dwPosId)==wPos) && (LOWORD(dwPosId)==wId)) {
  3277. wX = wUpdX;
  3278. wY = wUpdY;
  3279. wcX = wUpdcX;
  3280. wcY = wUpdcY;
  3281. wPointSize = wUpdPointSize;
  3282. dwStyle = dwUpdStyle;
  3283. strcpy(szCaption, szUpdCaption);
  3284. strcpy(szFaceName, szUpdFaceName);
  3285. }
  3286. // Write the header informations
  3287. dwOverAllSize += PutDWord( &lpNewImage, dwStyle, &dwNewImageSize );
  3288. dwOverAllSize += PutByte( &lpNewImage, bNumOfElem, &dwNewImageSize );
  3289. dwOverAllSize += PutWord( &lpNewImage, wX, &dwNewImageSize );
  3290. dwOverAllSize += PutWord( &lpNewImage, wY, &dwNewImageSize );
  3291. dwOverAllSize += PutWord( &lpNewImage, wcX, &dwNewImageSize );
  3292. dwOverAllSize += PutWord( &lpNewImage, wcY, &dwNewImageSize );
  3293. dwOverAllSize += PutNameOrOrd( &lpNewImage, wMenuName, &szMenuName[0], &dwNewImageSize );
  3294. dwOverAllSize += PutClassName( &lpNewImage, bClassName, &szClassName[0], &dwNewImageSize );
  3295. dwOverAllSize += PutCaptionOrOrd( &lpNewImage, wOrd, &szCaption[0], &dwNewImageSize,
  3296. bClassName, dwStyle );
  3297. if ( dwStyle & DS_SETFONT ) {
  3298. dwOverAllSize += PutWord( &lpNewImage, wPointSize, &dwNewImageSize );
  3299. dwOverAllSize += PutString( &lpNewImage, &szFaceName[0], &dwNewImageSize );
  3300. }
  3301. while ( (dwOldImageSize>0) && (bNumOfElem>0) ) {
  3302. wPos++;
  3303. // Get the info for the control
  3304. // Read the COntrols
  3305. GetWord( &lpOldImage, &wX, &dwOldImageSize );
  3306. GetWord( &lpOldImage, &wY, &dwOldImageSize );
  3307. GetWord( &lpOldImage, &wcX, &dwOldImageSize );
  3308. GetWord( &lpOldImage, &wcY, &dwOldImageSize );
  3309. GetWord( &lpOldImage, &wId, &dwOldImageSize );
  3310. GetDWord( &lpOldImage, &dwStyle, &dwOldImageSize );
  3311. GetControlClassName( &lpOldImage, &bControlClassName, &szClassName[0], &dwOldImageSize );
  3312. GetCaptionOrOrd( &lpOldImage, &wOrd, &szCaption[0], &dwOldImageSize,
  3313. bControlClassName, dwStyle );
  3314. SkipByte( &lpOldImage, 1, &dwOldImageSize );
  3315. bNumOfElem--;
  3316. if ((!wUpdPos) && dwNewSize ) {
  3317. TRACE1("\t\tUpdateDialog:\tdwNewSize=%ld\n",(LONG)dwNewSize);
  3318. TRACE1("\t\t\t\tlpszCaption=%Fs\n",lpResItem->lpszCaption);
  3319. lpResItem = (LPRESITEM) lpBuf;
  3320. wUpdX = lpResItem->wX;
  3321. wUpdY = lpResItem->wY;
  3322. wUpdcX = lpResItem->wcX;
  3323. wUpdcY = lpResItem->wcY;
  3324. dwUpdStyle = lpResItem->dwStyle;
  3325. dwPosId = lpResItem->dwItemID;
  3326. strcpy( szUpdCaption, lpResItem->lpszCaption );
  3327. lpBuf += lpResItem->dwSize;
  3328. dwNewSize -= lpResItem->dwSize;
  3329. }
  3330. // check if we have to update the header
  3331. if ((HIWORD(dwPosId)==wPos) && (LOWORD(dwPosId)==wId)) {
  3332. wX = wUpdX;
  3333. wY = wUpdY;
  3334. wcX = wUpdcX;
  3335. wcY = wUpdcY;
  3336. dwStyle = dwUpdStyle;
  3337. strcpy(szCaption, szUpdCaption);
  3338. }
  3339. //write the control
  3340. dwOverAllSize += PutWord( &lpNewImage, wX, &dwNewImageSize );
  3341. dwOverAllSize += PutWord( &lpNewImage, wY, &dwNewImageSize );
  3342. dwOverAllSize += PutWord( &lpNewImage, wcX, &dwNewImageSize );
  3343. dwOverAllSize += PutWord( &lpNewImage, wcY, &dwNewImageSize );
  3344. dwOverAllSize += PutWord( &lpNewImage, wId, &dwNewImageSize );
  3345. dwOverAllSize += PutDWord( &lpNewImage, dwStyle, &dwNewImageSize );
  3346. dwOverAllSize += PutControlClassName( &lpNewImage, bControlClassName, &szClassName[0], &dwNewImageSize );
  3347. dwOverAllSize += PutCaptionOrOrd( &lpNewImage, wOrd, &szCaption[0], &dwNewImageSize,
  3348. bControlClassName, dwStyle );
  3349. dwOverAllSize += PutByte( &lpNewImage, 0, &dwNewImageSize );
  3350. if (dwOldImageSize<=16) {
  3351. // Check if we are at the end and this is just padding
  3352. BYTE bPad = (BYTE)Pad16((DWORD)(dwOriginalOldSize-dwOldImageSize));
  3353. if (bPad==dwOldImageSize)
  3354. dwOldImageSize = 0;
  3355. }
  3356. }
  3357. if (dwOverAllSize>(LONG)*pdwNewImageSize) {
  3358. // calc the padding as well
  3359. dwOverAllSize += (BYTE)Pad4((DWORD)(dwOverAllSize));
  3360. *pdwNewImageSize = dwOverAllSize;
  3361. return uiError;
  3362. }
  3363. *pdwNewImageSize = *pdwNewImageSize-dwNewImageSize;
  3364. if (*pdwNewImageSize>0) {
  3365. // calculate padding
  3366. BYTE bPad = (BYTE)Pad4((DWORD)(*pdwNewImageSize));
  3367. if (bPad>dwNewImageSize) {
  3368. *pdwNewImageSize += bPad;
  3369. return uiError;
  3370. }
  3371. memset(lpNewImage, 0x00, bPad);
  3372. *pdwNewImageSize += bPad;
  3373. }
  3374. return uiError;
  3375. }
  3376. static
  3377. UINT
  3378. GenerateDialog( LPVOID lpNewBuf, LONG dwNewSize,
  3379. LPVOID lpNewI, DWORD* pdwNewImageSize )
  3380. {
  3381. // Should be almost impossible for a Dialog to be Huge
  3382. UINT uiError = ERROR_NO_ERROR;
  3383. BYTE far * lpNewImage = (BYTE far *) lpNewI;
  3384. LONG dwNewImageSize = *pdwNewImageSize;
  3385. BYTE far * lpBuf = (BYTE far *) lpNewBuf;
  3386. LPRESITEM lpResItem = LPNULL;
  3387. LONG dwOverAllSize = 0L;
  3388. BYTE bIdCount = 0;
  3389. // Dialog Elements
  3390. DWORD dwStyle = 0L;
  3391. BYTE bNumOfElem = 0;
  3392. WORD wX = 0;
  3393. WORD wY = 0;
  3394. WORD wcX = 0;
  3395. WORD wcY = 0;
  3396. WORD wId = 0;
  3397. char szClassName[128];
  3398. BYTE bClassName='\0', bControlClassName='\0';
  3399. char szCaption[128];
  3400. WORD wPointSize = 0;
  3401. char szFaceName[128];
  3402. WORD wPos = 1;
  3403. // Get the infrmation from the updated resource
  3404. if ( dwNewSize ) {
  3405. lpResItem = (LPRESITEM) lpBuf;
  3406. wX = lpResItem->wX;
  3407. wY = lpResItem->wY;
  3408. wcX = lpResItem->wcX;
  3409. wcY = lpResItem->wcY;
  3410. wId = LOWORD(lpResItem->dwItemID);
  3411. wPointSize = lpResItem->wPointSize;
  3412. dwStyle = lpResItem->dwStyle;
  3413. bClassName = LOBYTE(lpResItem->wClassName);
  3414. strcpy( szCaption, lpResItem->lpszCaption );
  3415. strcpy( szClassName, lpResItem->lpszClassName );
  3416. strcpy( szFaceName, lpResItem->lpszFaceName );
  3417. lpBuf += lpResItem->dwSize;
  3418. dwNewSize -= lpResItem->dwSize;
  3419. }
  3420. // Write the header informations
  3421. dwOverAllSize += PutDWord( &lpNewImage, dwStyle, &dwNewImageSize );
  3422. // Store the position of the numofelem for a later fixup
  3423. BYTE far * lpNumOfElem = lpNewImage;
  3424. dwOverAllSize += PutByte( &lpNewImage, bNumOfElem, &dwNewImageSize );
  3425. dwOverAllSize += PutWord( &lpNewImage, wX, &dwNewImageSize );
  3426. dwOverAllSize += PutWord( &lpNewImage, wY, &dwNewImageSize );
  3427. dwOverAllSize += PutWord( &lpNewImage, wcX, &dwNewImageSize );
  3428. dwOverAllSize += PutWord( &lpNewImage, wcY, &dwNewImageSize );
  3429. dwOverAllSize += PutNameOrOrd( &lpNewImage, 0, "", &dwNewImageSize );
  3430. dwOverAllSize += PutClassName( &lpNewImage, bClassName, &szClassName[0], &dwNewImageSize );
  3431. dwOverAllSize += PutCaptionOrOrd( &lpNewImage, 0, &szCaption[0], &dwNewImageSize,
  3432. bClassName, dwStyle );
  3433. if ( dwStyle & DS_SETFONT ) {
  3434. dwOverAllSize += PutWord( &lpNewImage, wPointSize, &dwNewImageSize );
  3435. dwOverAllSize += PutString( &lpNewImage, &szFaceName[0], &dwNewImageSize );
  3436. }
  3437. while ( dwNewSize>0 ) {
  3438. bNumOfElem++;
  3439. if ( dwNewSize ) {
  3440. /*
  3441. TRACE1("\t\tGenerateDialog:\tdwNewSize=%ld\n",(LONG)dwNewSize);
  3442. TRACE1("\t\t\t\tlpszCaption=%Fs\n",lpResItem->lpszCaption);
  3443. */
  3444. lpResItem = (LPRESITEM) lpBuf;
  3445. wX = lpResItem->wX;
  3446. wY = lpResItem->wY;
  3447. wcX = lpResItem->wcX;
  3448. wcY = lpResItem->wcY;
  3449. wId = LOWORD(lpResItem->dwItemID);
  3450. dwStyle = lpResItem->dwStyle;
  3451. bClassName = LOBYTE(lpResItem->wClassName);
  3452. strcpy( szCaption, lpResItem->lpszCaption );
  3453. strcpy( szClassName, lpResItem->lpszClassName );
  3454. lpBuf += lpResItem->dwSize;
  3455. dwNewSize -= lpResItem->dwSize;
  3456. }
  3457. //write the control
  3458. dwOverAllSize += PutWord( &lpNewImage, wX, &dwNewImageSize );
  3459. dwOverAllSize += PutWord( &lpNewImage, wY, &dwNewImageSize );
  3460. dwOverAllSize += PutWord( &lpNewImage, wcX, &dwNewImageSize );
  3461. dwOverAllSize += PutWord( &lpNewImage, wcY, &dwNewImageSize );
  3462. dwOverAllSize += PutWord( &lpNewImage, wId, &dwNewImageSize );
  3463. dwOverAllSize += PutDWord( &lpNewImage, dwStyle, &dwNewImageSize );
  3464. dwOverAllSize += PutControlClassName( &lpNewImage, bControlClassName, &szClassName[0], &dwNewImageSize );
  3465. dwOverAllSize += PutCaptionOrOrd( &lpNewImage, 0, &szCaption[0], &dwNewImageSize,
  3466. bControlClassName, dwStyle );
  3467. dwOverAllSize += PutByte( &lpNewImage, 0, &dwNewImageSize );
  3468. }
  3469. if (dwOverAllSize>(LONG)*pdwNewImageSize) {
  3470. // calc the padding as well
  3471. dwOverAllSize += (BYTE)Pad4((DWORD)(dwOverAllSize));
  3472. *pdwNewImageSize = dwOverAllSize;
  3473. return uiError;
  3474. }
  3475. *pdwNewImageSize = *pdwNewImageSize-dwNewImageSize;
  3476. if (*pdwNewImageSize>0) {
  3477. // calculate padding
  3478. BYTE bPad = (BYTE)Pad4((DWORD)(*pdwNewImageSize));
  3479. if (bPad>dwNewImageSize) {
  3480. *pdwNewImageSize += bPad;
  3481. return uiError;
  3482. }
  3483. memset(lpNewImage, 0x00, bPad);
  3484. *pdwNewImageSize += bPad;
  3485. }
  3486. // fixup the number of items
  3487. PutByte( &lpNumOfElem, bNumOfElem, &dwNewImageSize );
  3488. return uiError;
  3489. }
  3490. static
  3491. BYTE
  3492. SkipByte( BYTE far * far * lplpBuf, UINT uiSkip, LONG* pdwSize )
  3493. {
  3494. if (*pdwSize>=(int)uiSkip) {
  3495. *lplpBuf += uiSkip;;
  3496. *pdwSize -= uiSkip;
  3497. }
  3498. return (BYTE)uiSkip;
  3499. }
  3500. static
  3501. BYTE
  3502. PutDWord( BYTE far * far* lplpBuf, DWORD dwValue, LONG* pdwSize )
  3503. {
  3504. if (*pdwSize>=sizeofDWord && (*pdwSize != -1)) {
  3505. memcpy(*lplpBuf, &dwValue, sizeofDWord);
  3506. *lplpBuf += sizeofDWord;
  3507. *pdwSize -= sizeofDWord;
  3508. } else *pdwSize = -1;
  3509. return sizeofDWord;
  3510. }
  3511. static
  3512. BYTE
  3513. GetDWord( BYTE far * far* lplpBuf, DWORD* dwValue, LONG* pdwSize )
  3514. {
  3515. if (*pdwSize>=sizeofDWord) {
  3516. memcpy( dwValue, *lplpBuf, sizeofDWord);
  3517. *lplpBuf += sizeofDWord;
  3518. *pdwSize -= sizeofDWord;
  3519. }
  3520. return sizeofDWord;
  3521. }
  3522. static
  3523. BYTE
  3524. PutWord( BYTE far * far* lplpBuf, WORD wValue, LONG* pdwSize )
  3525. {
  3526. if (*pdwSize>=sizeofWord && (*pdwSize != -1)) {
  3527. memcpy(*lplpBuf, &wValue, sizeofWord);
  3528. *lplpBuf += sizeofWord;
  3529. *pdwSize -= sizeofWord;
  3530. } else *pdwSize = -1;
  3531. return sizeofWord;
  3532. }
  3533. static
  3534. BYTE
  3535. GetWord( BYTE far * far* lplpBuf, WORD* wValue, LONG* pdwSize )
  3536. {
  3537. if (*pdwSize>=sizeofWord) {
  3538. memcpy( wValue, *lplpBuf, sizeofWord);
  3539. *lplpBuf += sizeofWord;
  3540. *pdwSize -= sizeofWord;
  3541. }
  3542. return sizeofWord;
  3543. }
  3544. static
  3545. BYTE
  3546. PutByte( BYTE far * far* lplpBuf, BYTE bValue, LONG* pdwSize )
  3547. {
  3548. if (*pdwSize>=sizeofByte && (*pdwSize != -1)) {
  3549. memcpy(*lplpBuf, &bValue, sizeofByte);
  3550. *lplpBuf += sizeofByte;
  3551. *pdwSize -= sizeofByte;
  3552. } else *pdwSize = -1;
  3553. return sizeofByte;
  3554. }
  3555. static
  3556. BYTE
  3557. GetByte( BYTE far * far* lplpBuf, BYTE* bValue, LONG* pdwSize )
  3558. {
  3559. if (*pdwSize>=sizeofByte) {
  3560. memcpy(bValue, *lplpBuf, sizeofByte);
  3561. *lplpBuf += sizeofByte;
  3562. *pdwSize -= sizeofByte;
  3563. }
  3564. return sizeofByte;
  3565. }
  3566. static
  3567. UINT
  3568. GetCaptionOrOrd( BYTE far * far* lplpBuf, WORD* wOrd, LPSTR lpszText, LONG* pdwSize,
  3569. BYTE bClass, DWORD dwStyle )
  3570. {
  3571. UINT uiSize = 0;
  3572. // Icon might not have an ID so check first
  3573. *wOrd = 0;
  3574. // read the first BYTE to see if it is a string or an ordinal
  3575. uiSize += GetByte( lplpBuf, (BYTE*)wOrd, pdwSize );
  3576. if (LOBYTE(*wOrd)==0xFF) {
  3577. // This is an Ordinal
  3578. uiSize += GetWord( lplpBuf, wOrd, pdwSize );
  3579. *lpszText = '\0';
  3580. uiSize = 3;
  3581. } else {
  3582. *lpszText++ = LOBYTE(*wOrd);
  3583. if (LOBYTE(*wOrd))
  3584. uiSize += GetString( lplpBuf, lpszText, pdwSize);
  3585. *wOrd = 0;
  3586. }
  3587. return uiSize;
  3588. }
  3589. static
  3590. UINT
  3591. GetNameOrOrd( BYTE far * far* lplpBuf, WORD* wOrd, LPSTR lpszText, LONG* pdwSize )
  3592. {
  3593. UINT uiSize = 0;
  3594. *wOrd = 0;
  3595. // read the first BYTE to see if it is a string or an ordinal
  3596. uiSize += GetByte( lplpBuf, (BYTE*)wOrd, pdwSize );
  3597. if (LOBYTE(*wOrd)==0xFF) {
  3598. // This is an Ordinal
  3599. uiSize += GetWord( lplpBuf, wOrd, pdwSize );
  3600. *lpszText = '\0';
  3601. uiSize = 3;
  3602. } else {
  3603. *lpszText++ = LOBYTE(*wOrd);
  3604. if (LOBYTE(*wOrd))
  3605. uiSize += GetString( lplpBuf, lpszText, pdwSize);
  3606. *wOrd = 0;
  3607. }
  3608. return uiSize;
  3609. }
  3610. static
  3611. UINT
  3612. PutCaptionOrOrd( BYTE far * far* lplpBuf, WORD wOrd, LPSTR lpszText, LONG* pdwSize,
  3613. BYTE bClass, DWORD dwStyle )
  3614. {
  3615. UINT uiSize = 0;
  3616. // If this is an ICON then can just be an ID
  3617. if (wOrd) {
  3618. uiSize += PutByte(lplpBuf, 0xFF, pdwSize);
  3619. uiSize += PutWord(lplpBuf, wOrd, pdwSize);
  3620. } else {
  3621. uiSize += PutString(lplpBuf, lpszText, pdwSize);
  3622. }
  3623. return uiSize;
  3624. }
  3625. static
  3626. UINT
  3627. PutNameOrOrd( BYTE far * far* lplpBuf, WORD wOrd, LPSTR lpszText, LONG* pdwSize )
  3628. {
  3629. UINT uiSize = 0;
  3630. if (wOrd) {
  3631. uiSize += PutByte(lplpBuf, 0xFF, pdwSize);
  3632. uiSize += PutWord(lplpBuf, wOrd, pdwSize);
  3633. } else {
  3634. uiSize += PutString(lplpBuf, lpszText, pdwSize);
  3635. }
  3636. return uiSize;
  3637. }
  3638. static
  3639. UINT
  3640. GetClassName( BYTE far * far* lplpBuf, BYTE* bClass, LPSTR lpszText, LONG* pdwSize )
  3641. {
  3642. UINT uiSize = 0;
  3643. *bClass = 0;
  3644. // read the first BYTE to see if it is a string or an ordinal
  3645. uiSize += GetByte( lplpBuf, bClass, pdwSize );
  3646. if ( !(*bClass)) {
  3647. // This is an Ordinal
  3648. *lpszText = '\0';
  3649. } else {
  3650. *lpszText++ = *bClass;
  3651. if (*bClass)
  3652. uiSize += GetString( lplpBuf, lpszText, pdwSize);
  3653. *bClass = 0;
  3654. }
  3655. return uiSize;
  3656. }
  3657. static
  3658. UINT
  3659. GetControlClassName( BYTE far * far* lplpBuf, BYTE* bClass, LPSTR lpszText, LONG* pdwSize )
  3660. {
  3661. UINT uiSize = 0;
  3662. *bClass = 0;
  3663. // read the first BYTE to see if it is a string or an ordinal
  3664. uiSize += GetByte( lplpBuf, bClass, pdwSize );
  3665. if ( (*bClass) & 0x80) {
  3666. // This is an Ordinal
  3667. *lpszText = '\0';
  3668. } else {
  3669. *lpszText++ = *bClass;
  3670. if (*bClass)
  3671. uiSize += GetString( lplpBuf, lpszText, pdwSize);
  3672. *bClass = 0;
  3673. }
  3674. return uiSize;
  3675. }
  3676. static
  3677. UINT
  3678. PutClassName( BYTE far * far* lplpBuf, BYTE bClass, LPSTR lpszText, LONG* pdwSize )
  3679. {
  3680. UINT uiSize = 0;
  3681. if ( !(lpszText[0])) {
  3682. // This is an Ordinal
  3683. uiSize += PutByte(lplpBuf, bClass, pdwSize);
  3684. } else {
  3685. uiSize += PutString(lplpBuf, lpszText, pdwSize);
  3686. }
  3687. return uiSize;
  3688. }
  3689. static
  3690. UINT
  3691. PutControlClassName( BYTE far * far* lplpBuf, BYTE bClass, LPSTR lpszText, LONG* pdwSize )
  3692. {
  3693. UINT uiSize = 0;
  3694. if ( bClass & 0x80) {
  3695. // This is an Ordinal
  3696. uiSize += PutByte(lplpBuf, bClass, pdwSize);
  3697. } else {
  3698. uiSize += PutString(lplpBuf, lpszText, pdwSize);
  3699. }
  3700. return uiSize;
  3701. }
  3702. static
  3703. UINT
  3704. PutString( BYTE far * far* lplpBuf, LPSTR lpszText, LONG* pdwSize )
  3705. {
  3706. int iSize = strlen(lpszText)+1;
  3707. if (*pdwSize>=iSize && (*pdwSize != -1)) {
  3708. memcpy(*lplpBuf, lpszText, iSize);
  3709. *lplpBuf += iSize;
  3710. *pdwSize -= iSize;
  3711. } else *pdwSize = -1;
  3712. return iSize;
  3713. }
  3714. static
  3715. UINT
  3716. PutPascalString( BYTE far * far* lplpBuf, LPSTR lpszText, BYTE bLen, LONG* pdwSize )
  3717. {
  3718. BYTE bSize = PutByte( lplpBuf, bLen, pdwSize );
  3719. if (*pdwSize>=bLen && (*pdwSize != -1)) {
  3720. memcpy(*lplpBuf, lpszText, bLen);
  3721. *lplpBuf += bLen;
  3722. *pdwSize -= bLen;
  3723. } else *pdwSize = -1;
  3724. return bSize+bLen;
  3725. }
  3726. static
  3727. UINT
  3728. GetString( BYTE far * far* lplpBuf, LPSTR lpszText, LONG* pdwSize )
  3729. {
  3730. int iSize = strlen((char*)*lplpBuf)+1;
  3731. if (*pdwSize>=iSize) {
  3732. memcpy( lpszText, *lplpBuf, iSize);
  3733. *lplpBuf += iSize;
  3734. *pdwSize -= iSize;
  3735. } else {
  3736. *lplpBuf = '\0';
  3737. *lpszText = '\0';
  3738. }
  3739. return iSize;
  3740. }
  3741. static
  3742. int
  3743. GetVSString( BYTE far * far* lplpBuf, LPSTR lpszText, LONG* pdwSize, int cMaxLen )
  3744. {
  3745. // We have to stop at Maxlen to avoid read too much.
  3746. // This is to fix a bug where some string that are supposed to be NULL
  3747. // terminated are not.
  3748. int iSize = strlen((char*)*lplpBuf)+1;
  3749. if (iSize>cMaxLen)
  3750. iSize = cMaxLen;
  3751. if (*pdwSize>=iSize) {
  3752. memcpy( lpszText, *lplpBuf, iSize);
  3753. *lplpBuf += iSize;
  3754. *pdwSize -= iSize;
  3755. } else *lplpBuf = '\0';
  3756. *(lpszText+iSize) = '\0';
  3757. return iSize;
  3758. }
  3759. static
  3760. UINT
  3761. CopyText( BYTE far * far * lplpTgt, BYTE far * far * lplpSrc, LONG* pdwTgtSize, LONG* pdwSrcSize)
  3762. {
  3763. if (!*lplpSrc) return 1;
  3764. int uiStrlen = strlen((char*)*lplpSrc)+1;
  3765. TRACE("Len: %d\tTgtSize: %ld\tImageSize: %ld", uiStrlen, *pdwTgtSize, *pdwSrcSize);
  3766. if (uiStrlen>*pdwTgtSize) {
  3767. TRACE("\n");
  3768. *pdwTgtSize = -1;
  3769. return uiStrlen;
  3770. } else {
  3771. strcpy( (char*)*lplpTgt, (char*)*lplpSrc);
  3772. TRACE1("\tCaption: %Fs\n", (char*)*lplpTgt);
  3773. if (*pdwSrcSize>=uiStrlen) {
  3774. *lplpSrc += uiStrlen;
  3775. *pdwSrcSize -= uiStrlen;
  3776. }
  3777. *lplpTgt += uiStrlen;
  3778. *pdwTgtSize -= uiStrlen;
  3779. return uiStrlen;
  3780. }
  3781. }
  3782. static LPRESITEM
  3783. GetItem( BYTE far * lpBuf, LONG dwNewSize, LPSTR lpStr )
  3784. {
  3785. LPRESITEM lpResItem = (LPRESITEM) lpBuf;
  3786. while (strcmp(lpResItem->lpszClassName, lpStr)) {
  3787. lpBuf += lpResItem->dwSize;
  3788. dwNewSize -= lpResItem->dwSize;
  3789. if (dwNewSize<=0)
  3790. return LPNULL;
  3791. lpResItem = (LPRESITEM) lpBuf;
  3792. }
  3793. return lpResItem;
  3794. }
  3795. static DWORD CalcID( WORD wId, BOOL bFlag )
  3796. {
  3797. // We want to calculate the ID Relative to the WORD wId
  3798. // If we have any other ID with the same value then we return
  3799. // the incremental number + the value.
  3800. // If no other Item have been found then the incremental number will be 0.
  3801. // If bFlag = TRUE then the id get added to the present list.
  3802. // If bFlag = FALSE then the list is reseted and the function return
  3803. // Clean the array if needed
  3804. if (!bFlag) {
  3805. wIDArray.RemoveAll();
  3806. return 0;
  3807. }
  3808. // Add the value to the array
  3809. wIDArray.Add(wId);
  3810. // Walk the array to get the number of duplicated ID
  3811. short c = -1; // will be 0 based
  3812. for (short i=(short)wIDArray.GetUpperBound(); i>=0 ; i-- ) {
  3813. if (wIDArray.GetAt(i)==wId)
  3814. c++;
  3815. }
  3816. TRACE3("CalcID: ID: %hd\tPos: %hd\tFinal: %lx\n", wId, c, MAKELONG( wId, c ));
  3817. return MAKELONG( wId, c );
  3818. }
  3819. static LONG Allign( BYTE** lplpBuf, LONG* plBufSize, LONG lSize )
  3820. {
  3821. LONG lRet = 0;
  3822. BYTE bPad = (BYTE)Pad4(lSize);
  3823. lRet = bPad;
  3824. if (bPad && *plBufSize>=bPad) {
  3825. while (bPad && *plBufSize) {
  3826. **lplpBuf = 0x00;
  3827. *lplpBuf += 1;
  3828. *plBufSize -= 1;
  3829. bPad--;
  3830. }
  3831. }
  3832. return lRet;
  3833. }
  3834. static void ChangeLanguage( LPVOID lpBuffer, UINT uiBuffSize )
  3835. {
  3836. BYTE * pBuf = (BYTE*)lpBuffer;
  3837. LONG lSize = 0;
  3838. while (uiBuffSize) {
  3839. // Skip
  3840. lSize += SkipByte( &pBuf, 2, (LONG*)&uiBuffSize );
  3841. lSize += SkipByte( &pBuf, strlen((LPCSTR)pBuf)+1, (LONG*)&uiBuffSize );
  3842. lSize += SkipByte( &pBuf, Pad4(lSize), (LONG*)&uiBuffSize );
  3843. lSize += SkipByte( &pBuf, 2, (LONG*)&uiBuffSize );
  3844. lSize += SkipByte( &pBuf, strlen((LPCSTR)pBuf)+1, (LONG*)&uiBuffSize );
  3845. lSize += SkipByte( &pBuf, Pad4(lSize), (LONG*)&uiBuffSize );
  3846. lSize += PutDWord( &pBuf, gLang, (LONG*)&uiBuffSize );
  3847. lSize += SkipByte( &pBuf, 4, (LONG*)&uiBuffSize );
  3848. lSize += SkipByte( &pBuf, 4, (LONG*)&uiBuffSize );
  3849. }
  3850. }
  3851. ////////////////////////////////////////////////////////////////////////////
  3852. // DLL Specific code implementation
  3853. ////////////////////////////////////////////////////////////////////////////
  3854. // This function should be used verbatim. Any initialization or termination
  3855. // requirements should be handled in InitPackage() and ExitPackage().
  3856. //
  3857. extern "C" int APIENTRY
  3858. DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
  3859. {
  3860. if (dwReason == DLL_PROCESS_ATTACH) {
  3861. // NOTE: global/static constructors have already been called!
  3862. // Extension DLL one-time initialization - do not allocate memory
  3863. // here, use the TRACE or ASSERT macros or call MessageBox
  3864. AfxInitExtensionModule(extensionDLL, hInstance);
  3865. } else if (dwReason == DLL_PROCESS_DETACH) {
  3866. // Terminate the library before destructors are called
  3867. AfxWinTerm();
  3868. }
  3869. if (dwReason == DLL_PROCESS_DETACH || dwReason == DLL_THREAD_DETACH)
  3870. return 0; // CRT term Failed
  3871. return 1; // ok
  3872. }
  3873. /////////////////////////////////////////////////////////////////////////////