home *** CD-ROM | disk | FTP | other *** search
/ Delphi Programming Unleashed / Delphi_Programming_Unleashed_SAMS_Publishing_1995.iso / chap17 / appmem / getgdtw.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1995-03-21  |  11.9 KB  |  315 lines

  1. unit GetGDTW;
  2. {
  3.   Refer Undocumented Windows #356 (sgdt) and
  4.   Windows Tech Journal #28 1/93 and
  5.   The Processor and Coprocessor #96/99 and refer text
  6. }
  7.  
  8. interface
  9.  
  10. uses
  11.   Winprocs, SysUtils, StdCtrls;
  12.  
  13.  
  14. procedure FillList1(LBox: TListBox);
  15.  
  16. implementation
  17.  
  18. type
  19.   AccessedStr = array[0..3] of char;      {bit 0 $01 - AccessRights}
  20.   DataWriteStr = array[0..4] of char;     {bit 1 $02 - AccessRights}
  21.   CodeReadStr = array[0..4] of char;      {bit 1 $02 - AccessRights}
  22.   ConformingStr = array[0..3] of char;    {bit 2 $04 - AccessRights}
  23.   UpDownStr = array[0..3] of char;        {bit 2 $04 - AccessRights}
  24.   CodeDataStr = array[0..3] of char;      {bit 3 $08 - AccessRights}
  25.   DescTypeStr = array[0..3] of char;      {bit 4 $10 - AccessRights}
  26.   PresentStr = array[0..3] of char;       {bit 7 $80 - AccessRights}
  27.   Bit5Str = array[0..3] of char;          {bit 5 $20 - LimitH_Flags}
  28.   DefSizeStr = array[0..4] of char;       {bit 6 $40 - LimitH_Flags}
  29.   GranStr = array[0..3] of char;          {bit 7 $80 - LimitH_Flags}
  30.   TSystemDesc = array[0..25] of Char;
  31.  
  32.   PShowDesc = ^TShowDesc;                    {---------SYSTEM DESCRIPTORS----------}
  33.   TShowDesc = record                         {INT/TRAP     CALL      TASK gate     }
  34.    LimitL,                                   {<---- offset low ----> reserved      }
  35.    BaseL: word;                              {<-- code segm. sel --> TSS segm. sel.}
  36.    BaseM,                                    {<--- bits 0/2=0 ---->, bits 0/7=res.
  37.                                               3/7=count    3/7=reserved }
  38.    AccessRights: byte;
  39.           {data/stack segm. code segment
  40.      bit 0   0=not accessed/1=accessed     bits 0/3: 0=reserved, 1=available 16b TSS
  41.      bit 1   writable       readable       2=ldt, 3=busy 16b TSS, 4=16b call gate
  42.      bit 2   expand down    conforming     5=16b task gate, 6=16b int. gate,
  43.      bit 3   always 0        always 1      7=16b trap gate, 8=reserved, 9=avail.32b TSS
  44.                                            10=reserved, 11=busy 32b TSS, 12=32b call gate
  45.                                            13=reserved, 14=32b int.gate, 15=32b task gate
  46.      bit 4   0=system desc./1=segm.descriptor  <------------ 0 ---------------->
  47.      bit 5+6 descriptor privilege level      <------------- dpl --------------->
  48.      bit 7   present                         <----------- present ------------->}
  49.    LimitH_Flags,                                 {LimitH_Flags+BaseH =            }
  50.             {80386/486 only, must be 0 on 80286} {offset (High) for Trap/Call ... }
  51.     {bit 0/4 LimitH}                             {... gate, reserved for Task gate}
  52.     {bit 5   available
  53.      bit 6   default size 16/32 bits
  54.      bit 7   granularity}
  55.    BaseH: byte;
  56.             {80386/486 only, must be 0 on 80286}
  57.   end;
  58.  
  59.   PGDTMap =^TGDTMap;
  60.   TGDTMap = array[0..65521 div Sizeof(TShowDesc)] of TShowDesc;
  61.  
  62.   LongRemap = record
  63.     case Word of
  64.       0:(Long: LongInt);
  65.       1:(LoWord, HiWord: Word);
  66.    end;
  67.  
  68. const
  69.   Accessed: array[boolean] of AccessedStr = (' Na',' Ac');
  70.   DataWrite: array[boolean] of DataWriteStr = (' R  ',' R/W');
  71.   CodeRead: array[boolean] of CodeReadStr = ('  NR','   R');
  72.   Conforming: array[boolean] of ConformingStr = (' NC','  C');
  73.   UpDown: array[boolean] of UpDownStr = (' Up',' Do');
  74.   CodeData: array[boolean] of CodeDataStr = (' Da',' Co');
  75.   DescType: array[boolean] of DescTypeStr =(' Sy',' Se');
  76.   Present: array[boolean] of PresentStr = (' Nl',' Lo');
  77.   Bit5: array[boolean] of Bit5Str = (' 5f',' 5t');
  78.   DefSize: array[boolean] of DefSizeStr = (' 16b',' 32b');
  79.                                         {default operands/adress size}
  80.   Gran: array[boolean] of Granstr = (' 1b',' 4k'); {granularity}
  81.   SystemDescType: array[0..15] of TSystemDesc =
  82.    ('Reserved - type field: ', 'Available 16b TSS', 'LDT', 'Busy 16b TSS', '16b Call Gate',
  83.     '16b Task Gate', '16b Int. Gate', '16b Trap gate', 'Reserved - type field: ',
  84.     'Available 32b TSS', 'Reserved - type field: ', 'Busy 32b TSS', '32b Call Gate',
  85.     'Reserved - type field: ', '32b Int. Gate', '32b Task Gate');
  86.  
  87.  
  88. var SGDTable, DummyStr:Array[0..79] of Char;
  89.     PGDTable: PShowDesc;
  90.     GDTable: TShowDesc;
  91.     GDTMap: PGDTMap;
  92.     Selector, _ds: Word;
  93.     Typ, DPL: byte;
  94.     DummyBase, DummyLimit,
  95.     LDTBase, LDTLimit: Longint;
  96.     Loop, LoopLimit: Integer;
  97.     OutFile: Text;
  98.  
  99.  
  100. function HexB(Dest: PChar; B: Byte): PChar;
  101. const
  102.   h: array[0..15] of Char = '0123456789ABCDEF';
  103. begin
  104.   Dest[0] := h[b shr 4];
  105.   Dest[1] := h[b and $0F];
  106.   Dest[2] := #0;
  107.   HexB := Dest;
  108. end;
  109.  
  110. function HexW(Dest: PChar; I: Word): PChar;
  111. begin
  112.   HexB(Dest, Hi(I));
  113.   HexB(@Dest[2], Lo(I));
  114.   HexW := Dest;
  115. end;
  116.  
  117. function HexL(Dest: PChar; l:LongInt): PChar;
  118. var
  119.   lr: LongRemap absolute l;
  120. begin
  121.   HexW(Dest, lr.HiWord);
  122.   HexW(@Dest[4], lr.LoWord);
  123.   HexL := Dest;
  124. end;
  125.  
  126. function ShowGDT(var GlDescTable: TShowDesc): String;
  127. var
  128.   DummyAccess: Word;
  129.   MyString: String;
  130. begin
  131.   MyString := '';
  132.   with GlDescTable do
  133.    case (AccessRights and $10) of
  134.     0: begin
  135.          StrCopy(SGDTable, SystemDescType[AccessRights and $F]);
  136.          case (AccessRights and $F) of
  137.           0, 8, 10, 13: {Reserved}
  138.             begin
  139.               HexB(DummyStr, AccessRights and $F);
  140.               StrCat(SGDTable, DummyStr);
  141.               if (LimitL=0) and (BaseL=0) and (BaseM=0) and (AccessRights=0)
  142.                  and (LimitH_Flags=0) and (BaseH=0)
  143.                then StrCat(SGDTable, ' - All zero''s ')
  144.                else StrCat(SGDTable, ' - Not all zero''s ');
  145.             end;
  146.           1, 3:  {16b Task State Segment}
  147.             begin
  148.               {no further details displayed yet - refer #319}
  149.             end;
  150.           9, 11:  {32b Task State Segment}
  151.             begin
  152.               {no further details displayed yet - refer #320}
  153.             end;
  154.           5, 15:  {Task Gate}
  155.             begin
  156.               StrCat(SGDTable, ' TSS Segment Selector: ');
  157.               HexW(DummyStr, BaseL);
  158.               StrCat(SGDTable, DummyStr);
  159.             end;
  160.           4, 6, 7, 12, 14:  {Int/Trap/Call Gate}
  161.             begin
  162.               StrCat(SGDTable, '/Segment Sel. ');
  163.               HexW(DummyStr, BaseL);
  164.               StrCat(SGDTable, DummyStr);
  165.               StrCat(SGDTable, '/Limit ');
  166.               HexL(DummyStr, Longint(LimitL) + LongInt(LimitH_Flags) shl 16
  167.                                              + LongInt(BaseH) shl 24);
  168.               StrCat(SGDTable, DummyStr);     {32 bits significant #312}
  169.               StrCat(SGDTable, '/Dpl ');
  170.               DPL:=(AccessRights shr 5) and $03;
  171.               HexB(DummyStr, DPL);
  172.               StrCat(SGDTable, @DummyStr[1]);
  173.               StrCat(SGDTable, '/');   {is TARGET code segment present?}
  174.               StrCat(SGDTable, Present[AccessRights and $80 > 0]);
  175.               StrCat(SGDTable, '/Count ');
  176.               HexB(DummyStr, BaseM and $F8); {5 bits significant #315}
  177.               StrCat(SGDTable, DummyStr);
  178.             end;
  179.           2: {LDT}
  180.             begin
  181.               LDTBase:=longint(BaseL) + longint(BaseM) shl 16 + longint(BaseH) shl 24;
  182.               LDTLimit:=longint(LimitL) + longint(LimitH_Flags and $1F) shl 16;
  183.               StrCat(SGDTable, '/Segment Sel. ');
  184.               HexW(DummyStr, BaseL);
  185.               StrCat(SGDTable, DummyStr);
  186.               StrCat(SGDTable, '/Base ');
  187.               HexL(DummyStr, LDTBase);
  188.               StrCat(SGDTable, DummyStr);
  189.               StrCat(SGDTable, '/Limit ');
  190.               HexL(DummyStr, Longint(LimitL) + LongInt(LimitH_Flags) shl 16
  191.                                              + LongInt(BaseH) shl 24);
  192.               StrCat(SGDTable, @DummyStr[3]); {only 20 bits can be significant}
  193.               StrCat(SGDTable, '/Dpl ');
  194.               DPL:=(AccessRights shr 5) and $03;
  195.               HexB(DummyStr, DPL);
  196.               StrCat(SGDTable, @DummyStr[1]);
  197.             end;
  198.          end;
  199.        end;
  200.     else
  201.        begin
  202.           DummyBase:=longint(BaseL) + longint(BaseM) shl 16 + longint(BaseH) shl 24;
  203.           DummyLimit:=longint(LimitL) + longint(LimitH_Flags and $1F) shl 16;
  204.           HexL(SGDTable, DummyBase);
  205.           MyString := 'Base ' + StrPas(SGDTable);
  206.           { Write(OutFile, 'Base ', SGDTable); }
  207.           HexL(DummyStr, DummyLimit);
  208.           StrCopy(SGDTable, @DummyStr[3]); {only 20 bits can be significant}
  209.           MyString := MyString + ' Limit ';
  210.           { Write(OutFile, ' Limit '); }
  211.           StrCat(SGDTable, Accessed[AccessRights and $01 > 0]);
  212.           if AccessRights and $08 > 0 then      {code segment}
  213.            begin
  214.              StrCat(SGDTable, CodeRead[AccessRights and $02 > 0]);
  215.              StrCat(SGDTable, Conforming[AccessRights and $04 > 0]);
  216.              StrCat(SGDTable, CodeData[True]);
  217.            end
  218.            else begin                           {data/stack segment}
  219.                   StrCat(SGDTable, DataWrite[AccessRights and $02 > 0]);
  220.                   StrCat(SGDTable, UpDown[Typ and $04 > 0]);
  221.                   StrCat(SGDTable, CodeData[False]);
  222.                 end;
  223.           StrCat(SGDTable, DescType[AccessRights and $10 > 0]);
  224.           StrCat(SGDTable, ' ');
  225.           DPL:=(AccessRights shr 5) and $03;
  226.           HexB(DummyStr, DPL);
  227.           StrCat(SGDTable, @DummyStr[1]);
  228.           StrCat(SGDTable, Present[AccessRights and $80 > 0]);
  229.           StrCat(SGDTable, Bit5[LimitH_Flags and $20 > 0]);
  230.           StrCat(SGDTable, DefSize[LimitH_Flags and $40 > 0]);
  231.           StrCat(SGDTable, Gran[LimitH_Flags and $80 > 0]);
  232.         end;
  233.    end;
  234.   MyString := MyString + SGDTAble;
  235.   ShowGDT := MYString;
  236.   {Writeln(OutFile, SGDTable); }
  237. end;
  238.  
  239. function GetGDTMap(var Size: integer; Sel: Word): PGDTMap;
  240. var
  241.   AResult: PGDTMap;
  242. {Thanks to Dj Murdoch for the idea of the 'sizing' method}
  243. begin
  244.   AResult := GlobalLock(Sel);
  245.   Size:=(GetSelectorLimit(Sel)+1) div SizeOf(TShowDesc);
  246.   GetGDTMap := AResult;
  247. end;
  248.  
  249. procedure StartList(LBox: TListBox);
  250. var
  251.   MyString: String;
  252. begin
  253.   Assign(OutFile, 'dtable.txt');
  254.   Rewrite(OutFile);
  255.   PGDTable:=@GDTable;
  256.   asm
  257.    les bx, PGDTable
  258.    sgdt es:[bx]
  259.    mov _ds,ds
  260.   end;
  261.   Selector:=AllocSelector(_ds);
  262.   with GDTable do begin
  263.      DummyBase:=longint(BaseL) + longint(BaseM) shl 16 + longint(AccessRights) shl 24;
  264.      { Not regular descriptor, but just limit + base !!!!}
  265.      DummyLimit:=longint(LimitL) + longint(LimitH_Flags and $1F) shl 16;
  266.      SetSelectorBase(Selector, DummyBase);
  267.      SetSelectorLimit(Selector, DummyLimit);
  268.      GDTMap:=GetGDTMap(LoopLimit, Selector);
  269.      {  Writeln(OutFile, ' GDT Descriptor table at: '); }
  270.      HexL(SGDTable, DummyBase);
  271.      {     Write(OutFile, 'Base ', SGDTable); }
  272.      HexL(DummyStr, DummyLimit);
  273.      StrCopy(SGDTable, @DummyStr[3]);
  274.      {    Writeln(OutFile,' Limit ', SGDTable);
  275.      Writeln(OutFile,'Number of entries: '); }
  276.    end;
  277.   for Loop:=0 to LoopLimit-1 do
  278.     LBox.Items.Add(ShowGDT(GDTMap^[loop])); {walk the GDT array}
  279.  
  280.   with GDTable do
  281.    begin
  282.      SetSelectorBase(Selector, LDTBase);
  283.      SetSelectorLimit(Selector, LDTLimit);
  284.      GDTMap:=GetGDTMap(LoopLimit, Selector);
  285.  
  286.      
  287. {     Writeln(OutFile, ' LDT Descriptor table at: '); }
  288.      HexL(SGDTable, LDTBase);
  289. {     Write(OutFile, 'Base ', SGDTable); }
  290.      LBox.Items.Add('==========================================');
  291.      LBox.Items.Add('==========================================');
  292.      MyString := ' LDT Descriptor table at: ' + StrPas(SGDTable);
  293.      LBox.Items.Add(MyString);
  294.  
  295.      HexL(DummyStr, LDTLimit);
  296.      StrCopy(SGDTable, @DummyStr[3]);
  297.      Writeln(OutFile,' Limit ', SGDTable);
  298.      Writeln(OutFile,'Number of entries: ');
  299.    end;
  300.   for Loop:=0 to LoopLimit-1 do
  301.     LBox.Items.Add(ShowGDT(GDTMap^[loop])); {walk the GDT array}
  302.  
  303.   GlobalUnlock(Selector);
  304.   FreeSelector(Selector);
  305.   Close(OutFile);
  306. end; 
  307.  
  308. procedure FillList1(LBox: TListBox);
  309. begin
  310.   StartList(LBox);
  311. end;
  312.  
  313. end.
  314.  
  315.