618 lines
35 KiB
HTML
618 lines
35 KiB
HTML
<html xmlns:v="urn:schemas-microsoft-com:vml"
|
||
xmlns:o="urn:schemas-microsoft-com:office:office"
|
||
xmlns:w="urn:schemas-microsoft-com:office:word"
|
||
xmlns:st1="urn:schemas-microsoft-com:office:smarttags"
|
||
xmlns="http://www.w3.org/TR/REC-html40">
|
||
|
||
<head>
|
||
<meta http-equiv=Content-Type content="text/html; charset=windows-1252">
|
||
<meta name=ProgId content=Word.Document>
|
||
<meta name=Generator content="Microsoft Word 10">
|
||
<meta name=Originator content="Microsoft Word 10">
|
||
<link rel=File-List href="mux_files/filelist.xml">
|
||
<title>MUX Intermediate Miniport Driver Help</title>
|
||
<o:SmartTagType namespaceuri="urn:schemas-microsoft-com:office:smarttags"
|
||
name="PlaceType"/>
|
||
<o:SmartTagType namespaceuri="urn:schemas-microsoft-com:office:smarttags"
|
||
name="PlaceName"/>
|
||
<o:SmartTagType namespaceuri="urn:schemas-microsoft-com:office:smarttags"
|
||
name="place"/>
|
||
<!--[if gte mso 9]><xml>
|
||
<w:WordDocument>
|
||
<w:SpellingState>Clean</w:SpellingState>
|
||
<w:GrammarState>Clean</w:GrammarState>
|
||
<w:BrowserLevel>MicrosoftInternetExplorer4</w:BrowserLevel>
|
||
</w:WordDocument>
|
||
</xml><![endif]--><!--[if !mso]><object
|
||
classid="clsid:38481807-CA0E-42D2-BF39-B33AF135CC4D" id=ieooui></object>
|
||
<style>
|
||
st1\:*{behavior:url(#ieooui) }
|
||
</style>
|
||
<![endif]-->
|
||
<style>
|
||
<!--
|
||
/* Font Definitions */
|
||
@font-face
|
||
{font-family:Verdana;
|
||
panose-1:2 11 6 4 3 5 4 4 2 4;
|
||
mso-font-charset:0;
|
||
mso-generic-font-family:swiss;
|
||
mso-font-pitch:variable;
|
||
mso-font-signature:536871559 0 0 0 415 0;}
|
||
@font-face
|
||
{font-family:"MS Sans Serif";
|
||
mso-font-alt:"Times New Roman";
|
||
mso-font-charset:0;
|
||
mso-generic-font-family:auto;
|
||
mso-font-pitch:auto;
|
||
mso-font-signature:3 0 0 0 1 0;}
|
||
/* Style Definitions */
|
||
p.MsoNormal, li.MsoNormal, div.MsoNormal
|
||
{mso-style-parent:"";
|
||
margin:0in;
|
||
margin-bottom:.0001pt;
|
||
mso-pagination:widow-orphan;
|
||
font-size:12.0pt;
|
||
font-family:"Times New Roman";
|
||
mso-fareast-font-family:"Times New Roman";
|
||
color:black;}
|
||
h2
|
||
{mso-margin-top-alt:auto;
|
||
margin-right:0in;
|
||
mso-margin-bottom-alt:auto;
|
||
margin-left:0in;
|
||
mso-pagination:widow-orphan;
|
||
mso-outline-level:2;
|
||
font-size:18.0pt;
|
||
font-family:"Times New Roman";
|
||
color:black;
|
||
font-weight:bold;}
|
||
h3
|
||
{mso-margin-top-alt:auto;
|
||
margin-right:0in;
|
||
mso-margin-bottom-alt:auto;
|
||
margin-left:0in;
|
||
mso-pagination:widow-orphan;
|
||
mso-outline-level:3;
|
||
font-size:13.5pt;
|
||
font-family:"Times New Roman";
|
||
color:black;
|
||
font-weight:bold;}
|
||
h4
|
||
{mso-margin-top-alt:auto;
|
||
margin-right:0in;
|
||
mso-margin-bottom-alt:auto;
|
||
margin-left:0in;
|
||
mso-pagination:widow-orphan;
|
||
mso-outline-level:4;
|
||
font-size:12.0pt;
|
||
font-family:"Times New Roman";
|
||
color:black;
|
||
font-weight:bold;}
|
||
a:link, span.MsoHyperlink
|
||
{color:blue;
|
||
text-decoration:underline;
|
||
text-underline:single;}
|
||
a:visited, span.MsoHyperlinkFollowed
|
||
{color:purple;
|
||
text-decoration:underline;
|
||
text-underline:single;}
|
||
p
|
||
{mso-margin-top-alt:auto;
|
||
margin-right:0in;
|
||
mso-margin-bottom-alt:auto;
|
||
margin-left:0in;
|
||
mso-pagination:widow-orphan;
|
||
font-size:12.0pt;
|
||
font-family:"Times New Roman";
|
||
mso-fareast-font-family:"Times New Roman";
|
||
color:black;}
|
||
pre
|
||
{margin:0in;
|
||
margin-bottom:.0001pt;
|
||
mso-pagination:widow-orphan;
|
||
tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt;
|
||
font-size:10.0pt;
|
||
font-family:"Courier New";
|
||
mso-fareast-font-family:"Courier New";
|
||
color:black;}
|
||
span.SpellE
|
||
{mso-style-name:"";
|
||
mso-spl-e:yes;}
|
||
span.GramE
|
||
{mso-style-name:"";
|
||
mso-gram-e:yes;}
|
||
@page Section1
|
||
{size:8.5in 11.0in;
|
||
margin:1.0in 1.25in 1.0in 1.25in;
|
||
mso-header-margin:.5in;
|
||
mso-footer-margin:.5in;
|
||
mso-paper-source:0;}
|
||
div.Section1
|
||
{page:Section1;}
|
||
-->
|
||
</style>
|
||
<!--[if gte mso 10]>
|
||
<style>
|
||
/* Style Definitions */
|
||
table.MsoNormalTable
|
||
{mso-style-name:"Table Normal";
|
||
mso-tstyle-rowband-size:0;
|
||
mso-tstyle-colband-size:0;
|
||
mso-style-noshow:yes;
|
||
mso-style-parent:"";
|
||
mso-padding-alt:0in 5.4pt 0in 5.4pt;
|
||
mso-para-margin:0in;
|
||
mso-para-margin-bottom:.0001pt;
|
||
mso-pagination:widow-orphan;
|
||
font-size:10.0pt;
|
||
font-family:"Times New Roman";}
|
||
</style>
|
||
<![endif]-->
|
||
<meta name=Template content="C:\Program Files\Microsoft Office\Office\html.dot">
|
||
<!--[if gte mso 9]><xml>
|
||
<o:shapedefaults v:ext="edit" spidmax="7170"/>
|
||
</xml><![endif]--><!--[if gte mso 9]><xml>
|
||
<o:shapelayout v:ext="edit">
|
||
<o:idmap v:ext="edit" data="1"/>
|
||
</o:shapelayout></xml><![endif]-->
|
||
</head>
|
||
|
||
<body bgcolor=white lang=EN-US link=blue vlink=purple style='tab-interval:.5in'>
|
||
|
||
<div class=Section1>
|
||
|
||
<h2><a name=MYSAMPLE><span style='font-family:Verdana'>
|
||
|
||
<!doctype HTML>
|
||
|
||
<! ---------------- Snip Snip ---------------- >MUX.SYS - Sample NDIS MUX
|
||
Intermediate Driver</span></a><span style='font-family:Verdana'><o:p></o:p></span></h2>
|
||
|
||
<h3><span style='font-family:Verdana'>SUMMARY<o:p></o:p></span></h3>
|
||
|
||
<p><st1:place><st1:PlaceName><b><span style='font-family:Verdana'>MUX</span></b></st1:PlaceName><b><span
|
||
style='font-family:Verdana'> </span></b><st1:PlaceName><b><span
|
||
style='font-family:Verdana'>Intermediate</span></b></st1:PlaceName><b><span
|
||
style='font-family:Verdana'> </span></b><st1:PlaceType><b><span
|
||
style='font-family:Verdana'>Miniport</span></b></st1:PlaceType></st1:place><b><span
|
||
style='font-family:Verdana'> Driver<o:p></o:p></span></b></p>
|
||
|
||
<p><span style='font-size:10.0pt;font-family:Verdana'>The MUX Intermediate
|
||
Miniport (IM) driver is an NDIS 5 driver that demonstrates the operation of an
|
||
<EFBFBD>N<span class=GramE>:1</span><EFBFBD> MUX driver, i.e. one which creates multiple
|
||
virtual network devices on top of a single lower adapter. Protocols bind to
|
||
these virtual adapters as if they are real adapters. Examples of </span><st1:place><st1:PlaceName><span
|
||
style='font-size:10.0pt;font-family:Verdana'>Intermediate</span></st1:PlaceName><span
|
||
style='font-size:10.0pt;font-family:Verdana'> </span><st1:PlaceType><span
|
||
style='font-size:10.0pt;font-family:Verdana'>Miniport</span></st1:PlaceType></st1:place><span
|
||
style='font-size:10.0pt;font-family:Verdana'> drivers that can use this
|
||
framework are Virtual LAN (VLAN) drivers.<o:p></o:p></span></p>
|
||
|
||
<p><span style='font-size:10.0pt;font-family:Verdana'>This sample implements
|
||
IEEE 802.1Q VLAN tagging, which is enabled by changing the default VLAN ID to a
|
||
non-zero valid value (see <20>Configuring VLANs<4E> below).<o:p></o:p></span></p>
|
||
|
||
<p><b><span style='mso-bidi-font-size:10.0pt;font-family:Verdana'>Operation<o:p></o:p></span></b></p>
|
||
|
||
<p><span style='font-size:10.0pt;font-family:Verdana'>The driver binds to
|
||
Ethernet (NdisMedium802_3) adapters as a protocol, and exposes one or more
|
||
virtual Ethernet devices over each lower adapter, based on its configuration.
|
||
The term <20>VELAN<41> is used to denote a Virtual Ethernet LAN adapter implemented
|
||
by this driver.<o:p></o:p></span></p>
|
||
|
||
<p><span style='font-size:10.0pt;font-family:Verdana'>When it binds to a lower
|
||
adapter, MUX reads the standard <20>UpperBind<6E> key to obtain a list of VELANs
|
||
configured over this adapter. For each such VELAN, it calls <span class=GramE>NdisIMInitializeDeviceInstanceEx(</span>)
|
||
to instantiate the NDIS miniport for the VELAN. NDIS then calls the driver<65>s
|
||
MiniportInitialize (<i>MPInitialize</i>) routine to start the VELAN miniport.<o:p></o:p></span></p>
|
||
|
||
<p><span style='font-size:10.0pt;font-family:Verdana'>The MUX driver supports
|
||
configuring the MAC address for each VELAN miniport using the standard
|
||
<EFBFBD>NetworkAddress<EFBFBD> key that it reads from its MiniportInitialize routine. If this
|
||
is not configured, it computes a <20>locally significant<6E> MAC address for the
|
||
VELAN using the MAC address of the lower adapter. The MUX driver sets its lower
|
||
adapter to promiscuous mode in order to be able to receive frames directed to
|
||
any of the VELAN MAC addresses. <span class=GramE>However it does implement
|
||
packet-filtering (and multicast address filtering) logic for all its VELAN
|
||
miniports so that it only passes up relevant frames on each VELAN.</span> This
|
||
aspect of the driver may be modified if, for example, your driver design uses
|
||
the same MAC address as that of the lower adapter on all VELANs. With such a
|
||
modification, it is not required to set the lower adapter to promiscuous mode
|
||
and incur the costs of receiving all packets on the network.<o:p></o:p></span></p>
|
||
|
||
<p><span style='font-size:10.0pt;font-family:Verdana'>It supports dynamic
|
||
addition and deletion of VELANs in conjunction with <span class=GramE>its</span>
|
||
notify object (related sample). If a VELAN is deleted, the virtual device
|
||
corresponding to the VELAN is stopped and removed, which in turn results in
|
||
NDIS halting the miniport instance for the VELAN (see <i>MPHalt</i>). If a
|
||
VELAN is added, NDIS sends a global reconfiguration event to the protocol edge
|
||
of this driver. The handler function for this event, PtPNPHandler, goes through
|
||
all lower adapters to see if any new VELANs have been added, i.e. if any of the
|
||
<EFBFBD>UpperBind<EFBFBD> keys have been modified.<o:p></o:p></span></p>
|
||
|
||
<p><span style='font-size:10.0pt;font-family:Verdana'>Since the driver
|
||
implements a virtual device, it does not simply pass through most NDIS
|
||
queries/sets. It keeps its own device view that is reflected in its responses
|
||
to queries/sets. However it does pass through queries/sets for certain OIDs
|
||
that are best handled by the lower adapter driver. <o:p></o:p></span></p>
|
||
|
||
<p><span style='font-size:10.0pt;font-family:Verdana'>The driver supports Power
|
||
Management in the sense that it allows Wake-On-LAN and related functionality,
|
||
if supported by the lower adapter, to continue to function. It does so by
|
||
appropriately forwarding OID_PNP_XXX queries/sets to the lower adapter. <o:p></o:p></span></p>
|
||
|
||
<p><b style='mso-bidi-font-weight:normal'><span style='font-family:Verdana'>IEEE
|
||
802.1Q VLAN Operation<o:p></o:p></span></b></p>
|
||
|
||
<p><span style='font-size:10.0pt;font-family:Verdana'>The driver supports
|
||
configuring a VLAN ID on each VELAN. It then inserts a tag header containing
|
||
this VLAN ID on all outgoing frames. For incoming frames that contain a tag
|
||
header, it verifies that a matching VLAN ID is present before indicating it up
|
||
to protocols. It removes the tag header, if present, from all indicated frames.
|
||
In all cases, received frames that do not contain tag headers are always handed
|
||
up to protocols.<o:p></o:p></span></p>
|
||
|
||
<p><span style='font-size:10.0pt;font-family:Verdana'>With the default
|
||
configured VLAN ID of zero, the driver does not insert tag header information
|
||
on sent packets, except for sent packets that contain non-zero Ieee8021QInfo
|
||
per-packet information, for which the driver does insert corresponding tag
|
||
headers. Receive-side filtering on VLAN ID is enabled only with a non-zero
|
||
configured VLAN ID, in which case only received frames containing a matching
|
||
VLAN ID are passed up. With the default configured VLAN ID of zero, the driver
|
||
does not check the VLAN ID on received frames.<o:p></o:p></span></p>
|
||
|
||
<h3><span style='font-family:Verdana'>BUILDING THE SAMPLE<o:p></o:p></span></h3>
|
||
|
||
<p><span style='font-size:10.0pt;font-family:Verdana'>Run the <b>build</b>
|
||
command from this directory to build the sample<6C>it creates the binary mux.sys.
|
||
To disable IEEE VLAN support, comment out the following line in the sources
|
||
file before building:<o:p></o:p></span></p>
|
||
|
||
<p><span style='font-size:10.0pt;font-family:Verdana'>C_DEFINES=$(C_DEFINES)
|
||
<EFBFBD>DIEEE_VLAN_SUPPORT=1<o:p></o:p></span></p>
|
||
|
||
<p><span style='font-size:10.0pt;font-family:Verdana'>To install this driver on
|
||
Windows<EFBFBD> codename Whistler, use the MUX sample notification object and INFs,
|
||
also found in this DDK.<o:p></o:p></span></p>
|
||
|
||
<h3><span style='font-family:Verdana'>INSTALLING THE SAMPLE<o:p></o:p></span></h3>
|
||
|
||
<p><span style='font-size:10.0pt;font-family:Verdana'>MUX is installed as a
|
||
protocol (called <20>Sample <span class=SpellE>Mux</span>-IM Protocol Driver<65> in
|
||
the supplied INFs/notification object). To install, follow the steps below.<o:p></o:p></span></p>
|
||
|
||
<p><span style='font-size:10.0pt;font-family:Verdana'>Prepare a floppy disk (or
|
||
installation directory) that contains these files: <span class=SpellE>muxp.inf</span>,
|
||
<span class=SpellE>mux_mp.inf</span>, mux.sys and mux.dll (notification object
|
||
DLL, built in this DDK at network\<span class=SpellE>ndis\mux\notifyob</span>).<o:p></o:p></span></p>
|
||
|
||
<p><span style='font-size:10.0pt;font-family:Verdana'>On the desktop,
|
||
right-click the <b>My Network Places</b> icon and choose <b>Properties</b>. <o:p></o:p></span></p>
|
||
|
||
<p><span style='font-size:10.0pt;font-family:Verdana'>Right-click on the
|
||
relevant Local Area Connection icon and choose <b>Properties</b>. <o:p></o:p></span></p>
|
||
|
||
<p><span style='font-size:10.0pt;font-family:Verdana'>Click <b>Install</b>,
|
||
then <b>Protocol</b>, then <b>Add</b>, <span class=GramE>then</span> <b>Have
|
||
Disk</b>. <o:p></o:p></span></p>
|
||
|
||
<p><span style='font-size:10.0pt;font-family:Verdana'>Browse to the
|
||
drive/directory containing the files listed above. Click <b>OK</b>. This should
|
||
show <20>Sample <span class=SpellE>Mux</span>-IM Protocol Driver<65> in a list of
|
||
Network Protocols. Highlight this and click <b>OK</b>. This should install the
|
||
MUX driver. <o:p></o:p></span></p>
|
||
|
||
<p><span style='font-size:10.0pt;font-family:Verdana'>Click <b>OK</b> or <span
|
||
class=GramE><b>Yes</b></span> each time the system prompts with a warning
|
||
regarding installation of unsigned files. This is necessary because binaries
|
||
generated via the DDK build environment are not signed.<o:p></o:p></span></p>
|
||
|
||
<p><span style='font-size:10.0pt;font-family:Verdana'>Two .INF files are needed
|
||
rather than one because MUX is installed both as a protocol and a miniport.<o:p></o:p></span></p>
|
||
|
||
<p><b style='mso-bidi-font-weight:normal'><span style='font-family:Verdana'>Configuring
|
||
VLANs<o:p></o:p></span></b></p>
|
||
|
||
<p><span style='font-size:10.0pt;font-family:Verdana'>The VLAN ID for each
|
||
VELAN (virtual miniport) can be configured as follows. Right-click on the
|
||
virtual miniport Local Area Connection icon and choose <b style='mso-bidi-font-weight:
|
||
normal'>Properties</b>. Click on the <b style='mso-bidi-font-weight:normal'>Configure</b>
|
||
button to bring up the Device Manager UI for the virtual device. Select the <b
|
||
style='mso-bidi-font-weight:normal'>Advanced</b> property sheet <20> this should
|
||
contain a <20>VLAN ID<49> parameter that is configurable to the desired VLAN ID.
|
||
Choosing a value of 0 (zero) disables receive-side filtering based on VLAN ID.<o:p></o:p></span></p>
|
||
|
||
<h3><span style='font-family:Verdana'>CODE TOUR<o:p></o:p></span></h3>
|
||
|
||
<h4><span style='font-family:Verdana'>File Manifest<o:p></o:p></span></h4>
|
||
|
||
<pre><u>File<span style='mso-tab-count:2'><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> </span>Description<o:p></o:p></u></pre><pre><o:p> </o:p></pre><pre><span
|
||
class=SpellE>Makefile</span><span style='mso-tab-count:1'><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> </span>Used during compilation to create the object and sys files</pre><pre>Miniport.c<span
|
||
style='mso-tab-count:1'><EFBFBD><EFBFBD><EFBFBD><EFBFBD> </span>Miniport related routines for the MUX driver</pre><pre><span
|
||
class=SpellE>Mux.c</span><span style='mso-tab-count:2'><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> </span>DriverEntry routine and any routines common to the MUX miniport and protocol </pre><pre><span
|
||
class=SpellE>Mux.h</span><span style='mso-tab-count:2'><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> </span>Prototypes of all functions and data structures used by the MUX driver</pre><pre>Mux.htm<span
|
||
style='mso-tab-count:2'><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> </span>Documentation for the MUX driver (this file)</pre><pre><span
|
||
class=SpellE>Mux.rc</span><span style='mso-tab-count:2'><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> </span>Resource <span
|
||
class=GramE>file</span> for the MUX driver</pre><pre><span class=SpellE>Muxp.inf</span><span
|
||
style='mso-tab-count:1'><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> </span>Installation INF for the service (protocol side installation)</pre><pre><span
|
||
class=SpellE>Mux_mp.inf</span><span style='mso-tab-count:1'><EFBFBD><EFBFBD><EFBFBD><EFBFBD> </span>Installation INF for the miniport (virtual device installation)</pre><pre><span
|
||
class=SpellE>Precomp.h</span><span style='mso-tab-count:1'><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> </span><span
|
||
class=SpellE>Precompile</span> header file</pre><pre><span class=SpellE>Protocol.c</span><span
|
||
style='mso-tab-count:1'><EFBFBD><EFBFBD><EFBFBD><EFBFBD> </span>Protocol related routines for the MUX driver</pre><pre>Sources<span
|
||
style='mso-tab-count:2'><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> </span>List of source files that are compiled and linked to create the MUX driver. This can be modified to create binaries that operate on previous Windows versions (e.g. Windows 2000).</pre>
|
||
|
||
<h4 style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'><span
|
||
style='font-family:Verdana'>Programming Tour<o:p></o:p></span></h4>
|
||
|
||
<p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'><span
|
||
style='font-size:10.0pt;font-family:Verdana'>When it loads, i.e. from its <i>DriverEntry</i>
|
||
function, the MUX driver registers as an Intermediate miniport driver and as a
|
||
protocol, in that order.<o:p></o:p></span></p>
|
||
|
||
<p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'><b><span
|
||
style='font-size:10.0pt;font-family:Verdana'>Binding and VELAN Creation<o:p></o:p></span></b></p>
|
||
|
||
<p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'><span
|
||
style='font-size:10.0pt;font-family:Verdana'>NDIS calls MUX<55>s BindAdapter
|
||
function, <i>PtBindAdapter</i>, for each underlying NDIS adapter to which it is
|
||
configured to bind. This function allocates an ADAPT structure to represent the
|
||
lower adapter, and calls NdisOpenAdapter to set up a binding to it. In the
|
||
context of BindAdapterHandler, after successfully opening a binding to the
|
||
underlying adapter, the driver queries the reserved keyword
|
||
"UpperBindings" to get a list of device names for the virtual
|
||
adapters that this particular binding is to expose <20> see <i>PtBootStrapVElans</i>
|
||
for more details. Note that the MUX driver does not create bindings (i.e. call
|
||
NdisOpenAdapter) from any context other than its BindAdapter function <20> this is
|
||
recommended behavior for all drivers of this type.<o:p></o:p></span></p>
|
||
|
||
<p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'><span
|
||
style='font-size:10.0pt;font-family:Verdana'>For each device name specified in
|
||
the <20>UpperBindings<67> key, the MUX driver allocates a VELAN data structure to
|
||
represent the virtual miniport, calls NdisIMInitializeDeviceInstanceEx. In
|
||
response, NDIS eventually calls the MUX miniport<72>s MiniportInitialize entry
|
||
point, <i>MPInitialize</i>, for each VELAN. After <i>MPInitialize</i>
|
||
successfully returns, NDIS takes care of getting upper-layer protocols to bind
|
||
to the newly created virtual adapter(s).<o:p></o:p></span></p>
|
||
|
||
<p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'><b><span
|
||
style='font-size:10.0pt;font-family:Verdana'>Unbinding and Halting</span></b><span
|
||
style='font-size:10.0pt;font-family:Verdana'><o:p></o:p></span></p>
|
||
|
||
<p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'><span
|
||
style='font-size:10.0pt;font-family:Verdana'>NDIS calls MUX<55>s UnbindAdapter
|
||
handler, <i>PtUnbindAdapter</i>, to request it to unbind from a lower adapter.
|
||
In processing this, MUX calls NdisIMDeInitializeDeviceInstance for each VELAN
|
||
instantiated on the indicated adapter <20> see <i>PtStopVElan</i> for details.
|
||
This call results in NDIS first unbinding any protocols bound to the indicated
|
||
VELAN, and then calling the MiniportHalt routine, <i>MPHalt</i>, for that
|
||
VELAN. <i>MPHalt</i> waits for any outstanding receives/sends on the VELAN to
|
||
finish before unlinking the VELAN from the ADAPT.<o:p></o:p></span></p>
|
||
|
||
<p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'><i><span
|
||
style='font-size:10.0pt;font-family:Verdana'>PtUnbindAdapter</span></i><span
|
||
style='font-size:10.0pt;font-family:Verdana'> itself blocks until all VELANs
|
||
associated with the ADAPT structure have been unlinked from it. This is to make
|
||
sure that no thread running in the context of a miniport-edge entry point for a
|
||
VELAN will ever access an invalid lower binding handle. Once all VELANs have
|
||
been unlinked, <i>PtUnbindAdapter</i> closes the lower binding by calling
|
||
NdisCloseAdapter. Note that the MUX driver does not close its lower binding
|
||
from any context other than its UnbindAdapter function <20> this is recommended
|
||
behavior for all drivers of this type.<o:p></o:p></span></p>
|
||
|
||
<p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'><i><span
|
||
style='font-size:10.0pt;font-family:Verdana'>MPHalt</span></i><span
|
||
style='font-size:10.0pt;font-family:Verdana'> may also be called if the VELAN
|
||
device is disabled, e.g. from the Network Connections Folder. There is no
|
||
special code within <i>MPHalt</i> to handle this condition. However, <i>PtUnbindAdapter</i>
|
||
takes care to not attempt to deinitialize a VELAN miniport (via
|
||
NdisIMDeInitializeDeviceInstance) that has already been halted.<o:p></o:p></span></p>
|
||
|
||
<p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'><b><span
|
||
style='font-size:10.0pt;font-family:Verdana'>Handling Queries<o:p></o:p></span></b></p>
|
||
|
||
<p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'><i><span
|
||
style='font-size:10.0pt;font-family:Verdana'>MPQueryInformation</span></i><span
|
||
style='font-size:10.0pt;font-family:Verdana'> is the MUX driver<65>s function that
|
||
handles queries for OID values on VELAN miniports. Most of the <20>Ethernet<65> type
|
||
information for the virtual miniport is stored in the VELAN structure itself,
|
||
and the driver returns information from this structure. The queries that are
|
||
forwarded are OID_GEN_MEDIA_CONNECT_STATUS, OID_PNP_CAPABILITIES and
|
||
OID_PNP_WAKE_UP_PATTERN_LIST. See <20>Handling Power Management<6E> below for more
|
||
information about the latter two OIDs.<i><o:p></o:p></i></span></p>
|
||
|
||
<p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'><b><span
|
||
style='font-size:10.0pt;font-family:Verdana'>Handling Sets</span></b><span
|
||
style='font-size:10.0pt;font-family:Verdana'><o:p></o:p></span></p>
|
||
|
||
<p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'><i><span
|
||
style='font-size:10.0pt;font-family:Verdana'>MPSetInformation</span></i><span
|
||
style='font-size:10.0pt;font-family:Verdana'> handles setting OID values on
|
||
VELAN miniports. Data management OIDs handled by the MUX driver are
|
||
OID_802_3_MULTICAST_LIST and OID_GEN_CURRENT_PACKET_FILTER. The multicast list
|
||
is handled entirely within the MUX driver <20> it just stores the set of multicast
|
||
addresses in the VELAN structure, for reference during receive-side data processing.
|
||
The packet filter is handled in a different way <20> the MUX driver combines the
|
||
packet filter settings (bitwise OR) of all VELANs associated with the same
|
||
lower adapter. If the combined packet filter is non-zero, MUX sends a Set
|
||
request with a value of NDIS_PACKET_TYPE_PROMISCUOUS for
|
||
OID_GEN_CURRENT_PACKET_FILTER to start receives on the lower adapter. If the
|
||
combined packet filter is zero, MUX sets the lower adapter<65>s packet filter to 0
|
||
(turns off all receives if there aren<65>t any interested protocols).<o:p></o:p></span></p>
|
||
|
||
<p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'><span
|
||
style='font-size:10.0pt;font-family:Verdana'>Note that setting the lower
|
||
adapter to promiscuous mode is only done here in order to be able to receive <span
|
||
class=SpellE>unicast</span> frames directed to multiple MAC addresses. If, for
|
||
example, all VELANs are assigned the same MAC address (which is identical to
|
||
the address of the lower adapter), then the MUX driver should only pass down
|
||
the combined (bitwise OR) setting of packet filter settings of all VELANs.<o:p></o:p></span></p>
|
||
|
||
<p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'><span
|
||
style='font-size:10.0pt;font-family:Verdana'>Some power management OIDs are
|
||
forwarded to the lower miniport. See <20>Handling Power Management<6E> below for details.
|
||
<o:p></o:p></span></p>
|
||
|
||
<p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'><b><span
|
||
style='font-size:10.0pt;font-family:Verdana'>Sending Data<o:p></o:p></span></b></p>
|
||
|
||
<p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'><span
|
||
style='font-size:10.0pt;font-family:Verdana'>Data sent down on a VELAN miniport
|
||
is forwarded to the lower adapter. The MUX driver itself does not generate any
|
||
data of its own. The MUX driver allocates a new NDIS_PACKET for each packet
|
||
passed to its <i>MPSendPackets</i> function, and saves a pointer to the
|
||
original NDIS_PACKET in the reserved area of the packet structure. When the
|
||
lower adapter completes the send (<i>PtSendComplete</i>), MUX picks up the
|
||
original packet and calls NdisMSendComplete to complete the original send
|
||
request.<o:p></o:p></span></p>
|
||
|
||
<p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'><span
|
||
style='font-size:10.0pt;font-family:Verdana'>If a non-zero VLAN ID is
|
||
configured for the VELAN, and/or the packet has non-zero Ieee8021QInfo
|
||
per-packet information, then the MUX driver inserts an NDIS buffer containing a
|
||
tag header to the front of the packet before sending it down <20> see function <i
|
||
style='mso-bidi-font-style:normal'>MPHandleSendTagging</i> for details.<o:p></o:p></span></p>
|
||
|
||
<p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'><b><span
|
||
style='font-size:10.0pt;font-family:Verdana'>Receiving Data<o:p></o:p></span></b></p>
|
||
|
||
<p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'><span
|
||
style='font-size:10.0pt;font-family:Verdana'>Data received from a lower adapter
|
||
is indicated up on zero or more VELANs. The <i>PtReceivePacket</i> or <i>PtReceive</i>
|
||
function is called for each packet received from the lower adapter. In both
|
||
cases, the received data is checked for matches with the packet filter and
|
||
multicast list for each VELAN associated with the adapter (see <i>PtMatchPacketToVElan</i>).
|
||
Whenever a match is found, a new NDIS_PACKET is allocated and set to point to
|
||
the received data. A pointer to the original received packet (if any) is also
|
||
stored in the new packet<65>s reserved area. This packet is indicated up via
|
||
NdisMIndicateReceivePacket to all interested protocols on that VELAN. <o:p></o:p></span></p>
|
||
|
||
<p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'><span
|
||
style='font-size:10.0pt;font-family:Verdana'>The driver<65>s <i>MPReturnPacket</i>
|
||
function is called either by NDIS or by MUX itself when protocols are done with
|
||
a received packet. This function returns the original packet indicated by the
|
||
lower driver, if any, by calling NdisReturnPackets.<o:p></o:p></span></p>
|
||
|
||
<p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'><span
|
||
style='font-size:10.0pt;font-family:Verdana'>The driver indicates up received
|
||
frames that do not have an IEEE 802.1Q tag header in them <20> see function <i
|
||
style='mso-bidi-font-style:normal'>PtHandleRcvTagging</i>. It always strips off
|
||
tag headers, if present, on received frames. If a non-zero VLAN ID is
|
||
configured, then it checks received frames that contain tag headers for
|
||
matching VLAN Ids <20> only matching frames are indicated up to protocols. Any
|
||
VLAN/priority information present in incoming frames is copied to per-packet
|
||
information fields of indicated NDIS_PACKET structures.<o:p></o:p></span></p>
|
||
|
||
<p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'><b><span
|
||
style='font-size:10.0pt;font-family:Verdana'>Status Indications</span></b><span
|
||
style='font-size:10.0pt;font-family:Verdana'><o:p></o:p></span></p>
|
||
|
||
<p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'><span
|
||
style='font-size:10.0pt;font-family:Verdana'>The only status indications that
|
||
are forwarded up by MUX are media connect status indications. See <i>PtStatus</i>
|
||
for more details.<o:p></o:p></span></p>
|
||
|
||
<p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'><b><span
|
||
style='font-size:10.0pt;font-family:Verdana'>Handling Power Management</span></b><span
|
||
style='font-size:10.0pt;font-family:Verdana'><o:p></o:p></span></p>
|
||
|
||
<p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'><span
|
||
style='font-size:10.0pt;font-family:Verdana'>During initialization (<i>MPInitialize</i>),
|
||
the MUX miniport sets the attribute <i>NDIS_ATTRIBUTE_NO_HALT_ON_SUSPEND</i> in
|
||
its call to NdisMSetAttributesEx. When the MUX miniport is requested to report
|
||
its Plug and Play capabilities (OID_PNP_CAPABILITIES), the MUX miniport
|
||
forwards the request to the underlying miniport. If this request succeeds, then
|
||
the MUX miniport overwrites the following fields before successfully completing
|
||
the original request: <o:p></o:p></span></p>
|
||
|
||
<p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'><span
|
||
style='font-size:10.0pt;font-family:Verdana'>NDIS_DEVICE_POWER_STATE<span
|
||
style='mso-tab-count:1'><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> </span>MinMagicPacketWakeUp =
|
||
NdisDeviceStateUnspecified;<o:p></o:p></span></p>
|
||
|
||
<p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'><span
|
||
style='font-size:10.0pt;font-family:Verdana'>NDIS_DEVICE_POWER_STATE<span
|
||
style='mso-tab-count:1'><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> </span><span class=SpellE>MinPatternWakeUp</span>=
|
||
NdisDeviceStateUnspecified;<o:p></o:p></span></p>
|
||
|
||
<p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'><span
|
||
style='font-size:10.0pt;font-family:Verdana'>NDIS_DEVICE_POWER_STATE<span
|
||
style='mso-tab-count:1'><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> </span>MinLinkChangeWakeUp=NdisDeviceStateUnspecified<o:p></o:p></span></p>
|
||
|
||
<p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'><span
|
||
style='font-size:10.0pt;font-family:Verdana'>See <i>PtPostProcessPnPCapabilities</i>
|
||
for details. <o:p></o:p></span></p>
|
||
|
||
<p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'><span
|
||
style='font-size:10.0pt;font-family:Verdana'>OID_PNP_SET_POWER and
|
||
OID_PNP_QUERY_POWER are not passed to the lower adapter, since the lower layer
|
||
miniport will receive independent requests from NDIS.<o:p></o:p></span></p>
|
||
|
||
<p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'><span
|
||
style='font-size:10.0pt;font-family:Verdana'>NDIS calls the MUX driver<65>s
|
||
ProtocolPnPEvent function (<i>PtPNPHandler</i>) whenever the underlying adapter
|
||
is transitioned to a different power state. If the underlying adapter is
|
||
transitioning to a low power state, the driver waits for all outstanding sends
|
||
and requests to complete.<o:p></o:p></span></p>
|
||
|
||
<p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'><span
|
||
style='font-size:10.0pt;font-family:Verdana'>Queries/sets received on a VELAN
|
||
miniport that are to be forwarded to the underlying adapter are queued on the
|
||
VELAN if the underlying adapter is at a low power state. These are picked up
|
||
for processing on receiving a notification that the underlying adapter is back
|
||
to a powered-up state.<o:p></o:p></span></p>
|
||
|
||
<p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'><b><span
|
||
style='font-size:10.0pt;font-family:Verdana'>Handling Global Reconfiguration</span></b><span
|
||
style='font-size:10.0pt;font-family:Verdana'><o:p></o:p></span></p>
|
||
|
||
<p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'><span
|
||
style='font-size:10.0pt;font-family:Verdana'>All modifications to VELAN
|
||
configuration are accompanied by PnP reconfigure notifications, i.e.
|
||
NetEventReconfigure events passed to the MUX<55>s PnPEventHandler, <i>PtPNPHandler</i>.
|
||
This driver takes a broad approach to handling reconfiguration, which is to
|
||
simply re-examine all the <20>UpperBindings<67> keys for all currently bound
|
||
adapters, and start off VELANs for any that do not exist <20> see <i>PtBootStrapVElans</i>
|
||
for details.<o:p></o:p></span></p>
|
||
|
||
<p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'><b><span
|
||
style='font-size:10.0pt;font-family:Verdana'>NDIS 5.1 Features</span></b><span
|
||
style='font-size:10.0pt;font-family:Verdana'><o:p></o:p></span></p>
|
||
|
||
<p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'><span
|
||
style='font-size:10.0pt;font-family:Verdana'>The NDIS 5.1 features in MUX are
|
||
identified by #ifdef NDIS51 compiler directives. The following feature is
|
||
illustrated (refer to the DDK documentation for more information on these):<o:p></o:p></span></p>
|
||
|
||
<p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'><b><span
|
||
style='font-size:10.0pt;font-family:Verdana'>Canceling Sends</span></b><span
|
||
style='font-size:10.0pt;font-family:Verdana'>: MUX propagates send
|
||
cancellations from protocols above it to lower miniports.<o:p></o:p></span></p>
|
||
|
||
<p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'><span
|
||
style='font-size:10.0pt;font-family:Verdana'><span
|
||
style='mso-spacerun:yes'><EFBFBD></span><o:p></o:p></span></p>
|
||
|
||
<p align=center style='text-align:center;tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'><a
|
||
href="#top"><span style='font-size:10.0pt;font-family:Verdana'>Top of page</span></a><span
|
||
style='font-size:10.0pt;font-family:Verdana'> <o:p></o:p></span></p>
|
||
|
||
<table class=MsoNormalTable border=0 cellspacing=0 cellpadding=0 width=624
|
||
style='width:6.5in;mso-cellspacing:0in;mso-padding-alt:0in 0in 0in 0in'>
|
||
<tr style='mso-yfti-irow:0;mso-yfti-lastrow:yes;height:1.5pt'>
|
||
<td style='background:aqua;padding:.75pt .75pt .75pt .75pt;height:1.5pt'>
|
||
<p class=MsoNormal><o:p> </o:p></p>
|
||
</td>
|
||
</tr>
|
||
</table>
|
||
|
||
<p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'><span
|
||
style='font-size:7.5pt;font-family:"MS Sans Serif"'><EFBFBD> 1999 Microsoft
|
||
Corporation</span><span style='font-size:10.0pt;font-family:Verdana'> <o:p></o:p></span></p>
|
||
|
||
</div>
|
||
|
||
</body>
|
||
|
||
</html>
|