home *** CD-ROM | disk | FTP | other *** search
/ World of A1200 / World_Of_A1200.iso / programs / monitors / rsys / source.lha / src / RSysHunks.c < prev    next >
C/C++ Source or Header  |  1995-01-09  |  19KB  |  745 lines

  1. /*
  2. ***************************************************************************
  3. *
  4. * Datei:
  5. *    RSysHunks.c
  6. *
  7. * Inhalt:
  8. *    void PrintHunkStruct(char *file);
  9. *    void HunkStruct(void);
  10. *
  11. * Bemerkungen:
  12. *    Ermittlung der Hunkstruktur einer ausführbaren oder ladbaren Datei.
  13. *
  14. * Erstellungsdatum:
  15. *    07-Jul-93    Rolf Böhme
  16. *
  17. * Änderungen:
  18. *    07-Jul-93    Rolf Böhme    Erstellung
  19. *
  20. ***************************************************************************
  21. */
  22.  
  23. #include "RSysDebug.h"
  24. #include "RSysFunc.h"
  25.  
  26. static struct hunkentry
  27. {
  28.    struct Node denode;
  29.    char *name;
  30.    struct hunkentry *next;
  31. };
  32.  
  33. static struct Remember *hekey = NULL;
  34.  
  35. #define RKEY   ((struct Remember **)&hekey)
  36. #define SIZEDE sizeof(struct hunkentry)
  37.  
  38. extern struct Window *TreeWnd;
  39. extern struct Gadget *TreeGadgets[3],*TreeGList;
  40.  
  41. extern int decnt,breakit;
  42.  
  43. extern UBYTE *TreeWdt;
  44. extern UBYTE *TreeWdt1;
  45.  
  46. enum
  47. {
  48.    GD_TreeLV,
  49.    GD_SaveGad,
  50.    GD_KindCY
  51. };
  52.  
  53. static struct hunkentry *loop, *firstde;
  54. static struct List Tree;
  55.  
  56. static enum ext_types1
  57. {
  58.    ext_def = 1,
  59.    ext_abs,
  60.    ext_res
  61. };
  62.  
  63. static char *ext_names1[] =
  64. {
  65.    "dummy   ",
  66.    "ext_def ",
  67.    "ext_abs ",
  68.    "ext_res "
  69. };
  70.  
  71. static enum ext_types2
  72. {
  73.    ext_ref32 = 129,
  74.    ext_common,
  75.    ext_ref16,
  76.    ext_ref8,
  77.    ext_dref32,
  78.    ext_dref16,
  79.    ext_dref8
  80. };
  81.  
  82. static char *ext_names2[] =
  83. {
  84.    "ext_ref32  ",
  85.    "ext_common ",
  86.    "ext_ref16  ",
  87.    "ext_ref8   ",
  88.    "ext_dref32 ",
  89.    "ext_dref16 ",
  90.    "ext_dref8  "
  91. };
  92.  
  93. static enum hunktypes
  94. {
  95.    hunk_unit = 0x3e7,
  96.    hunk_name,                   /* 0x3e8 */
  97.    hunk_code,                   /* 0x3e9 */
  98.    hunk_data,                   /* 0x3ea */
  99.    hunk_bss,                    /* 0x3eb */
  100.    hunk_reloc32,                /* 0x3ec */
  101.    hunk_reloc16,                /* 0x3ed */
  102.    hunk_reloc8,                 /* 0x3ee */
  103.    hunk_ext,                    /* 0x3ef */
  104.    hunk_symbol,                 /* 0x3f0 */
  105.    hunk_debug,                  /* 0x3f1 */
  106.    hunk_end,                    /* 0x3f2 */
  107.    hunk_header,                 /* 0x3f3 */
  108.    dummy,                       /* 0x3f4 */
  109.    hunk_overlay,                /* 0x3f5 */
  110.    hunk_break,                  /* 0x3f6 */
  111.    dummy1,                      /* 0x3f7 */
  112.    dummy2,                      /* 0x3f8 */
  113.    dummy3,                      /* 0x3f9 */
  114.    hunk_lib,                    /* 0x3fa */
  115.    hunk_libindex                /* 0x3fb */
  116. };
  117.  
  118. char *names[]=
  119. {
  120.    "hunk_unit",
  121.    "hunk_name",
  122.    "  hunk_code",
  123.    "  hunk_data",
  124.    "  hunk_bss",
  125.    "    hunk_reloc32",
  126.    "    hunk_reloc16",
  127.    "    hunk_reloc8 ",
  128.    "    hunk_ext",
  129.    "    hunk_symbol",
  130.    "  hunk_debug",
  131.    "hunk_end",
  132.    "hunk_header",
  133.    "dummy",
  134.    "hunk_overlay",
  135.    "hunk_break  ",
  136.    "dummy",
  137.    "dummy",
  138.    "dummy",
  139.    "lib_hunk",
  140.    "lib_index"
  141. };
  142. /*
  143. static char hunkblanks[] =
  144. {
  145.    "", "",
  146.    "  ", "  ", "  ",
  147.    "    ", "    ", "    ", "    ", "    ", "    ",
  148.    "", "", "",
  149.    "  ", "  ",
  150.    "", "", "",
  151.    "  ", "  "
  152. };
  153. */
  154. static BPTR file;
  155.  
  156.    /*
  157.     * makehunkentry() erzeugt einen Listeneintrag aus einem Hunk
  158.     * einer ausführbaren Datei
  159.     */
  160. static struct hunkentry *
  161. makehunkentry(struct hunkentry *last, char *name)
  162. {
  163.    DPOS;
  164.  
  165.    if ((last = (struct hunkentry *) AllocRemember(RKEY, SIZEDE,
  166.                                                   MEMF_CLEAR | MEMF_ANY)) &&
  167.        (last->name = (char *)AllocRemember(RKEY, strlen(name) + 1,
  168.                                            MEMF_CLEAR | MEMF_ANY)))
  169.  
  170.    {
  171.       strcpy(last->name, name);
  172.  
  173.       last->next = NULL;
  174.       last->denode.ln_Name = last->name;
  175.       last->denode.ln_Type = 0;
  176.  
  177.       InitListView(TreeWnd,TreeGadgets[GD_TreeLV],NULL,UNSETLVPOS);
  178.  
  179.       AddTail(&Tree, &last->denode);
  180.  
  181.       InitListView(TreeWnd,TreeGadgets[GD_TreeLV],&Tree,decnt);
  182.  
  183.       decnt++;
  184.  
  185.       return (last->next);
  186.    }
  187.    else
  188.       ErrorHandle(MEMORY_ERR, ALLOC_FAIL, KILL);
  189.  
  190.    return (NULL);
  191. }
  192.  
  193.    /*
  194.     * jumpinfile() setzt den Dateizeiger um eine Anzahl ULONG's
  195.     * weiter vor
  196.     */
  197. static int
  198. jumpinfile(ULONG d)
  199. {
  200.    int serr;
  201.  
  202.    serr = Seek(file, d * sizeof(ULONG), OFFSET_CURRENT);
  203.    if (serr < 0)
  204.       return(FALSE);
  205.  
  206.    return(TRUE);
  207. }
  208.  
  209.    /*
  210.     * readlong() liest ein ULONG aus einer Datei aus
  211.     */
  212. static int
  213. readlong(ULONG *d)
  214. {
  215.    return (Read(file, d, sizeof(ULONG)));
  216. }
  217.  
  218.    /*
  219.     * readtext() liest einen Text definierter Länge aus
  220.     * einer Datei aus
  221.     */
  222. static int
  223. readtext(char *d,long count)
  224. {
  225.    ULONG readdata[MAXSTRLEN];
  226.    int ret = 0,i,len = 0;
  227.    union {
  228.       ULONG ul;
  229.       unsigned char ut[4];
  230.    } cv;
  231.  
  232.    if(count == 0)
  233.    {
  234.       strcpy(d, field[NO_FIELD]);
  235.       return(ret);
  236.    }
  237.  
  238.    ret = Read(file, readdata, count * sizeof(ULONG));
  239.  
  240.    d[0] = STRINGEND;
  241.    cv.ul = 0L;
  242.    cv.ul = readdata[0];
  243.    strncpy(d,(char *)cv.ut,4);
  244.    len +=4;
  245.    d[len] = STRINGEND;
  246.  
  247.    for(i = 1; i < count; i++)
  248.    {
  249.       cv.ul = 0L;
  250.       cv.ul = readdata[i];
  251.       strncat(d,(char *)cv.ut,4);
  252.       len += 4;
  253.       d[len] = STRINGEND;
  254.    }
  255.  
  256.    return (ret);
  257. }
  258.  
  259.    /*
  260.     * currentpos() ermittelt die aktuelle Position des Dateizeigers
  261.     */
  262. static long
  263. currentpos(void)
  264. {
  265.    return (Seek(file, 0L, OFFSET_CURRENT) - sizeof(ULONG));
  266. }
  267.  
  268.    /*
  269.     * ScanHunks() ermittelt alle Hunks eines ausführbaren Files und
  270.     * trägt diese in eine interne Liste ein
  271.     */
  272. static void
  273. ScanHunks(char *filename)
  274. {
  275.    ULONG data,
  276.          data2,
  277.          data3,
  278.          type,
  279.          typeofmem,
  280.          type_of_hunk,
  281.          lasthunk = hunk_name;
  282.    char  datatext[120];
  283.    int   error,
  284.          i,
  285.          z;
  286.    char  buffer[MAXFULLNAME],
  287.          blanks[10] = "  ",
  288.          *memtype[3] = {"MEMF_CHIP","MEMF_FAST"};
  289.    int   ext_type,failure = 0;
  290.  
  291.    DPOS;
  292.  
  293.    sprintf(buffer, "File name : %s", filename);
  294.    loop = makehunkentry(loop, buffer);
  295.  
  296.    sprintf(buffer, "File size : %ld", SizeOfFile(filename));
  297.    loop = makehunkentry(loop, buffer);
  298.  
  299.    if (file = Open((UBYTE *) filename, MODE_OLDFILE))
  300.    {
  301.       error = readlong(&data);
  302.  
  303.       while ((error > 0) && NOT(ClickedCloseGadget()))
  304.       {
  305.          type = data - hunk_unit;
  306.          type_of_hunk = ((data << 8) >> 8);
  307.  
  308.          if ((type_of_hunk >= hunk_unit) &&
  309.              (type_of_hunk <= hunk_libindex) &&
  310.              (type_of_hunk != hunk_end) &&
  311.              (type_of_hunk != hunk_break))
  312.          {
  313.             loop = makehunkentry(loop, (char *)field[BLANK_FIELD]);
  314.             sprintf(buffer, "%s (o: \$%lx,\#%ld t: \$%lx,\#%ld)",
  315.                     names[type], currentpos(),
  316.                     currentpos(),data,data);
  317.             loop = makehunkentry(loop, buffer);
  318.          }
  319.  
  320.          switch (type_of_hunk)
  321.          {
  322.             case hunk_unit:
  323.             case hunk_name:
  324.                error = readlong(&data);
  325.  
  326.                if((error > 0) && data)
  327.                {
  328.                   error = readtext(datatext,data);
  329.                   sprintf(buffer, "  Name: %s",(char *)datatext);
  330.                }
  331.                else
  332.                   strcpy(buffer, "  Name: -");
  333.  
  334.                loop = makehunkentry(loop, buffer);
  335.                break;
  336.  
  337.             case hunk_code:
  338.             case hunk_bss:
  339.             case hunk_data:
  340.                typeofmem = ((data & (1L<<30)) ? 0 : 1);
  341.  
  342.                error = readlong(&data);
  343.  
  344.                sprintf(buffer, "    Size: \$%lx, \#%ld (%s)",
  345.                        data * 4, data * 4,memtype[typeofmem]);
  346.                loop = makehunkentry(loop, buffer);
  347.  
  348.                if (type_of_hunk != hunk_bss)
  349.                   if (NOT(jumpinfile(data)))
  350.                      loop = makehunkentry(loop, "Seek() error!");
  351.  
  352.                break;
  353.  
  354.             case hunk_reloc32:
  355.             case hunk_reloc16:
  356.             case hunk_reloc8:
  357.                error = readlong(&data);
  358.                while ((error > 0) && data != 0L)
  359.                {
  360.                   data2 = data;
  361.                   error = readlong(&data3);
  362.                   sprintf(buffer, "     \#%-3ld offsets in Hunk \#%-3ld",
  363.                           data, data3);
  364.                   loop = makehunkentry(loop, buffer);
  365.  
  366.                   if (NOT(jumpinfile(data2)))
  367.                   {
  368.                      loop = makehunkentry(loop, "Seek() error!");
  369.                      break;
  370.                   }
  371.  
  372.                   error = readlong(&data);
  373.                }
  374.  
  375.                break;
  376.  
  377.             case hunk_ext:
  378.                error = readlong(&data);
  379.                z = 0;
  380.  
  381.                while(data && (error > 0))
  382.                {
  383.                   ext_type = (int)(data >> 24);
  384.                   data = (data << 8) >> 8;
  385.  
  386.                   switch(ext_type)
  387.                   {
  388.                      case ext_def:
  389.                      case ext_abs:
  390.                      case ext_res:
  391.                         error = readtext(datatext,data);
  392.                         error = readlong(&data2);
  393.                         sprintf(buffer, "      %s: %-22s val: %ld",
  394.                                  ext_names1[ext_type-ext_def+1],datatext, data2);
  395.  
  396.                         loop = makehunkentry(loop, buffer);
  397.                         break;
  398.  
  399.                      case ext_ref32:
  400.                      case ext_dref32:
  401.                         error = readtext(datatext,data);
  402.                         error = readlong(&data2);
  403.                         sprintf(buffer, "      %s: %-22s refs: %ld",
  404.                                  ext_names2[ext_type-ext_ref32],datatext,data2);
  405.  
  406.                         loop = makehunkentry(loop, buffer);
  407.  
  408.                         if (NOT(jumpinfile(data2)))
  409.                            loop = makehunkentry(loop, "Seek() error!");
  410.                         break;
  411.  
  412.                      case ext_common:
  413.                         error = readlong(&data);
  414.                         error = readlong(&data2);
  415.                         sprintf(buffer, "      %s (size): %ld  refs: %ld",
  416.                                 ext_names2[ext_type-ext_ref32],data,data2);
  417.                         loop = makehunkentry(loop, buffer);
  418.  
  419.                         if (NOT(jumpinfile(data2)))
  420.                            loop = makehunkentry(loop, "Seek() error!");
  421.  
  422.                         break;
  423.  
  424.                      case ext_ref16:
  425.                      case ext_ref8:
  426.                      case ext_dref16:
  427.                      case ext_dref8:
  428.                         error = readtext(datatext,data);
  429.                         error = readlong(&data2);
  430.                         sprintf(buffer, "      %s: %-22s refs: %ld",
  431.                                  ext_names2[ext_type-ext_ref32],datatext, data2);
  432.  
  433.                         loop = makehunkentry(loop, buffer);
  434.  
  435.                         if (NOT(jumpinfile(data2)))
  436.                            loop = makehunkentry(loop, "Seek() error!");
  437.                         break;
  438.  
  439.                      default:
  440.                         loop = makehunkentry(loop, "Unknown external reference!");
  441.                         break;
  442.                   }
  443.  
  444.                   z++;
  445.                   error = readlong(&data);
  446.                }
  447.  
  448.                sprintf(buffer, "      External refs: %ld",z);
  449.                loop = makehunkentry(loop, buffer);
  450.                break;
  451.  
  452.             case hunk_symbol:
  453.                error = readlong(&data);
  454.                z=0;
  455.                while(data && (error > 0))
  456.                {
  457.                   data = (data << 8) >> 8;
  458.                   error = readtext(datatext,data);
  459.                   error = readlong(&data);
  460.                   sprintf(buffer, "      Symbol: %-22s  val: %ld",
  461.                           datatext,data);
  462.                   loop = makehunkentry(loop, buffer);
  463.  
  464.                   error = readlong(&data);
  465.                   z++;
  466.                }
  467.  
  468.                sprintf(buffer, "      External symbols: %ld", z);
  469.                loop = makehunkentry(loop, buffer);
  470.                break;
  471.  
  472.             case hunk_debug:
  473.                error = readlong(&data);
  474.                sprintf(buffer, "  \$%lx, \#%ld",data * 4, data * 4);
  475.                loop = makehunkentry(loop, buffer);
  476.  
  477.                if (NOT(jumpinfile(data)))
  478.                   loop = makehunkentry(loop, "Seek() error!");
  479.  
  480.                break;
  481.  
  482.             case hunk_end:
  483.                if(lasthunk >= hunk_code && lasthunk <= hunk_debug)
  484.                   strcpy(blanks,"  ");
  485.                else
  486.                   strcpy(blanks,"      ");
  487.  
  488.                sprintf(buffer, "%s%s (o: \$%lx,\#%ld t: \$%lx,\#%ld)",
  489.                        blanks,names[type], currentpos(), currentpos(),data,data);
  490.                loop = makehunkentry(loop, buffer);
  491.                break;
  492.  
  493.             case hunk_header:
  494.                error = readlong(&data);
  495.                while ((error > 0) && data != 0L)
  496.                   error = readlong(&data);
  497.  
  498.                error = readlong(&data);
  499.                sprintf(buffer, "  Count hunks : \#%ld",data);
  500.                loop = makehunkentry(loop, buffer);
  501.  
  502.                error = readlong(&data2);
  503.                sprintf(buffer, "  First hunk  : \#%ld", data2);
  504.                loop = makehunkentry(loop, buffer);
  505.  
  506.                error = readlong(&data3);
  507.                sprintf(buffer, "  Last hunk   : \#%ld", data3);
  508.                loop = makehunkentry(loop, buffer);
  509.  
  510.                for (i = data2; error && i <= data3; i++)
  511.                {
  512.                   error = readlong(&data);
  513.                   if (error > 0)
  514.                   {
  515.                      sprintf(buffer, "    Hunk \#%ld, Length \$%lx, \#%ld",
  516.                              i, data * 4, data * 4);
  517.                      loop = makehunkentry(loop, buffer);
  518.                   }
  519.                   else
  520.                   {
  521.                      sprintf(buffer, "    Hunk \#%ld, Length ??", i);
  522.                      loop = makehunkentry(loop, buffer);
  523.                   }
  524.                }
  525.  
  526.                break;
  527.  
  528.             case hunk_overlay:
  529.                error = readlong(&data);
  530.                sprintf(buffer, "  Table size: \$%lx, \#%ld",data, data);
  531.                loop = makehunkentry(loop, buffer);
  532.  
  533.                if (NOT(jumpinfile(data)))
  534.                   loop = makehunkentry(loop, "Seek() error!");
  535.  
  536.                break;
  537.  
  538.             case hunk_break:
  539.                loop = makehunkentry(loop, (char *)field[BLANK_FIELD]);
  540.                sprintf(buffer, "%s (o: \$%lx,\#%ld t: \$%lx,\#%ld)",
  541.                        names[type], currentpos(), currentpos(),data,data);
  542.                loop = makehunkentry(loop, buffer);
  543.  
  544.                break;
  545.  
  546.             case hunk_lib:
  547.             case hunk_libindex:
  548.                error = readlong(&data);
  549.                sprintf(buffer, "\$%lx, \#%ld", data * 4, data * 4);
  550.                loop = makehunkentry(loop, buffer);
  551.  
  552.                if (NOT(jumpinfile(data)))
  553.                   loop = makehunkentry(loop, "Seek() error!");
  554.  
  555.                break;
  556.  
  557.             default:
  558.                loop = makehunkentry(loop, (char *)field[BLANK_FIELD]);
  559.                sprintf(buffer, "%s: \#%ld (\$%lX)", "Unknown hunk type position",
  560.                        currentpos(),currentpos());
  561.                loop = makehunkentry(loop, buffer);
  562.                failure++;
  563.  
  564.                if(failure >= 5)
  565.                   Seek(file, 0L, OFFSET_END);
  566.                break;
  567.          }
  568.  
  569.          lasthunk = type_of_hunk;
  570.  
  571.          error = readlong(&data);
  572.       }
  573.  
  574.       Close(file);
  575.    }
  576.  
  577.    return;
  578. }
  579.  
  580.    /*
  581.     * MakeHunkList() erzeugt aus einem ausführbaren File eine
  582.     * Liste aus den Hunks, aus denen das Executable besteht. Zuvor
  583.     * werden die Gadgets deaktiviert
  584.     */
  585. static void
  586. MakeHunkList(char *file)
  587. {
  588.    loop = firstde;
  589.  
  590.    if(SysWnd)
  591.       PrintInfo("Scanning Hunks", SPEAK, 0);
  592.  
  593.    SetWindowTitles(TreeWnd, (UBYTE *) "<- Cancel reading Hunks...",
  594.                             NOSCREENTITLECHANGE);
  595.    EnableGadget(TreeWnd, TreeGadgets[GD_SaveGad], FALSE);
  596.    EnableGadget(TreeWnd, TreeGadgets[GD_KindCY], FALSE);
  597.  
  598.    ScanHunks(file);
  599.  
  600.    SetWindowTitles(TreeWnd, TreeWdt1, NOSCREENTITLECHANGE);
  601.    EnableGadget(TreeWnd, TreeGadgets[GD_SaveGad], TRUE);
  602.    EnableGadget(TreeWnd, TreeGadgets[GD_KindCY], TRUE);
  603.  
  604.    return;
  605. }
  606.  
  607.    /*
  608.     * PrintHunkStruct() bietet eine kleine Benutzeroberfläche an
  609.     * und ermittelt die Hunks eines Executables. Diese werden dann
  610.     * in einem ListView angezeigt
  611.     */
  612. void
  613. PrintHunkStruct(char *file)
  614. {
  615.    struct IntuiMessage *message;
  616.    ULONG class,
  617.          code;
  618.    APTR  object;
  619.    APTR  req;
  620.    int id;
  621.  
  622.    DPOS;
  623.  
  624.    Flags.quit_hunk = 0;
  625.  
  626.    NewList(&Tree);
  627.  
  628.    if (NOT(OpenTreeWindow(NULL, TRUE)))
  629.    {
  630.       if (SysWnd)
  631.       {
  632.          req = LockWindow(SysWnd);
  633.          PrintInfo("Scanning Hunks", SPEAK, 0);
  634.       }
  635.  
  636.       decnt = 0;
  637.  
  638.       if(file)
  639.       {
  640.          InitListView(TreeWnd,TreeGadgets[GD_TreeLV],NULL,UNSETLVPOS);
  641.  
  642.          breakit = FALSE;
  643.  
  644.          MakeHunkList(file);
  645.       }
  646.  
  647.       do
  648.       {
  649.          Wait(1L << TreeWnd->UserPort->mp_SigBit);
  650.  
  651.          while ((message = (struct IntuiMessage *)
  652.                  GT_GetIMsg(TreeWnd->UserPort)) != NULL)
  653.          {
  654.             class = message->Class;
  655.             code = message->Code;
  656.             object = message->IAddress;
  657.  
  658.             GT_ReplyIMsg(message);
  659.  
  660.             switch(class)
  661.             {
  662.                case IDCMP_CLOSEWINDOW:
  663.                   Flags.quit_hunk = 1;
  664.                   break;
  665.  
  666.                case IDCMP_GADGETUP:
  667.                   id = ((struct Gadget *)object)->GadgetID;
  668.  
  669.                   switch(id)
  670.                   {
  671.                      case GD_SaveGad:
  672.                         if (GetFile(TreeWnd,"RAM:","RSys-Hunk.DAT","#?.dat",
  673.                                     "Select File for saving hunklist","Save"))
  674.                            SaveList(TreeWnd, (char *)_fullpath,
  675.                                     (char *)"RSys-Hunk.DAT",&Tree, FALSE);
  676.                         break;
  677.  
  678.                      case GD_KindCY:
  679.                         InitListView(TreeWnd,TreeGadgets[GD_TreeLV],NULL,UNSETLVPOS);
  680.  
  681.                         if (NOT(IsListEmpty(&Tree)))
  682.                         {
  683.                            NewList(&Tree);
  684.                            FreeRemember(RKEY, TRUE);
  685.                         }
  686.  
  687.                         decnt = 0;
  688.                         breakit = FALSE;
  689.  
  690.                         if (GetFile(TreeWnd,NULL,NULL,NULL,
  691.                                     "Select File for Hunk list","Show"))
  692.                            MakeHunkList((char *)_fullpath);
  693.  
  694.                         break;
  695.                   }
  696.                   break;
  697.  
  698.                case IDCMP_VANILLAKEY:
  699.                   if((char)code == ESC)
  700.                      Flags.quit_hunk = 1;
  701.                   break;
  702.             }
  703.          }
  704.       }
  705.       while (NOT(Flags.quit_hunk));
  706.  
  707.       InitListView(TreeWnd,TreeGadgets[GD_TreeLV],NULL,UNSETLVPOS);
  708.  
  709.       if (NOT(IsListEmpty(&Tree)))
  710.       {
  711.          NewList(&Tree);
  712.          FreeRemember(RKEY, TRUE);
  713.       }
  714.  
  715.       CloseASysWindow(&TreeWnd, &TreeGList, NULL);
  716.  
  717.       if (SysWnd)
  718.       {
  719.          UnlockWindow(req);
  720.          RefreshMainWindowPattern();
  721.          RefreshList(LastID);
  722.       }
  723.    }
  724.    else
  725.       ErrorHandle(WINDOW_ERR, OPEN_FAIL, NO_KILL);
  726.  
  727.    return;
  728. }
  729.  
  730.    /*
  731.     * PrintHunkStruct() kann mit einem Parameter aufgerufen werden
  732.     * oder ohne. Kommt der Aufruf nicht vom RSysAppIcon, so wird kein
  733.     * Filename übergeben und der Aufruf wird von HunkStruct() aus
  734.     * getätigt
  735.     */
  736. void
  737. HunkStruct(void)
  738. {
  739.    DPOS;
  740.  
  741.    PrintHunkStruct(NULL);
  742.    return;
  743. }
  744.  
  745.