{ ³>anybody know how I can determine the size of the driver in ³>memory? ³ I would assume they take the Drivers name and search through the ³ Memory Control Blocks maintained by DOS and seeing if the driver ³ owns any of them. But there might be an easier way. There is. An undocumented DOS function (52h) gives you the "list of lists", which contains the first device driver in a linked list, which you can then traverse. (See Schulman's _Undocumented DOS_.) Take the address of the device driver header, and look at the 0 offset in the "segment" which is 1 segment address unit before the beginning of the device driver header. For example, if the device driver header is at $1234:$0000, look at address $1233:0. If the byte at that address is "M", "Z", or "D", we have either a valid memory control block header ("M" or "Z"), or a "device driver subheader" ("D") which follows the same format. In either case, the word at :0003 gives the number of 16-byte paragraphs used by that memory block; multiply by 16 to get the size in bytes. The following TP code should illustrate this (*only* HexW is used from OPString; substitute your own or any PD/Shareware hex conversion routine if you don't have OPro): } USES DOS, OPString; TYPE PMCBhdr = ^TMCBhdr; TMCBhdr = RECORD Signature: CHAR; { 'M', 'Z', or one of the valid 'subblock' letters} OwnerSeg: WORD; { Segment of "owner" of this block } SizeParas: WORD; { Size of block, in 16-byte paragraphs } Unused: ARRAY [1..3] OF CHAR; Name: ARRAY [1..8] OF CHAR; {Name of owner program (DOS 4+)} END; PDevHdr = ^TDevHdr; TDevHdr = RECORD NextDriver: POINTER; { Next driver in device chain } Attr: WORD; { Driver attribute word } Strategy: WORD; { Offset within this segment } Interrupt: WORD; { of the driver strategy & } { interrupt routines. } Name: ARRAY [1..8] OF CHAR; { Device name for char devs; } { for block devices, first byte is # of logical } { devices associated with this driver, others } { are unused. } END; PROCEDURE DisplayDeviceHeader( DevHdr: PDevHdr ); VAR MCBptr: ^TMCBhdr; Size: LONGINT; BEGIN { The line to be displayed will look something like this: } { ssss:oooo dev_name mem_size owner_name } { The last two columns are displayed only under DOS 4+, and } { only when the information is found -- may fail under 386^Max } Write( HexW( Seg( DevHdr^ ) ), ':', HexW( Ofs( DevHdr^ ) ), ' ' ); { See if it's a character device. If it is, then it has a name } { to display. } IF (DevHdr^.Attr AND $8000) <> 0 THEN Write( DevHdr^.Name:12, ' ' ) ELSE { Block device -- write # of logical drives } Write( Ord( DevHdr^.Name[1] ):3, ' drive(s) ' ); { See if the DOS version supports the 'sub-MCBs' introduced for } { device drivers in the first MCB in DOS version 4, and/or the } { Name field in the MCB introduced in v4. } IF Lo( DosVersion ) >= 4 THEN BEGIN MCBptr := Ptr( Seg( DevHdr^ ) - 1, 0 ); { Check for MCB sig., and make sure the MCB "owns itself" } IF (MCBptr^.Signature IN ['M', 'Z', 'D']) AND (MCBptr^.OwnerSeg = Seg( DevHdr^ ) ) THEN BEGIN Size := MCBptr^.SizeParas * 16; Write( Size:6, MCBptr^.Name:9 ); END; { IF MCB signature } END; { IF DosVersion } WriteLn; END; {DisplayDeviceHeader} VAR Regs: REGISTERS; CurDevice: PDevHdr; BEGIN { main program } Regs.AH := $52; MSDos( Regs ); IF Lo( DosVersion ) < 3 THEN { Get first device in list; } CurDevice := Ptr( Regs.ES, Regs.BX+$17 ) { location varies by DOS } ELSE { version. } CurDevice := Ptr( Regs.ES, Regs.BX+$22 ); REPEAT DisplayDeviceHeader( CurDevice ); CurDevice := CurDevice^.NextDriver; UNTIL Ofs( CurDevice^ ) = $FFFF; END.