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

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