[comp.sys.ibm.pc.misc] finding the directory structures in DOS

devolder@matt.ksu.ksu.edu (Eric DeVolder) (11/12/90)

Hello all,
  I recently read the following article (which is included in the header of
the test program) that describes how to 'hide' a drive through DOS.  In an
attempt to do just that, I have created the following sample Turbo Pascal 
program to do that.  
  I run the program (yes, I know it is rather bullish with no style), but it
works, well to some degree.  What the program does is to take the pointer
returned upon the Dos function call for Get list of lists, and use it, as Ralf
Brown says to do.  The pointer that is returned is valid and I can get it
to point to its correct data.  I tested this by printing the LASTDRIVE= value,
which is the writeln that contains the +$21 offset.  This is correct.  I tested
it by changing my LASTDRIVE= line in config.sys to several values, rebooted,  
and ran the program, and it would show a correct value everytime.  However,
I tried to get it to point to the array of drive structures.  the series
of writelns show the 4 bytes that make up the pointer.  (I did this because
TP does not handle pointers well compared to C).   So I next tried to do a 
loop that prints out the first $42 bytes which is supposed to be current
directory for that drive.  I am assuming that the pointer is pointing to the
first drive, which I assume is the A drive.  So i set a current directory on
the A drive and ran the program. I do not get the current directory as I should
but I get a bunch of characters that are not standard ascii, in other words, I
get garbage.  I tried all sorts of things, and double checked everything.  I
am possitive that the pointer that I formed is done correctly, though bullishly,
and that i should be getting the correct data.

  I should mention that I am running this under IBM PC-DOS 4.0.

  At this point, i don't know what is wrong.  Is there another link that is
not specified in the DOS data structures that is not given?  Has anybody tried
to accomlish this task yet?
  I would appreciate any info that you could offer, (outside of doing this in C)

  I included the program so you can test if you want to try and run it.
Please mail me any solutions or ideas you have.  Thank you.

--------------  cut here -------------------------
program Hide;
uses dos, crt;
 
{
In article <9461@ur-cc.UUCP>, dsew@uhura.cc.rochester.edu (David Sewell) wrote:
 
    I'm about to start sharing my office computer with another user.
I have a hard disk with two partitions, C: and D:.  I would like to
make the D: drive invisible or inaccessible to the sharee because it
contains personal data and files.  Since the sharee is not a
 
The fastest way of temporarily making a drive inaccessible under DOS 3+
would be to diddle the "drive exists" bit in the current directory
structure for the drive.  It's anything other than elegant, though,
since it involves various undocumented data structures inside DOS.
 
INT 21 - DOS 2+ internal - GET LIST OF LISTS
	AH = 52h
Return: ES:BX -> DOS list of lists
 
Format of List of Lists:
Offset	Size	Description
---DOS 3.0---
 17h	DWORD	pointer to array of current directory structures (see below)
---DOS 3.1-3.3---
 16h	DWORD	pointer to array of current directory structures (see below)
---DOS 4.x---
 16h	DWORD	pointer to array of current directory structures (see below)
 21h    BYTE    BYTE value of the LASTDRIVE= in CONFIG.SYS (5 is default)
 
Format of current directory structure (array, 51h bytes [58h for DOS 4.x] per
drive):
Offset	Size	Description
 00h 67 BYTEs	current path as ASCIZ, starting with 'x:\'
 43h	WORD	bit flags
		bit 15: network drive	\ installable file system if both set
		bit 14: physical drive	/ invalid drive if neither bit set
		bit 13: JOIN'ed, current path is actual path without JOIN
			drive letter in path may differ from logical drive name
		bit 12: SUBST'ed, current path is actual path without SUBST
			drive letter in path may differ from logical drive name
[rest omitted, see the Interrupt List]
 
 
--
UUCP: ucbvax,harvard !cs.cmu.edu!ralf -=- 412-268-3053 (school) -=- FAX: ask
ARPA: ralf@cs.cmu.edu  BIT: ralf%cs.cmu.edu@CMUCCVMA  FIDO: 1:129/3.1
Disclaimer?    |   I was gratified to be able to answer promptly, and I did.
What's that?   |   I said I didn't know.  --Mark Twain
 
 
 
}
 
type
 DirPtr    = ^DirStruct;
 DirStruct = record
              path : array[0..$42] of byte;
              bits : Word;
             end;
 
 
var
 Regs: Registers;
 PtrSeg1,
 PtrOff1: Word;
 TmpSeg,
 TmpOff: word;
 TmpPtr: pointer;
 word1,
 word2,
 word3,
 word4 : word;
 
 X: INTEGER;
 
 P : DirPtr;
 
begin
clrscr;
 Regs.AH := $52;
 MsDos   (Regs);
 TmpSeg :=Regs.ES;   (* word *)
 TmpOff := Regs.BX;  (* word *)
 
 writeln ('tmpseg = ',tmpseg,'  tmpoff = ',tmpoff);
 
(* create pointer to the directory structures *)
 writeln (mem[tmpseg:tmpoff+$16],' ',mem[tmpseg:tmpoff+$17]);
 writeln (mem[tmpseg:tmpoff+$18],' ',mem[tmpseg:tmpoff+$19]);
 word1 := mem[tmpseg:tmpoff+$16];
 word1 := word1 shl 8;
 word2 := mem[tmpseg:tmpoff+$17];
 word1 := word1 + word2;
 ptrseg1 := word1;
 writeln ('ptr seg  :  ',ptrseg1);
 
 word3 := mem[tmpseg:tmpoff+$18];
 word3 := word3 shl 8;
 word4 := mem[tmpseg:tmpoff+$19];
 word3 := word3 + word4;
 ptroff1 := word3;
 writeln ('ptr off  :  ',ptroff1);
(* ***************************************** *)
 
 
 writeln ('lastdrive = ', mem[tmpseg:tmpoff+$21]);
 
 P := Ptr(PtrSeg1,PtrOff1);

(* this subroutine tests to see if the path is anywhere nearby *)
                           {
 for x:= 0 to 1884 do
  write( char( mem[ptrseg1:ptroff1 + x]));
                            }
 
 for x := 0 to $42 do
  write(char (p^.path[x]));
end.