[comp.sys.ibm.pc.programmer] .SYS

mshiels@tmsoft.uucp (Michael A. Shiels) (07/02/90)

I have been folling around with the MS-NET and Lan Manager connection
using NDIS network drivers.  And low and behold the drivers are .SYS files
but they don't have a standard header.  They actually have a .EXE header.

Does anyone know if Microsoft has allowed RELOCATABLE Device Drivers as .EXEs?

pipkins@qmsseq.imagen.com (Jeff Pipkins) (07/02/90)

In article <j8t1seef8@tmsoft.uucp> mshiels@tmsoft.UUCP (Michael A. Shiels) writes:
>I have been folling around with the MS-NET and Lan Manager connection
>using NDIS network drivers.  And low and behold the drivers are .SYS files
>but they don't have a standard header.  They actually have a .EXE header.
>
>Does anyone know if Microsoft has allowed RELOCATABLE Device Drivers as .EXEs?

In MS-DOS versions < 3.0, the EXEC function call (EXE loader) was actually
a part of COMMAND.COM.  Because COMMAND.COM is not loaded until after
CONFIG.SYS is processed, device drivers could not be in .EXE format.
(incidently, that is also why it's COMMAND.COM instead of COMMAND.EXE)

With MS-DOS versions >= 3.0, the EXEC function is part of MS-DOS proper
(if indeed one can use the word "proper" in the same sentence with the
word "MS-DOS"), so now device drivers can be in .EXE format.  After the 
program is loaded and the relocation is performed, the image must look just
like the .SYS image, with device driver header at ORG 0 and all that.

It is also possible to create a plain old .EXE file program that can be
invoked from the command line that can install itself as a device driver.
To do this, it must find the device driver chain (via an undocumented
function call) and link a device driver header into it.  The initialization
call will not be made, of course.  If you need to write a device driver
in a high-level language (even <GASP> turdo pascal or <NOOOO!> basic),
this is your best bet.

david@metapyr.UUCP (David Relson) (07/03/90)

In OS/2, device drivers have the .SYS extension and are .EXE files complete
with headers, relocation information, dynamic library link information, etc.

kaleb@mars.jpl.nasa.gov (Kaleb Keithley) (07/03/90)

In article <141@qmsseq.imagen.com> pipkins@imagen.com (Jeff Pipkins) writes:
>
>In MS-DOS versions < 3.0, the EXEC function call (EXE loader) was actually
>a part of COMMAND.COM.  Because COMMAND.COM is not loaded until after
>CONFIG.SYS is processed, device drivers could not be in .EXE format.
>(incidently, that is also why it's COMMAND.COM instead of COMMAND.EXE)

Wrong!  I just whipped out the M'soft Encyclopedia, and the EXEC function
call has been there all along.  Maybe you're thinking of that short lived
abortion known as DOS 1.0.

Not to mention, I remember playing with the SHELL option to CONFIG.SYS
back in the days of 2.0 and 2.1.  Really neat tricks like having the
machine boot right into Lotus, Dbase, or Wordstar.  Only drawback was,
don't try to quit the program; very unfriendly.

kaleb@thyme.jpl.nasa.gov            Jet Propeller Labs
Kaleb Keithley

"So that's what an invisible barrier looks like"

mshiels@tmsoft.uucp (Michael A. Shiels) (07/04/90)

>It is also possible to create a plain old .EXE file program that can be
>invoked from the command line that can install itself as a device driver.
>To do this, it must find the device driver chain (via an undocumented
>function call) and link a device driver header into it.  The initialization
>call will not be made, of course.  If you need to write a device driver
>in a high-level language (even <GASP> turdo pascal or <NOOOO!> basic),
>this is your best bet.
Most if not all of my drivers can use this technique already.  What I had
not even thought about was the ability to use a.EXE driver in the normal
DEVICE= line.  Most of not all the drivers I write are C with a small
.ASM stub to get things going.

ralf@b.gp.cs.cmu.edu (Ralf Brown) (07/04/90)

In article <4237@jato.Jpl.Nasa.Gov> kaleb@mars.UUCP (Kaleb Keithley) writes:
}In article <141@qmsseq.imagen.com> pipkins@imagen.com (Jeff Pipkins) writes:
}>In MS-DOS versions < 3.0, the EXEC function call (EXE loader) was actually
}>a part of COMMAND.COM.  Because COMMAND.COM is not loaded until after
}>CONFIG.SYS is processed, device drivers could not be in .EXE format.
}>(incidently, that is also why it's COMMAND.COM instead of COMMAND.EXE)
}
}Wrong!  I just whipped out the M'soft Encyclopedia, and the EXEC function
}call has been there all along.  Maybe you're thinking of that short lived
}abortion known as DOS 1.0.

DOS 1.x had the program loader in COMMAND.COM (there was no EXEC function as
such).  At least PCDOS 2.10 had the EXEC function INT 21/AH=48h in a second
transient portion of COMMAND.COM.  All versions of DOS 3 and up have the
EXEC function in the kernel.


-- 
{backbone}!cs.cmu.edu!ralf  ARPA: RALF@CS.CMU.EDU   FIDO: Ralf Brown 1:129/3.1
BITnet: RALF%CS.CMU.EDU@CMUCCVMA   AT&Tnet: (412)268-3053 (school)   FAX: ask
_How_to_Prove_It_ by Dana Angluin  23. proof by semantic shift: some standard
    but inconvenient definitions are changed for the statement of the result.

bambi@kirk.nmg.bu.oz (David J. Hughes) (07/05/90)

From article <4237@jato.Jpl.Nasa.Gov>, by kaleb@mars.jpl.nasa.gov (Kaleb Keithley):
> In article <141@qmsseq.imagen.com> pipkins@imagen.com (Jeff Pipkins) writes:
>>
>>In MS-DOS versions < 3.0, the EXEC function call (EXE loader) was actually
>>a part of COMMAND.COM.  Because COMMAND.COM is not loaded until after
> 
> Wrong!  I just whipped out the M'soft Encyclopedia, and the EXEC function
> call has been there all along.  Maybe you're thinking of that short lived
> abortion known as DOS 1.0.

To coin a phrase - "Wrong !".  It is in fact true that the EXEC call
"has been there all along" but that was not the statement made by Jeff.
His statement implied that the code that supported the EXEC function was
implemented within command.com.  

This is quite a true statement.  What Jeff meant to say was that in 
versions of DOS earlier than 3.0, the EXEC function call was implemented 
within the *** transient *** portion of the command processor.  This is 
only the case for IBM DOS 2.x.  I cannot imagine why you would place the 
EXEC routine in the transient section as it is quite legal for an 
application to stomp all over the transient part of command.com and then
issue an EXEC - but IBM did it that way.

They must have realised the problem - as IBM DOS 3.x did not work in
this way (neither did MS DOS 2.x).  All this information and more can
found in Dave Williams Shareware "Dos Technial Information" manual.  A
must for any DOS sysprog (but UNIX is more fun anyway :-)



bambi
+----------------------------------------------------------------------------+
| David J. Hughes   (AKA bambi)	 |   bambi@kowande.bu.oz.au                  |
| Systems Programmer		 |   bambi@kowande.bu.oz.au@uunet.uu.net     |
| Network Management Group       |   ..!uunet!munnari!kowande.bu.oz.au!bambi |
| Bond University, Gold Coast    |   Phone : +61 75 951111                   |
| Queensland,  Australia  4229   |   Fax :   +61 75 951456                   |
+----------------------------------------------------------------------------+

silver@xrtll.uucp (Hi Ho Silver) (07/05/90)

In article <4237@jato.Jpl.Nasa.Gov> kaleb@mars.UUCP (Kaleb Keithley) writes:
$In article <141@qmsseq.imagen.com> pipkins@imagen.com (Jeff Pipkins) writes:
$>In MS-DOS versions < 3.0, the EXEC function call (EXE loader) was actually
$>a part of COMMAND.COM.  Because COMMAND.COM is not loaded until after
$>CONFIG.SYS is processed, device drivers could not be in .EXE format.
$>(incidently, that is also why it's COMMAND.COM instead of COMMAND.EXE)
$Wrong!  I just whipped out the M'soft Encyclopedia, and the EXEC function
$call has been there all along.  Maybe you're thinking of that short lived
$abortion known as DOS 1.0.

   He didn't say it didn't exist, just that it was part of COMMAND.COM.
Depending on whose DOS (IBM/Microsoft/other), the version in which it was
moved from COMMAND.COM to MSDOS.SYS/IBMDOS.COM may vary, but it _did_
originally exist in COMMAND.COM.

   From _Advanced MS-DOS_ (Ray Duncan, Microsoft Press, first edition):

	In addition, EXE-format drivers cannot be used with the IBM
	PC, since the EXE loader is located in COMMAND.COM ...

   That's from the section on installable device drivers, which are a
feature that came in with version 2.0, implying that at least some
2.0-and-higher DOS versions/flavours work that way.
-- 
   /Nikebo \ Nikebo says "Nikebo knows how to post.  Just do it."\silver@xrtll/
  /---------\_____________________________________________________\----------/
 /yunexus!xrtll!silver (L, not 1)\ Hi Ho Silver \   just silver for short   /
/Silver:  Ever Searching for SNTF \  Life sucks. \  someone buy me a BEER! /

david@csource.oz.au (david nugent) (07/05/90)

In <141@qmsseq.imagen.com> pipkins@qmsseq.imagen.com (Jeff Pipkins) writes:

>It is also possible to create a plain old .EXE file program that can be
>invoked from the command line that can install itself as a device driver.
>To do this, it must find the device driver chain (via an undocumented
>function call) and link a device driver header into it.  The initialization
>call will not be made, of course.  If you need to write a device driver
>in a high-level language (even <GASP> turdo pascal or <NOOOO!> basic),
>this is your best bet.


DESQview comes with small utility called DEVICE.COM (around 600 bytes or
so) which allows loading _some_ device drivers - namely those that don't
link into the chain.  It loads the driver, calls the init function and
leaves it as a TSR.  It specifically checks for block device drivers (since
these MUST be linked into the device chain) and only allows character
device drivers to be loaded.  Some will work; but you couldn't load a
replacement for device which requires access from DOS - only those which
intercept and use interrupts.


david

-- 
_______________________________________________________________________________
 Unique Computing Pty Ltd  Melbourne  Australia  -  Communications Specialists 
        david@csource.oz.au    3:632/348@fidonet    28:4100/1@signet           

pipkins@qmsseq.imagen.com (Jeff Pipkins) (07/06/90)

In article <552@csource.oz.au> david@csource.oz.au (david nugent) writes:
>In <141@qmsseq.imagen.com> pipkins@qmsseq.imagen.com (Jeff Pipkins) writes:
>
>>It is also possible to create a plain old .EXE file program that can be
>>invoked from the command line that can install itself as a device driver.
>>[deleted]
>
>
>DESQview comes with small utility called DEVICE.COM (around 600 bytes or
>so) which allows loading _some_ device drivers - namely those that don't
>link into the chain.  [deleted...]

It would not be any great feat to create a program that would load a
traditional character device driver and link it into the chain.  I'm not
sure what extra would be involved for doing the same with a block
device driver.  Also, the loaded device driver could be removed later.
The combination would give you a dynamically configurable system without
rebooting.  I've been asked for such programs many times, but not by
anyone who was willing to pay for it, and time allocated for charity
work is getting shorter all the time ;-)

Additional interesting functions are to rename devices that are already
loaded, and to rotate devices with the same name.  (If more than one
device driver is loaded with the same name, the one most recently
loaded is closer to the beginning of the chain, so the older one is no
longer used.)

TOMIII@MTUS5.BITNET (Thomas Dwyer III) (07/06/90)

Just what *is* involved in loading a block driver and linking it into
the chain?  What about removing drivers?  Can I just set the previous
driver to point to the following one, and then free some memory?  One
more thing - suppose I want to install a ram disk, and have my autoexec
copy some files there.  How can I determine the device number (ie A=0,
B=1, etc) of the ramdisk?  No, I do not want to boot once and start
guessing letters until I find it, and then code that into the autoexec.
I want to determine the device number(s) independant of hard drive
partitions, switch settings, and the order of my config.sys file.

My solution was to patch the init routine of the ramdisk I use now to
save the device number passed to it by DOS.  Then I track down the
driver in memory, and grab the number from a predetermined offset from
the device header.  Isn't there a better method that does not require
me to patch my driver(s)?

Thanks,
Thomas Dwyer III                            TOMIII   @ MTUS5.BITNET
Network Programmer                          DWYERIII @ MTUS5.BITNET
Computing Technology Services
Michigan Technological University

andrews@hpcupt1.HP.COM (Edward E. Andrews) (07/06/90)

> They must have realised the problem - as IBM DOS 3.x did not work in
> this way (neither did MS DOS 2.x).  All this information and more can
> found in Dave Williams Shareware "Dos Technial Information" manual.  A
           ---------------------------------------------------------
> must for any DOS sysprog (but UNIX is more fun anyway :-)

Where can this great manual be found?

dixon@sagittarius.crd.ge.com (walt dixon) (07/07/90)

In <90187.102930TOMIII@MTUS5.BITNET> Thomas Dwyer writes:

>Just what *is* involved in loading a block driver and linking it into
>the chain?

Block devices require patching two additional lists and updating the
current drive count. The listheads for both lists as well as the
drive count is in the data structure returned by the undocumented int
21h ah=52h. The two lists in question are the Current Directory Structure
(CDS) and the Device Control Block (DCB) chain.  The CDS is a contiguous
array whose size is determined by LASTDRIVE (or its default value).
The DCB is a linked list.  The CDS contains the DCB address and the
DCB contains the address of the device header.  This information is
documented in Chapter 10 of "The MS-DOS Papers", (Howard Sams, 1988).

>What about removing drivers?  Can I just set the previous
>driver to point to the following one, and then free some memory?

Removing drivers can be troublesome.  There is no absolutely fool-proof
method.  The issue here is one of tracking down device references.  Does
the driver support Open/Close operations?  Are there any open files?
Are there references to the device in the System File Table?  (FCB access
causes problems here.  Although there is a SFT for FCB access,  one
may not find information here.  The FCB maintains complete context
information).  What about cached disk blocks?  A reset will flush the
cache.  What about a program doing absolute reads/writes (int 25 and 26).
What about lower level access?  What about a program that determines
the driver address and then bypasses DOS? (Print.com does this).
The bottom line here is that removing a driver is tricky.  It may work
most of the time.

>  One
>more thing - suppose I want to install a ram disk, and have my autoexec
>copy some files there.  How can I determine the device number (ie A=0,
>B=1, etc) of the ramdisk?

The index into the current directory structure determines the drive
number.  If there is some way to identify the ram disk (eg it contains
the string RAM DISK following the device header,  it creates a RAM DISK
volume label,  it has a unique media code/structure),  then one can walk
the CDS looking for a particular driver.

[text deleted]

>My solution was to patch the init routine of the ramdisk I use now to
>save the device number passed to it by DOS.  Then I track down the
>driver in memory, and grab the number from a predetermined offset from
>the device header.  Isn't there a better method that does not require
>me to patch my driver(s)?

I've offered an alternative technique.  Whether it is better or not is
subjective.

Walt Dixon		{internet:	dixon@crd.ge.com	}
			{us mail:	ge crd			}
			{		po box 8		}
			{		schenectady, ny 12301	}
			{phone		518-387-5798 (W)	}
			{		518-875-6203 (H)	}
Walt Dixon dixon@crd.ge.com

pipkins@qmsseq.imagen.com (Jeff Pipkins) (07/10/90)

In article <90187.102930TOMIII@MTUS5.BITNET> TOMIII@MTUS5.BITNET (Thomas Dwyer III) writes:
>Just what *is* involved in loading a block driver and linking it into
>the chain?  What about removing drivers?  Can I just set the previous
>driver to point to the following one, and then free some memory?

Don't forget that there are other data structures you have to deal with
other than just the device driver chain.  Also, if you intercepted any
vectors, you must make sure that you still own them before you restore
them and release the memory.  Programs that restore vectors and leave
without checking first can cause some really weird stuff to happen later.

>One more thing - suppose I want to install a ram disk, and have my autoexec
>copy some files there.  How can I determine the device number (ie A=0,
>B=1, etc) of the ramdisk?  No, I do not want to boot once and start
>guessing letters until I find it, and then code that into the autoexec.
>I want to determine the device number(s) independant of hard drive
>partitions, switch settings, and the order of my config.sys file.
>
>My solution was to patch the init routine of the ramdisk I use now to
>save the device number passed to it by DOS.  Then I track down the
>driver in memory, and grab the number from a predetermined offset from
>the device header.  Isn't there a better method that does not require
>me to patch my driver(s)?

Character devices have a name field.  For block devices, the first byte
of this is used instead to tell how many units it supports.  By going
through the device driver chain and counting these, you should be able
to determine the drive letters associated with that driver.  Note that
if you inserted your driver anywhere but at the end of the chain, you
would change the drive letters of the drives supported by the other
drivers.  That would cause problems for using a technique like the one
you have just described.

--Jeff Pipkins
pipkins@imagen.com

Disclaimer: "I've already told you more than I know!"

dixon@sagittarius.crd.ge.com (walt dixon) (07/10/90)

In <143@qmsseq.imagen.com> Jeff Pipkins writes:

[initial text deleted]
>Character devices have a name field.  For block devices, the first byte
>of this is used instead to tell how many units it supports.  By going
>through the device driver chain and counting these, you should be able
>to determine the drive letters associated with that driver.
Despite what some documentation says,  this field is never used.  DOS
looks only at the unit count returned in the init request header.

>Note that
>if you inserted your driver anywhere but at the end of the chain, you
>would change the drive letters of the drives supported by the other
>drivers.  That would cause problems for using a technique like the one
>you have just described.

This is not true.  DOS maitains a data structure refered to as the
current directory structure (CDS).  This structure is a contiguous
array of entries for each drive;  its size is set by the LASTDRIVE
statement (or its default value).  The first entry corresponds to
drive A:,  etc.  In addition to status (joined, etc),  and then current
directory,  each entry condains a pointer to the Device Control Block
(DCB) for the device which in turn points to the Device Header.  Any
relationship between drive letter and position in the driver chain is
merely a conincedence.

Walt Dixon	{internet:	dixon@crd.ge.com	}
		{us mail:	ge crd			}
		{		po box 8		}
		{		schenectady, ny 12301	}
		{phone:		518-387-5798 (W)	}
		{		518-875-6203 (H)	}
Walt Dixon dixon@crd.ge.com