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.

2021 lines
64 KiB

  1. //=============================================================================
  2. // Mac Reader/Writer functions
  3. //
  4. // Alessandro Muti - August 25 1994
  5. //=============================================================================
  6. #include <afxwin.h>
  7. #include <limits.h>
  8. #include <iodll.h>
  9. #include "helper.h"
  10. #include "m68k.h"
  11. #include "..\mac\mac.h"
  12. #define MAX_STR 1024
  13. static char szTextBuf[MAX_STR];
  14. static WORD szWTextBuf[MAX_STR];
  15. //=============================================================================
  16. //=============================================================================
  17. //
  18. // PE Header parsing functions
  19. //
  20. //=============================================================================
  21. //=============================================================================
  22. //=============================================================================
  23. // FindMacResourceSection
  24. //
  25. // Will walk the section header searching for ";;resxxx" resource name.
  26. // If pResName is NULL then will return the first section otherwise will
  27. // return the first section matching after the pResName.
  28. // If there are no more resource section will return FALSE.
  29. //=============================================================================
  30. UINT FindMacResourceSection( CFile* pfile, BYTE * * pRes, PIMAGE_SECTION_HEADER * ppSectTbl, int * piNumOfSect )
  31. {
  32. UINT uiError = ERROR_NO_ERROR;
  33. LONG lRead = 0;
  34. PIMAGE_SECTION_HEADER pResSect = NULL;
  35. // Check all the sections for the ";;resXXX"
  36. USHORT us =0;
  37. for (PIMAGE_SECTION_HEADER pSect = *ppSectTbl;
  38. *piNumOfSect; (*piNumOfSect)-- ) {
  39. if ( !strncmp((char*)pSect->Name, ";;res", 5) ) {
  40. // we have a matching
  41. TRACE("\tFindMacResourceSection: Name: %s\tSize: %d\n", pSect->Name, pSect->SizeOfRawData);
  42. pResSect = pSect;
  43. *ppSectTbl = pSect;
  44. break;
  45. }
  46. pSect++;
  47. }
  48. if (!pResSect) {
  49. return ERROR_RW_NO_RESOURCES;
  50. }
  51. BYTE * pResources = (BYTE *) malloc((pResSect)->SizeOfRawData);
  52. if (pResources==LPNULL) {
  53. return ERROR_NEW_FAILED;
  54. }
  55. // We read the data for the first section
  56. pfile->Seek( (LONG)(pResSect)->PointerToRawData, CFile::begin);
  57. lRead = ReadFile(pfile, pResources, (LONG)(pResSect)->SizeOfRawData);
  58. if (lRead!=(LONG)(pResSect)->SizeOfRawData) {
  59. free(pResources);
  60. return ERROR_FILE_READ;
  61. }
  62. // We want to copy the pointer to the resources
  63. *pRes = (BYTE*)pResources;
  64. return 0;
  65. }
  66. //=============================================================================
  67. // ParseResourceFile
  68. //
  69. // pResFile is pointing to the resource file data.
  70. // We will read the resource header to find the resource data and the resource
  71. // map address.
  72. // We will walk the resource map and find the offset to the data for each type
  73. //=============================================================================
  74. UINT ParseResourceFile( BYTE * pResFile, PIMAGE_SECTION_HEADER pResSection, BYTE ** ppBuf, LONG * pBufSize, int iFileNameLen)
  75. {
  76. MACTOWINDOWSMAP MacToWindows;
  77. PMACRESHEADER pResHeader = (PMACRESHEADER)pResFile;
  78. // Move at the beginning of the Resource Map
  79. PMACRESMAP pResMap = (PMACRESMAP)(pResFile+MacLongToLong(pResHeader->mulOffsetToResMap));
  80. //Read all the Type in this resource
  81. WORD wItems = MacWordToWord((BYTE*)pResMap+MacWordToWord(pResMap->mwOffsetToTypeList))+1;
  82. BYTE * pStartResTypeList = ((BYTE*)pResMap+MacWordToWord(pResMap->mwOffsetToTypeList));
  83. BYTE * pStartNameList = ((BYTE*)pResMap+MacWordToWord(pResMap->mwOffsetToNameList));
  84. PMACRESTYPELIST pResTypeList = (PMACRESTYPELIST)(pStartResTypeList+sizeof(WORD));
  85. while(wItems--){
  86. memcpy(&MacToWindows.szTypeName[0], pResTypeList->szResName, 4);
  87. MacToWindows.szTypeName[4] = '\0';
  88. WORD wResItems = MacWordToWord(pResTypeList->mwNumOfThisType)+1;
  89. TRACE("\t\tType: %s\t Num: %d\n", MacToWindows.szTypeName, wResItems);
  90. // Check if is has a valid Windows Mapping
  91. MacToWindows.wType = MapToWindowsRes(MacToWindows.szTypeName);
  92. // For all the items
  93. PMACRESREFLIST pResRefList = (PMACRESREFLIST)(pStartResTypeList+MacWordToWord(pResTypeList->mwOffsetToRefList));
  94. while(wResItems && MacToWindows.wType)
  95. {
  96. if(MacWordToWord(pResRefList->mwOffsetToResName)==0xFFFF) {
  97. MacToWindows.wResID = MacWordToWord(pResRefList->mwResID);
  98. MacToWindows.szResName[0] = '\0';
  99. TRACE("\t\t\tResId: %d",MacToWindows.wResID);
  100. }
  101. else {
  102. // It is a named resource
  103. BYTE * pName = pStartNameList+MacWordToWord(pResRefList->mwOffsetToResName);
  104. memcpy( &MacToWindows.szResName[0], pName+1, *pName );
  105. MacToWindows.szResName[*pName] = '\0';
  106. //if(!strcmp("DITL", MacToWindows.szTypeName))
  107. MacToWindows.wResID = MacWordToWord(pResRefList->mwResID);
  108. //else MacToWindows.wResID = 0;
  109. TRACE("\t\t\tResName: %s (%d)",MacToWindows.szResName, MacWordToWord(pResRefList->mwResID) );
  110. }
  111. // Get the offset to the data (relative to the beginning of the section)
  112. MacToWindows.dwOffsetToData = MacLongToLong(pResHeader->mulOffsetToResData)+MacOffsetToLong(pResRefList->bOffsetToResData);
  113. BYTE * pData = (pResFile + MacToWindows.dwOffsetToData);
  114. MacToWindows.dwSizeOfData = MacLongToLong(pData);
  115. // add the space for the file name
  116. MacToWindows.dwSizeOfData += iFileNameLen;
  117. //Fix up offet to data relative to the beginning of the file
  118. MacToWindows.dwOffsetToData += pResSection->PointerToRawData+sizeof(DWORD);
  119. TRACE("\tSize: %d\tOffset: %X\n", MacToWindows.dwSizeOfData, MacToWindows.dwOffsetToData);
  120. // Write the info in the IODLL buffer
  121. WriteResInfo(
  122. ppBuf, pBufSize,
  123. MacToWindows.wType, MacToWindows.szTypeName, 5,
  124. MacToWindows.wResID, MacToWindows.szResName, 255,
  125. 0l,
  126. MacToWindows.dwSizeOfData, MacToWindows.dwOffsetToData );
  127. wResItems--;
  128. pResRefList++;
  129. }
  130. // Read next type
  131. pResTypeList++;
  132. }
  133. return 0;
  134. }
  135. //=============================================================================
  136. // FindResource
  137. //
  138. // Will find the resource of the specified type and ID in the file.
  139. // Return a pointer to the resource data. Will need to be freed by the caller
  140. //=============================================================================
  141. DWORD FindMacResource( CFile * pfile, LPSTR pType, LPSTR pName )
  142. {
  143. DWORD dwOffset = 0;
  144. ////////////////////////////////////
  145. // Check if it is a valid mac file
  146. // Is a Mac Resource file ...
  147. if(IsMacResFile( pfile )) {
  148. // load the file in memory
  149. BYTE * pResources = (BYTE*)malloc(pfile->GetLength());
  150. if(!pResources) {
  151. return 0;
  152. }
  153. pfile->Seek(0, CFile::begin);
  154. pfile->ReadHuge(pResources, pfile->GetLength());
  155. IMAGE_SECTION_HEADER Sect;
  156. memset(&Sect, 0, sizeof(IMAGE_SECTION_HEADER));
  157. dwOffset = FindResourceInResFile(pResources, &Sect, pType, pName);
  158. free(pResources);
  159. return dwOffset;
  160. }
  161. // or is a PE Mac File ...
  162. // Read the Windows Header
  163. WORD w;
  164. pfile->Seek(0, CFile::begin);
  165. pfile->Read((WORD*)&w, sizeof(WORD));
  166. if (w!=IMAGE_DOS_SIGNATURE) return 0;
  167. pfile->Seek( 0x18, CFile::begin );
  168. pfile->Read((WORD*)&w, sizeof(WORD));
  169. if (w<0x0040) {
  170. // this is not a Windows Executable
  171. return 0;
  172. }
  173. // get offset to new header
  174. pfile->Seek( 0x3c, CFile::begin );
  175. pfile->Read((WORD*)&w, sizeof(WORD));
  176. // read windows new header
  177. static IMAGE_NT_HEADERS NTHdr;
  178. pfile->Seek( w, CFile::begin );
  179. pfile->Read(&NTHdr, sizeof(IMAGE_NT_HEADERS));
  180. // Check if the magic word is the right one
  181. if (!((NTHdr.Signature==IMAGE_NT_SIGNATURE) &&
  182. (NTHdr.FileHeader.Machine==IMAGE_FILE_MACHINE_M68K)))
  183. return 0;
  184. // Read the section table
  185. UINT uisize = sizeof(IMAGE_SECTION_HEADER) * NTHdr.FileHeader.NumberOfSections;
  186. PIMAGE_SECTION_HEADER pSectTbl = new IMAGE_SECTION_HEADER[NTHdr.FileHeader.NumberOfSections];
  187. if (pSectTbl==LPNULL)
  188. return 0;
  189. // Clean the memory we allocated
  190. memset( (PVOID)pSectTbl, 0, uisize);
  191. LONG lRead = pfile->Read(pSectTbl, uisize);
  192. if (lRead!=(LONG)uisize) {
  193. delete []pSectTbl;
  194. return LPNULL;
  195. }
  196. BYTE * pResources = LPNULL;
  197. int iNumOfSect = NTHdr.FileHeader.NumberOfSections;
  198. PIMAGE_SECTION_HEADER pStartSectTbl = pSectTbl;
  199. // Search all the resource section in the file
  200. while(!FindMacResourceSection( pfile, &pResources, &pSectTbl, &iNumOfSect))
  201. {
  202. if(dwOffset = FindResourceInResFile(pResources, pSectTbl++, pType, pName)) {
  203. delete []pStartSectTbl;
  204. return dwOffset;
  205. }
  206. iNumOfSect--;
  207. free(pResources);
  208. }
  209. delete []pStartSectTbl;
  210. return 0;
  211. }
  212. //=============================================================================
  213. // FindResourceInResFile
  214. //
  215. // pResFile is pointing to the resource file data.
  216. // We will read the resource header to find the resource data and the resource
  217. // map address.
  218. // We will walk the resource map and find the offset to the data for the res
  219. // we are searching for.
  220. //=============================================================================
  221. DWORD FindResourceInResFile( BYTE * pResFile, PIMAGE_SECTION_HEADER pResSection, LPSTR pResType, LPSTR pResName)
  222. {
  223. MACTOWINDOWSMAP MacToWindows;
  224. PMACRESHEADER pResHeader = (PMACRESHEADER)pResFile;
  225. // Move at the beginning of the Resource Map
  226. PMACRESMAP pResMap = (PMACRESMAP)(pResFile+MacLongToLong(pResHeader->mulOffsetToResMap));
  227. //Read all the Type in this resource
  228. WORD wItems = MacWordToWord((BYTE*)pResMap+MacWordToWord(pResMap->mwOffsetToTypeList))+1;
  229. BYTE * pStartResTypeList = ((BYTE*)pResMap+MacWordToWord(pResMap->mwOffsetToTypeList));
  230. BYTE * pStartNameList = ((BYTE*)pResMap+MacWordToWord(pResMap->mwOffsetToNameList));
  231. PMACRESTYPELIST pResTypeList = (PMACRESTYPELIST)(pStartResTypeList+sizeof(WORD));
  232. while(wItems--){
  233. memcpy(&MacToWindows.szTypeName[0], pResTypeList->szResName, 4);
  234. MacToWindows.szTypeName[4] = '\0';
  235. if(!strcmp(MacToWindows.szTypeName, pResType)) {
  236. WORD wResItems = MacWordToWord(pResTypeList->mwNumOfThisType)+1;
  237. // For all the items
  238. PMACRESREFLIST pResRefList = (PMACRESREFLIST)(pStartResTypeList+MacWordToWord(pResTypeList->mwOffsetToRefList));
  239. while(wResItems)
  240. {
  241. if(!HIWORD(pResName)) {
  242. if(MacWordToWord(pResRefList->mwResID)==LOWORD(pResName))
  243. return MacLongToLong(pResHeader->mulOffsetToResData)+
  244. MacOffsetToLong(pResRefList->bOffsetToResData)+
  245. pResSection->PointerToRawData;
  246. }
  247. else {
  248. // It is a named resource
  249. if(HIWORD(pResName)) {
  250. BYTE * pName = pStartNameList+MacWordToWord(pResRefList->mwOffsetToResName);
  251. memcpy( &MacToWindows.szResName[0], pName+1, *pName );
  252. MacToWindows.szResName[*pName] = '\0';
  253. if(!strcmp(MacToWindows.szResName,pResName))
  254. return MacLongToLong(pResHeader->mulOffsetToResData)+
  255. MacOffsetToLong(pResRefList->bOffsetToResData)+
  256. pResSection->PointerToRawData;
  257. }
  258. }
  259. wResItems--;
  260. pResRefList++;
  261. }
  262. }
  263. // Read next type
  264. pResTypeList++;
  265. }
  266. return 0;
  267. }
  268. //=========================================================================
  269. // Determine heuristicaly whether it is a MAC resource file.
  270. // Resource file has a well-defined format, so this should be reliable.
  271. //=========================================================================
  272. BOOL IsMacResFile ( CFile * pFile )
  273. {
  274. LONG flen, dataoff, mapoff, datalen, maplen;
  275. BYTE Buf[4];
  276. BYTE * pBuf = &Buf[0];
  277. // From IM I-128:
  278. //
  279. // Resource file structure:
  280. //
  281. // 256 bytes Resource Header (and other info):
  282. // 4 bytes - Offset from beginning of resource file to resource data
  283. // 4 bytes - Offset from beginning of resource file to resource map
  284. // 4 bytes - Length of resource data
  285. // 4 bytes - Length of resource map
  286. // Resource Data
  287. // Resource Map
  288. flen = pFile->GetLength();
  289. if (flen < 256) {
  290. return FALSE;
  291. }
  292. pFile->Seek(0, CFile::begin);
  293. pFile->Read(pBuf, 4);
  294. dataoff = MacLongToLong(pBuf);
  295. if (dataoff != 256) {
  296. return FALSE;
  297. }
  298. pFile->Read(pBuf, 4);
  299. mapoff = MacLongToLong(pBuf);
  300. pFile->Read(pBuf, 4);
  301. datalen = MacLongToLong(pBuf);
  302. pFile->Read(pBuf, 4);
  303. maplen = MacLongToLong(pBuf);
  304. if (mapoff != datalen + 256) {
  305. return FALSE;
  306. }
  307. if (flen != datalen + maplen + 256) {
  308. return FALSE;
  309. }
  310. return TRUE;
  311. }
  312. //=============================================================================
  313. //=============================================================================
  314. //
  315. // Parsing functions
  316. //
  317. //=============================================================================
  318. //=============================================================================
  319. //=============================================================================
  320. // ParseWMNU
  321. //
  322. //
  323. //=============================================================================
  324. UINT ParseWMNU( LPVOID lpImageBuf, DWORD dwImageSize, LPVOID lpBuffer, DWORD dwSize )
  325. {
  326. return 0;
  327. }
  328. //=============================================================================
  329. // ParseMENU
  330. //
  331. //
  332. //=============================================================================
  333. UINT ParseMENU( LPVOID lpImageBuf, DWORD dwImageSize, LPVOID lpBuffer, DWORD dwSize )
  334. {
  335. PMACMENU pMenu = (PMACMENU)lpImageBuf;
  336. LPRESITEM pResItem = (LPRESITEM)lpBuffer;
  337. // fill in the first resitem
  338. WORD wResItemSize = sizeof(RESITEM)+pMenu->bSizeOfTitle+1;
  339. // check if is the apple menu
  340. if(pMenu->bSizeOfTitle==1 && *((BYTE*)&pMenu->bSizeOfTitle+1)==appleMark)
  341. wResItemSize += strlen(_APPLE_MARK_);
  342. DWORD dwResItemsSize = wResItemSize;
  343. if(wResItemSize<=dwSize) {
  344. memset(pResItem, 0, wResItemSize);
  345. pResItem->lpszCaption = (char*)memcpy((BYTE*)pResItem+sizeof(RESITEM), (char*)pMenu+sizeof(MACMENU), pMenu->bSizeOfTitle+1);
  346. *(pResItem->lpszCaption+pMenu->bSizeOfTitle) = '\0';
  347. // check if is the apple menu
  348. if(pMenu->bSizeOfTitle==1 && *((BYTE*)&pMenu->bSizeOfTitle+1)==appleMark)
  349. strcpy(pResItem->lpszCaption, _APPLE_MARK_);
  350. pResItem->lpszCaption = (char*)memcpy((BYTE*)pResItem+sizeof(RESITEM), MacCpToAnsiCp(pResItem->lpszCaption), strlen(pResItem->lpszCaption));
  351. //pResItem->dwStyle = MacLongToLong(pWdlg->dwStyle); make up a style
  352. pResItem->dwTypeID = MENU_TYPE;
  353. pResItem->dwItemID = 0x0000ffff;
  354. pResItem->dwCodePage = CODEPAGE;
  355. pResItem->dwFlags = MF_POPUP | MF_END;
  356. pResItem->dwSize = wResItemSize;
  357. dwSize -= wResItemSize;
  358. pResItem = (LPRESITEM)((BYTE*)lpBuffer+dwResItemsSize);
  359. }
  360. // parse the items in the menu
  361. BYTE* pMenuText = (BYTE*)pMenu+sizeof(MACMENU)+pMenu->bSizeOfTitle;
  362. PMACMENUITEM pMenuItem = (PMACMENUITEM)(pMenuText+*pMenuText+1);
  363. WORD wItem = 1;
  364. while((BYTE)*pMenuText)
  365. {
  366. wResItemSize = sizeof(RESITEM)+*pMenuText+1;
  367. if(pMenuItem->bKeyCodeId)
  368. wResItemSize += 3;
  369. dwResItemsSize += wResItemSize;
  370. if(wResItemSize<=dwSize) {
  371. memset(pResItem, 0, wResItemSize);
  372. pResItem->lpszCaption = (char*)memcpy((BYTE*)pResItem+sizeof(RESITEM), (char*)pMenuText+sizeof(BYTE), *pMenuText);
  373. *(pResItem->lpszCaption+*pMenuText) = '\0';
  374. if(*pResItem->lpszCaption=='-')
  375. {
  376. *pResItem->lpszCaption = '\0';
  377. pResItem->dwFlags = 0;
  378. pResItem->dwItemID = 0;
  379. }
  380. else {
  381. pResItem->dwItemID = wItem++;
  382. if(pMenuItem->bKeyCodeMark)
  383. pResItem->dwFlags |= MF_CHECKED;
  384. if(pMenuItem->bKeyCodeId) {
  385. strcat(pResItem->lpszCaption, "\t&");
  386. strncat(pResItem->lpszCaption, (LPCSTR)&pMenuItem->bKeyCodeId, 1 );
  387. }
  388. }
  389. pResItem->lpszCaption = (char*)memcpy((BYTE*)pResItem+sizeof(RESITEM), MacCpToAnsiCp(pResItem->lpszCaption), strlen(pResItem->lpszCaption));
  390. pResItem->dwTypeID = MENU_TYPE;
  391. pResItem->dwCodePage = CODEPAGE;
  392. pResItem->dwSize = wResItemSize;
  393. dwSize -= wResItemSize;
  394. pMenuText = (BYTE*)pMenuText+sizeof(MACMENUITEM)+*pMenuText+1;
  395. pMenuItem = (PMACMENUITEM)(pMenuText+*pMenuText+1);
  396. if(!(BYTE)*pMenuText)
  397. pResItem->dwFlags |= MF_END;
  398. pResItem = (LPRESITEM)((BYTE*)lpBuffer+dwResItemsSize);
  399. }
  400. }
  401. return dwResItemsSize;
  402. }
  403. //=============================================================================
  404. // ParseMBAR
  405. //
  406. //
  407. //=============================================================================
  408. UINT ParseMBAR( LPVOID lpImageBuf, DWORD dwImageSize, LPVOID lpBuffer, DWORD dwSize )
  409. {
  410. return 0;
  411. }
  412. //=============================================================================
  413. // ParseSTR
  414. //
  415. // The STR resource is a plain Pascal string
  416. //=============================================================================
  417. UINT ParseSTR( LPVOID lpImageBuf, DWORD dwImageSize, LPVOID lpBuffer, DWORD dwSize )
  418. {
  419. WORD wLen = (WORD)GetPascalStringA( (BYTE**)&lpImageBuf, &szTextBuf[0], (MAX_STR>255?255:MAX_STR), (LONG*)&dwImageSize);
  420. WORD wResItemSize = sizeof(RESITEM)+wLen;
  421. if(wResItemSize<=dwSize) {
  422. LPRESITEM pResItem = (LPRESITEM)lpBuffer;
  423. // Fill the Res Item structure
  424. memset(pResItem, 0, wResItemSize);
  425. pResItem->lpszCaption = (char*)memcpy((BYTE*)pResItem+sizeof(RESITEM), MacCpToAnsiCp(szTextBuf), wLen);
  426. pResItem->dwSize = wResItemSize;
  427. pResItem->dwTypeID = STR_TYPE;
  428. pResItem->dwItemID = 1;
  429. pResItem->dwCodePage = CODEPAGE;
  430. }
  431. return wResItemSize;
  432. }
  433. //=============================================================================
  434. // ParseSTRNUM
  435. //
  436. // The STR# is an array of Pascal string
  437. //=============================================================================
  438. UINT ParseSTRNUM( LPVOID lpImageBuf, DWORD dwImageSize, LPVOID lpBuffer, DWORD dwSize )
  439. {
  440. UINT uiResItemsSize = 0;
  441. DWORD dwBufferSize = dwSize;
  442. LPRESITEM pResItem = (LPRESITEM)lpBuffer;
  443. WORD wItems = MacWordToWord((BYTE*)lpImageBuf);
  444. BYTE * pImage = (BYTE*)((BYTE*)lpImageBuf+sizeof(WORD));
  445. WORD wResItemSize = 0;
  446. int iCount = 0;
  447. while(iCount++<wItems)
  448. {
  449. BYTE bLen = *((BYTE*)pImage)+1;
  450. wResItemSize = (WORD)ParseSTR( pImage, bLen, pResItem, dwBufferSize );
  451. pImage = pImage+bLen;
  452. uiResItemsSize += wResItemSize;
  453. if(dwBufferSize>=wResItemSize) {
  454. dwBufferSize -= wResItemSize;
  455. pResItem->dwItemID = iCount;
  456. pResItem->dwTypeID = MSG_TYPE;
  457. pResItem = (LPRESITEM)((BYTE*)lpBuffer+uiResItemsSize);
  458. }
  459. else dwBufferSize = 0;
  460. }
  461. return uiResItemsSize;
  462. }
  463. //=============================================================================
  464. // ParseTEXT
  465. //
  466. // The TEXT resource is a plain Pascal string
  467. //=============================================================================
  468. UINT ParseTEXT( LPVOID lpImageBuf, DWORD dwImageSize, LPVOID lpBuffer, DWORD dwSize )
  469. {
  470. DWORD dwLen = MacLongToLong((BYTE*)lpImageBuf);
  471. DWORD dwResItemSize = sizeof(RESITEM)+dwLen;
  472. if(dwResItemSize<=dwSize) {
  473. LPRESITEM pResItem = (LPRESITEM)lpBuffer;
  474. // Fill the Res Item structure
  475. memset(pResItem, 0, dwResItemSize);
  476. pResItem->lpszCaption = (char*)memcpy((BYTE*)pResItem+sizeof(RESITEM), MacCpToAnsiCp((char*)lpImageBuf+sizeof(DWORD)), dwLen);
  477. pResItem->dwSize = dwResItemSize;
  478. pResItem->dwTypeID = STR_TYPE;
  479. pResItem->dwItemID = 1;
  480. pResItem->dwCodePage = CODEPAGE;
  481. }
  482. return dwResItemSize;
  483. }
  484. //=============================================================================
  485. // ParseWDLG
  486. //
  487. //
  488. //=============================================================================
  489. UINT ParseWDLG( LPVOID lpImageBuf, DWORD dwImageSize, LPVOID lpBuffer, DWORD dwSize )
  490. {
  491. // Get the file name
  492. char * pFileName = (char*)lpImageBuf;
  493. lpImageBuf = ((BYTE*)lpImageBuf+strlen(pFileName)+1);
  494. dwImageSize -= strlen(pFileName)+1;
  495. DWORD dwResItemsSize = 0;
  496. LPRESITEM pResItem = (LPRESITEM)lpBuffer;
  497. PMACWDLG pWdlg = (PMACWDLG)lpImageBuf;
  498. WORD * pWStr = (WORD*)((BYTE*)pWdlg+sizeof(MACWDLG));
  499. // Check if we have a menu name
  500. if(*pWStr!=0xffff) {
  501. // Just skip the string
  502. while(*pWStr)
  503. pWStr++;
  504. }
  505. else pWStr = pWStr+1;
  506. // check if we have a class name
  507. if(*pWStr!=0xffff) {
  508. // Just skip the string
  509. while(*pWStr)
  510. pWStr++;
  511. }
  512. else pWStr = pWStr+1;
  513. // get the caption
  514. WORD wLen = GetMacWString( &pWStr, &szTextBuf[0], MAX_STR );
  515. TRACE("\t\t\tWDLG: Caption: %s\n", szTextBuf);
  516. // fill the dialog frame informations
  517. WORD wResItemSize = sizeof(RESITEM)+wLen+1;
  518. dwResItemsSize += wResItemSize;
  519. if(wResItemSize<=dwSize) {
  520. memset(pResItem, 0, wResItemSize);
  521. // convert the coordinate
  522. pResItem->wX = MacWordToWord(pWdlg->wX);
  523. pResItem->wY = MacWordToWord(pWdlg->wY);
  524. pResItem->wcX = MacWordToWord(pWdlg->wcX);
  525. pResItem->wcY = MacWordToWord(pWdlg->wcY);
  526. pResItem->lpszCaption = (char*)memcpy((BYTE*)pResItem+sizeof(RESITEM), MacCpToAnsiCp(szTextBuf), wLen+1);
  527. pResItem->dwStyle = MacLongToLong(pWdlg->dwStyle);
  528. pResItem->dwExtStyle = MacLongToLong(pWdlg->dwExtStyle);
  529. pResItem->dwSize = wResItemSize;
  530. pResItem->dwTypeID = DLOG_TYPE;
  531. pResItem->dwItemID = 0;
  532. pResItem->dwCodePage = CODEPAGE;
  533. dwSize -= wResItemSize;
  534. pResItem = (LPRESITEM)((BYTE*)lpBuffer+dwResItemsSize);
  535. }
  536. if(MacLongToLong(pWdlg->dwStyle) & DS_SETFONT) {
  537. pWStr = pWStr+1;
  538. GetMacWString( &pWStr, &szTextBuf[0], MAX_STR );
  539. }
  540. // check the alignment
  541. pWStr=(WORD*)((BYTE*)pWStr+Pad4((BYTE)((DWORD_PTR)pWStr-(DWORD_PTR)pWdlg)));
  542. // for all the item in the dialog ...
  543. WORD wItems = MacWordToWord(pWdlg->wNumOfElem);
  544. WORD wCount = 0;
  545. WORD wClassID = 0;
  546. char szClassName[128] = "";
  547. PMACWDLGI pItem = (PMACWDLGI)pWStr;
  548. while(wCount<wItems)
  549. {
  550. wLen = 0;
  551. // check if we have a class name
  552. pWStr = (WORD*)((BYTE*)pItem+sizeof(MACWDLGI));
  553. if(*pWStr==0xFFFF) {
  554. wClassID = MacWordToWord((BYTE*)++pWStr);
  555. szClassName[0] = 0;
  556. pWStr++;
  557. }
  558. else
  559. wLen += GetMacWString( &pWStr, &szClassName[0], 128 )+1;
  560. // get the caption
  561. wLen += GetMacWString( &pWStr, &szTextBuf[0], MAX_STR )+1;
  562. TRACE("\t\t\t\tWDLGI: Caption: %s\n", szTextBuf);
  563. // Skip the extra stuff
  564. if(*pWStr) {
  565. pWStr = (WORD*)((BYTE*)pWStr+*pWStr);
  566. }
  567. pWStr = pWStr+1;
  568. // check the alignment
  569. pWStr=(WORD*)((BYTE*)pWStr+Pad4((BYTE)((DWORD_PTR)pWStr-(DWORD_PTR)pItem)));
  570. // Fill the ResItem Buffer
  571. wResItemSize = sizeof(RESITEM)+wLen;
  572. dwResItemsSize += wResItemSize;
  573. if(wResItemSize<=dwSize) {
  574. memset(pResItem, 0, wResItemSize);
  575. // convert the coordinate
  576. pResItem->wX = MacWordToWord(pItem->wX);
  577. pResItem->wY = MacWordToWord(pItem->wY);
  578. pResItem->wcX = MacWordToWord(pItem->wcX);
  579. pResItem->wcY = MacWordToWord(pItem->wcY);
  580. pResItem->lpszCaption = (char*)memcpy((BYTE*)pResItem+sizeof(RESITEM), MacCpToAnsiCp(szTextBuf), strlen(szTextBuf)+1);
  581. if(*szClassName)
  582. pResItem->lpszClassName = (char*)memcpy((BYTE*)pResItem->lpszCaption+strlen(szTextBuf)+1,
  583. szClassName, strlen(szClassName)+1);
  584. pResItem->wClassName = wClassID;
  585. pResItem->dwSize = wResItemSize;
  586. pResItem->dwTypeID = DLOG_TYPE;
  587. pResItem->dwItemID = MacWordToWord(pItem->wID);
  588. pResItem->dwCodePage = CODEPAGE;
  589. pResItem->dwStyle = MacLongToLong(pItem->dwStyle);
  590. pResItem->dwExtStyle = MacLongToLong(pItem->dwExtStyle);
  591. dwSize -= wResItemSize;
  592. pResItem = (LPRESITEM)((BYTE*)lpBuffer+dwResItemsSize);
  593. }
  594. pItem = (PMACWDLGI)(BYTE*)pWStr;
  595. wCount++;
  596. }
  597. return dwResItemsSize;
  598. }
  599. //=============================================================================
  600. // ParseDLOG
  601. //
  602. //
  603. //=============================================================================
  604. UINT ParseDLOG( LPVOID lpImageBuf, DWORD dwImageSize, LPVOID lpBuffer, DWORD dwSize )
  605. {
  606. // Get the file name
  607. char * pFileName = (char*)lpImageBuf;
  608. lpImageBuf = ((BYTE*)lpImageBuf+strlen(pFileName)+1);
  609. dwImageSize -= strlen(pFileName)+1;
  610. DWORD dwResItemsSize = 0;
  611. LPRESITEM pResItem = (LPRESITEM)lpBuffer;
  612. PMACDLOG pDlog = (PMACDLOG)lpImageBuf;
  613. // fill the dialog frame informations
  614. WORD wResItemSize = sizeof(RESITEM)+pDlog->bLenOfTitle+1;
  615. dwResItemsSize += wResItemSize;
  616. if(wResItemSize<=dwSize) {
  617. memset(pResItem, 0, wResItemSize);
  618. // convert the coordinate
  619. pResItem->wX = MacValToWinVal(pDlog->wLeft);
  620. pResItem->wY = MacValToWinVal(pDlog->wTop);
  621. pResItem->wcX = MacValToWinVal(pDlog->wRight) - pResItem->wX;
  622. pResItem->wcY = MacValToWinVal(pDlog->wBottom) - pResItem->wY;
  623. // Make up a Style for the dialog
  624. pResItem->dwStyle = DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION;
  625. pResItem->lpszCaption = (char*)memcpy((BYTE*)pResItem+sizeof(RESITEM), MacCpToAnsiCp((char*)pDlog+sizeof(MACDLOG)), pDlog->bLenOfTitle);
  626. *(pResItem->lpszCaption+pDlog->bLenOfTitle) = 0;
  627. pResItem->dwSize = wResItemSize;
  628. pResItem->dwTypeID = DLOG_TYPE;
  629. pResItem->dwItemID = 0;
  630. pResItem->dwCodePage = CODEPAGE;
  631. dwSize -= wResItemSize;
  632. pResItem = (LPRESITEM)((BYTE*)lpBuffer+dwResItemsSize);
  633. }
  634. // Find the DITL for this Dialog
  635. LPSTR pResName = (LPSTR)MacWordToWord(pDlog->wRefIdOfDITL);
  636. CFile file;
  637. // Open the file and try to read the information on the resource in it.
  638. if (!file.Open(pFileName, CFile::modeRead | CFile::typeBinary | CFile::shareDenyNone))
  639. return LPNULL;
  640. DWORD dwOffsetToDITL = FindMacResource(&file, "DITL", pResName );
  641. TRACE("\t\t\tParseDLOG:\tItemList %d at offset: %X\n", MacWordToWord(pDlog->wRefIdOfDITL), dwOffsetToDITL );
  642. if(dwOffsetToDITL) {
  643. BYTE szSize[4];
  644. file.Seek(dwOffsetToDITL, CFile::begin);
  645. file.Read(szSize, 4);
  646. // Parse the Item List
  647. LONG lSize = MacLongToLong(szSize);
  648. BYTE * pData = (BYTE*)malloc(lSize);
  649. if(!pData)
  650. return 0;
  651. file.Read(pData, lSize);
  652. dwResItemsSize += ParseDITL( pData, lSize, pResItem, dwSize );
  653. free(pData);
  654. }
  655. file.Close();
  656. return dwResItemsSize;
  657. }
  658. //=============================================================================
  659. // ParseALRT
  660. //
  661. //
  662. //=============================================================================
  663. UINT ParseALRT( LPVOID lpImageBuf, DWORD dwImageSize, LPVOID lpBuffer, DWORD dwSize )
  664. {
  665. // Get the file name
  666. char * pFileName = (char*)lpImageBuf;
  667. lpImageBuf = ((BYTE*)lpImageBuf+strlen(pFileName)+1);
  668. dwImageSize -= strlen(pFileName)+1;
  669. DWORD dwResItemsSize = 0;
  670. LPRESITEM pResItem = (LPRESITEM)lpBuffer;
  671. PMACALRT pAlrt = (PMACALRT)lpImageBuf;
  672. // fill the dialog frame informations
  673. WORD wResItemSize = sizeof(RESITEM);
  674. dwResItemsSize += wResItemSize;
  675. if(wResItemSize<=dwSize) {
  676. memset(pResItem, 0, wResItemSize);
  677. // convert the coordinate
  678. pResItem->wX = MacValToWinVal(pAlrt->wLeft);
  679. pResItem->wY = MacValToWinVal(pAlrt->wTop);
  680. pResItem->wcX = MacValToWinVal(pAlrt->wRight) - pResItem->wX;
  681. pResItem->wcY = MacValToWinVal(pAlrt->wBottom) - pResItem->wY;
  682. // Make up a Style for the dialog
  683. pResItem->dwStyle = DS_MODALFRAME | WS_POPUP | WS_VISIBLE;
  684. pResItem->lpszCaption = LPNULL; // ALRT don't have a title
  685. pResItem->dwSize = wResItemSize;
  686. pResItem->dwTypeID = DLOG_TYPE;
  687. pResItem->dwItemID = 0;
  688. pResItem->dwCodePage = CODEPAGE;
  689. dwSize -= wResItemSize;
  690. pResItem = (LPRESITEM)((BYTE*)lpBuffer+dwResItemsSize);
  691. }
  692. // Find the DITL for this Dialog
  693. LPSTR pResName = (LPSTR)MacWordToWord(pAlrt->wRefIdOfDITL);
  694. CFile file;
  695. // Open the file and try to read the information on the resource in it.
  696. if (!file.Open(pFileName, CFile::modeRead | CFile::typeBinary | CFile::shareDenyNone))
  697. return LPNULL;
  698. DWORD dwOffsetToDITL = FindMacResource(&file, "DITL", pResName );
  699. TRACE("\t\t\tParseALRT:\tItemList %d at offset: %X\n", MacWordToWord(pAlrt->wRefIdOfDITL), dwOffsetToDITL );
  700. if(dwOffsetToDITL) {
  701. BYTE szSize[4];
  702. file.Seek(dwOffsetToDITL, CFile::begin);
  703. file.Read(szSize, 4);
  704. // Parse the Item List
  705. LONG lSize = MacLongToLong(szSize);
  706. BYTE * pData = (BYTE*)malloc(lSize);
  707. if(!pData)
  708. return 0;
  709. file.Read(pData, lSize);
  710. dwResItemsSize += ParseDITL( pData, lSize, pResItem, dwSize );
  711. free(pData);
  712. }
  713. file.Close();
  714. return dwResItemsSize;
  715. }
  716. //=============================================================================
  717. // ParseWIND
  718. // WIND is the frame window. I simulate this as a dialog itself, even if all
  719. // the other components will be inside this one.
  720. //=============================================================================
  721. UINT ParseWIND( LPVOID lpImageBuf, DWORD dwImageSize, LPVOID lpBuffer, DWORD dwSize )
  722. {
  723. // Get the file name
  724. char * pFileName = (char*)lpImageBuf;
  725. lpImageBuf = ((BYTE*)lpImageBuf+strlen(pFileName)+1);
  726. dwImageSize -= strlen(pFileName)+1;
  727. DWORD dwResItemsSize = 0;
  728. LPRESITEM pResItem = (LPRESITEM)lpBuffer;
  729. PMACWIND pWind = (PMACWIND)lpImageBuf;
  730. // fill the dialog frame informations
  731. WORD wResItemSize = sizeof(RESITEM)+pWind->bLenOfTitle+1;
  732. dwResItemsSize += wResItemSize;
  733. if(wResItemSize<=dwSize) {
  734. memset(pResItem, 0, wResItemSize);
  735. // convert the coordinate
  736. pResItem->wX = MacValToWinVal(pWind->wLeft);
  737. pResItem->wY = MacValToWinVal(pWind->wTop);
  738. pResItem->wcX = MacValToWinVal(pWind->wRight) - pResItem->wX;
  739. pResItem->wcY = MacValToWinVal(pWind->wBottom) - pResItem->wY;
  740. // Make up a Style for the dialog
  741. pResItem->dwStyle = DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION;
  742. pResItem->lpszCaption = (char*)memcpy((BYTE*)pResItem+sizeof(RESITEM), MacCpToAnsiCp((char*)pWind+sizeof(MACWIND)), pWind->bLenOfTitle);
  743. *(pResItem->lpszCaption+pWind->bLenOfTitle) = 0;
  744. pResItem->dwSize = wResItemSize;
  745. pResItem->dwTypeID = STR_TYPE; // even if is marked as a WIND_TYPE, mark it a s STR here.
  746. pResItem->dwItemID = 0;
  747. pResItem->dwCodePage = CODEPAGE;
  748. dwSize -= wResItemSize;
  749. pResItem = (LPRESITEM)((BYTE*)lpBuffer+dwResItemsSize);
  750. }
  751. return dwResItemsSize;
  752. }
  753. //=============================================================================
  754. // ParseDITL
  755. //
  756. //
  757. //=============================================================================
  758. UINT ParseDITL( LPVOID lpImageBuf, DWORD dwImageSize, LPVOID lpBuffer, DWORD dwSize )
  759. {
  760. BYTE bDataLen = 0;
  761. LPRESITEM pResItem = (LPRESITEM)lpBuffer;
  762. WORD wItems = MacWordToWord(((BYTE*)lpImageBuf))+1;
  763. WORD wCount = 1;
  764. PMACDIT pDitem = (PMACDIT)((BYTE*)lpImageBuf+sizeof(WORD));
  765. BYTE * pData = (BYTE*)pDitem+sizeof(MACDIT);
  766. dwImageSize -= sizeof(WORD);
  767. WORD wResItemSize = 0;
  768. DWORD dwResItemsSize = 0;
  769. while(wItems--)
  770. {
  771. if((bDataLen = pDitem->bSizeOfDataType) % 2)
  772. bDataLen++;
  773. switch((pDitem->bType | 128) - 128)
  774. {
  775. case 4: //button
  776. case 5: //checkbox
  777. case 6: //radio button
  778. case 8: //static text
  779. case 16: //edit text
  780. memcpy(szTextBuf, pData, pDitem->bSizeOfDataType);
  781. szTextBuf[pDitem->bSizeOfDataType] = 0;
  782. wResItemSize = sizeof(RESITEM)+pDitem->bSizeOfDataType+1;
  783. break;
  784. case 32: //icon
  785. case 64: //quick draw
  786. default:
  787. szTextBuf[0] = 0;
  788. wResItemSize = sizeof(RESITEM)+1;
  789. break;
  790. }
  791. // Fill the ResItem Buffer
  792. dwResItemsSize += wResItemSize;
  793. if(wResItemSize<=dwSize) {
  794. memset(pResItem, 0, wResItemSize);
  795. pResItem->dwStyle = WS_CHILD | WS_VISIBLE;
  796. // set the correct flag
  797. switch((pDitem->bType | 128) - 128)
  798. {
  799. case 0: //user defined
  800. pResItem->wClassName = 0x82;
  801. pResItem->dwStyle |= SS_GRAYRECT;
  802. break;
  803. case 4: //button
  804. pResItem->wClassName = 0x80;
  805. break;
  806. case 5: //checkbox
  807. pResItem->wClassName = 0x80;
  808. pResItem->dwStyle |= BS_AUTOCHECKBOX;
  809. break;
  810. case 6: //radio button
  811. pResItem->wClassName = 0x80;
  812. pResItem->dwStyle |= BS_AUTORADIOBUTTON;
  813. break;
  814. case 8: //static text
  815. pResItem->wClassName = 0x82;
  816. break;
  817. case 16: //edit text
  818. pResItem->wClassName = 0x81;
  819. pResItem->dwStyle |= ES_AUTOHSCROLL | WS_BORDER;
  820. break;
  821. case 32: //icon
  822. pResItem->wClassName = 0x82;
  823. pResItem->dwStyle |= SS_ICON;
  824. break;
  825. case 64: //picture
  826. pResItem->wClassName = 0x82;
  827. pResItem->dwStyle |= SS_BLACKRECT;
  828. break;
  829. default:
  830. break;
  831. }
  832. // convert the coordinate
  833. pResItem->wX = MacValToWinVal(pDitem->wLeft);
  834. pResItem->wY = MacValToWinVal(pDitem->wTop);
  835. pResItem->wcX = MacValToWinVal(pDitem->wRight) - pResItem->wX;
  836. pResItem->wcY = MacValToWinVal(pDitem->wBottom) - pResItem->wY;
  837. pResItem->lpszCaption = (char*)memcpy((BYTE*)pResItem+sizeof(RESITEM), MacCpToAnsiCp(szTextBuf), strlen(szTextBuf)+1);
  838. pResItem->dwSize = wResItemSize;
  839. pResItem->dwTypeID = DLOG_TYPE;
  840. pResItem->dwItemID = wCount++;
  841. pResItem->dwCodePage = CODEPAGE;
  842. dwSize -= wResItemSize;
  843. pResItem = (LPRESITEM)((BYTE*)lpBuffer+dwResItemsSize);
  844. }
  845. TRACE("\t\t\tDITL: #%d Type: %d (%d)\tLen: %d\tStr: %s\n", wCount-1,pDitem->bType, ((pDitem->bType | 128) - 128), pDitem->bSizeOfDataType, szTextBuf);
  846. dwImageSize -= sizeof(MACDIT)+bDataLen;
  847. pDitem = (PMACDIT)((BYTE*)pDitem+sizeof(MACDIT)+bDataLen);
  848. pData = (BYTE*)pDitem+sizeof(MACDIT);
  849. }
  850. return dwResItemsSize;
  851. }
  852. //=============================================================================
  853. //=============================================================================
  854. //
  855. // Updating functions
  856. //
  857. //=============================================================================
  858. //=============================================================================
  859. //=============================================================================
  860. // UpdateMENU
  861. //
  862. //=============================================================================
  863. UINT UpdateMENU( LPVOID lpNewBuf, DWORD dwNewSize,
  864. LPVOID lpOldImage, DWORD dwOldImageSize, LPVOID lpNewImage, DWORD * pdwNewImageSize )
  865. {
  866. DWORD dwNewImageSize = *pdwNewImageSize;
  867. LONG lNewSize = 0;
  868. // Copy the name to the new image
  869. WORD wLen = strlen((char*)lpOldImage)+1;
  870. if(!MemCopy( lpNewImage, lpOldImage, wLen, dwNewImageSize)) {
  871. dwNewImageSize = 0;
  872. } else {
  873. dwNewImageSize -= wLen;
  874. lpNewImage = (BYTE*)lpNewImage + wLen;
  875. }
  876. lNewSize += wLen;
  877. PMACMENU pMenu = (PMACMENU)((BYTE*)lpOldImage+wLen);
  878. BYTE* pMenuText = (BYTE*)pMenu+sizeof(MACMENU)+pMenu->bSizeOfTitle;
  879. LPRESITEM pResItem = (LPRESITEM)lpNewBuf;
  880. // check if is the apple menu
  881. if(pMenu->bSizeOfTitle==1 && *((BYTE*)&pMenu->bSizeOfTitle+1)==appleMark)
  882. {
  883. // write the MENU image
  884. if(!MemCopy( lpNewImage, pMenu, sizeof(MACMENU)+pMenu->bSizeOfTitle, dwNewImageSize)) {
  885. dwNewImageSize = 0;
  886. } else {
  887. dwNewImageSize -= sizeof(MACMENU)+pMenu->bSizeOfTitle;
  888. lpNewImage = (BYTE*)lpNewImage + sizeof(MACMENU)+pMenu->bSizeOfTitle;
  889. }
  890. lNewSize += sizeof(MACMENU)+pMenu->bSizeOfTitle;
  891. }
  892. else {
  893. // update caption size
  894. wLen = strlen(AnsiCpToMacCp(pResItem->lpszCaption));
  895. pMenu->bSizeOfTitle = LOBYTE(wLen);
  896. // write the MENU image
  897. if(!MemCopy( lpNewImage, pMenu, sizeof(MACMENU), dwNewImageSize)) {
  898. dwNewImageSize = 0;
  899. } else {
  900. dwNewImageSize -= sizeof(MACMENU);
  901. lpNewImage = (BYTE*)lpNewImage + sizeof(MACMENU);
  902. }
  903. lNewSize += sizeof(MACMENU);
  904. // ... string ...
  905. if(!MemCopy( lpNewImage, (void*)AnsiCpToMacCp(pResItem->lpszCaption), wLen, dwNewImageSize)) {
  906. dwNewImageSize = 0;
  907. } else {
  908. dwNewImageSize -= wLen;
  909. lpNewImage = (BYTE*)lpNewImage + wLen;
  910. }
  911. lNewSize += wLen;
  912. }
  913. // and now update the menu items
  914. PMACMENUITEM pMenuItem = (PMACMENUITEM)(pMenuText+*pMenuText+1);
  915. pResItem = (LPRESITEM)((BYTE*)pResItem+pResItem->dwSize);
  916. while((BYTE)*pMenuText)
  917. {
  918. // update caption size
  919. wLen = strlen(AnsiCpToMacCp(pResItem->lpszCaption));
  920. // check if is a separator
  921. if(*pMenuText==1 && *(pMenuText+1)=='-') {
  922. wLen = 1;
  923. *pResItem->lpszCaption = '-';
  924. }
  925. // check if the menu has an Hotkey
  926. if(pMenuItem->bKeyCodeId) {
  927. pMenuItem->bKeyCodeId = *(pResItem->lpszCaption+wLen-1);
  928. *(pResItem->lpszCaption+wLen-3)='\0';
  929. wLen -=3;
  930. }
  931. // ... size of the string ...
  932. if(!MemCopy( lpNewImage, &wLen, sizeof(BYTE), dwNewImageSize)) {
  933. dwNewImageSize = 0;
  934. } else {
  935. dwNewImageSize -= sizeof(BYTE);
  936. lpNewImage = (BYTE*)lpNewImage + sizeof(BYTE);
  937. }
  938. lNewSize += sizeof(BYTE);
  939. // ... string ...
  940. if(!MemCopy( lpNewImage, (void*)AnsiCpToMacCp(pResItem->lpszCaption), wLen, dwNewImageSize)) {
  941. dwNewImageSize = 0;
  942. } else {
  943. dwNewImageSize -= wLen;
  944. lpNewImage = (BYTE*)lpNewImage + wLen;
  945. }
  946. lNewSize += wLen;
  947. // write the MENU ITEM image
  948. if(!MemCopy( lpNewImage, pMenuItem, sizeof(MACMENUITEM), dwNewImageSize)) {
  949. dwNewImageSize = 0;
  950. } else {
  951. dwNewImageSize -= sizeof(MACMENUITEM);
  952. lpNewImage = (BYTE*)lpNewImage + sizeof(MACMENUITEM);
  953. }
  954. lNewSize += sizeof(MACMENUITEM);
  955. pMenuText = (BYTE*)pMenuText+sizeof(MACMENUITEM)+*pMenuText+1;
  956. pMenuItem = (PMACMENUITEM)(pMenuText+*pMenuText+1);
  957. pResItem = (LPRESITEM)((BYTE*)pResItem+pResItem->dwSize);
  958. }
  959. // add the null at the end of the menu
  960. wLen = 0;
  961. // ... menu termination ...
  962. if(!MemCopy( lpNewImage, &wLen, sizeof(BYTE), dwNewImageSize)) {
  963. dwNewImageSize = 0;
  964. } else {
  965. dwNewImageSize -= sizeof(BYTE);
  966. lpNewImage = (BYTE*)lpNewImage + sizeof(BYTE);
  967. }
  968. lNewSize += sizeof(BYTE);
  969. *pdwNewImageSize = lNewSize;
  970. return 0;
  971. }
  972. //=============================================================================
  973. // UpdateSTR
  974. //
  975. // Plain old Pascal string
  976. //=============================================================================
  977. UINT UpdateSTR( LPVOID lpNewBuf, DWORD dwNewSize,
  978. LPVOID lpOldImage, DWORD dwOldImageSize, LPVOID lpNewImage, DWORD * pdwNewImageSize )
  979. {
  980. DWORD dwNewImageSize = *pdwNewImageSize;
  981. LONG lNewSize = 0;
  982. // Copy the name to the new image
  983. WORD wLen = strlen((char*)lpOldImage)+1;
  984. if(!MemCopy( lpNewImage, lpOldImage, wLen, dwNewImageSize)) {
  985. dwNewImageSize = 0;
  986. } else {
  987. dwNewImageSize -= wLen;
  988. lpNewImage = (BYTE*)lpNewImage + wLen;
  989. }
  990. lNewSize += wLen;
  991. // Update the string
  992. PRESITEM pItem = (PRESITEM)lpNewBuf;
  993. wLen = strlen(AnsiCpToMacCp(pItem->lpszCaption));
  994. // ... size ...
  995. if(!MemCopy( lpNewImage, &wLen, sizeof(BYTE), dwNewImageSize)) {
  996. dwNewImageSize = 0;
  997. } else {
  998. dwNewImageSize -= sizeof(BYTE);
  999. lpNewImage = (BYTE*)lpNewImage + sizeof(BYTE);
  1000. }
  1001. // ... string ...
  1002. if(!MemCopy( lpNewImage, (void*)AnsiCpToMacCp(pItem->lpszCaption), wLen, dwNewImageSize)) {
  1003. dwNewImageSize = 0;
  1004. } else {
  1005. dwNewImageSize -= wLen;
  1006. lpNewImage = (BYTE*)lpNewImage + wLen;
  1007. }
  1008. lNewSize += wLen+sizeof(BYTE);
  1009. *pdwNewImageSize = lNewSize;
  1010. return 0;
  1011. }
  1012. //=============================================================================
  1013. // UpdateSTRNUM
  1014. //
  1015. // Array of pascal strings.
  1016. //=============================================================================
  1017. UINT UpdateSTRNUM( LPVOID lpNewBuf, DWORD dwNewSize,
  1018. LPVOID lpOldImage, DWORD dwOldImageSize, LPVOID lpNewImage, DWORD * pdwNewImageSize )
  1019. {
  1020. DWORD dwNewImageSize = *pdwNewImageSize;
  1021. LONG lNewSize = 0;
  1022. LONG lItemsBuf = dwNewSize;
  1023. // Copy the name to the new image
  1024. WORD wLen = strlen((char*)lpOldImage)+1;
  1025. if(!MemCopy( lpNewImage, lpOldImage, wLen, dwNewImageSize)) {
  1026. dwNewImageSize = 0;
  1027. } else {
  1028. dwNewImageSize -= wLen;
  1029. lpNewImage = (BYTE*)lpNewImage + wLen;
  1030. }
  1031. lNewSize += wLen;
  1032. // save space for the number of strings
  1033. WORD wItems = 0;
  1034. BYTE * pNumOfItems = LPNULL;
  1035. if(!MemCopy( lpNewImage, &wItems, sizeof(WORD), dwNewImageSize)) {
  1036. dwNewImageSize = 0;
  1037. } else {
  1038. dwNewImageSize -= sizeof(WORD);
  1039. pNumOfItems = (BYTE*)lpNewImage;
  1040. lpNewImage = (BYTE*)lpNewImage + sizeof(WORD);
  1041. }
  1042. lNewSize += sizeof(WORD);
  1043. PRESITEM pItem = (PRESITEM)lpNewBuf;
  1044. while(lItemsBuf)
  1045. {
  1046. wItems++;
  1047. // Update the string
  1048. wLen = strlen(AnsiCpToMacCp(pItem->lpszCaption));
  1049. // ... size ...
  1050. if(!MemCopy( lpNewImage, &wLen, sizeof(BYTE), dwNewImageSize)) {
  1051. dwNewImageSize = 0;
  1052. } else {
  1053. dwNewImageSize -= sizeof(BYTE);
  1054. lpNewImage = (BYTE*)lpNewImage + sizeof(BYTE);
  1055. }
  1056. // ... string ...
  1057. if(!MemCopy( lpNewImage, (void*)AnsiCpToMacCp(pItem->lpszCaption), wLen, dwNewImageSize)) {
  1058. dwNewImageSize = 0;
  1059. } else {
  1060. dwNewImageSize -= wLen;
  1061. lpNewImage = (BYTE*)lpNewImage + wLen;
  1062. }
  1063. lNewSize += wLen+sizeof(BYTE);
  1064. lItemsBuf -= pItem->dwSize;
  1065. pItem = (PRESITEM)((BYTE*)pItem+pItem->dwSize);
  1066. }
  1067. // fix up number of items
  1068. if(pNumOfItems)
  1069. memcpy(pNumOfItems, WordToMacWord(wItems), sizeof(WORD));
  1070. *pdwNewImageSize = lNewSize;
  1071. return 0;
  1072. }
  1073. UINT UpdateWDLG( LPVOID lpNewBuf, DWORD dwNewSize,
  1074. LPVOID lpOldImage, DWORD dwOldImageSize, LPVOID lpNewImage, DWORD * pdwNewImageSize )
  1075. {
  1076. DWORD dwNewImageSize = *pdwNewImageSize;
  1077. LONG lNewSize = 0;
  1078. DWORD dwItemsSize = dwNewSize;
  1079. char * pFileName = (char*)lpOldImage;
  1080. // Copy the name to the new image
  1081. WORD wLen = strlen((char*)lpOldImage)+1;
  1082. if(!MemCopy( lpNewImage, lpOldImage, wLen, dwNewImageSize)) {
  1083. dwNewImageSize = 0;
  1084. } else {
  1085. dwNewImageSize -= wLen;
  1086. lpNewImage = (BYTE*)lpNewImage + wLen;
  1087. }
  1088. lNewSize += wLen;
  1089. // Update the DLOG first....
  1090. PMACWDLG pWdlg = (PMACWDLG)((BYTE*)lpOldImage+wLen);
  1091. LPRESITEM pResItem = (LPRESITEM)lpNewBuf;
  1092. // Update coordinates
  1093. memcpy(pWdlg->wY,WinValToMacVal(pResItem->wY), sizeof(WORD));
  1094. memcpy(pWdlg->wX,WinValToMacVal(pResItem->wX), sizeof(WORD));
  1095. memcpy(pWdlg->wcY,WinValToMacVal(pResItem->wcY), sizeof(WORD));
  1096. memcpy(pWdlg->wcX,WinValToMacVal(pResItem->wcX), sizeof(WORD));
  1097. // write the DLOG image
  1098. if(!MemCopy( lpNewImage, pWdlg, sizeof(MACWDLG), dwNewImageSize)) {
  1099. dwNewImageSize = 0;
  1100. } else {
  1101. dwNewImageSize -= sizeof(MACWDLG);
  1102. lpNewImage = (BYTE*)lpNewImage + sizeof(MACWDLG);
  1103. }
  1104. lNewSize += sizeof(MACWDLG);
  1105. WORD * pWStr = (WORD*)((BYTE*)pWdlg+sizeof(MACWDLG));
  1106. wLen = 0;
  1107. // ...copy the menu name
  1108. if(*pWStr!=0xffff) {
  1109. wLen = 1;
  1110. WORD * pWOld = pWStr;
  1111. while(*(pWStr++))
  1112. wLen++;
  1113. wLen = wLen*sizeof(WORD);
  1114. if(wLen>=dwNewImageSize)
  1115. {
  1116. memcpy(lpNewImage, pWOld, wLen);
  1117. dwNewImageSize -= wLen;
  1118. lpNewImage = (BYTE*)lpNewImage + wLen;
  1119. }
  1120. } else {
  1121. wLen = sizeof(WORD)*2;
  1122. if(wLen>=dwNewImageSize)
  1123. {
  1124. memcpy(lpNewImage, pWStr, wLen);
  1125. dwNewImageSize -= wLen;
  1126. lpNewImage = (BYTE*)lpNewImage + wLen;
  1127. pWStr+=wLen;
  1128. }
  1129. }
  1130. // ...copy the class name
  1131. if(*pWStr!=0xffff) {
  1132. wLen = 1;
  1133. WORD * pWOld = pWStr;
  1134. while(*(pWStr++))
  1135. wLen++;
  1136. wLen = wLen*sizeof(WORD);
  1137. if(wLen>=dwNewImageSize)
  1138. {
  1139. memcpy(lpNewImage, pWOld, wLen);
  1140. dwNewImageSize -= wLen;
  1141. lpNewImage = (BYTE*)lpNewImage + wLen;
  1142. }
  1143. } else {
  1144. wLen = sizeof(WORD)*2;
  1145. if(wLen>=dwNewImageSize)
  1146. {
  1147. memcpy(lpNewImage, pWStr, wLen);
  1148. dwNewImageSize -= wLen;
  1149. lpNewImage = (BYTE*)lpNewImage + wLen;
  1150. pWStr+=wLen;
  1151. }
  1152. }
  1153. // convert the string back to "Mac WCHAR".
  1154. wLen = PutMacWString(&szWTextBuf[0], (char*)AnsiCpToMacCp(pResItem->lpszCaption), MAX_STR);
  1155. // ... string ...
  1156. if(!MemCopy( lpNewImage, &szWTextBuf[0], wLen, dwNewImageSize)) {
  1157. dwNewImageSize = 0;
  1158. } else {
  1159. dwNewImageSize -= wLen;
  1160. lpNewImage = (BYTE*)lpNewImage + wLen;
  1161. }
  1162. lNewSize += wLen;
  1163. // ... skip the caption from the old image ...
  1164. wLen = GetMacWString( &pWStr, &szTextBuf[0], MAX_STR );
  1165. // ... copy the fonts info
  1166. if(MacLongToLong(pWdlg->dwStyle) & DS_SETFONT) {
  1167. wLen = sizeof(WORD);
  1168. if(!MemCopy( lpNewImage, pWStr, wLen, dwNewImageSize)) {
  1169. dwNewImageSize = 0;
  1170. } else {
  1171. dwNewImageSize -= wLen;
  1172. lpNewImage = (BYTE*)lpNewImage + wLen;
  1173. }
  1174. lNewSize += wLen;
  1175. pWStr = pWStr+1;
  1176. GetMacWString( &pWStr, &szTextBuf[0], MAX_STR );
  1177. wLen = PutMacWString(&szWTextBuf[0], &szTextBuf[0], MAX_STR);
  1178. // ... string ...
  1179. if(!MemCopy( lpNewImage, &szWTextBuf[0], wLen, dwNewImageSize)) {
  1180. dwNewImageSize = 0;
  1181. } else {
  1182. dwNewImageSize -= wLen;
  1183. lpNewImage = (BYTE*)lpNewImage + wLen;
  1184. }
  1185. lNewSize += wLen;
  1186. }
  1187. // check the alignment
  1188. pWStr=(WORD*)((BYTE*)pWStr+Pad4((BYTE)((DWORD_PTR)pWStr-(DWORD_PTR)pWdlg)));
  1189. *pdwNewImageSize = lNewSize;
  1190. return 0;
  1191. }
  1192. //=============================================================================
  1193. // UpdateDLOG
  1194. //
  1195. // We will have to update the DITL as well as the DLOG
  1196. // The Mac Dialog have an ID of a DITL for each dialog. In the DITL there
  1197. // are the info on the Items in the dialog. The DLOG hold only the size of
  1198. // the frame and the title of the dialog
  1199. //
  1200. //=============================================================================
  1201. UINT UpdateDLOG( LPVOID lpNewBuf, DWORD dwNewSize,
  1202. LPVOID lpOldImage, DWORD dwOldImageSize, LPVOID lpNewImage, DWORD * pdwNewImageSize )
  1203. {
  1204. DWORD dwNewImageSize = *pdwNewImageSize;
  1205. LONG lNewSize = 0;
  1206. DWORD dwItemsSize = dwNewSize;
  1207. char * pFileName = (char*)lpOldImage;
  1208. // Copy the name to the new image
  1209. WORD wLen = strlen((char*)lpOldImage)+1;
  1210. if(!MemCopy( lpNewImage, lpOldImage, wLen, dwNewImageSize)) {
  1211. dwNewImageSize = 0;
  1212. } else {
  1213. dwNewImageSize -= wLen;
  1214. lpNewImage = (BYTE*)lpNewImage + wLen;
  1215. }
  1216. lNewSize += wLen;
  1217. // Update the DLOG first....
  1218. PMACDLOG pDlog = (PMACDLOG)((BYTE*)lpOldImage+wLen);
  1219. LPRESITEM pResItem = (LPRESITEM)lpNewBuf;
  1220. // Update coordinates
  1221. memcpy(pDlog->wTop,WinValToMacVal(pResItem->wY), sizeof(WORD));
  1222. memcpy(pDlog->wLeft,WinValToMacVal(pResItem->wX), sizeof(WORD));
  1223. memcpy(pDlog->wBottom,WinValToMacVal(pResItem->wY+pResItem->wcY), sizeof(WORD));
  1224. memcpy(pDlog->wRight,WinValToMacVal(pResItem->wX+pResItem->wcX), sizeof(WORD));
  1225. // update caption size
  1226. wLen = strlen(AnsiCpToMacCp(pResItem->lpszCaption));
  1227. pDlog->bLenOfTitle = LOBYTE(wLen);
  1228. // write the DLOG image
  1229. if(!MemCopy( lpNewImage, pDlog, sizeof(MACDLOG), dwNewImageSize)) {
  1230. dwNewImageSize = 0;
  1231. } else {
  1232. dwNewImageSize -= sizeof(MACDLOG);
  1233. lpNewImage = (BYTE*)lpNewImage + sizeof(MACDLOG);
  1234. }
  1235. lNewSize += sizeof(MACDLOG);
  1236. // ... string ...
  1237. if(!MemCopy( lpNewImage, (void*)AnsiCpToMacCp(pResItem->lpszCaption), wLen, dwNewImageSize)) {
  1238. dwNewImageSize = 0;
  1239. } else {
  1240. dwNewImageSize -= wLen;
  1241. lpNewImage = (BYTE*)lpNewImage + wLen;
  1242. }
  1243. lNewSize += wLen;
  1244. *pdwNewImageSize = lNewSize;
  1245. // and now update the DITL
  1246. dwItemsSize -= pResItem->dwSize;
  1247. pResItem = (LPRESITEM)((BYTE*)pResItem+pResItem->dwSize);
  1248. if(!InitIODLLLink())
  1249. return ERROR_DLL_LOAD;
  1250. // Find the DITL for this Dialog
  1251. LPSTR pResName = (LPSTR)MacWordToWord(pDlog->wRefIdOfDITL);
  1252. // Get the image from the iodll
  1253. HANDLE hResFile = (*g_lpfnHandleFromName)(pFileName);
  1254. DWORD dwImageSize = (*g_lpfnGetImage)( hResFile, (LPSTR)DITL_TYPE, pResName, 0, NULL, 0);
  1255. if(dwImageSize)
  1256. {
  1257. BYTE * pOldData = (BYTE*)malloc(dwImageSize);
  1258. if(!pOldData)
  1259. return 0;
  1260. DWORD dwNewSize = dwImageSize*2;
  1261. BYTE * pNewData = (BYTE*)malloc(dwNewSize);
  1262. if(!pNewData)
  1263. return 0;
  1264. (*g_lpfnGetImage)( hResFile, (LPSTR)DITL_TYPE, pResName, 0, pOldData, dwImageSize);
  1265. UpdateDITL( pResItem, dwItemsSize, pOldData, dwImageSize, pNewData, &dwNewSize );
  1266. // Update the data in the IODLL
  1267. (*g_lpfnUpdateResImage)(hResFile, (LPSTR)DITL_TYPE, pResName, 0, -1, pNewData, dwNewSize);
  1268. free(pOldData);
  1269. free(pNewData);
  1270. }
  1271. return 0;
  1272. }
  1273. //=============================================================================
  1274. // UpdateALRT
  1275. //
  1276. //=============================================================================
  1277. UINT UpdateALRT( LPVOID lpNewBuf, DWORD dwNewSize,
  1278. LPVOID lpOldImage, DWORD dwOldImageSize, LPVOID lpNewImage, DWORD * pdwNewImageSize )
  1279. {
  1280. DWORD dwNewImageSize = *pdwNewImageSize;
  1281. LONG lNewSize = 0;
  1282. DWORD dwItemsSize = dwNewSize;
  1283. char * pFileName = (char*)lpOldImage;
  1284. // Copy the name to the new image
  1285. WORD wLen = strlen((char*)lpOldImage)+1;
  1286. if(!MemCopy( lpNewImage, lpOldImage, wLen, dwNewImageSize)) {
  1287. dwNewImageSize = 0;
  1288. } else {
  1289. dwNewImageSize -= wLen;
  1290. lpNewImage = (BYTE*)lpNewImage + wLen;
  1291. }
  1292. lNewSize += wLen;
  1293. // Update the ALRT first....
  1294. PMACALRT pAlrt = (PMACALRT)((BYTE*)lpOldImage+wLen);
  1295. LPRESITEM pResItem = (LPRESITEM)lpNewBuf;
  1296. // Update coordinates
  1297. memcpy(pAlrt->wTop,WinValToMacVal(pResItem->wY), sizeof(WORD));
  1298. memcpy(pAlrt->wLeft,WinValToMacVal(pResItem->wX), sizeof(WORD));
  1299. memcpy(pAlrt->wBottom,WinValToMacVal(pResItem->wY+pResItem->wcY), sizeof(WORD));
  1300. memcpy(pAlrt->wRight,WinValToMacVal(pResItem->wX+pResItem->wcX), sizeof(WORD));
  1301. // write the ALRT image
  1302. if(!MemCopy( lpNewImage, pAlrt, sizeof(MACALRT), dwNewImageSize)) {
  1303. dwNewImageSize = 0;
  1304. } else {
  1305. dwNewImageSize -= sizeof(MACALRT);
  1306. lpNewImage = (BYTE*)lpNewImage + sizeof(MACALRT);
  1307. }
  1308. lNewSize += sizeof(MACALRT);
  1309. *pdwNewImageSize = lNewSize;
  1310. // and now update the DITL
  1311. dwItemsSize -= pResItem->dwSize;
  1312. pResItem = (LPRESITEM)((BYTE*)pResItem+pResItem->dwSize);
  1313. if(!InitIODLLLink())
  1314. return ERROR_DLL_LOAD;
  1315. // Find the DITL for this Dialog
  1316. LPSTR pResName = (LPSTR)MacWordToWord(pAlrt->wRefIdOfDITL);
  1317. // Get the image from the iodll
  1318. HANDLE hResFile = (*g_lpfnHandleFromName)(pFileName);
  1319. DWORD dwImageSize = (*g_lpfnGetImage)( hResFile, (LPSTR)DITL_TYPE, pResName, 0, NULL, 0);
  1320. if(dwImageSize)
  1321. {
  1322. BYTE * pOldData = (BYTE*)malloc(dwImageSize);
  1323. if(!pOldData)
  1324. return 0;
  1325. DWORD dwNewSize = dwImageSize*2;
  1326. BYTE * pNewData = (BYTE*)malloc(dwNewSize);
  1327. if(!pNewData)
  1328. return 0;
  1329. (*g_lpfnGetImage)( hResFile, (LPSTR)DITL_TYPE, pResName, 0, pOldData, dwImageSize);
  1330. UpdateDITL( pResItem, dwItemsSize, pOldData, dwImageSize, pNewData, &dwNewSize );
  1331. // Update the data in the IODLL
  1332. (*g_lpfnUpdateResImage)(hResFile, (LPSTR)DITL_TYPE, pResName, 0, -1, pNewData, dwNewSize);
  1333. free(pOldData);
  1334. free(pNewData);
  1335. }
  1336. return 0;
  1337. }
  1338. //=============================================================================
  1339. // UpdateWIND
  1340. //
  1341. //
  1342. //=============================================================================
  1343. UINT UpdateWIND( LPVOID lpNewBuf, DWORD dwNewSize,
  1344. LPVOID lpOldImage, DWORD dwOldImageSize, LPVOID lpNewImage, DWORD * pdwNewImageSize )
  1345. {
  1346. DWORD dwNewImageSize = *pdwNewImageSize;
  1347. LONG lNewSize = 0;
  1348. DWORD dwItemsSize = dwNewSize;
  1349. char * pFileName = (char*)lpOldImage;
  1350. // Copy the name to the new image
  1351. WORD wLen = strlen((char*)lpOldImage)+1;
  1352. if(!MemCopy( lpNewImage, lpOldImage, wLen, dwNewImageSize)) {
  1353. dwNewImageSize = 0;
  1354. } else {
  1355. dwNewImageSize -= wLen;
  1356. lpNewImage = (BYTE*)lpNewImage + wLen;
  1357. }
  1358. lNewSize += wLen;
  1359. PMACWIND pWind = (PMACWIND)((BYTE*)lpOldImage+wLen);
  1360. LPRESITEM pResItem = (LPRESITEM)lpNewBuf;
  1361. // Update coordinates
  1362. memcpy(pWind->wTop,WinValToMacVal(pResItem->wY), sizeof(WORD));
  1363. memcpy(pWind->wLeft,WinValToMacVal(pResItem->wX), sizeof(WORD));
  1364. memcpy(pWind->wBottom,WinValToMacVal(pResItem->wY+pResItem->wcY), sizeof(WORD));
  1365. memcpy(pWind->wRight,WinValToMacVal(pResItem->wX+pResItem->wcX), sizeof(WORD));
  1366. // update caption size
  1367. wLen = strlen(AnsiCpToMacCp(pResItem->lpszCaption));
  1368. pWind->bLenOfTitle = LOBYTE(wLen);
  1369. // write the DLOG image
  1370. if(!MemCopy( lpNewImage, pWind, sizeof(MACWIND), dwNewImageSize)) {
  1371. dwNewImageSize = 0;
  1372. } else {
  1373. dwNewImageSize -= sizeof(MACWIND);
  1374. lpNewImage = (BYTE*)lpNewImage + sizeof(MACWIND);
  1375. }
  1376. lNewSize += sizeof(MACWIND);
  1377. // ... string ...
  1378. if(!MemCopy( lpNewImage, (void*)AnsiCpToMacCp(pResItem->lpszCaption), wLen, dwNewImageSize)) {
  1379. dwNewImageSize = 0;
  1380. } else {
  1381. dwNewImageSize -= wLen;
  1382. lpNewImage = (BYTE*)lpNewImage + wLen;
  1383. }
  1384. lNewSize += wLen;
  1385. *pdwNewImageSize = lNewSize;
  1386. return 0;
  1387. }
  1388. //=============================================================================
  1389. // UpdateDITL
  1390. //
  1391. //
  1392. //=============================================================================
  1393. UINT UpdateDITL( LPVOID lpNewBuf, DWORD dwNewSize,
  1394. LPVOID lpOldImage, DWORD dwOldImageSize, LPVOID lpNewImage, DWORD * pdwNewImageSize )
  1395. {
  1396. LONG lNewSize = 0;
  1397. LONG lItemsBuf = dwNewSize;
  1398. DWORD dwNewImageSize = *pdwNewImageSize;
  1399. BYTE bDataLen = 0;
  1400. // Copy the name to the new image
  1401. WORD wLen = strlen((char*)lpOldImage)+1;
  1402. if(!MemCopy( lpNewImage, lpOldImage, wLen, dwNewImageSize)) {
  1403. dwNewImageSize = 0;
  1404. } else {
  1405. dwNewImageSize -= wLen;
  1406. lpNewImage = (BYTE*)lpNewImage + wLen;
  1407. }
  1408. lNewSize += wLen;
  1409. // save space for the number of items
  1410. WORD wItems = 0;
  1411. BYTE * pNumOfItems = LPNULL;
  1412. if(!MemCopy( lpNewImage, &wItems, sizeof(WORD), dwNewImageSize)) {
  1413. dwNewImageSize = 0;
  1414. } else {
  1415. dwNewImageSize -= sizeof(WORD);
  1416. pNumOfItems = (BYTE*)lpNewImage;
  1417. lpNewImage = (BYTE*)lpNewImage + sizeof(WORD);
  1418. }
  1419. lNewSize += sizeof(WORD);
  1420. PRESITEM pResItem = (PRESITEM)lpNewBuf;
  1421. PMACDIT pDitem = (PMACDIT)((BYTE*)lpOldImage+wLen+sizeof(WORD));
  1422. while(lItemsBuf)
  1423. {
  1424. wItems++;
  1425. if((bDataLen = pDitem->bSizeOfDataType) % 2)
  1426. bDataLen++;
  1427. // Update coordinates
  1428. memcpy(pDitem->wTop,WinValToMacVal(pResItem->wY), sizeof(WORD));
  1429. memcpy(pDitem->wLeft,WinValToMacVal(pResItem->wX), sizeof(WORD));
  1430. memcpy(pDitem->wBottom,WinValToMacVal(pResItem->wY+pResItem->wcY), sizeof(WORD));
  1431. memcpy(pDitem->wRight,WinValToMacVal(pResItem->wX+pResItem->wcX), sizeof(WORD));
  1432. switch((pDitem->bType | 128) - 128)
  1433. {
  1434. case 4: //button
  1435. case 5: //checkbox
  1436. case 6: //radio button
  1437. case 8: //static text
  1438. case 16: //edit text
  1439. // update caption size
  1440. wLen = strlen(AnsiCpToMacCp(pResItem->lpszCaption));
  1441. pDitem->bSizeOfDataType = LOBYTE(wLen);
  1442. // write the DIT image
  1443. if(!MemCopy( lpNewImage, pDitem, sizeof(MACDIT), dwNewImageSize)) {
  1444. dwNewImageSize = 0;
  1445. } else {
  1446. dwNewImageSize -= sizeof(MACDIT);
  1447. lpNewImage = (BYTE*)lpNewImage + sizeof(MACDIT);
  1448. }
  1449. lNewSize += sizeof(MACDIT);
  1450. // ... string ...
  1451. if(!MemCopy( lpNewImage, (void*)AnsiCpToMacCp(pResItem->lpszCaption), wLen, dwNewImageSize)) {
  1452. dwNewImageSize = 0;
  1453. } else {
  1454. dwNewImageSize -= wLen;
  1455. lpNewImage = (BYTE*)lpNewImage + wLen;
  1456. }
  1457. lNewSize += wLen;
  1458. if(pDitem->bSizeOfDataType % 2) {
  1459. BYTE b = 0;
  1460. if(!MemCopy( lpNewImage, &b, 1, dwNewImageSize)) {
  1461. dwNewImageSize = 0;
  1462. } else {
  1463. dwNewImageSize -= wLen;
  1464. lpNewImage = (BYTE*)lpNewImage + 1;
  1465. }
  1466. lNewSize += 1;
  1467. }
  1468. break;
  1469. case 32: //icon
  1470. case 64: //quick draw
  1471. default:
  1472. wLen = sizeof(MACDIT)+pDitem->bSizeOfDataType;
  1473. if(!MemCopy( lpNewImage, pDitem, wLen, dwNewImageSize)) {
  1474. dwNewImageSize = 0;
  1475. } else {
  1476. dwNewImageSize -= wLen;
  1477. lpNewImage = (BYTE*)lpNewImage + wLen ;
  1478. }
  1479. lNewSize += wLen;
  1480. if(pDitem->bSizeOfDataType % 2) {
  1481. BYTE b = 0;
  1482. if(!MemCopy( lpNewImage, &b, 1, dwNewImageSize)) {
  1483. dwNewImageSize = 0;
  1484. } else {
  1485. dwNewImageSize -= wLen;
  1486. lpNewImage = (BYTE*)lpNewImage + 1;
  1487. }
  1488. lNewSize += 1;
  1489. }
  1490. break;
  1491. }
  1492. lItemsBuf -= pResItem->dwSize;
  1493. pResItem = (PRESITEM)((BYTE*)pResItem+pResItem->dwSize);
  1494. pDitem = (PMACDIT)((BYTE*)pDitem+sizeof(MACDIT)+bDataLen);
  1495. }
  1496. // fix up number of items
  1497. if(pNumOfItems)
  1498. memcpy(pNumOfItems, WordToMacWord(wItems-1), sizeof(WORD));
  1499. *pdwNewImageSize = lNewSize;
  1500. return 0;
  1501. }
  1502. //=============================================================================
  1503. //=============================================================================
  1504. //
  1505. // General helper functions
  1506. //
  1507. //=============================================================================
  1508. //=============================================================================
  1509. WORD GetMacWString( WORD ** pWStr, char * pStr, int iMaxLen)
  1510. {
  1511. WORD wLen = 0;
  1512. while(**pWStr && wLen<iMaxLen)
  1513. {
  1514. if(LOBYTE(**pWStr)) {
  1515. // This is a DBCS String
  1516. TRACE("WARNING ******** WARNING ******** WARNING ******** WARNING ********\n");
  1517. TRACE("DBCS string in the MAC file not supported yet\n");
  1518. TRACE("WARNING ******** WARNING ******** WARNING ******** WARNING ********\n");
  1519. return 0; // This is a DBCS String
  1520. }
  1521. *pStr++ = HIBYTE(*(*pWStr)++);
  1522. wLen ++;
  1523. }
  1524. *pStr = HIBYTE(*(*pWStr)++);
  1525. return wLen;
  1526. }
  1527. WORD PutMacWString( WORD * pWStr, char * pStr, int iMaxLen)
  1528. {
  1529. WORD wLen = 0;
  1530. while(*pStr && wLen<iMaxLen)
  1531. {
  1532. *(pWStr++) = *(pStr++);
  1533. wLen ++;
  1534. }
  1535. *(pWStr++) = *(pStr++);
  1536. return wLen;
  1537. }
  1538. static BYTE b[4]; // used as a buffer for the conversion utils
  1539. BYTE * WordToMacWord(WORD w)
  1540. {
  1541. BYTE *pw = (BYTE *) &w;
  1542. BYTE *p = (BYTE *) &b[0];
  1543. pw += 1;
  1544. *p++ = *pw--;
  1545. *p = *pw;
  1546. return &b[0];
  1547. }
  1548. BYTE * LongToMacLong(LONG l)
  1549. {
  1550. BYTE *pl = (BYTE *) &l;
  1551. BYTE *p = (BYTE *) &b[0];
  1552. pl += 3;
  1553. *p++ = *pl--;
  1554. *p++ = *pl--;
  1555. *p++ = *pl--;
  1556. *p = *pl;
  1557. return &b[0];
  1558. }
  1559. BYTE * LongToMacOffset(LONG l)
  1560. {
  1561. BYTE *pl = (BYTE *) &l;
  1562. BYTE *p = (BYTE *) &b[0];
  1563. pl += 2;
  1564. *p++ = *pl--;
  1565. *p++ = *pl--;
  1566. *p = *pl;
  1567. return &b[0];
  1568. }
  1569. BYTE * WinValToMacVal(WORD w)
  1570. {
  1571. return WordToMacWord((WORD)(w / COORDINATE_FACTOR));
  1572. }
  1573. //=============================================================================
  1574. // Created a list of updated resource. This list will be used in the
  1575. // IsResUpdated funtion to detect if the resource has been updated.
  1576. PUPDATEDRESLIST UpdatedResList( LPVOID lpBuf, UINT uiSize )
  1577. {
  1578. if(!uiSize)
  1579. return LPNULL;
  1580. BYTE * pUpd = (BYTE*)lpBuf;
  1581. PUPDATEDRESLIST pListHead = (PUPDATEDRESLIST)malloc(uiSize*3); // this should be enough in all cases
  1582. if(!pListHead)
  1583. return LPNULL;
  1584. memset(pListHead, 0, uiSize*3);
  1585. PUPDATEDRESLIST pList = pListHead;
  1586. BYTE bPad = 0;
  1587. WORD wSize = 0;
  1588. while(uiSize>0) {
  1589. pList->pTypeId = (WORD*)pUpd;
  1590. pList->pTypeName = (BYTE*)pList->pTypeId+sizeof(WORD);
  1591. // check the allignement
  1592. bPad = strlen((LPSTR)pList->pTypeName)+1+sizeof(WORD);
  1593. bPad += Pad4(bPad);
  1594. wSize = bPad;
  1595. pList->pResId = (WORD*)((BYTE*)pUpd+bPad);
  1596. pList->pResName = (BYTE*)pList->pResId+sizeof(WORD);
  1597. bPad = strlen((LPSTR)pList->pResName)+1+sizeof(WORD);
  1598. bPad += Pad4(bPad);
  1599. wSize += bPad;
  1600. pList->pLang = (DWORD*)((BYTE*)pList->pResId+bPad);
  1601. pList->pSize = (DWORD*)((BYTE*)pList->pLang+sizeof(DWORD));
  1602. pList->pNext = (PUPDATEDRESLIST)pList+1;
  1603. wSize += sizeof(DWORD)*2;
  1604. pUpd = pUpd+wSize;
  1605. uiSize -= wSize;
  1606. if(!uiSize)
  1607. pList->pNext = LPNULL;
  1608. else
  1609. pList++;
  1610. }
  1611. return pListHead;
  1612. }
  1613. PUPDATEDRESLIST IsResUpdated( BYTE* pTypeName, MACRESREFLIST reflist, PUPDATEDRESLIST pList)
  1614. {
  1615. if(!pList)
  1616. return LPNULL;
  1617. PUPDATEDRESLIST pLast = pList;
  1618. while(pList)
  1619. {
  1620. if(!strcmp((LPSTR)pList->pTypeName, (LPSTR)pTypeName)) {
  1621. if(MacWordToWord(reflist.mwResID)==*pList->pResId) {
  1622. pLast->pNext = pList->pNext;
  1623. return pList;
  1624. }
  1625. }
  1626. pLast = pList;
  1627. pList = pList->pNext;
  1628. }
  1629. return LPNULL;
  1630. }
  1631. //=============================================================================
  1632. //=============================================================================
  1633. //
  1634. // Mac to ANSI and back conversion
  1635. //
  1636. //=============================================================================
  1637. //=============================================================================
  1638. #define MAXWSTR 8192
  1639. static WCHAR szwstr[MAXWSTR];
  1640. static CHAR szstr[MAXWSTR];
  1641. LPCSTR MacCpToAnsiCp(LPCSTR str)
  1642. {
  1643. WORD wLen = strlen(str);
  1644. LPWSTR pwstr = &szwstr[0];
  1645. LPSTR pstr = &szstr[0];
  1646. if(wLen==0)
  1647. //if(1)
  1648. return str;
  1649. if(wLen>MAXWSTR)
  1650. {
  1651. TRACE("MacCpToAnsiCp. String too long. Buffer need to be increased!");
  1652. return NULL;
  1653. }
  1654. // Convert the mac string in to an ANSI wchar
  1655. if(!MultiByteToWideChar(CP_MACCP, MB_PRECOMPOSED | MB_USEGLYPHCHARS, str, wLen, pwstr, MAXWSTR))
  1656. {
  1657. TRACE("MacCpToAnsiCp. MultiByteToWideChar(...) failed.");
  1658. return NULL;
  1659. }
  1660. *(pwstr+wLen) = 0x0000;
  1661. // Convert the WideChar string in to an ANSI CP
  1662. if(!WideCharToMultiByte(CP_ACP, 0, pwstr, MAXWSTR, pstr, MAXWSTR, NULL, NULL))
  1663. {
  1664. TRACE("MacCpToAnsiCp. WideCharToMultiByte(...) failed.");
  1665. return NULL;
  1666. }
  1667. return pstr;
  1668. }
  1669. LPCSTR AnsiCpToMacCp(LPCSTR str)
  1670. {
  1671. WORD wLen = strlen(str);
  1672. LPWSTR pwstr = &szwstr[0];
  1673. LPSTR pstr = &szstr[0];
  1674. if(wLen==0)
  1675. return str;
  1676. if(wLen>MAXWSTR)
  1677. {
  1678. TRACE("AnsiCpToMacCp. String too long. Buffer need to be increased!");
  1679. return NULL;
  1680. }
  1681. // Convert the ANSI string in to a Mac wchar
  1682. if(!MultiByteToWideChar(CP_ACP, 0, str, wLen, pwstr, MAXWSTR))
  1683. {
  1684. TRACE("AnsiCpToMacCp. MultiByteToWideChar(...) failed.");
  1685. return NULL;
  1686. }
  1687. *(pwstr+wLen) = 0x0000;
  1688. // Convert the WideChar string in to an ANSI CP
  1689. if(!WideCharToMultiByte(CP_MACCP, 0, pwstr, MAXWSTR, pstr, MAXWSTR, NULL, NULL))
  1690. {
  1691. TRACE("AnsiCpToMacCp. WideCharToMultiByte(...) failed.");
  1692. return NULL;
  1693. }
  1694. return pstr;
  1695. }