|
Macintosh Development |
[Home]
[About Us]
[People]
[Information Systems]
[Kerberos for Macintosh]
[Applications]
[Miscellaneous Documentation]
This summer while working on allowing Macintoshes to print
authenticated over Athena printers, I experimented with writing
extensions, print drivers and user authentication methods. In this
document I will explain basic concepts and list good sources so that the
next person who has to write or modify one of these will not have to
spend the time I spent looking for sources and can jump straight to
writing code. For quick reference, I have listed all the sources I
recomend at the end. Happy coding!
--Alexandra Ellwood, August 18, 1993
Stand-alone Code Resources
Stand-alone code resources are similar to the 'CODE' resources
of applications, only instead of requiring the other resources (BNDLs,
FREFs, etc), they can be executed without application status. Here is
a list of the most common stand-alone code resources:
- DRVR
- Driver resource. Neccessary for drivers and desk accessories.
Called at system startup.
- CDEF
- Control definition function: defines a non-standard control.
Exectuted by an application; portable between applications.
- cdev
- Resource for control panels: called at system startup.
- INIT
- Initialization resource: called at system startup.
- MDEF
- Menu definition code.
- WDEF
- Window definition resource: defines a window.
- XCMD, XFNC
- Easily portable units of code for use with Hypercard.
- FKEY
- Executed when a control key combination is pressed.
A complete listing can be found in the Macintosh Technical Notes (TN
#256).
Without Application Status: the A5 World
There is a critical difference between an application and
stand-alone code: the A5 world. There is a detailed description
of the A5 world in the Technical Notes (#256), but in short,
the A5 world is the mechanism by which an application's memory
management and access to system globals is handled. Without
an A5 world, as is the case with most stand-alone code, the
program cannot access any system globals or call any toolbox
calls which use globals (a lot of QuickDraw functions are like
this).
The solution to this is to have the code save the present A5
world (since an application or the finder will probably be
running simultaneuosly), create its own A5 world, make calls
to globals, and then dispose of its A5 world and restore the
old one. In this way, the stand-alone code creates its own
temporary A5 world.
Technical Note #256 gives a good explanation and sample code for
how to do this. The important thing to remember is that
compilers will not check to see if an A5 world is neccessary.
Therefore, the error that will occur if you need one and don't
have one will happen during run time.
The program must also have an A5 world if its memory
consumption is to exceed 32k. This is because the A5 world
is the mechanism by which the segment loader (which divides
an application into 32k blocks of memory to accomodate the
68000 processor) controls memory management. Without it the
microprocessor will be overloaded. However, a stand-alone
code resource should never really have to exceed this limit.
If it is, then the job it is trying to do is too large.
Stand-alone code should perform small, specific tasks.
The most common thing for INITs and other stand-alone code
resources to do is to add a feature to some existing toolbox
call. They do this by trapping into the memory locations of
the toolbox calls and making their own calls before the
toolbox call executes. The easiest toolbox calls to trap are
those in ROM. A listing of which calls are in ROM and which
are not is in the TrapWords section in Think Reference.
Using NGetTrapAddress and NSetTrapAddress, you can get the
location of a system call in ROM, make a modified version
of it, and replace the call with your modified one.
Trapping commands not in ROM is more difficult, but in some
cases not impossible. For the managers whose routines are
not in ROM, there is usually one routine that is. In the
case of the Print Manager, this command is _PrGlue or
_Printing, depending on what Macintosh you are using (you
can use the Gestalt manager to determine this) -- _Printing
is more common and recent than _PrGlue. To trap any command,
such as PrOpen, you just trap _Printing and check the routine
selector on the stack to see which Print Manager call is
going to be executed. The routines and selectors are
described in Inside Macintosh Volume 5, p. 409. After this,
the process is the same.
However, before you do this, make sure that the trap exists
on the system you are running. If you want your program to
run on systems like the new PowerPC or really old systems,
then you must check to see if the trap exists there.
Think Reference describes a way of determining which trap to
use in the "Determining Whether a Trap is Available" section of
About Compatibility.
Print Drivers
Print Drivers are also stand-alone code resources, however, in
general, they are much more complicated than the average extension or
control panel. A print driver must allow the Print Manager to take
the data from the application and translate it into something that the
printer can use. The print driver must supply dialogs for printing,
page setup, and any other related dialogs it wishes to support. It
must also respond to calls from the Chooser asking what kind of
printer it supports and what it is (laserwriter, inkjet, dotmatrix,
etc). If the print driver translates to postscript (laserwriters do
this), then it must also implement Printer Access Protocol (PAP). This
is a series of calls (described in the PAP chapter of Inside AppleTalk)
which send postscript to the printer. The PAP code is contained within
PDEF 10 of postscript print drivers.
The easiest way to learn how a print driver works, is to read
Learning to Drive. This document is the best source for information
about print drivers, the chooser, and the print manager. If you are
writing your own print driver, some useful code to look at is the STD
File Saver. STD File Saver is a print driver which prints to a PICT
file. It is a good example of all the calls that a print driver is
required to support and is a good starting place for writing from
scratch. (It can also be a useful utility if the program you are
running doesn't support printing to PICTs.)
A Couple Things You Can't Do With Print Drivers
You can't use more than one print driver at once. The reason
is that all the Print Manager calls are not driver specific.
The Chooser tells the Print Manager which driver to use. The
Print Manager then opens this driver and uses it to print. If
the driver tries to open another driver and call it, it must
use Print Manager calls. Unfortunately the Print Manager
calls, aside from DrvrOpen and DrvrClose, do not specify
which driver to use. The Print Manager will use the driver
first opened (not the most recently opened one) to make the
calls from. In order to actually use a second driver you
would have to imitate the Print Manager and interpret the
print driver yourself. This is not impossible (see below)
but as writing the print driver itself is time consuming,
the extra coding to load another isn't worth it (look for
an easier way to do it).
You cannot depend on every application call a print driver
(or even the Print Manager) to print. Certain older
applictions and some of the more complex ones (eg: PageMaker)
*do not call* the Print Manager at all. Instead they come
with their own drivers and call those themselves in order to
print. Any extension trapping Print Manager calls or modified
print driver (this includes PAP) will not be called by these
applications. So if you are trying to modify the printing
process for all applications, be careful.
User Authentication Methods
User Authentication Methods (or UAMs) are another kind of
code that does not have application status. UAMs are used to authenticate
users of services over AppleTalk networks. They are presently implemented
for file servers and a method exists for print servers.
When a user tries to connect to a file server, the server requests
a UAM, at which point AppleShare looks in the AppleShare folder (if there
is one) for the correct type of UAM. If the UAM is not present, it will
refuse the connection. Otherwise, AppleShare will call the UAM. The UAM
will bring up a dialog asking for a username and password. When both have
been entered, the UAM will do any scrambling of the password and then
AppleShare will send the username and password to the server, which then
must interpret both and either let the user use the service or deny them
access. (Note that if the "Randnum Exchange" UAM is used, the password
does not actually go across the network -- see Inside AppleTalk 2ed. for
the protocol)
The print server UAM works similarly, however, instead of the UAM
being a separate piece of code, it is incorporated into the PAP code (see
print drivers above) within PDEF 10. While it may be presently incorporated
into some versions of the LaserWriter driver, this UAM cannot be guaranteed
to be on any driver. If it is not already on, you can modify the PDEF 10
resource (specifically the JMP to the call "PAPOpen") to add the features
described the UAM. Note, however, that any program which uses its own
drivers will never call this code, and therefore cannot be supported by
this method. (See trapping above).
The best way to learn how UAMs work is to read Inside AppleTalk.
A good example of UAM code is the University of Michigan's AFS Kerberos.
this is available via FTP from terminator.cc.umich.edu. This UAM
authenticates AFS servers, using the University of Michigan's version of
Kerberos (not the same as MIT's, but close). At some point, Apple will
also be releasing a document which is more specific on how file server
UAMs, like AFS Kerberos, should work. UAMs for print servers are basically
undocumented outside of Inside AppleTalk.
Sources
- Macintosh Technical Note #256: Contains a generic description
of stand-alone code resources and how to manipulate A5 worlds.
Also contains sample code for many of the more common stand-
alone code resources. I got this from the February '92 Apple
Developers' CD. (Dev.CD Feb 92:Developers Essentials:Technical
Docs:Macintosh Technical Notes:TN.251.300:TN.256.Stand-Alone-
Code)
- Think Reference: Most of the functions described above are
defined in detail by Think Reference, however, don't use it as
your only source. Some of the suggestions made in it are not
neccessarily the best way to do something.
- comp.sys.mac.programmer
and other related groups. This is
where I got the information on how to trap print commands
not in ROM. People in these groups are always helpful and
many may already tried what you are doing and can give you
hints and sample code.
- Learning To Drive: The most extensive freely accessible
document on writing print drivers anywhere. Can be found on
the May '93 Developer's CD. (Dev.CD May 93:Tool Chest:Graphics
& Imaging:Learning to Drive)
- STD File Saver: Sample Print Driver code. Can be found on
the May '93 Developer's CD (Dev.CD May 93:Tool Chest: Graphics
& Imaging:Print Drivers:STD File Saver)
- Inside AppleTalk: A comprehensive overview of how AppleTalk
works from the inside out. Not very detailed in some areas.
- AFS Kerberos: An example UAM for authenticating AFS servers.
Available via anonymous ftp from terminator.cc.umich.edu
(/unix/netatalk/afskerberos1.xxx.sit.hqx).
*comp.protocols.appletalk: A good place to ask questions about
appletalk. Is also the source of information about Columbia's
CAP server (a UNIX file/print server -- presently in version 6.0).
Questions or comments? Send mail to macdev@mit.edu
Last updated on $Date: 2003/11/18 21:58:21 $
Last modified by $Author: smcguire $