home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / resmgr.zip / source.zip / rdcpp.c < prev    next >
Text File  |  1995-05-26  |  8KB  |  305 lines

  1. /* rdcpp.c - A Warp-compatible resource decompiler            950525 */
  2. /* (c) Copyright Martin Lafaix 1995                                  */
  3.  
  4. #define  INCL_DOSRESOURCES     /* Resources values */
  5. #define  INCL_DOSMODULEMGR     /* Module Manager values */
  6. #define  INCL_DOSFILEMGR       /* File System values */
  7. #define  INCL_DOSMEMMGR        /* Memory Manager values */
  8. #include <os2.h>
  9. #include <stdio.h>
  10.  
  11. #include "rdcpp.h"
  12. #include <newexe.h>
  13. #include <exe386.h>
  14.  
  15.  
  16. int main(int argc, char *argv[], char *envp[])
  17. {
  18.   CHAR      LoadError[256];
  19.   HMODULE   ModuleHandle;
  20.   HFILE     hf, hDestFile;
  21.   ULONG     ulAction, i, ulSize;
  22.   PRESENTRY pre;
  23.   APIRET    rc;
  24.  
  25.   /*
  26.    * argv[1] is input file name (a DLL)
  27.    * argv[2] is output file name (a RES)
  28.    */
  29.  
  30.   /**** Extracting resource table ****/
  31.  
  32.   rc = DosOpen(argv[1],
  33.                &hf,
  34.                &ulAction,
  35.                0,
  36.                FILE_NORMAL,
  37.                FILE_OPEN,
  38.                OPEN_ACCESS_READWRITE | OPEN_SHARE_DENYREADWRITE,
  39.                (PEAOP2) NULL);
  40.  
  41.   ENSURE(DosOpen MODULE_NAME)
  42.  
  43.   rc = _getresourcetable(hf, &ulSize, &pre);
  44.  
  45.   ENSURE(_getresourcetable)
  46.  
  47.   rc = DosClose(hf);
  48.  
  49.   ENSURE(DosClose MODULE_NAME)
  50.   /**** Done! ****/
  51.  
  52.   /**** Opening module ****/
  53.   rc = DosLoadModule(LoadError,
  54.                      sizeof(LoadError),
  55.                      argv[1],
  56.                      &ModuleHandle);
  57.  
  58.   ENSURE(DosLoadModule)
  59.   /**** Done! ****/
  60.  
  61.   /**** Creating resource file ****/
  62.   rc = DosOpen(argv[2],
  63.                &hDestFile,
  64.                &ulAction,
  65.                0,
  66.                FILE_NORMAL,
  67.                FILE_CREATE | OPEN_ACTION_REPLACE_IF_EXISTS,
  68.                OPEN_ACCESS_WRITEONLY | OPEN_SHARE_DENYREADWRITE,
  69.                (PEAOP2) NULL);
  70.  
  71.   ENSURE(DosOpen RES_FILE_NAME)
  72.  
  73.   printf("\n\nWriting binary resources to %s\n",argv[2]);
  74.  
  75.   for(i = 0; i < ulSize; i++)
  76.     _extractresource(ModuleHandle, 
  77.                      pre[i].name,
  78.                      pre[i].type,
  79.                      pre[i].flags,
  80.                      hDestFile);
  81.  
  82.   rc = DosClose(hDestFile);
  83.  
  84.   ENSURE(DosClose RES_FILE_NAME)
  85.   /**** Done! ****/
  86.  
  87.   /**** Clean up ****/
  88.   rc = _freeresourcetable(pre);
  89.  
  90.   ENSURE(_freeresourcetable)
  91.  
  92.   rc = DosFreeModule(ModuleHandle);
  93.  
  94.   ENSURE(DosFreeModule)
  95.  
  96.   /**** Done! ****/
  97.   return 0;
  98. }
  99.  
  100. /* extract resource ulName.ulType from hmod, and write it with its header in hf */
  101. APIRET _extractresource(HMODULE hmod, ULONG ulName, ULONG ulType, ULONG ulFlags, HFILE hf)
  102. {
  103.   ULONG     ulSize;         /* Size of the resource (returned) */
  104.   PVOID     pvOffset;       /* Offset of the resource (returned) */
  105.   ULONG     cbWritten;      /* Number of bytes written to file */
  106.   RESHEADER rh;
  107.   APIRET    rc;
  108.  
  109.   rc = DosQueryResourceSize(hmod, ulType, ulName, &ulSize);
  110.  
  111.   ENSURE(DosQueryResourceSize)
  112.  
  113.   rc = DosGetResource(hmod, ulType, ulName, &pvOffset);
  114.  
  115.   ENSURE(DosGetResource)
  116.  
  117.   rh.b1 = 0xFF;
  118.   rh.type = ulType;
  119.   rh.b2 = 0xFF;
  120.   rh.name = ulName;
  121.   rh.flags = ulFlags;
  122.   rh.cb = ulSize;
  123.   rc = DosWrite(hf, &rh, sizeof(RESHEADER), &cbWritten);
  124.  
  125.   ENSURE(DosWrite)
  126.  
  127.   rc = DosWrite(hf, pvOffset, ulSize, &cbWritten);
  128.  
  129.   ENSURE(DosWrite)
  130.  
  131.   rc = DosFreeResource(pvOffset);
  132.  
  133.   ENSURE(DosFreeResource)
  134.  
  135.   printf("    %ld.%ld (%ld)\n", ulName, ulType, ulSize);
  136.   return 0;
  137. }
  138.  
  139. /* get the resource table from EXE or DLL, 286 or 386 format */
  140. APIRET _getresourcetable(HFILE hf, PULONG pulSize, PRESENTRY *ppre)
  141. {
  142.   ULONG     ulPos, ulDummy;
  143.   APIRET    rc;
  144.   char buff[2];
  145.  
  146.   rc = DosSetFilePtr(hf, 0, FILE_BEGIN, &ulDummy);
  147.  
  148.   ENSURE(DosSetFilePtr)
  149.  
  150.   rc = DosRead(hf, &buff, sizeof(buff), &ulDummy);
  151.  
  152.   ENSURE(DosRead)
  153.  
  154.   if(buff[0] == 'M' && buff[1] == 'Z')
  155.     {
  156.     /* it's a DOS header, find the new header offset */
  157.     rc = DosSetFilePtr(hf, 60, FILE_BEGIN, &ulDummy);
  158.     rc = DosRead(hf, &ulPos, sizeof(ulPos), &ulDummy);
  159.     }
  160.   else
  161.     ulPos = 0;
  162.  
  163.   rc = DosSetFilePtr(hf, ulPos, FILE_BEGIN, &ulDummy);
  164.   rc = DosRead(hf, &buff, sizeof(buff), &ulDummy);
  165.  
  166.   if(buff[0] == 'L' && buff[1] == 'X')
  167.     {
  168.     /* read the 386 header */
  169.     struct e32_exe header;
  170.     int i;
  171.  
  172.     puts("Reading OS/2 v2.x .EXE file");
  173.  
  174.     rc = DosSetFilePtr(hf, -sizeof(buff), FILE_CURRENT, &ulDummy);
  175.     rc = DosRead(hf, &header, sizeof(header), &ulDummy);
  176.  
  177.     E32_MFLAGS(header) = E32NOTP|(E32_MFLAGS(header)&(E32NOEXTFIX|E32NOINTFIX));
  178.     E32_STARTOBJ(header) = 0;
  179.     E32_EIP(header) = 0;
  180.     E32_STACKOBJ(header) = 0;
  181.     E32_ESP(header) = 0;
  182.     E32_HEAPSIZE(header) = 0;
  183.     E32_STACKSIZE(header) = 0;
  184.     E32_IMPMODCNT(header) = 0;
  185.     E32_INSTDEMAND(header) = 0;
  186.     E32_INSTPRELOAD(header) = 0;
  187.  
  188.     rc = DosSetFilePtr(hf, ulPos, FILE_BEGIN, &ulDummy);
  189.     rc = DosWrite(hf, &header, sizeof(header), &ulDummy);
  190.  
  191.     *pulSize = E32_RSRCCNT(header);
  192.  
  193.     rc = DosAllocMem((PPVOID)ppre,
  194.                      *pulSize*sizeof(RESENTRY),
  195.                      PAG_READ|PAG_WRITE|PAG_COMMIT);
  196.  
  197.     ENSURE(DosAllocMem)
  198.  
  199.     rc = DosSetFilePtr(hf, ulPos+E32_RSRCTAB(header), FILE_BEGIN, &ulDummy);
  200.     for(i = 0; i < *pulSize; i++)
  201.       {
  202.       /* read rsrctab */
  203.       struct rsrc32 rs;
  204.  
  205.       rc = DosRead(hf, &rs, 14, &ulDummy); /* KLUDGE: gcc returns 16 instead of 14 for sizeof(rs) */
  206.       (*ppre)[i].name = rs.name;
  207.       (*ppre)[i].type = rs.type;
  208.       (*ppre)[i].flags = rs.obj;
  209.       }
  210.  
  211.     for(i = 0; i < *pulSize; i++)
  212.       {
  213.       /* read objtab (for resource flag) */
  214.       struct o32_obj ot;
  215.  
  216.       rc = DosSetFilePtr(hf,
  217.                          ulPos+E32_OBJTAB(header)+sizeof(ot)*((*ppre)[i].flags - 1),
  218.                          FILE_BEGIN,
  219.                          &ulDummy);
  220.       rc = DosRead(hf, &ot, sizeof(ot), &ulDummy);
  221.  
  222.       (*ppre)[i].flags  = (O32_FLAGS(ot) & OBJWRITE) ? 0 : RNPURE;
  223.       (*ppre)[i].flags |= (O32_FLAGS(ot) & OBJDISCARD) ? 4096 : 0;
  224.       (*ppre)[i].flags |= (O32_FLAGS(ot) & OBJSHARED) ? RNMOVE : 0;
  225.       (*ppre)[i].flags |= (O32_FLAGS(ot) & OBJPRELOAD) ? RNPRELOAD : 0;
  226.  
  227.       printf(".");
  228.       }
  229.     }
  230.   else
  231.   if(buff[0] == 'N' && buff[1] == 'E')
  232.     {
  233.     /* read the 286 header */
  234.     struct new_exe header;
  235.     int i;
  236.  
  237.     puts("Reading OS/2 v1.x .EXE file");
  238.  
  239.     rc = DosSetFilePtr(hf, -sizeof(buff), FILE_CURRENT, &ulDummy);
  240.     rc = DosRead(hf, &header, sizeof(header), &ulDummy);
  241.  
  242.     NE_FLAGS(header) = NENOTP | NEPROT | NEINST;
  243.     NE_CSIP(header) = 0;
  244.     NE_SSSP(header) = 0;
  245.     NE_STACK(header) = 0;
  246.     NE_HEAP(header) = 0;
  247.  
  248.     rc = DosSetFilePtr(hf, ulPos, FILE_BEGIN, &ulDummy);
  249.     rc = DosWrite(hf, &header, sizeof(header), &ulDummy);
  250.  
  251.     *pulSize = NE_CRES(header);
  252.  
  253.     rc = DosAllocMem((PPVOID)ppre,
  254.                      *pulSize*sizeof(RESENTRY),
  255.                      PAG_READ|PAG_WRITE|PAG_COMMIT);
  256.  
  257.     ENSURE(DosAllocMem)
  258.  
  259.     rc = DosSetFilePtr(hf, ulPos+NE_RSRCTAB(header), FILE_BEGIN, &ulDummy);
  260.     for(i = 0; i < *pulSize; i++)
  261.       {
  262.       /* read rsrctab */
  263.       struct {unsigned short type; unsigned short name;} rti;
  264.  
  265.       rc = DosRead(hf, &rti, sizeof(rti), &ulDummy);
  266.       (*ppre)[i].name = rti.name;
  267.       (*ppre)[i].type = rti.type;
  268.       }
  269.  
  270.     for(i = 0; i < *pulSize; i++)
  271.       {
  272.       struct new_seg ns;
  273.  
  274.       rc = DosSetFilePtr(hf,
  275.                          ulPos+NE_SEGTAB(header)+sizeof(ns)*i,
  276.                          FILE_BEGIN,
  277.                          &ulDummy);
  278.       rc = DosRead(hf, &ns, sizeof(ns), &ulDummy);
  279.  
  280.       (*ppre)[i].flags  = (NS_FLAGS(ns) & NSPRELOAD) ? RNPRELOAD : 0;
  281.       (*ppre)[i].flags |= (NS_FLAGS(ns) & NSSHARED) ? RNPURE : 0;
  282.       (*ppre)[i].flags |= (NS_FLAGS(ns) & NSMOVE) ? RNMOVE : 0;
  283.       (*ppre)[i].flags |= (NS_FLAGS(ns) & NSDISCARD) ? 4096 : 0;
  284.  
  285.       printf(".");
  286.       }
  287.     }
  288.   else
  289.     {
  290.     puts("Invalid EXE header!");
  291.     *ppre = 0;
  292.     }
  293.  
  294.   return 0;
  295. }
  296.  
  297. /* free the previously allocated resource table */
  298. APIRET _freeresourcetable(PRESENTRY pre)
  299. {
  300.   if(pre)
  301.     DosFreeMem(pre);
  302.  
  303.   return 0;
  304. }
  305.