Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

595 lines
19 KiB

------------ Structures: -------------
What will be stored in the GPD binary file:
A Master table of contents with ptrs/offsets
to all Arrays and heaps.
typedef struct
{
DWORD size ;
DWORD parserVersion ;
DWORD totalBinarySize ;
DWORD firstSynthesizedFeature ; // zero based index
ARRAYREF FeaturesAndOptions ; // union of all feature, option and
// extra option data.
ARRAYREF AttributeTreeArray ;
ARRAYREF InvalidComboArray ;
ARRAYREF UIConstraintArray ;
ARRAYREF GroupTreeArray ;
ARRAYREF DCommandMap ;
ARRAYREF CommandArray ;
ARRAYREF ParameterArray ;
ARRAYREF ValueStack ;
ARRAYREF OperatorStack ;
ARRAYREF ListArray;
ARRAYREF FontArray;
ARRAYREF PriorityArray;
DGLOBAL_ATTRIBUTES Dglobals ;
} RAW_INFOHEADER ;
typedef struct
{
} DFEATURE_OPTIONS ;
String heap
Items that will not be stored:
Symbol Table: all symbols will be dereferenced - replaced by
indicies to structures.
Macro structures: all macros will have been expanded.
-------------------------------------------------------
Operations needed to create a snapshot for
UI and Control Module:
Take tree type info stored in FeaturesAndOptions and
distribute it among hundreds of Amanda's Feature and
option structures and extra option structures.
Synthesize a direct command table which maps
Unidrv command ID to index in the command array.
Create the SEQUENCED_CMDS lists and ptrs to each list
from OrderDependency data in the command array.
Init the actual Global attributes structure.
Init some fields in UIINFO and DRIVERINFO structs.
--
----------------------------------
priority array: an array of feature indicies, the
feature index occupying index 0 in the priority array
has highest priority. If there is a conflict between
two features the setting of the feature with lower
priority will be changed to resolve the conflict.
All synthesized features will have a higher priority
then any explicitly defined features.
----- installable features and options ----
Whenever an installable option or feature is
specified in the GPD file, the parser will create
a generic feature with two options "Installed" and
"Not Installed". This feature is also refered to as
an "Installable Configuration Feature" or a "synthesized
feature". These features are considered "printer sticky"
and the UI may display them at the appropriate time.
Each option or feature structure declared 'installable'
will have an index (InstallableFeatureIndex) that points to
the synthesized feature.
Correspondingly, each synthesized feature's
InstallableFeatureIndex will point back to the
Installable feature or the feature containing the
Installable option. If it is an installable
feature, the InstallableOptionIndex is set to -1,
if its an installable option, it is set to the
option index of the installable option.
---------------------------------------------
Notes:
If an option is marked *installable it will appear on
the selections UI as being enabled or grayed out.
If grayed out you can select it, else you cannot.
If all options in the feature are installable, there must
be one option that isn't. The default option will be
overridden if it points to an uninstalled option.
If a feature is marked installed, then all the options
enumerated there will be displayed just as if it were
a normal feature. If it is marked "Not Installed" then
the UI should consider the entire feature to be disabled.
There will still be a slot on the features array reserved
for its option selection however, but the control module
code should not access it.
------- UIConstraints Array --------
The GPD source format defines the following keywords
to express constraints between two or more options.
The parser stores this information in either a UICONSTRAINT
or INVALIDCOMBO structure depending on the number of items
needed to effect a constraint.
Note: some helper functions may ignore UICONSTRAINTS between
synthesized and non-synthesized features. These are generated
by the *InstalledConstraints and *NotInstalledConstraints
keywords.
*Constraints: selecting this option prevents/precludes
the following options from being selected.
UICONSTRAINT (mirrored)
*InvalidCombinations: some but not all of the following
options can be selected at the same time.
UICONSTRAINT (mirrored) or INVALIDCOMBO
*InvalidInstallableCombinations: some but not all of the following
feature/options can be INSTALLED at the same time.
This imposes constraints between 2 or more synthesized
(printer sticky) features
UICONSTRAINT (mirrored) or INVALIDCOMBO
*InstalledConstraints: if this synthesized
(printer sticky) feature is installed, this prevents/precludes
the following options from being selected.
UICONSTRAINT (one way: installed constrains option)
*NotInstalledConstraints: if this synthesized
(printer sticky) feature is NOT installed, this prevents/precludes
the following options from being selected.
UICONSTRAINT (one way: not installed constrains option)
the definition of an installable feature/option implies
one *NotInstalledConstraints: the installable option if not
installed will always constrain the option from being selected.
Constraints involving just two items are stored
in an list of UICONSTRAINT structures which is implemented
within an array. The list is referenced by the array index of
the first member of the list.
If a synthesized feature is set so it disables another
feature completely, this is indicated by having wOptionIndex
take on the value FEATURE_DISABLED. wOptionIndex may
also take on the value NONE_OR_FALSE to indicate
all options except 'none' or 'false' are disabled for this feature.
typedef struct
{
WORD wNextConstraintID ; // 0xffff signifies end of constraint list.
WORD wFeatureIndex; // may reference an installable feature
WORD wOptionIndex ;
} UICONSTRAINT ;
The Constraints field in the options structure
may take on the value 0xffff to indicate this option
does not constrain any other . Otherwise this field contains
the index to start of constraints list for this option. The list is
interpreted as follows: if this option is selected, the following
list of options CANNOT be selected.
Lists of INVALIDCOMBO structures are used to express constraints
involving 3 or more items before taking effect.
Each option structure contains an index to the
InvalidCombo array element which heads one or more
InvalidCombo lists involving this option. A value of 0xffff
indicates this option is not involved in any invalidCombinations.
The entire list of elements generated by following
the chain of wNextElements is the set of options that forms
the current invalidcombination. If there are other invalidcombinations
involving this option, they can be accessed by traversing wNextElements
until this option is found, then accessing wNewCombination to
find the start of chain defining a new invalidcombination.
The first element in the new list is not necessarily the
sought after option.
typedef struct
{
WORD wFeature; // may reference an installable feature
WORD wOption ;
WORD wNextElement ; // 0xffff signifies end of elements list.
WORD wNewCombination ; // 0xffff signifies no more constraints
// involving this element.
}INVALIDCOMBO ;
----------------------------------------------------
UIGroup: allowing the UI to group related features
together.
This is implemented via a tree:
typedef struct
{
STRINGREF GroupName;
WORD wNextGroup ; // if -1, indicates no more
// groups in this level.
WORD FirstSubGroup ; // index of another
// grouptree structure or
// actually contains a Feature index.
DWORD wFlags ; // UIGROUP_NOSUBGROUP if set
// FirstSubGroup contains a Feature index.
} GROUPTREE ;
This is a multi-level tree whose leaf nodes contain
feature indicies. Any UI group may contain a mixture
of subgroups and individual features.
A leaf node has:
No GroupName
wNextGroup contains the index of another Branch or leaf node
which has the same parent group has this leaf node.
FirstSubGroups contains a Feature index,
wFlags = UIGROUP_NOSUBGROUP
a branch node describes one UIGroup:
GroupName contains the name of the group
wNextGroup contains the index of another Branch or leaf node
which has the same parent group has this group
FirstSubGroup contains the index of a branch or leaf node
that is contained within this UIGroup.
wFlags is cleared.
lpGroupTree may be NULL if there are no grouping
constructs.
---- Attribute Trees ----------
A multi-level tree allows the value of an attribute
to be multi-valued depending on the option selected
one or more features. The DWORD in each attribute
points to the root of the tree. The nodes of the tree
point to the values possible for this attribute for
each option selected. Each feature occupies a different
level in the tree. The simplest tree contains one
element which has offsetmeans = VALUE.
Note: the tree may Not be organized based upon Features of the
type PICKMANY. This will cause problems if two options
are selected at the same time.
The tree is implemented by an array of structures
of the form:
typedef struct
{
WORD feature ;
WORD option ;
DWORD nextOption ; // index to another element
// holding branches to another
// option.
enum {NEXT_FEATURE, VALUE} offsetmeans ;
DWORD offset ; // If value of offsetmeans == NEXT_FEATURE
// 'offset' constains the
// index to another element holding branches
// representing a different feature.
// This occurs if the value of an attribute
// depends on the options selected for more
// than one feature.
// Otherwise 'offset' constains the offset
// in the heap to the actual VALUE.
// The code navigating the tree is
// responsible for applying the correct
// typecast when retrieving this data from
// the heap.
} TREE_BRANCH ;
Multiple trees may be defined within one array.
--- storage of default initializers ----
The root of the tree may contain a default initializer that
may be used by the parser to initialize the values of the attribute
in the absence of an explict initializer.
This is indicated by having 'feature' set to -1.
Each feature level in the tree may contain a default initializer
which is used if the current option is not explicitly enumerated
in the tree.
This is indicated by having 'option' set to -1.
The default option nodes reside at the end of the chain
of options. (nextOption = -1)
--------------------------------------------------------------------
Commands:
Commands are divided into two groups:
Synchronous and Asynchronous.
Synchronous commands are issued at one well defined point
in the job (ie paper selection). Asynchronous commands
are issued by the driver as the need arises (ie cursor movement).
Synchronous commands are accessed outside of the parser
via a linked list of
SEQUENCED_CMDS structures. Any command containing
a *OrderDependency keyword in its GPD definition is
considered a Synchronous command. If such a command
also happens to be a Unidrv recognized command, it
can be accessed both Synchronously and Asynchronously.
It should be noted since COMMAND constructs are 'relocatable'
the SEQUENCED_CMDS lists must be built dynamically using the
orderDependency fields of the commands applicable to the
current option configuration. If the command is an option
selection, the proper selection command will be referenced in
the SEQUENCED_CMDS list.
If the options are PICKMANY, the SEQUENCED_CMDS list will contain
all of the selected option invocation commands in the order
specified by the orderdependency information included with each
invocation command. If an installable feature is disabled,
no option selection commands for that feature will be
present in the list.
typedef struct
{
WORD IndexOfCommand ; // index to an element in the CommandArray
WORD NextInSequence ;
}
SEQUENCED_CMDS ;
Several linked lists co-exist in one array of SEQUENCED_CMDS.
Each section of the print job has an associated
list containing the commands that are to be emitted
at that time with each command ordered properly
relative to each other.
The fields dwJobSetupIndex ... dwJobFinishIndex in DRIVERINFO
contain the index to the first element of each
SEQUENCED_CMDS list corresponding to each section of the
print job.
Asynchronous commands are accessed by a command table.
Each Unidrv recognized command occupies a position (index)
in the table. The table is simply an array of DWORDS
where each DWORD points to an attribute tree. The nodes
of the attribute tree point to indicies in the
COMMAND_ARRAY.
When a 'snapshot' is taken, a new command table is created
that contains the index of the proper command in the
COMMAND_ARRAY instead of an index to an attribute tree.
DWORD raw_command_table[NUM_OF_UNIDRV_COMMANDS],
user_command_table[NUM_OF_UNIDRV_COMMANDS];
COMMAND CommandArray[num_of_command_variations] ;
typedef struct
{
STRINGREF invocation;
ORDERDEPENDENCY order ; // only used in construction of
// SEQUENCED_CMDS array.
DWORD dwCmdCallbackID ;
} COMMAND ;
typedef struct
{
WORD section ; // JOBSETUP, DOCSETUP, PAGESETUP etc.
WORD order ; // integer denoting relative order within each section.
}
ORDERDEPENDENCY
-------------------------------
Details of Command storage format.
The Command invocation is of the form one or more binary strings
and parameter references concatenated together in any order.
"binary string" %paramref "more binary string" ...
White spaces may separate the binary strings from the parameter
reference.
(macros will have been resolved before storing the command.)
A binary string is of the form: any set of binary bytes
enclosed by double quotes. Note the % acts to escape itself
and the " in a binary string. Thus "%%" is really (%)
"%"" is really (") , "%%%"" is really (%"), "%a" is just (a).
A % preceeding any other character is ignored. All bytes between
the opening and closing " are part of the binary string.
A paramref is a % followed by one or more decimal digits representing
an index to the array of PARAMETERS.
Multiple PARAMETERS may be embedded into a command.
typedef struct
{
BYTE bFormat; // The first letter after the %
BYTE bDigits; // only valid if format = 'd' or 'D'
DWORD dwFlags; // MIN_USED, MAX_USED, MAXREPEAT_USED
LONG lMin, lMax ; // look here only if dwFlags
DWORD lMaxRepeat ; // indicates field is used.
ARRAYREF ValuesStack; // may contain refs to StandardVariables
ARRAYREF OperatorStack; (Min, Max, +, -, *, / , MOD, HALT)
} PARAMETER
typedef struct
{
DWORD dwValue; // a integer constant or symbol index.
DWORD dwFlags ; // VALUE_SYMBOL indicates value
// is index to Control Module's state variable table.
} VALUE ;
The value stack is an array of VALUEs.
The ValueStack field in PARAMETER is an index to the
an element in the Value stack. This value is considered
the top of the stack, the value at index n+1 is next on the stack
and so forth. The count in the array ref indicates how
many stack elements will be used in the calculation.
This allows the user to copy the appropriate number of elements
to a temp working stack since altering the value stack
will render it unusable for subsequent command processing.
Also if the user wishes to emit floating pt values, the
temp stack should be able to hold floating pt formats
and perform floating pt math.
The Operator Stack is simply an array of words.
Each operator is assigned an enumeration value.
Each operator starting from the top of the stack is
used to operate on the contents of the Value stack until
the HALT operator is encountered. The result on the
top of the value stack is formatted according to the
the format specifier and emitted in the command stream.
----------------------------
Global Attributes: all attributes not stored within
fields in FEATURE, OPTION or other specialized structures
are stored in the global attribute structure.
All elements of the internal global attribute structure
are DWORDS.
The fields for attributes defined by the parser to be
'relocatable' (ie may appear within a *Switch construct)
are DWORDS which contain an index to an array of TREE_BRANCH
structures.
The DWORD for 'non-relocatable' attributes is an offset to the
actual value stored in the heap. The code reading the structure
is responsible for applying the correct typecast when retrieving
this data from the heap.
typedef struct
{
DWORD GPDSpecVersion ;
DWORD MasterUnits ;
DWORD MaxCopies ;
....
DWORD MaxPrintableArea ;
DWORD DefaultFont ;
} GLOBAL_ATTRIBUTES ;
In summary, the code accessing attribute structures must
know whether the attribute is 'relocatable' or not
and its data type. And whether the data is in a LIST()
format.
------------
SYMBOLS, CONSTANTS, and QUALIFIED_NAMES can be stored as a LIST()
of one or more elements. Since each type is actually stored
internally as a DWORD, the data type can only be determined
from the context. This also means all the elements in the LIST()
must be of the same data type.
The list will be implemented as an array of LIST_ELEMENT
structures. Each attribute that references a list will
have one DWORD that indexes the first element of the list.
Attributes that can take on either a list or single value
must be stored internally as a list.
typedef struct
{
DWORD data ;
DWORD nextItemInList; // -1 means end of list.
} LIST_ELEMENT ;
LIST_ELEMENT listArray[] ;
-----------------------------------------------
------ implementation details -------------------------------
Code emitting option invocations must check that the
Feature is Installed before emitting the strings.
Code checking for UI constraints may ignore entries
constraining Disabled Features.
Code evaluating all UI constraints must ignore effect
of Uninstalled Features.
Code displaying features must first check if the feature is
disabled.