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.

749 lines
24 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // File: mac.cpp
  4. //
  5. // Contents: Implementation for the Macintosh Read/Write module
  6. //
  7. // History: 23-Aug-94 alessanm created
  8. //
  9. //----------------------------------------------------------------------------
  10. #include <afxwin.h>
  11. #include <limits.h>
  12. #include <malloc.h>
  13. #include "..\common\rwdll.h"
  14. #include "..\common\m68k.h"
  15. #include "..\common\helper.h"
  16. #include "mac.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 RWTAG "MAC"
  24. static ULONG gType;
  25. static ULONG gLng;
  26. static ULONG gResId;
  27. static WCHAR gwszResId[256];
  28. HINSTANCE g_IODLLInst = 0;
  29. DWORD (PASCAL * g_lpfnGetImage)(HANDLE, LPCSTR, LPCSTR, DWORD, LPVOID, DWORD);
  30. DWORD (PASCAL * g_lpfnUpdateResImage)(HANDLE, LPSTR, LPSTR, DWORD, DWORD, LPVOID, DWORD);
  31. HANDLE (PASCAL * g_lpfnHandleFromName)(LPCSTR);
  32. /////////////////////////////////////////////////////////////////////////////
  33. // Public C interface implementation
  34. //[registration]
  35. extern "C"
  36. BOOL FAR PASCAL RWGetTypeString(LPSTR lpszTypeName)
  37. {
  38. strcpy( lpszTypeName, RWTAG );
  39. return FALSE;
  40. }
  41. //=============================================================================
  42. //
  43. // To validate a mac res binary file we will walk the resource header and see
  44. // if it matches with what we have.
  45. //
  46. //=============================================================================
  47. extern "C"
  48. BOOL FAR PASCAL RWValidateFileType (LPCSTR lpszFilename)
  49. {
  50. BOOL bRet = FALSE;
  51. TRACE("MAC.DLL: RWValidateFileType()\n");
  52. CFile file;
  53. // we Open the file to see if it is a file we can handle
  54. if (!file.Open( lpszFilename, CFile::typeBinary | CFile::modeRead | CFile::shareDenyNone ))
  55. return bRet;
  56. // Check if this is a MAC Resource file ...
  57. if(IsMacResFile( &file ))
  58. bRet = TRUE;
  59. file.Close();
  60. return bRet;
  61. }
  62. //=============================================================================
  63. //
  64. // We will walk the resource header, walk the resource map and then normalize
  65. // the Mac it to Windows id and pass this info to the RW.
  66. //
  67. //=============================================================================
  68. extern "C"
  69. DllExport
  70. UINT
  71. APIENTRY
  72. RWReadTypeInfo(
  73. LPCSTR lpszFilename,
  74. LPVOID lpBuffer,
  75. UINT* puiSize
  76. )
  77. {
  78. TRACE("MAC.DLL: RWReadTypeInfo()\n");
  79. UINT uiError = ERROR_NO_ERROR;
  80. BYTE far * lpBuf = (BYTE far *)lpBuffer;
  81. UINT uiBufSize = *puiSize;
  82. CFile file;
  83. int iFileNameLen = strlen(lpszFilename)+1;
  84. if (!file.Open(lpszFilename, CFile::modeRead | CFile::typeBinary | CFile::shareDenyNone))
  85. return ERROR_FILE_OPEN;
  86. UINT uiBufStartSize = uiBufSize;
  87. ////////////////////////////////////
  88. // Check if it is a valid mac file
  89. // Is a Mac Resource file ...
  90. if(IsMacResFile( &file )) {
  91. // load the file in memory
  92. // NOTE: WIN16 This might be to expensive in memory allocation
  93. // on a 16 bit platform
  94. BYTE * pResources = (BYTE*)malloc(file.GetLength());
  95. if(!pResources) {
  96. file.Close();
  97. return ERROR_NEW_FAILED;
  98. }
  99. file.Seek(0, CFile::begin);
  100. file.ReadHuge(pResources, file.GetLength());
  101. IMAGE_SECTION_HEADER Sect;
  102. memset(&Sect, 0, sizeof(IMAGE_SECTION_HEADER));
  103. ParseResourceFile(pResources, &Sect, (BYTE**)&lpBuffer, (LONG*)puiSize, iFileNameLen);
  104. free(pResources);
  105. *puiSize = uiBufSize - *puiSize;
  106. file.Close();
  107. return uiError;
  108. }
  109. file.Close();
  110. return uiError;
  111. }
  112. /////////////////////////////////////////////////////////////////////////////
  113. // We will prepend to the image the file name. This will be usefull later on
  114. // to retrive the dialog item list
  115. /////////////////////////////////////////////////////////////////////////////
  116. extern "C"
  117. DllExport
  118. DWORD
  119. APIENTRY
  120. RWGetImage(
  121. LPCSTR lpszFilename,
  122. DWORD dwImageOffset,
  123. LPVOID lpBuffer,
  124. DWORD dwSize
  125. )
  126. {
  127. UINT uiError = ERROR_NO_ERROR;
  128. BYTE far * lpBuf = (BYTE far *)lpBuffer;
  129. int iNameLen = strlen(lpszFilename)+1;
  130. DWORD dwBufSize = dwSize - iNameLen;
  131. // we can consider the use of a CMemFile so we get the same speed as memory access.
  132. CFile file;
  133. // Open the file and try to read the information on the resource in it.
  134. if (!file.Open(lpszFilename, CFile::modeRead | CFile::typeBinary | CFile::shareDenyNone))
  135. return (DWORD)ERROR_FILE_OPEN;
  136. if ( dwImageOffset!=(DWORD)file.Seek( dwImageOffset, CFile::begin) )
  137. return (DWORD)ERROR_FILE_INVALID_OFFSET;
  138. // copy the file name at the beginning of the buffer
  139. memcpy((BYTE*)lpBuf, lpszFilename, iNameLen);
  140. lpBuf = ((BYTE*)lpBuf+iNameLen);
  141. if (dwBufSize>UINT_MAX) {
  142. // we have to read the image in different steps
  143. return (DWORD)0L;
  144. } else uiError = file.Read( lpBuf, (UINT)dwBufSize)+iNameLen;
  145. file.Close();
  146. return (DWORD)uiError;
  147. }
  148. extern "C"
  149. DllExport
  150. UINT
  151. APIENTRY
  152. RWParseImage(
  153. LPCSTR lpszType,
  154. LPVOID lpImageBuf,
  155. DWORD dwImageSize,
  156. LPVOID lpBuffer,
  157. DWORD dwSize
  158. )
  159. {
  160. UINT uiError = ERROR_NO_ERROR;
  161. BYTE * lpBuf = (BYTE *)lpBuffer;
  162. DWORD dwBufSize = dwSize;
  163. // Remove the filename...
  164. if( !strcmp(lpszType, "MENU") ||
  165. !strcmp(lpszType, "STR ") ||
  166. !strcmp(lpszType, "STR#") ||
  167. !strcmp(lpszType, "TEXT")
  168. ) {
  169. int iFileNameLen = strlen((LPSTR)lpImageBuf)+1;
  170. lpImageBuf = ((BYTE*)lpImageBuf+iFileNameLen);
  171. dwImageSize -= iFileNameLen;
  172. }
  173. //===============================================================
  174. // Menus
  175. if( !strcmp(lpszType, "MENU") )
  176. return ParseMENU( lpImageBuf, dwImageSize, lpBuffer, dwSize );
  177. //===============================================================
  178. // Dialogs
  179. if( !strcmp(lpszType, "WDLG") )
  180. return ParseWDLG( lpImageBuf, dwImageSize, lpBuffer, dwSize );
  181. if( !strcmp(lpszType, "DLOG") )
  182. return ParseDLOG( lpImageBuf, dwImageSize, lpBuffer, dwSize );
  183. if( !strcmp(lpszType, "ALRT") )
  184. return ParseALRT( lpImageBuf, dwImageSize, lpBuffer, dwSize );
  185. //===============================================================
  186. // Strings
  187. if( !strcmp(lpszType, "STR ") )
  188. return ParseSTR( lpImageBuf, dwImageSize, lpBuffer, dwSize );
  189. if( !strcmp(lpszType, "STR#") )
  190. return ParseSTRNUM( lpImageBuf, dwImageSize, lpBuffer, dwSize );
  191. if( !strcmp(lpszType, "TEXT") )
  192. return ParseTEXT( lpImageBuf, dwImageSize, lpBuffer, dwSize );
  193. if( !strcmp(lpszType, "WIND") )
  194. return ParseWIND( lpImageBuf, dwImageSize, lpBuffer, dwSize );
  195. return uiError;
  196. }
  197. extern"C"
  198. DllExport
  199. UINT
  200. APIENTRY
  201. RWWriteFile(
  202. LPCSTR lpszSrcFilename,
  203. LPCSTR lpszTgtFilename,
  204. HANDLE hResFileModule,
  205. LPVOID lpBuffer,
  206. UINT uiSize,
  207. HINSTANCE hDllInst,
  208. LPCSTR lpszSymbolPath
  209. )
  210. {
  211. TRACE("RWMAC.DLL: Source: %s\t Target: %s\n", lpszSrcFilename, lpszTgtFilename);
  212. UINT uiError = ERROR_NO_ERROR;
  213. PUPDATEDRESLIST pUpdList = LPNULL;
  214. // Get the handle to the IODLL
  215. if(InitIODLLLink())
  216. hDllInst = g_IODLLInst;
  217. else return ERROR_DLL_LOAD;
  218. CFile fileIn;
  219. CFile fileOut;
  220. if (!fileIn.Open(lpszSrcFilename, CFile::modeRead | CFile::typeBinary | CFile::shareDenyNone))
  221. return (DWORD)ERROR_FILE_OPEN;
  222. if (!fileOut.Open(lpszTgtFilename, CFile::modeWrite | CFile::typeBinary))
  223. return (DWORD)ERROR_FILE_OPEN;
  224. MACRESHEADER fileHeader;
  225. // Read the header of the file...
  226. fileIn.Read(&fileHeader, sizeof(MACRESHEADER));
  227. // allocate a buffer to hold the new resource map
  228. // The buffer will be as big as the other one since there is no
  229. // need, for now, to support the adding of resource
  230. LONG lMapSize = MacLongToLong(fileHeader.mulSizeOfResMap);
  231. BYTE * pNewMap = (BYTE*)malloc(lMapSize);
  232. if(!pNewMap) {
  233. uiError = ERROR_NEW_FAILED;
  234. goto exit;
  235. }
  236. { // This is for the goto. Check error:C2362
  237. PUPDATEDRESLIST pListItem = LPNULL;
  238. // Create the list of update resource
  239. pUpdList = UpdatedResList( lpBuffer, uiSize );
  240. // set the map buffer to 0 ...
  241. memset(pNewMap, 0, lMapSize);
  242. ////////////////////////////////////////////////////////////////////////////////
  243. // Read each resource from the resource map and check if the resource has been
  244. // updated. If it has been updated, get the new resource image. Otherwise use
  245. // the original resource data.
  246. // Write the resource data in the Tgt file and write the info on the offset etc.
  247. // in the pNewMap buffer so, when all the resources have been read and written
  248. // the only thing left is to fix up some sizes and to write the buffer to disk.
  249. ////////////////////////////////////////////////////////////////////////////////
  250. // Write the resource header in the Tgt file
  251. fileOut.Write(&fileHeader, sizeof(MACRESHEADER));
  252. BYTE * pByte = (BYTE*)malloc(256);
  253. if(!pByte) {
  254. uiError = ERROR_NEW_FAILED;
  255. goto exit;
  256. }
  257. // Copy the Reserved and user data
  258. fileIn.Read(pByte, 240);
  259. fileOut.Write(pByte, 240);
  260. free(pByte);
  261. // store the position of the beginning of the res data
  262. DWORD dwBeginOfResData = fileOut.GetPosition();
  263. MACRESMAP resMap;
  264. // Read the resource map ...
  265. fileIn.Seek(MacLongToLong(fileHeader.mulOffsetToResMap), CFile::begin);
  266. fileIn.Read(&resMap, sizeof(MACRESMAP));
  267. BYTE * pTypeList = pNewMap+28;
  268. BYTE * pTypeInfo = pTypeList+2;
  269. BYTE * pRefList = LPNULL;
  270. BYTE * pNameList = LPNULL;
  271. BYTE * pName = LPNULL;
  272. DWORD dwOffsetToTypeList = fileIn.GetPosition();
  273. WORD wType;
  274. fileIn.Read(&wType, sizeof(WORD));
  275. memcpy( pNewMap+sizeof(MACRESMAP), &wType, sizeof(WORD)); // number of types - 1
  276. wType = MacWordToWord((BYTE*)&wType)+1;
  277. MACRESTYPELIST TypeList;
  278. MACRESREFLIST RefList;
  279. WORD wOffsetToRefList = wType*sizeof(MACRESTYPELIST)+sizeof(WORD);
  280. DWORD dwOffsetToLastTypeInfo = 0;
  281. DWORD dwOffsetToLastRefList = 0;
  282. DWORD dwOffsetToNameList = MacLongToLong(fileHeader.mulOffsetToResMap)+MacWordToWord(resMap.mwOffsetToNameList);
  283. DWORD dwSizeOfData = 0;
  284. while(wType) {
  285. // Read the type info ...
  286. fileIn.Read(&TypeList, sizeof(MACRESTYPELIST));
  287. dwOffsetToLastTypeInfo = fileIn.GetPosition();
  288. // ... and update the newmap buffer
  289. memcpy( pTypeInfo, &TypeList, sizeof(MACRESTYPELIST));
  290. // Fix up the offset to the ref list
  291. memcpy(((PMACRESTYPELIST)pTypeInfo)->mwOffsetToRefList, WordToMacWord(wOffsetToRefList), sizeof(WORD));
  292. pRefList = pTypeList+wOffsetToRefList;
  293. pTypeInfo = pTypeInfo+sizeof(MACRESTYPELIST);
  294. // go to the refence list ...
  295. fileIn.Seek(dwOffsetToTypeList+MacWordToWord(TypeList.mwOffsetToRefList), CFile::begin);
  296. WORD wItems = MacWordToWord(TypeList.mwNumOfThisType)+1;
  297. while(wItems){
  298. // and read the reference list for this type
  299. fileIn.Read( &RefList, sizeof(MACRESREFLIST));
  300. dwOffsetToLastRefList = fileIn.GetPosition();
  301. // is this a named resource ...
  302. if(MacWordToWord(RefList.mwOffsetToResName)!=0xffff) {
  303. // read the string
  304. fileIn.Seek(dwOffsetToNameList+MacWordToWord(RefList.mwOffsetToResName), CFile::begin);
  305. BYTE bLen = 0;
  306. fileIn.Read(&bLen, 1);
  307. if(!pNameList) {
  308. pName = pNameList = (BYTE*)malloc(1024);
  309. if(!pNameList) {
  310. uiError = ERROR_NEW_FAILED;
  311. goto exit;
  312. }
  313. }
  314. // check the free space we have
  315. if((1024-((pName-pNameList)%1024))<=bLen+1){
  316. BYTE * pNew = (BYTE*)realloc(pNameList, _msize(pNameList)+1024);
  317. if(!pNew) {
  318. uiError = ERROR_NEW_FAILED;
  319. goto exit;
  320. }
  321. pName = pNew+(pName-pNameList);
  322. pNameList = pNew;
  323. }
  324. // Update the pointer to the string
  325. memcpy(RefList.mwOffsetToResName, WordToMacWord((WORD)(pName-pNameList)), 2);
  326. memcpy(pName++, &bLen, 1);
  327. // we have room for the string
  328. fileIn.Read(pName, bLen);
  329. pName = pName+bLen;
  330. }
  331. // check if this item has been updated
  332. if(pListItem = IsResUpdated(&TypeList.szResName[0], RefList, pUpdList)) {
  333. // Save the offset to the resource
  334. DWORD dwOffsetToData = fileOut.GetPosition();
  335. DWORD dwSize = *pListItem->pSize;
  336. // allocate the buffer to hold the resource data
  337. pByte = (BYTE*)malloc(dwSize);
  338. if(!pByte){
  339. uiError = ERROR_NEW_FAILED;
  340. goto exit;
  341. }
  342. // get the data from the iodll
  343. LPSTR lpType = LPNULL;
  344. LPSTR lpRes = LPNULL;
  345. if (*pListItem->pTypeId) {
  346. lpType = (LPSTR)((WORD)*pListItem->pTypeId);
  347. } else {
  348. lpType = (LPSTR)pListItem->pTypeName;
  349. }
  350. if (*pListItem->pResId) {
  351. lpRes = (LPSTR)((WORD)*pListItem->pResId);
  352. } else {
  353. lpRes = (LPSTR)pListItem->pResName;
  354. }
  355. DWORD dwImageBufSize = (*g_lpfnGetImage)( hResFileModule,
  356. lpType,
  357. lpRes,
  358. *pListItem->pLang,
  359. pByte,
  360. *pListItem->pSize
  361. );
  362. // Remove the file name from the image
  363. int iFileNameLen = strlen((LPSTR)pByte)+1;
  364. dwSize -= iFileNameLen;
  365. // write the size of the data block
  366. fileOut.Write(LongToMacLong(dwSize), sizeof(DWORD));
  367. dwSizeOfData += dwSize+sizeof(DWORD);
  368. fileOut.Write((pByte+iFileNameLen), dwSize);
  369. free(pByte);
  370. // fix up the offset to the resource in the ref list
  371. memcpy(RefList.bOffsetToResData, LongToMacOffset(dwOffsetToData-dwBeginOfResData), 3);
  372. }
  373. else {
  374. // Get the data from the Src file
  375. // get to the data
  376. fileIn.Seek(MacLongToLong(fileHeader.mulOffsetToResData)+
  377. MacOffsetToLong(RefList.bOffsetToResData), CFile::begin);
  378. // read the size of the data block
  379. DWORD dwSize = 0;
  380. fileIn.Read(&dwSize, sizeof(DWORD));
  381. // Save the offset to the resource
  382. DWORD dwOffsetToData = fileOut.GetPosition();
  383. // write the size of the data block
  384. fileOut.Write(&dwSize, sizeof(DWORD));
  385. dwSizeOfData += sizeof(DWORD);
  386. // allocate the buffer to hold the resource data
  387. dwSizeOfData += dwSize = MacLongToLong((BYTE*)&dwSize);
  388. pByte = (BYTE*)malloc(dwSize);
  389. if(!pByte){
  390. uiError = ERROR_NEW_FAILED;
  391. goto exit;
  392. }
  393. // copy the data
  394. fileIn.Read(pByte, dwSize);
  395. fileOut.Write(pByte, dwSize);
  396. free(pByte);
  397. // fix up the offset to the resource in the ref list
  398. memcpy(RefList.bOffsetToResData, LongToMacOffset(dwOffsetToData-dwBeginOfResData), 3);
  399. }
  400. // return in the right place
  401. fileIn.Seek(dwOffsetToLastRefList, CFile::begin);
  402. // copy this data in the new map buffer
  403. memcpy(pRefList, &RefList, sizeof(MACRESREFLIST));
  404. wOffsetToRefList+=sizeof(MACRESREFLIST);
  405. // move to the new ref list
  406. pRefList = pTypeList+wOffsetToRefList;
  407. wItems--;
  408. }
  409. fileIn.Seek(dwOffsetToLastTypeInfo, CFile::begin);
  410. wType--;
  411. }
  412. // copy the resource map header info
  413. memcpy( pNewMap, &resMap, sizeof(MACRESMAP));
  414. // copy the name list at the end of the res map
  415. dwOffsetToNameList = 0;
  416. if(pNameList) {
  417. dwOffsetToNameList = (DWORD)(pRefList-pNewMap);
  418. // copy the name list
  419. memcpy(pRefList, pNameList, (size_t)(pName-pNameList));
  420. free(pNameList);
  421. }
  422. // write the resource map
  423. DWORD dwOffsetToResMap = fileOut.GetPosition();
  424. fileOut.Write(pNewMap, lMapSize);
  425. // We need to fix up the file header ...
  426. fileOut.Seek(4, CFile::begin);
  427. fileOut.Write(LongToMacLong(dwOffsetToResMap), sizeof(DWORD));
  428. fileOut.Write(LongToMacLong(dwSizeOfData), sizeof(DWORD));
  429. // ... and the resource map header
  430. fileOut.Seek(dwOffsetToResMap+4, CFile::begin);
  431. fileOut.Write(LongToMacLong(dwOffsetToResMap), sizeof(DWORD));
  432. fileOut.Write(LongToMacLong(dwSizeOfData), sizeof(DWORD));
  433. fileOut.Seek(dwOffsetToResMap+26, CFile::begin);
  434. fileOut.Write(WordToMacWord(LOWORD(dwOffsetToNameList)), sizeof(WORD));
  435. }
  436. exit:
  437. fileIn.Close();
  438. fileOut.Close();
  439. if(pNewMap)
  440. free(pNewMap);
  441. if(pUpdList)
  442. free(pUpdList);
  443. return (UINT)uiError;
  444. }
  445. extern "C"
  446. DllExport
  447. UINT
  448. APIENTRY
  449. RWUpdateImage(
  450. LPCSTR lpszType,
  451. LPVOID lpNewBuf,
  452. DWORD dwNewSize,
  453. LPVOID lpOldImage,
  454. DWORD dwOldImageSize,
  455. LPVOID lpNewImage,
  456. DWORD* pdwNewImageSize
  457. )
  458. {
  459. UINT uiError = ERROR_RW_NOTREADY;
  460. //===============================================================
  461. // Since all the Type are named in the mac at this stage we need to
  462. // know the original name of the Type and not the Windows type.
  463. // Use the typeID stored in the new ites buffer
  464. LPSTR lpRealType = ((PRESITEM)lpNewBuf)->lpszTypeID;
  465. if(!HIWORD(lpRealType)) // something is wrong if this is not valid
  466. return uiError;
  467. //===============================================================
  468. // Menus
  469. if( !strcmp(lpRealType, "MENU") )
  470. return UpdateMENU( lpNewBuf, dwNewSize, lpOldImage, dwOldImageSize, lpNewImage, pdwNewImageSize );
  471. //===============================================================
  472. // Strings
  473. if( !strcmp(lpRealType, "STR ") )
  474. return UpdateSTR( lpNewBuf, dwNewSize, lpOldImage, dwOldImageSize, lpNewImage, pdwNewImageSize );
  475. if( !strcmp(lpRealType, "STR#") )
  476. return UpdateSTRNUM( lpNewBuf, dwNewSize, lpOldImage, dwOldImageSize, lpNewImage, pdwNewImageSize );
  477. if( !strcmp(lpRealType, "WIND") )
  478. return UpdateWIND( lpNewBuf, dwNewSize, lpOldImage, dwOldImageSize, lpNewImage, pdwNewImageSize );
  479. //===============================================================
  480. // Dialogs
  481. if( !strcmp(lpRealType, "DLOG") )
  482. return UpdateDLOG( lpNewBuf, dwNewSize, lpOldImage, dwOldImageSize, lpNewImage, pdwNewImageSize );
  483. if( !strcmp(lpRealType, "ALRT") )
  484. return UpdateALRT( lpNewBuf, dwNewSize, lpOldImage, dwOldImageSize, lpNewImage, pdwNewImageSize );
  485. *pdwNewImageSize = 0L;
  486. return uiError;
  487. }
  488. ///////////////////////////////////////////////////////////////////////////
  489. // Functions implementation
  490. //=============================================================================
  491. // MapToWindowsRes
  492. //
  493. // Map a Mac resource name to a Windows resource
  494. //=============================================================================
  495. WORD MapToWindowsRes( char * pResName )
  496. {
  497. if( !strcmp(pResName, "PICT") ||
  498. !strcmp(pResName, "WBMP"))
  499. return 2;
  500. if( !strcmp(pResName, "MENU") ||
  501. !strcmp(pResName, "WMNU"))
  502. return 4;
  503. if( !strcmp(pResName, "DLOG") ||
  504. !strcmp(pResName, "ALRT") ||
  505. !strcmp(pResName, "WDLG"))
  506. return 5;
  507. if( !strcmp(pResName, "STR "))
  508. return STR_TYPE;
  509. if( !strcmp(pResName, "STR#") ||
  510. !strcmp(pResName, "TEXT"))
  511. return MSG_TYPE;
  512. if( !strcmp(pResName, "vers") ||
  513. !strcmp(pResName, "VERS"))
  514. return 16;
  515. // For the Item list return 17. This means nothing to windows and will
  516. // give us the flexibility to update the DITL list from the RW, without user
  517. // input.
  518. if( !strcmp(pResName, "DITL"))
  519. return DITL_TYPE;
  520. // For the Frame Window Caption mark it as type 18
  521. if( !strcmp(pResName, "WIND"))
  522. return WIND_TYPE;
  523. return 0;
  524. }
  525. //=============================================================================
  526. // WriteResInfo
  527. //
  528. // Fill the buffer to pass back to the iodll
  529. //=============================================================================
  530. LONG WriteResInfo(
  531. BYTE** lplpBuffer, LONG* plBufSize,
  532. WORD wTypeId, LPSTR lpszTypeId, BYTE bMaxTypeLen,
  533. WORD wNameId, LPSTR lpszNameId, BYTE bMaxNameLen,
  534. DWORD dwLang,
  535. DWORD dwSize, DWORD dwFileOffset )
  536. {
  537. LONG lSize = 0;
  538. lSize = PutWord( lplpBuffer, wTypeId, plBufSize );
  539. lSize += PutStringA( lplpBuffer, lpszTypeId, plBufSize );
  540. // Check if it is alligned
  541. lSize += Allign( lplpBuffer, plBufSize, lSize);
  542. lSize += PutWord( lplpBuffer, wNameId, plBufSize );
  543. lSize += PutStringA( lplpBuffer, lpszNameId, plBufSize );
  544. lSize += Allign( lplpBuffer, plBufSize, lSize);
  545. lSize += PutDWord( lplpBuffer, dwLang, plBufSize );
  546. lSize += PutDWord( lplpBuffer, dwSize, plBufSize );
  547. lSize += PutDWord( lplpBuffer, dwFileOffset, plBufSize );
  548. return (LONG)lSize;
  549. }
  550. BOOL InitIODLLLink()
  551. {
  552. if(!g_IODLLInst)
  553. {
  554. // Init the link with the iodll
  555. g_IODLLInst = LoadLibrary("iodll.dll");
  556. if(!g_IODLLInst)
  557. return FALSE;
  558. if((g_lpfnGetImage = (DWORD (PASCAL *)(HANDLE, LPCSTR, LPCSTR, DWORD, LPVOID, DWORD))
  559. GetProcAddress( g_IODLLInst, "RSGetResImage" ))==NULL)
  560. return FALSE;
  561. if((g_lpfnHandleFromName = (HANDLE (PASCAL *)(LPCSTR))
  562. GetProcAddress( g_IODLLInst, "RSHandleFromName" ))==NULL)
  563. return FALSE;
  564. if((g_lpfnUpdateResImage = (DWORD (PASCAL *)(HANDLE, LPSTR, LPSTR, DWORD, DWORD, LPVOID, DWORD))
  565. GetProcAddress( g_IODLLInst, "RSUpdateResImage" ))==NULL)
  566. return FALSE;
  567. }
  568. else {
  569. if(g_lpfnGetImage==NULL || g_lpfnHandleFromName==NULL)
  570. return FALSE;
  571. }
  572. return TRUE;
  573. }
  574. ////////////////////////////////////////////////////////////////////////////
  575. // DLL Specific code implementation
  576. ////////////////////////////////////////////////////////////////////////////
  577. // Library init
  578. ////////////////////////////////////////////////////////////////////////////
  579. // This function should be used verbatim. Any initialization or termination
  580. // requirements should be handled in InitPackage() and ExitPackage().
  581. //
  582. extern "C" int APIENTRY
  583. DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
  584. {
  585. if (dwReason == DLL_PROCESS_ATTACH)
  586. {
  587. // NOTE: global/static constructors have already been called!
  588. // Extension DLL one-time initialization - do not allocate memory
  589. // here, use the TRACE or ASSERT macros or call MessageBox
  590. AfxInitExtensionModule(extensionDLL, hInstance);
  591. }
  592. else if (dwReason == DLL_PROCESS_DETACH)
  593. {
  594. // Terminate the library before destructors are called
  595. AfxWinTerm();
  596. // remove the link with iodll
  597. if(g_IODLLInst)
  598. FreeLibrary(g_IODLLInst);
  599. }
  600. if (dwReason == DLL_PROCESS_DETACH || dwReason == DLL_THREAD_DETACH)
  601. return 0; // CRT term Failed
  602. return 1; // ok
  603. }
  604. /////////////////////////////////////////////////////////////////////////////