home *** CD-ROM | disk | FTP | other *** search
/ Reverse Code Engineering RCE CD +sandman 2000 / ReverseCodeEngineeringRceCdsandman2000.iso / RCE / Mammon_ / Reslib.idc < prev    next >
Text File  |  2000-05-25  |  41KB  |  937 lines

  1.  
  2. //------------------------------------------------------------------------------------------------------
  3. //Reslib.idc (rev 1.31): Resource parsing/handling functions for the PE file format
  4. //                       _____Function_____Listing_____
  5. //GetResDir(), ResolveOffset( ea ), ParseResDirOld( ea ), MakeDword_Cmt( ea, char ),
  6. //MakeWord_Cmt( ea, char), IDResource( long), ParseUnkRes( ea, ea),
  7. //ParseLeafNode( ea, char, long ), ParseSubDirData( ea, char, long, long ),  ParseDirHdr( ea ),
  8. //ParseSubDirHdr( ea, char, long, long ), ParseRootData( ea ), ParseRootHdr( ea)
  9. //
  10. // Thanks to Quine and Ssspyder for help with the enums implementation (file under "eternal gratitude" ;)
  11. // code by mammon_ All rights reversed, use as you see fit.....
  12. //------------------------------------------------------------------------------------------------------
  13.  
  14. #include <idc.idc>
  15.  
  16. #ifndef _RECURSE_
  17. #define _RECURSE_               0
  18. #endif
  19.  
  20. #ifndef _DISPLAY_RESOURCES_
  21. #define _DISPLAY_RESOUCRES_     0
  22. #endif
  23.  
  24. //GetResourceDirectory checks each segment of the program until it finds one named .rsrc
  25. //Syntax: GetResDir()
  26. //Returns: ea starting address of .rsrc segment
  27. static GetResDir()
  28. {
  29.     auto ea, next, name;
  30.     ea = FirstSeg();
  31.     next = ea;
  32.     while ( (next = NextSeg(next)) != -1) {
  33.         name = SegName(next);
  34.         if ( substr( name, 0, 5 ) == ".rsrc" ) break;
  35.    }
  36.    return next;
  37. }
  38.  
  39. //ResolveOffset adds the offset of a res data/subdir to the base address of the .rsrc directory
  40. //The offset is stored in the program as data; this data is read and added to the .rsrc RVA
  41. //Syntax: ResolveOffset(ea address_containing_offset_to_be_resolved )
  42. //Returns: ea complete address
  43. static ResolveOffset( BytePtr )
  44. {
  45.     auto res_offset;
  46.     res_offset = SegStart(BytePtr) + Word(BytePtr);
  47.     return res_offset;
  48. }
  49.  
  50. static StripZeros( BytePtr )
  51. {
  52.     if( Byte(BytePtr + 1) == 0 ) {
  53.         if( Byte(BytePtr + 2) == 0 && Byte(BytePtr + 3) == 0) {
  54.             MakeDword(BytePtr);
  55.             BytePtr = BytePtr + 4;
  56.         }
  57.         else {
  58.             MakeWord( BytePtr );
  59.             BytePtr = BytePtr + 2;
  60.         }
  61.     }
  62.     else {
  63.         MakeByte( BytePtr );
  64.         BytePtr = BytePtr + 1;
  65.     }
  66.     return BytePtr;
  67. }
  68.  
  69. //ParseResDirOld takes no parameters, and creates two databases containing the elementary
  70. //structure of the resource tree as given in the .rsrc directory header
  71. //Note: Not currently functional; included for salvage purposes
  72. //Syntax: ParseResDirOld(ea starting_address_of_.rsrc_directory)
  73. static ParseResDirOld(ea)
  74. {
  75.     auto aResType, aResLoc, BytePtr, x, total_entries;
  76.     aResType = CreateArray( "RES_TYPE" );
  77.     aResLoc = CreateArray( "RES_LOC" );
  78.     BytePtr = SegStart( ea ) + 12;
  79.     total_entries = Word( BytePtr ) + Word( BytePtr + 2 );
  80.     BytePtr = BytePtr + 4;
  81.     for ( x = 1; x <= total_entries; x = x + 1 ) {
  82.         SetArrayString( aResType, x, IdentifyTypeID( BytePtr ) );
  83.         BytePtr = BytePtr + 4;
  84.         SetArrayLong( aResLoc, x, ResolveOffset( BytePtr ) );
  85.         BytePtr = BytePtr + 4;
  86.     }
  87. }
  88.  
  89. //MakeDoubleWordWithComment: Defines 4 Unexplored bytes as a DWord (data), adds a posterior comment line,
  90. //and increments BytePtr by 4
  91. //Syntax: MakeDWord_Cmt(ea address_of_leading_byte, char comment_line)
  92. //Returns: ea BytePtr
  93. static MakeDword_Cmt(BytePtr, ResComment)
  94. {
  95.     MakeDword(BytePtr);
  96.     //ExtLinB(BytePtr, 0, ResComment);
  97.     MakeComm(BytePtr, ResComment);
  98.     BytePtr = BytePtr + 4;
  99.     return BytePtr;
  100. }
  101.  
  102. //MakeWordWithComment: Defines 2 Unexplored bytes as a Word (data), adds a posterior comment line,
  103. //and increments BytePtr by 2
  104. //Syntax: MakeWord_Cmt(ea address_of_leading_byte, char comment_line)
  105. //Returns: ea BytePtr
  106. static MakeWord_Cmt(BytePtr, ResComment)
  107. {
  108.     MakeWord(BytePtr);
  109.     //ExtLinB(BytePtr, 0, ResComment);
  110.     MakeComm(BytePtr, ResComment);
  111.     BytePtr = BytePtr + 2;
  112.     return BytePtr;
  113. }
  114.  
  115. //MakeByteWithComment: Defines 1 Unexplored byte as a Byte (data), adds a posterior comment line,
  116. //and increments BytePtr by 1
  117. //Syntax: MakeByte_Cmt(ea address_of_byte, char comment_line)
  118. //Returns: ea BytePtr
  119. static MakeByte_Cmt(BytePtr, ResComment)
  120. {
  121.     MakeByte(BytePtr);
  122.     //ExtLinB(BytePtr, 0, ResComment);
  123.     MakeComm(BytePtr, ResComment);
  124.     BytePtr = BytePtr + 1;
  125.     return BytePtr;
  126. }
  127.  
  128. //IdentifyResource: Translates a resource TypeID to its character name/designation
  129. //Syntax: ID_Resource(long TypeID)
  130. //Returns: char Resource_Type
  131. static ID_Resource(Res_ID)
  132. {
  133.     auto Resource_Type;
  134.     if ( Res_ID == 0x01) Resource_Type = "Cursor";
  135.     else if (Res_ID == 0x02) Resource_Type = "Bitmap";
  136.     else if (Res_ID == 0x03) Resource_Type = "Icon";
  137.     else if (Res_ID == 0x04) Resource_Type = "Menu";
  138.     else if (Res_ID == 0x05) Resource_Type = "Dialog";
  139.     else if (Res_ID == 0x06) Resource_Type = "String_Table";
  140.     else if (Res_ID == 0x07) Resource_Type = "Font_Directory";
  141.     else if (Res_ID == 0x08) Resource_Type = "Font";
  142.     else if (Res_ID == 0x09) Resource_Type = "Accelerator_Table";
  143.     else if (Res_ID == 0x0A) Resource_Type = "RCDATA_(Dynamically_Defined_Resource)";
  144.     else if (Res_ID == 0x0B) Resource_Type = "Message_Table";
  145.     else if (Res_ID == 0x0C) Resource_Type = "Group_Cursor";
  146.     else if (Res_ID == 0x0E) Resource_Type = "Group_Icon";
  147.     else if (Res_ID == 0x10) Resource_Type = "Version";
  148.     else if (Res_ID == 0x11) Resource_Type = "DLG_Include";
  149.     else if (Res_ID == 0x13) Resource_Type = "PlugPlay";
  150.     else if (Res_ID == 0x14) Resource_Type = "VXD";
  151.     else if (Res_ID == 0x15) Resource_Type = "AniCursor";
  152.     else if (Res_ID == 0x2002) Resource_Type = "NewBitmap";
  153.     else if (Res_ID == 0x2004) Resource_Type = "NewMenu";
  154.     else if (Res_ID == 0x2005) Resource_Type = "NewDialog";
  155.     else Resource_Type = "Unknown_Resource_Type " + ltoa(Res_ID, 10);
  156.     return Resource_Type;
  157. }
  158.  
  159. //MakeDataOffset determines the RVA of a data offset (distance of offset from start of file, not seg)
  160. //Syntax: MakeDataOffset( ea address_containing_offset_to_data )
  161. //Returns: ea RVA (Relative Virtual Address) of data
  162. static MakeDataOffset(BytePtr)
  163. {
  164.     auto Data_Offset;
  165.     Data_Offset = (FirstSeg() - 0x1000) + Dword(BytePtr);
  166.     return Data_Offset;
  167. }
  168.  
  169. //ParseStrTable: Formats String Table
  170. //Syntax: ParseStringTable(ea address_of_resource_to_parse, ea address_of_next_resource)
  171. static ParseStrTable(BytePtr, Next_Resource, str_tbl_num)
  172. {
  173.         auto curr_enum, str_num, str_rc_id, enum_id;
  174.         SetLongPrm(INF_STRTYPE, ASCSTR_UNICODE);
  175.         curr_enum = GetEnumQty() + 1;
  176.         str_num = 0;
  177.         enum_id = AddEnum(curr_enum, "String_Table" + ltoa(BytePtr, 16), FF_0NUMH);
  178.         while ( BytePtr < Next_Resource) {
  179.             if ( Word(BytePtr) != 0x00) {
  180.                 str_rc_id = ( str_tbl_num - 1) * 16 + str_num;
  181.                 MakeWord(BytePtr);
  182.                 MakeStr(BytePtr + 2, BytePtr + (2 * (Byte(BytePtr) + 1)));
  183.                 AddConst(enum_id, "string" + ltoa(BytePtr, 16), str_rc_id);
  184.                 SetConstCmt( GetConst(enum_id, str_rc_id), Name(BytePtr + 2), 1);
  185.                 str_num = str_num + 1;
  186.                 BytePtr = BytePtr + ( 2 * Byte(BytePtr)) + 2;
  187.             }
  188.             else if ( Dword(BytePtr) == 0x0000 && (BytePtr + 6) > Next_Resource) {
  189.                 MakeDword(BytePtr);
  190.                 break;
  191.                 }
  192.             else {
  193.                 MakeWord(BytePtr);
  194.                 str_num = str_num + 1;
  195.                 BytePtr = BytePtr + 2;
  196.             }
  197.         }
  198. }
  199.  
  200. //IdentifyVirtualKeyCode
  201. //Syntax: IDVKeyCode ( long virtual_key_code )
  202. static IDVKeyCode(VKeyCode)
  203. {
  204.     auto KeyCmd;
  205.     KeyCmd="";
  206.     //Note: The following is awkward as IDA does not allow Switch statements or a large number of
  207.     //else if statements...however it allows infinite "if" statements
  208.     if (VKeyCode == 0x01) KeyCmd = "VK_LBUTTON";
  209.     if (VKeyCode == 0x02  ) KeyCmd = "VK_RBUTTON";
  210.     if (VKeyCode == 0x03  ) KeyCmd = "VK_CANCEL";
  211.     if (VKeyCode == 0x04  ) KeyCmd = "VK_MBUTTON";
  212.     if (VKeyCode == 0x08  ) KeyCmd = "VK_BACK";
  213.     if (VKeyCode == 0x09  ) KeyCmd = "VK_TAB";
  214.     if (VKeyCode == 0x0C  ) KeyCmd = "VK_CLEAR";
  215.     if (VKeyCode == 0x0D  ) KeyCmd = "VK_RETURN";
  216.     if (VKeyCode == 0x10  ) KeyCmd = "VK_SHIFT";
  217.     if (VKeyCode == 0x11  ) KeyCmd = "VK_CONTROL";
  218.     if (VKeyCode == 0x12  ) KeyCmd = "VK_MENU(ALT)";
  219.     if (VKeyCode == 0x13  ) KeyCmd = "VK_PAUSE";
  220.     if (VKeyCode == 0x14  ) KeyCmd = "VK_CAPITAL";
  221.     if (VKeyCode == 0x1B  ) KeyCmd = "VK_ESCAPE";
  222.     if (VKeyCode == 0x20  ) KeyCmd = "VK_SPACE";
  223.     if (VKeyCode == 0x21  ) KeyCmd = "VK_PRIOR";
  224.     if (VKeyCode == 0x22  ) KeyCmd = "VK_NEXT";
  225.     if (VKeyCode == 0x23  ) KeyCmd = "VK_END";
  226.     if (VKeyCode == 0x24  ) KeyCmd = "VK_HOME";
  227.     if (VKeyCode == 0x25  ) KeyCmd = "VK_LEFT";
  228.     if (VKeyCode == 0x26  ) KeyCmd = "VK_UP";
  229.     if (VKeyCode == 0x27  ) KeyCmd = "VK_RIGHT";
  230.     if (VKeyCode == 0x28  ) KeyCmd = "VK_DOWN";
  231.     if (VKeyCode == 0x29  ) KeyCmd = "VK_SELECT";
  232.     if (VKeyCode == 0x2A  ) KeyCmd = "VK_PRINT";
  233.     if (VKeyCode == 0x2B  ) KeyCmd = "VK_EXECUTE";
  234.     if (VKeyCode == 0x2C  ) KeyCmd = "VK_SNAPSHOT";
  235.     if (VKeyCode == 0x2D  ) KeyCmd = "VK_INSERT";
  236.     if (VKeyCode == 0x2E  ) KeyCmd = "VK_DELETE";
  237.     if (VKeyCode == 0x2F  ) KeyCmd = "VK_HELP";
  238.     if (VKeyCode == 0x30  ) KeyCmd = "VK_0";
  239.     if (VKeyCode == 0x31  ) KeyCmd = "VK_1";
  240.     if (VKeyCode == 0x32  ) KeyCmd = "VK_2";
  241.     if (VKeyCode == 0x33  ) KeyCmd = "VK_3";
  242.     if (VKeyCode == 0x34  ) KeyCmd = "VK_4";
  243.     if (VKeyCode == 0x35  ) KeyCmd = "VK_5";
  244.     if (VKeyCode == 0x36  ) KeyCmd = "VK_6";
  245.     if (VKeyCode == 0x37  ) KeyCmd = "VK_7";
  246.     if (VKeyCode == 0x38  ) KeyCmd = "VK_8";
  247.     if (VKeyCode == 0x39  ) KeyCmd = "VK_9";
  248.     if (VKeyCode == 0x41  ) KeyCmd = "VK_A";
  249.     if (VKeyCode == 0x42  ) KeyCmd = "VK_B";
  250.     if (VKeyCode == 0x43  ) KeyCmd = "VK_C";
  251.     if (VKeyCode == 0x44  ) KeyCmd = "VK_D";
  252.     if (VKeyCode == 0x45  ) KeyCmd = "VK_E";
  253.     if (VKeyCode == 0x46  ) KeyCmd = "VK_F";
  254.     if (VKeyCode == 0x47  ) KeyCmd = "VK_G";
  255.     if (VKeyCode == 0x48  ) KeyCmd = "VK_H";
  256.     if (VKeyCode == 0x49  ) KeyCmd = "VK_I";
  257.     if (VKeyCode == 0x4A  ) KeyCmd = "VK_J";
  258.     if (VKeyCode == 0x4B  ) KeyCmd = "VK_K";
  259.     if (VKeyCode == 0x4C  ) KeyCmd = "VK_L";
  260.     if (VKeyCode == 0x4D  ) KeyCmd = "VK_M";
  261.     if (VKeyCode == 0x4E  ) KeyCmd = "VK_N";
  262.     if (VKeyCode == 0x4F  ) KeyCmd = "VK_O";
  263.     if (VKeyCode == 0x50  ) KeyCmd = "VK_P";
  264.     if (VKeyCode == 0x51  ) KeyCmd = "VK_Q";
  265.     if (VKeyCode == 0x52  ) KeyCmd = "VK_R";
  266.     if (VKeyCode == 0x53  ) KeyCmd = "VK_S";
  267.     if (VKeyCode == 0x54  ) KeyCmd = "VK_T";
  268.     if (VKeyCode == 0x55  ) KeyCmd = "VK_U";
  269.     if (VKeyCode == 0x56  ) KeyCmd = "VK_V";
  270.     if (VKeyCode == 0x57  ) KeyCmd = "VK_W";
  271.     if (VKeyCode == 0x58  ) KeyCmd = "VK_X";
  272.     if (VKeyCode == 0x59  ) KeyCmd = "VK_Y";
  273.     if (VKeyCode == 0x5A  ) KeyCmd = "VK_Z";
  274.     if (VKeyCode == 0x5B  ) KeyCmd = "VK_LWIN";
  275.     if (VKeyCode == 0x5C  ) KeyCmd = "VK_RWIN";
  276.     if (VKeyCode == 0x5D  ) KeyCmd = "VK_APS";
  277.     if (VKeyCode == 0x60  ) KeyCmd = "VK_NUMPAD0";
  278.     if (VKeyCode == 0x61  ) KeyCmd = "VK_NUMPAD1";
  279.     if (VKeyCode == 0x62  ) KeyCmd = "VK_NUMPAD2";
  280.     if (VKeyCode == 0x63  ) KeyCmd = "VK_NUMPAD3";
  281.     if (VKeyCode == 0x64  ) KeyCmd = "VK_NUMPAD4";
  282.     if (VKeyCode == 0x65  ) KeyCmd = "VK_NUMPAD5";
  283.     if (VKeyCode == 0x66  ) KeyCmd = "VK_NUMPAD6";
  284.     if (VKeyCode == 0x67  ) KeyCmd = "VK_NUMPAD7";
  285.     if (VKeyCode == 0x68  ) KeyCmd = "VK_NUMPAD8";
  286.     if (VKeyCode == 0x69  ) KeyCmd = "VK_NUMPAD9";
  287.     if (VKeyCode == 0x6A  ) KeyCmd = "VK_MULTIPLY";
  288.     if (VKeyCode == 0x6B  ) KeyCmd = "VK_ADD";
  289.     if (VKeyCode == 0x6C  ) KeyCmd = "VK_SEPERATOR";
  290.     if (VKeyCode == 0x6D  ) KeyCmd = "VK_SUBTRACT";
  291.     if (VKeyCode == 0x6E  ) KeyCmd = "VK_DECIMAL";
  292.     if (VKeyCode == 0x6F  ) KeyCmd = "VK_DIVIDE";
  293.     if (VKeyCode == 0x70  ) KeyCmd = "VK_F1";
  294.     if (VKeyCode == 0x71  ) KeyCmd = "VK_F2";
  295.     if (VKeyCode == 0x72  ) KeyCmd = "VK_F3";
  296.     if (VKeyCode == 0x73  ) KeyCmd = "VK_F4";
  297.     if (VKeyCode == 0x74  ) KeyCmd = "VK_F5";
  298.     if (VKeyCode == 0x75  ) KeyCmd = "VK_F6";
  299.     if (VKeyCode == 0x76  ) KeyCmd = "VK_F7";
  300.     if (VKeyCode == 0x77  ) KeyCmd = "VK_F8";
  301.     if (VKeyCode == 0x78  ) KeyCmd = "VK_F9";
  302.     if (VKeyCode == 0x79  ) KeyCmd = "VK_F10";
  303.     if (VKeyCode == 0x7A  ) KeyCmd = "VK_F11";
  304.     if (VKeyCode == 0x7B  ) KeyCmd = "VK_F12";
  305.     if (VKeyCode == 0x90  ) KeyCmd = "VK_NUMLOCK";
  306.     if (VKeyCode == 0x91  ) KeyCmd = "VK_SCROLL";
  307.     if (VKeyCode == 0xA0  ) KeyCmd = "VK_LSHIFT";
  308.     if (VKeyCode == 0xA1  ) KeyCmd = "VK_RSHIFT";
  309.     if (VKeyCode == 0xA2  ) KeyCmd = "VK_LCONTROL";
  310.     if (VKeyCode == 0xA3  ) KeyCmd = "VK_RCONTROL";
  311.     if (VKeyCode == 0xA4  ) KeyCmd = "VK_LMENU(ALT)";
  312.     if (VKeyCode == 0xA5  ) KeyCmd = "VK_RMENU(ALT)";
  313.     if (VKeyCode == 0xE5  ) KeyCmd = "VK_PROCESSKEY";
  314.     if (VKeyCode == 0xF6  ) KeyCmd = "VK_ATTN";
  315.     if (VKeyCode == 0xF7  ) KeyCmd = "VK_CRSEL";
  316.     if (VKeyCode == 0xF8  ) KeyCmd = "VK_EXSEL";
  317.     if (VKeyCode == 0xF9  ) KeyCmd = "VK_EREOF";
  318.     if (VKeyCode == 0xFA  ) KeyCmd = "VK_PLAY";
  319.     if (VKeyCode == 0xFB  ) KeyCmd = "VK_ZOOM";
  320.     if (VKeyCode == 0xFC  ) KeyCmd = "VK_NONAME";
  321.     if (VKeyCode == 0xFD  ) KeyCmd = "VK_PA1";
  322.     if (VKeyCode == 0xFE  ) KeyCmd = "VK_OEM_CLEAR";
  323.     if (KeyCmd == "") KeyCmd = "Unknown Keyboard Command";
  324.     return KeyCmd;
  325. }
  326.  
  327. //ParseAcceleratorTable
  328. //Syntax: ParseAccel (ea address_of_resource_to_parse, ea address_of_next_resource)
  329. static ParseAccel(BytePtr, Next_Resource)
  330. {
  331.     auto VKType, VKeyCode, CmdID, VKMod, KeyType, KeyCmd, KeyMod;
  332.     KeyType = " ";
  333.     ExtLinA( BytePtr, 1, "     ----- Start of Accelerator Table -----");
  334.     while ( BytePtr + 7 < Next_Resource)   {
  335.         VKType = Word(BytePtr); //Get Virtual Key Type
  336.         VKeyCode = Word(BytePtr + 2); //Get Virtual Key Code
  337.         CmdID = Word(BytePtr + 4); //Get Command ID for Accelerator
  338.         VKMod = Word(BytePtr + 6); //Get Key Modifier
  339.         MakeQword(BytePtr);
  340.         if ((VKType - 10) > 0) {
  341.             KeyType = KeyType + "ALT ";
  342.             VKType = VKType - 10;
  343.         }
  344.         if ((VKType - 8) > 0){
  345.             KeyType = KeyType + "CTRL ";
  346.             VKType = VKType - 8;
  347.         }
  348.         if ((VKType - 1) > 0){
  349.             KeyType = KeyType + "VIRTKEY ";
  350.             VKType = VKType - 1;
  351.         }
  352.         else KeyType = "ASCII ";
  353.         KeyCmd = IDVKeyCode( VKeyCode );
  354.         KeyMod = IDVKeyCode( VKMod );
  355.         ExtLinB( BytePtr, 0, KeyCmd + " Type: " + KeyType +  " Modifier: " + KeyMod +
  356.                 " Command ID: " + ltoa(CmdID,16) );
  357.         BytePtr = BytePtr + 8;
  358.     }
  359.     ExtLinB( BytePtr - 1, 1, "     ------ End of Accelerator Table ------     ");
  360.     ExtLinB( BytePtr - 1, 2, "  ");
  361. }
  362.  
  363. //ParseImageData
  364. static ParseImageData(BytePtr, ImgType, ImgNum)
  365. {
  366.     auto NumRGBElements, x, ImageSize, ImageEnd;
  367.     ExtLinA(BytePtr, 1, "========== Image Data for " + ImgType + ltoa(ImgNum, 10) + " ==========");
  368.     BytePtr = MakeDword_Cmt(BytePtr, "Size " + ltoa(Dword(BytePtr), 16));
  369.     BytePtr = MakeWord_Cmt(BytePtr, "Width " + ltoa(Word(BytePtr), 10));
  370.     BytePtr = MakeWord_Cmt(BytePtr, "Height " + ltoa(Word(BytePtr), 10));
  371.     BytePtr = MakeWord_Cmt(BytePtr, "Color Planes " + ltoa(Word(BytePtr), 10));
  372.     NumRGBElements = Word(BytePtr);
  373.     BytePtr = MakeWord_Cmt(BytePtr, "Bit Count " + ltoa(Word(BytePtr), 10));
  374.     ImageSize = Dword(BytePtr);
  375.     BytePtr = MakeDWord_Cmt(BytePtr, "Size Of Image " + ltoa(ImageSize, 16));
  376.     ExtLinA(BytePtr, 1, "__________Win32 Color Table__________");
  377.     for(x = 0; x <= NumRGBElements; x = x + 1){
  378.         MakeDWord(BytePtr);
  379.         ExtLinB(BytePtr, 0, ltoa(x, 16) + ": Red " + ltoa(Byte(BytePtr + 2), 10) + " Green " + ltoa(Byte(BytePtr + 1), 10) +
  380.             " Blue " + ltoa(Byte(BytePtr), 10));
  381.         BytePtr = BytePtr + 4;
  382.     }
  383.     ExtLinA(BytePtr, 0, "_____________________________________");
  384.     BytePtr = MakeByte_Cmt(BytePtr, "XOR Mask");
  385.     BytePtr = MakeByte_Cmt(BytePtr, "AND Mask");
  386.     ImageEnd = BytePtr + ImageSize;
  387.     ExtLinB(ImageEnd, 1, "==================================================");
  388. }
  389.  
  390. //ParseBitmapHeader: Currently for Icons & Cursors
  391. static ParseBitmapHdr(BytePtr, Next_Resource)
  392. {
  393.     auto ImgType, Count, ImageOffset, x;
  394.     BytePtr = MakeWord_Cmt(BytePtr, "Reserved");
  395.     ImgType = IDResource( Word(BytePtr));
  396.     BytePtr = MakeWord_Cmt(BytePtr, "Resource Type " + ImgType);
  397.     Count = Word( BytePtr);
  398.     BytePtr = MakeWord_Cmt(BytePtr, "Number of Resources "+ ltoa(Count, 10));
  399.     //____Each Entry: for 1 to Count
  400.     for( x = 1; x <= Count; x = x + 1){
  401.         ExtLinA(BytePtr, 1, "      ______" + ImgType + " " + ltoa(x, 10) + "______      ");
  402.         BytePtr = MakeByte_Cmt(BytePtr, "Width " + ltoa(Byte(BytePtr), 10));
  403.         BytePtr = MakeByte_Cmt(BytePtr, "Height " + ltoa(Byte(BytePtr), 10));
  404.         BytePtr = MakeByte_Cmt(BytePtr, "Color Count " + ltoa(Byte(BytePtr), 10));
  405.         BytePtr = MakeByte_Cmt(BytePtr, "Reserved");
  406.         if ( ImgType == "Cursor") BytePtr = MakeWord_Cmt(BytePtr, "XHotSpot " + ltoa(Word(BytePtr), 10));
  407.         else BytePtr = MakeWord_Cmt(BytePtr, "Color Panes " + ltoa(Word(BytePtr), 10));
  408.         if ( ImgType == "Cursor") BytePtr = MakeWord_Cmt(BytePtr, "YHotSpot " + ltoa(Word(BytePtr), 10));
  409.         else BytePtr = MakeWord_Cmt(BytePtr, "Bit Count " + ltoa(Word(BytePtr), 10));
  410.         BytePtr = MakeDword_Cmt(BytePtr, "Bytes in Resource: " + ltoa(Dword(BytePtr), 16));
  411.         ImageOffset = MakeDataOffset(BytePtr);
  412.         BytePtr = MakeDword_Cmt(BytePtr, "Image Data Offset: " + atoa(ImageOffset));
  413.         ParseImageData(ImageOffset, ImgType, x);
  414.     }
  415. }
  416.  
  417. //ParseIcon: Formats Icon Resource
  418. //Syntax: ParseIcon(ea address_of_resource_to_parse, ea address_of_next_resource)
  419. static ParseIcon(BytePtr, Next_Resource)
  420. {
  421.         SetLongPrm(INF_STRTYPE, ASCSTR_UNICODE);
  422.         while ( BytePtr < Next_Resource) {
  423.             if ( Byte(BytePtr) == 0 ) BytePtr = StripZeros(BytePtr);
  424.             MakeStr(BytePtr + 2, BytePtr + (2 * (Byte(BytePtr) + 1)));
  425.             BytePtr = BytePtr + ( 2 * Byte(BytePtr)) + 2;
  426.         }
  427.         //word reserved (0)
  428.         //word idtype (1 = icon)
  429.         //word # of images
  430.         //per icon:
  431.         //byte  width in pixels of the image
  432.         //byte height in pixels of the image
  433.         //byte number of colors in the image (0 if >= 8bpp)
  434.         //byte reserved
  435.         //word wPlanes:Color Panes
  436.         //word Bitcount: Bits per pixel
  437.         //dword # of bytes in this resource  (size)
  438.         //word ID
  439. }
  440.  
  441. static ParseMenu(BytePtr, Next_Resource)
  442. {
  443.       auto MenuID, enum_id;
  444.       enum_id = AddEnum( (GetEnumQty()+1), "App_Menu", FF_0NUMH );
  445.       SetLongPrm(INF_STRTYPE, ASCSTR_UNICODE);
  446.       MakeDword(BytePtr);
  447.       MakeComm(BytePtr, "MenuHeader");
  448.       BytePtr = BytePtr + 4;
  449.       while ( BytePtr < Next_Resource) {
  450.         MakeWord(BytePtr);
  451.         if (Word(BytePtr) == 0x10 || Dword(BytePtr-4) == 0x100000) {
  452.             MakeComm( BytePtr, "POPUP Menu Item");
  453.             BytePtr = BytePtr + 2;
  454.             MakeStr(BytePtr, -1);
  455.             MakeName(BytePtr, "Popup_Menu_" + Name(BytePtr) );
  456.             ExtLinA(BytePtr, 0, "--------------------------------------------------");
  457.             BytePtr = ItemEnd(BytePtr);
  458.         }
  459.         else if (Word(BytePtr) == 0x00) {
  460.             MakeComm( BytePtr, "SEPARATOR");
  461.             BytePtr = BytePtr + 2;
  462.         }
  463.         else{
  464.             MenuID = Word(BytePtr);
  465.             MakeComm(BytePtr, "Menu Item ID: " + ltoa(MenuID, 10));
  466.             BytePtr = BytePtr + 2;
  467.             MakeStr(BytePtr, -1);
  468.             MakeName(BytePtr, "Menu_Item" + ltoa(MenuID, 10));
  469.             AddConst(enum_id, "Menu_Item_" + Name(BytePtr), MenuID);
  470.             BytePtr = ItemEnd(BytePtr);
  471.         }
  472.       MakeDword(BytePtr);
  473.       MakeComm( BytePtr, "FLAGS");
  474.       BytePtr = BytePtr + 4;
  475.       }
  476.         //while ( BytePtr < Next_Resource) {
  477.            // while ( Byte(BytePtr) == 0x0 && BytePtr < Next_Resource) BytePtr = StripZeros( BytePtr );
  478.            // MakeByte(BytePtr);
  479.            // MenuID = Byte(BytePtr);
  480.            // MakeName(BytePtr,
  481.            // BytePtr = BytePtr + 1;
  482.            // while (Byte(BytePtr) < 0x20 || Byte(BytePtr) > 0x126) {
  483.            //     MakeByte(BytePtr);
  484.            //     BytePtr = BytePtr + 1;
  485.            // }
  486.            // if ( BytePtr + 1 >= Next_Resource) break;
  487.            // ExtLinA(BytePtr, 1, "Menu ID: " + ltoa(MenuID, 10));
  488.            // MakeStr(BytePtr, -1);
  489.            // MenuID = "";
  490.            // BytePtr = ItemEnd(BytePtr);
  491.        // }
  492. }
  493.  
  494. static ResolveDlgMask(DlgStyle)
  495. {
  496.     auto DialogStyle;
  497.     DialogStyle = " ";
  498.     if ((DlgStyle - 0x80000000) > 0) {
  499.             DialogStyle = DialogStyle + "WS_POPUP ";
  500.             DlgStyle = DlgStyle - 0x80000000;
  501.         }
  502.     if ((DlgStyle - 0x40000000) > 0) {
  503.             DialogStyle = DialogStyle + "WS_CHILD ";
  504.             DlgStyle = DlgStyle - 0x40000000;
  505.         }
  506.     if ((DlgStyle - 0x20000000) > 0) {
  507.             DialogStyle = DialogStyle + "WS_MINIMIZE ";
  508.             DlgStyle = DlgStyle - 0x200000000;
  509.         }
  510.     if ((DlgStyle - 0x10000000) > 0) {
  511.             DialogStyle = DialogStyle + "WS_MAXIMIZE ";
  512.             DlgStyle = DlgStyle - 0x10000000;
  513.         }
  514.     if ((DlgStyle - 0x08000000) > 0) {
  515.             DialogStyle = DialogStyle + "WS_DISABLED ";
  516.             DlgStyle = DlgStyle - 0x08000000;
  517.         }
  518.     if ((DlgStyle - 0x04000000) > 0) {
  519.             DialogStyle = DialogStyle + "WS_CLIPSIBLINGS ";
  520.             DlgStyle = DlgStyle -0x04000000;
  521.         }
  522.     if ((DlgStyle -0x02000000) > 0) {
  523.             DialogStyle = DialogStyle + "WS_CLIPCHILDREN ";
  524.             DlgStyle = DlgStyle - 0x02000000;
  525.         }
  526.     if ((DlgStyle - 0x01000000) > 0) {
  527.             DialogStyle = DialogStyle + "WS_MAXIMIZE ";
  528.             DlgStyle = DlgStyle - 0x01000000;
  529.         }
  530.     if ((DlgStyle - 0x00C00000) > 0) {
  531.             DialogStyle = DialogStyle + "WS_CAPTION ";
  532.             DlgStyle = DlgStyle - 0x00C00000;
  533.         }
  534.     if ((DlgStyle - 0x00800000) > 0) {
  535.             DialogStyle = DialogStyle + "WS_BORDER ";
  536.             DlgStyle = DlgStyle - 0x00800000;
  537.         }
  538.     if ((DlgStyle - 0x00400000) > 0) {
  539.             DialogStyle = DialogStyle + "WS_DLGFRAME  ";
  540.             DlgStyle = DlgStyle - 0x00400000;
  541.         }
  542.     if ((DlgStyle - 0x00200000) > 0) {
  543.             DialogStyle = DialogStyle + "WS_VSCROLL ";
  544.             DlgStyle = DlgStyle - 0x00200000;
  545.         }
  546.     if ((DlgStyle - 0x00100000) > 0) {
  547.             DialogStyle = DialogStyle + "WS_HSCROLL ";
  548.             DlgStyle = DlgStyle - 0x00100000;
  549.         }
  550.     if ((DlgStyle - 0x00080000) > 0) {
  551.             DialogStyle = DialogStyle + "WS_SYSMENU ";
  552.             DlgStyle = DlgStyle - 0x00080000;
  553.         }
  554.     if ((DlgStyle - 0x00040000) > 0) {
  555.             DialogStyle = DialogStyle + "WS_THICKFRAME ";
  556.             DlgStyle = DlgStyle - 0x00040000;
  557.         }
  558.     if ((DlgStyle - 0x00020000) > 0) {
  559.             DialogStyle = DialogStyle + "WS_MINIMIZEBOX  ";
  560.             DlgStyle = DlgStyle - 0x00020000;
  561.         }
  562.     if ((DlgStyle - 0x00010000) > 0) {
  563.             DialogStyle = DialogStyle + "WS_MAXIMIZEBOX ";
  564.             DlgStyle = DlgStyle - 0x00010000;
  565.         }
  566.     if ((DlgStyle - 0x00020000) > 0) {
  567.             DialogStyle = DialogStyle + "WS_GROUP ";
  568.             DlgStyle = DlgStyle - 0x00020000;
  569.         }
  570.     if ((DlgStyle - 0x00010000) > 0) {
  571.             DialogStyle = DialogStyle + "WS_TABSTOP ";
  572.             DlgStyle = DlgStyle - 0x00010000;
  573.         }
  574.     if ((DlgStyle - 0x100) > 0) {
  575.             DialogStyle = DialogStyle + "NOIDLEMESSAGE ";
  576.             DlgStyle = DlgStyle - 0x100;
  577.         }
  578.     if ((DlgStyle - 0x80) > 0) {
  579.             DialogStyle = DialogStyle + "MODALFRAME ";
  580.             DlgStyle = DlgStyle - 0x80;
  581.     }
  582.     if ((DlgStyle - 0x40) > 0) {
  583.             DialogStyle = DialogStyle + "SETFONT ";
  584.             DlgStyle = DlgStyle - 0x40;
  585.         }
  586.     if ((DlgStyle - 0x20) > 0) {
  587.             DialogStyle = DialogStyle + "LOCALEDIT ";
  588.             DlgStyle = DlgStyle - 0x20;
  589.         }
  590.     if ((DlgStyle - 0x02) > 0){
  591.             DialogStyle = DialogStyle + "SYSMODAL ";
  592.             DlgStyle = DlgStyle - 0x02;
  593.         }
  594.     if ((DlgStyle - 0x01) > 0){
  595.             DialogStyle = DialogStyle + "ABSALIGN ";
  596.             DlgStyle = DlgStyle - 0x01;
  597.     }
  598.     else DialogStyle = DialogStyle + "WS_OVERLAPPED ";
  599.     return DialogStyle;
  600. }
  601.  
  602. static ResolveCtrlMask( CtrlMask )
  603. {
  604.     //if blahblhblah;
  605.  //* Edit Control Styles
  606. //#define ES_LEFT             0x0000L
  607. //#define ES_CENTER           0x0001L
  608. //#define ES_RIGHT            0x0002L
  609. //#define ES_MULTILINE        0x0004L
  610. //#define ES_UPPERCASE        0x0008L
  611. //#define ES_LOWERCASE        0x0010L
  612. //#define ES_PASSWORD         0x0020L
  613. //#define ES_AUTOVSCROLL      0x0040L
  614. //#define ES_AUTOHSCROLL      0x0080L
  615. //#define ES_NOHIDESEL        0x0100L
  616. //#define ES_OEMCONVERT       0x0400L
  617. //#define ES_READONLY         0x0800L
  618. //#define ES_WANTRETURN       0x1000L
  619. //#define ES_NUMBER           0x2000L
  620.  //* Button Control Styles
  621. //#define BS_PUSHBUTTON       0x00000000L
  622. //#define BS_DEFPUSHBUTTON    0x00000001L
  623. //#define BS_CHECKBOX         0x00000002L
  624. //#define BS_AUTOCHECKBOX     0x00000003L
  625. //#define BS_RADIOBUTTON      0x00000004L
  626. //#define BS_3STATE           0x00000005L
  627. //#define BS_AUTO3STATE       0x00000006L
  628. //#define BS_GROUPBOX         0x00000007L
  629. //#define BS_USERBUTTON       0x00000008L
  630. //#define BS_AUTORADIOBUTTON  0x00000009L
  631. //#define BS_OWNERDRAW        0x0000000BL
  632. //#define BS_LEFTTEXT         0x00000020L
  633. //#define BS_TEXT             0x00000000L
  634. //#define BS_ICON             0x00000040L
  635. //#define BS_BITMAP           0x00000080L
  636. //#define BS_LEFT             0x00000100L
  637. //#define BS_RIGHT            0x00000200L
  638. //#define BS_CENTER           0x00000300L
  639. //#define BS_TOP              0x00000400L
  640. //#define BS_BOTTOM           0x00000800L
  641. //#define BS_VCENTER          0x00000C00L
  642. //#define BS_PUSHLIKE         0x00001000L
  643. //#define BS_MULTILINE        0x00002000L
  644. //#define BS_NOTIFY           0x00004000L
  645. //#define BS_FLAT             0x00008000L
  646. //#define BS_RIGHTBUTTON      BS_LEFTTEXT
  647.  //* Static Control Constants
  648. //#define SS_LEFT             0x00000000L
  649. //#define SS_CENTER           0x00000001L
  650. //#define SS_RIGHT            0x00000002L
  651. //#define SS_ICON             0x00000003L
  652. //#define SS_BLACKRECT        0x00000004L
  653. //#define SS_GRAYRECT         0x00000005L
  654. //#define SS_WHITERECT        0x00000006L
  655. //#define SS_BLACKFRAME       0x00000007L
  656. //#define SS_GRAYFRAME        0x00000008L
  657. //#define SS_WHITEFRAME       0x00000009L
  658. //#define SS_USERITEM         0x0000000AL
  659. //#define SS_SIMPLE           0x0000000BL
  660. //#define SS_LEFTNOWORDWRAP   0x0000000CL
  661. //#define SS_BITMAP           0x0000000EL
  662. //#define SS_OWNERDRAW        0x0000000DL
  663. //#define SS_ENHMETAFILE      0x0000000FL
  664. //#define SS_ETCHEDHORZ       0x00000010L
  665. //#define SS_ETCHEDVERT       0x00000011L
  666. //#define SS_ETCHEDFRAME      0x00000012L
  667. //#define SS_TYPEMASK         0x0000001FL
  668. //#define SS_NOPREFIX         0x00000080L /* Don't do "&" character translation */
  669. //#define SS_NOTIFY           0x00000100L
  670. //#define SS_CENTERIMAGE      0x00000200L
  671. //#define SS_RIGHTJUST        0x00000400L
  672. //#define SS_REALSIZEIMAGE    0x00000800L
  673. //#define SS_SUNKEN           0x00001000L
  674.  //* Dialog Styles
  675. //#define DS_ABSALIGN         0x01L
  676. //#define DS_SYSMODAL         0x02L
  677. //#define DS_LOCALEDIT        0x20L   /* Edit items get Local storage. */
  678. //#define DS_SETFONT          0x40L   /* User specified font for Dlg controls */
  679. //#define DS_MODALFRAME       0x80L   /* Can be combined with WS_CAPTION  */
  680. //#define DS_NOIDLEMSG        0x100L  /* WM_ENTERIDLE message will not be sent */
  681. //#define DS_SETFOREGROUND    0x200L  /* not in win3.1 */
  682. //#define DS_3DLOOK           0x0004L
  683. //#define DS_FIXEDSYS         0x0008L
  684. //#define DS_NOFAILCREATE     0x0010L
  685. //#define DS_CONTROL          0x0400L
  686. //#define DS_CENTER           0x0800L
  687. //#define DS_CENTERMOUSE      0x1000L
  688. //#define DS_CONTEXTHELP      0x2000L
  689.  //* Listbox Styles
  690. //#define LBS_NOTIFY            0x0001L
  691. //#define LBS_SORT              0x0002L
  692. //#define LBS_NOREDRAW          0x0004L
  693. //#define LBS_MULTIPLESEL       0x0008L
  694. //#define LBS_OWNERDRAWFIXED    0x0010L
  695. //#define LBS_OWNERDRAWVARIABLE 0x0020L
  696. //#define LBS_HASSTRINGS        0x0040L
  697. //#define LBS_USETABSTOPS       0x0080L
  698. //#define LBS_NOINTEGRALHEIGHT  0x0100L
  699. //#define LBS_MULTICOLUMN       0x0200L
  700. //#define LBS_WANTKEYBOARDINPUT 0x0400L
  701. //#define LBS_EXTENDEDSEL       0x0800L
  702. //#define LBS_DISABLENOSCROLL   0x1000L
  703. //#define LBS_NODATA            0x2000L
  704. //#define LBS_NOSEL             0x4000L
  705. //#define LBS_STANDARD          (LBS_NOTIFY | LBS_SORT | WS_VSCROLL | WS_BORDER)
  706. // * Combo Box styles
  707. //#define CBS_DROPDOWN          0x0002L
  708. //#define CBS_DROPDOWNLIST      0x0003L
  709. //#define CBS_OWNERDRAWFIXED    0x0010L
  710. //#define CBS_OWNERDRAWVARIABLE 0x0020L
  711. //#define CBS_AUTOHSCROLL       0x0040L
  712. //#define CBS_OEMCONVERT        0x0080L
  713. //#define CBS_SORT              0x0100L
  714. //#define CBS_HASSTRINGS        0x0200L
  715. //#define CBS_NOINTEGRALHEIGHT  0x0400L
  716. //#define CBS_DISABLENOSCROLL   0x0800L
  717. //#define CBS_UPPERCASE           0x2000L
  718. //#define CBS_LOWERCASE           0x4000L
  719.  
  720.  
  721. }
  722.  
  723. static ParseDlgItem( BytePtr, Next_Resource )
  724. {
  725.     auto Mask;
  726.     SetLongPrm(INF_STRTYPE, ASCSTR_UNICODE);
  727.      while ( Byte(BytePtr) != 0x50 && BytePtr < Next_Resource ) BytePtr = BytePtr + 1;
  728.      if ( BytePtr + 22 >= Next_Resource ) return;
  729.     Mask = Dword(BytePtr-3);
  730.     // ResolveCtrlMask( Mask );
  731.     BytePtr = MakeDword_Cmt( BytePtr - 3, "Control Style: " + ltoa(Mask, 16));
  732.     BytePtr = MakeDword_Cmt( BytePtr, "Reserved");
  733.     BytePtr = MakeWord_Cmt( BytePtr, "X Location: " + ltoa(Word(BytePtr), 10));
  734.     BytePtr = MakeWord_Cmt( BytePtr, "Y Location: " + ltoa(Word(BytePtr), 10));
  735.     BytePtr = MakeWord_Cmt( BytePtr, "X Size: " + ltoa(Word(BytePtr), 10));
  736.     BytePtr = MakeWord_Cmt( BytePtr, "Y Size: " + ltoa(Word(BytePtr), 10));
  737.     BytePtr = MakeWord_Cmt( BytePtr, "Control Number: " + ltoa(Word(BytePtr), 10));
  738.     BytePtr = MakeWord_Cmt( BytePtr, "Reserved");
  739.     BytePtr = MakeWord_Cmt( BytePtr, "Control Type: " + ltoa(Word(BytePtr), 10));
  740.     if ( Word(BytePtr) != 0x0000) MakeStr( BytePtr, -1); // Unicode ControlText
  741.     MakeComm(BytePtr, "Control Text");
  742.     BytePtr = ItemEnd(BytePtr);
  743.     return BytePtr;
  744. }
  745.  
  746. static ParseDialog(BytePtr, Next_Resource)
  747. {
  748.     auto DlgStyle, x, Num_Controls;
  749.     SetLongPrm(INF_STRTYPE, ASCSTR_UNICODE);
  750.     BytePtr = MakeWord_Cmt(BytePtr, "Dialog #");
  751.     DlgStyle = ResolveDlgMask(Dword(BytePtr));
  752.     BytePtr = MakeDword_Cmt(BytePtr, "Dialog Style: " + DlgStyle);
  753.     BytePtr = MakeWord_Cmt(BytePtr, "Reserved");
  754.     Num_Controls = Word(BytePtr);
  755.     BytePtr = MakeWord_Cmt(BytePtr, "Number of Controls: " + ltoa(Num_Controls, 10));
  756.     BytePtr = MakeWord_Cmt(BytePtr, "X Location");
  757.     BytePtr = MakeWord_Cmt(BytePtr, "Y Location");
  758.     BytePtr = MakeWord_Cmt(BytePtr, "X Size");
  759.     BytePtr = MakeWord_Cmt(BytePtr, "Y Size");
  760.     BytePtr = MakeDword_Cmt(BytePtr, "Reserved");
  761.     MakeComm(BytePtr, "Caption");
  762.     MakeStr(BytePtr, -1);
  763.     BytePtr = ItemEnd(BytePtr);
  764.     BytePtr = MakeWord_Cmt(BytePtr, "Reserved");
  765.     BytePtr = MakeWord_Cmt(BytePtr, "Font Number ");
  766.     MakeStr(BytePtr, -1);
  767.     BytePtr = ItemEnd(BytePtr);
  768.     for (x = 1; x <= Num_Controls; x = x + 1) {
  769.         ExtLinA(BytePtr, 0, "__________Control__" + ltoa(x, 10) + "__________");
  770.         BytePtr = ParseDlgItem( BytePtr, Next_Resource );
  771.         while ( Byte(BytePtr) == 0 && BytePtr < Next_Resource) BytePtr = StripZeros( BytePtr );
  772.     }
  773. }
  774.  
  775. static ParseVerInfo(BytePtr, Next_Resource)
  776. {
  777.     auto EndOfString;
  778.     SetLongPrm(INF_STRTYPE, ASCSTR_UNICODE);
  779.     // 3x DW, Unicode
  780.     //for ( x = 1; x <= 31; x = x + 1){ MakeWord(BytePtr); BytePtr = BytePtr + 2;}
  781.     while ( BytePtr < Next_Resource) {
  782.         while ( Byte(BytePtr) == 0 && BytePtr < Next_Resource) BytePtr = StripZeros( BytePtr );
  783.         while (Byte(BytePtr) < 0x20 || Byte(BytePtr) > 0x126) {
  784.                 if ( BytePtr + 1 >= Next_Resource) break;
  785.                 MakeByte(BytePtr);
  786.                 BytePtr = BytePtr + 1;
  787.         }
  788.         if ( BytePtr + 1 >= Next_Resource) break;
  789.         MakeStr(BytePtr, -1);
  790.         BytePtr = ItemEnd( BytePtr );
  791.     }
  792. }
  793.  
  794. //ParseUnknownResource: Formats Resource Data into an 8-byte-per-line (QWord) output
  795. //Syntax: ParseUnkRes(ea address_of_resource_to_parse, ea address_of_next_resource)
  796. static ParseUnkRes(BytePtr, Next_Resource)
  797. {
  798.     for ( BytePtr; BytePtr < Next_Resource; BytePtr = BytePtr + 1) {
  799.         if (BytePtr + 7 < Next_Resource){
  800.             MakeQword(BytePtr);
  801.             BytePtr = BytePtr + 7;
  802.         }
  803.                 else MakeByte(BytePtr);
  804.      }
  805. }
  806.  
  807. //ParseLeafNode adds an anterior comment, calls a parsing routine dependent on resource type if the
  808. //display resource flag (_DISPLAY_RESOURCES_) is set.
  809. //Syntax: ParseLeafNode( ea add_of_resource, char resource_type, long resource_ID_number)
  810. static ParseLeafNode(BytePtr, Resource_Type, Resource_Num)
  811. {
  812.     auto Next_Resource, Data_Offset;
  813.     Data_Offset = MakeDataOffset(BytePtr);
  814.     ExtLinA(BytePtr, 0, "------------------------------------------------------------------" );
  815.     ExtLinA(BytePtr, 1, "-- Pointer to " + Resource_Type + " at address " + ltoa(Data_Offset, 16) +
  816.             " of size " + ltoa(Dword(BytePtr + 4), 16) + " --");
  817.     Next_Resource = MakeDataOffset(BytePtr + 16);
  818.     MakeStruct(BytePtr, "DataEntry");
  819.     BytePtr = Data_Offset;
  820.     ExtLinA(BytePtr, 0, Resource_Type + " " + ltoa(Resource_Num, 10));
  821.     if ( _DISPLAY_RESOURCES_ ==  1) {
  822.         if ( Resource_Type == "String_Table" ) ParseStrTable( BytePtr, Next_Resource, Resource_Num );
  823.         else if ( Resource_Type == "Menu" ) ParseMenu( BytePtr, Next_Resource );
  824.         else if ( Resource_Type == "Accelerator_Table") ParseAccel( BytePtr, Next_Resource );
  825.         else if ( Resource_Type == "Version" ) ParseVerInfo( BytePtr, Next_Resource );
  826.         else if ( Resource_Type == "Dialog" ) ParseDialog( BytePtr, Next_Resource );
  827.         //else if ( Resource_Type == "Cursor" || Resource_Type == "Icon") ParseBitmapHdr( BytePtr, Next_Resource);
  828.         else ParseUnkRes( BytePtr, Next_Resource );
  829.     }
  830. }
  831.  
  832. //ParseSubdirectoryData parses resource subdirectory entries, then either continues parsing the
  833. //resource directory tree (if the recursion flag _RECURSE_ is set), or calls ParseLeafNode to
  834. //format and display the resource (if the entry is a pointer to resource data)
  835. //Syntax: ParseSubDirData( ea addess_of_resource_subdir_entry, char resource_type, , long num, long nest )
  836. static ParseSubDirData(BytePtr, Resource_Type, Resource_Num, nest)
  837. {
  838.     auto Next_Resource;
  839.     if (nest == 1) Resource_Num = Dword(BytePtr);
  840.     MakeStruct(BytePtr, "DirEntry");
  841.     Next_Resource = ResolveOffset(BytePtr + 8);
  842.     if( Next_Resource >= SegEnd(BytePtr)) Next_Resource = SegEnd(BytePtr);
  843.     BytePtr = BytePtr + 4;
  844.     if ( Byte(BytePtr + 3) == 0x80) {
  845.         ExtLinB(BytePtr, 0, "  --- Offset to Subdirectory at " + ltoa(ResolveOffset(BytePtr),16) + " ---");
  846.         if ( _RECURSE_ == 1) ParseSubDirHdr( ResolveOffset(BytePtr), Resource_Type, Resource_Num, nest );
  847.     }
  848.     else ParseLeafNode(ResolveOffset(BytePtr), Resource_Type, Resource_Num);
  849. }
  850.  
  851. //ParseDirectoryHeader parses & comments a directory header and returns the total # of dir data entries
  852. //Syntax: ParseDirHdr( ea starting_address_of_dir_header )
  853. //Returns: ea total_number_of_data_entries
  854. static ParseDirHdr(BytePtr)
  855. {
  856.     auto Num_Named, Num_IDs, Total_Res_Entries;
  857.     MakeStruct(BytePtr, "ResDirHeader");
  858.     Num_Named = Word(BytePtr + 12);
  859.     Num_IDs = Word(BytePtr + 14 );
  860.     Total_Res_Entries = Num_Named + Num_IDs;
  861.     return Total_Res_Entries;
  862. }
  863.  
  864. //ParseSubdirectoryHeader calls ParseDirHdr to parse the header for a subdirectory, then calls
  865. //ParseSubDirData for each resource subdirectory entry
  866. //Syntax: ParseSubDirHdr( ea address_of_subdirectory_header, char resource_type, long num, long nest )
  867. static ParseSubDirHdr(BytePtr, Resource_Type, Resource_Num, nest)
  868. {
  869.     auto Total_Res_Entries, x;
  870.     nest = nest + 1;
  871.     MakeName( BytePtr, "rsrc" + Resource_Type + "Dir" + atoa(BytePtr));
  872.     ExtLinA( BytePtr, 0, "-------------------- Start " + Resource_Type + " Header --------------------");
  873.     Total_Res_Entries = ParseDirHdr(BytePtr);
  874.     BytePtr = BytePtr + 14;
  875.     ExtLinB(BytePtr, 0, "Total Number of " + Resource_Type + " Entries: " + ltoa(Total_Res_Entries,10));
  876.     ExtLinB( BytePtr, 1, "--------------------- End " + Resource_Type + " Header ---------------------");
  877.     BytePtr = BytePtr + 2;
  878.     for ( x = 1; x <= Total_Res_Entries; x = x + 1) {
  879.         ParseSubDirData(BytePtr, Resource_Type, Resource_Num, nest);
  880.         BytePtr = BytePtr + 8;
  881.     }
  882.     nest = nest - 1;
  883. }
  884.  
  885. //ParseRootDirData parses the "resource directory entries" for the root .rsrc directory, then
  886. //calls ParseSubDirHdr to handle subsequent subdirectories if the recursion flag _RECURSE_ is set
  887. //Syntax: ParseRootData( ea address_of_resource_directory_entry)
  888. static ParseRootData(BytePtr)
  889. {
  890.     auto Resource_Type, Resource_Num, nest;
  891.     nest = 0;
  892.     Resource_Num = 0;
  893.     Resource_Type = ID_Resource(Dword(BytePtr));
  894.     MakeStruct(BytePtr, "DirEntry");
  895.     ExtLinA(BytePtr, 0, "        Resource Type: " + Resource_Type);
  896.     BytePtr = BytePtr + 4;
  897.     if ( Byte(BytePtr + 3) == 0x80) {
  898.         ExtLinB(BytePtr, 0, "  --- Offset to " + Resource_Type + " Subdirectory at " + ltoa(ResolveOffset(BytePtr),16) + " ---");
  899.         if ( _RECURSE_ == 1) ParseSubDirHdr(ResolveOffset(BytePtr), Resource_Type, Resource_Num, nest);
  900.     }
  901. }
  902.  
  903. //ParseRootDirectoryHeader calls ParseDirHdr to parse & comments the root directory of the .rsrc segment,
  904. //then calls ParseRootData for each entry in its listing
  905. //Syntax: ParseRootHdr( ea starting_address_of_rsrc_segment)
  906. static ParseRootHdr(BytePtr)
  907. {
  908.     auto Total_Res_Entries, x, DirHeaderID, DirEntryID, DataEntryID;
  909.     DirHeaderID = AddStruc( -1, "ResDirHeader" );
  910.     AddStrucMember( DirHeaderID, "Characteristics", 0x0000, FF_DWRD + FF_DATA, -1, 1);
  911.     AddStrucMember( DirHeaderID, "TimeDate", 0x0004, FF_DWRD + FF_DATA, -1, 1);
  912.     AddStrucMember( DirHeaderID, "Version", 0x0008, FF_DWRD + FF_DATA, -1, 1);
  913.     AddStrucMember( DirHeaderID, "NamedEntries", 0x000C, FF_WORD + FF_DATA, -1, 1);
  914.     AddStrucMember( DirHeaderID, "IDEntries", 0x000E, FF_WORD + FF_DATA, -1, 1);
  915.     DirEntryID = AddStruc( -1, "DirEntry");
  916.     AddStrucMember( DirEntryID, "Name", 0x0000, FF_DWRD + FF_DATA, -1, 1);
  917.     AddStrucMember( DirEntryID, "OffsetToData", 0x0004, FF_DWRD + FF_DATA, -1, 1);
  918.     DataEntryID = AddStruc( -1, "DataEntry" );
  919.     AddStrucMember( DataEntryID, "OffsetToData", 0x0000, FF_DWRD + FF_DATA, -1, 1);
  920.     AddStrucMember( DataEntryID, "Size", 0x0004, FF_DWRD + FF_DATA, -1, 1);
  921.     AddStrucMember( DataEntryID, "CodePage", 0x0008, FF_DWRD + FF_DATA, -1, 1);
  922.     AddStrucMember( DataEntryID, "Reserved", 0x000C, FF_DWRD + FF_DATA, -1, 1);
  923.     MakeName( BytePtr, "rsrcRootDirHeader");
  924.     Total_Res_Entries = ParseDirHdr(BytePtr);
  925.     BytePtr = BytePtr + 14;
  926.     ExtLinB(BytePtr, 0, "Total Number of Entries: " + ltoa(Total_Res_Entries,10));
  927.     ExtLinB(BytePtr, 1, "---------------------- End Of Resource Root Directory -------------------");
  928.     ExtLinB(BytePtr, 2, "=========================================================================");
  929.     BytePtr = BytePtr + 2;
  930.     for ( x = 1; x <= Total_Res_Entries; x = x + 1) {
  931.         ParseRootData(BytePtr);
  932.         BytePtr = BytePtr + 8;
  933.     }
  934. }
  935.  
  936.  
  937.