mirror of https://github.com/tongzx/nt5src
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.
531 lines
19 KiB
531 lines
19 KiB
/*
|
|
§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§
|
|
|
|
(C) Copyright 1999
|
|
All rights reserved.
|
|
|
|
§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§
|
|
|
|
Portions of this software are:
|
|
|
|
(C) Copyright 1995 TriplePoint, Inc. -- http://www.TriplePoint.com
|
|
License to use this software is granted under the same terms
|
|
outlined in the Microsoft Windows Device Driver Development Kit.
|
|
|
|
(C) Copyright 1992 Microsoft Corp. -- http://www.Microsoft.com
|
|
License to use this software is granted under the terms outlined in
|
|
the Microsoft Windows Device Driver Development Kit.
|
|
|
|
§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§
|
|
|
|
@doc INTERNAL Miniport Miniport_h
|
|
|
|
@module Miniport.h |
|
|
|
|
This module defines the interface to the <t MINIPORT_DRIVER_OBJECT_TYPE>.
|
|
|
|
@comm
|
|
|
|
This module defines the software structures and values used to support
|
|
the NDIS WAN/TAPI Minport. It's a good place to look when your trying
|
|
to figure out how the driver structures are related to each other.
|
|
|
|
Include this file at the top of each module in the Miniport.
|
|
|
|
@head3 Contents |
|
|
@index class,mfunc,func,msg,mdata,struct,enum | Miniport_h
|
|
|
|
@end
|
|
§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§
|
|
*/
|
|
|
|
/* @doc EXTERNAL INTERNAL
|
|
§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§
|
|
|
|
@topic 1.0 Miniport Call Manager Overview |
|
|
|
|
The NDIS wrapper provides services to both the Transport drivers, and the
|
|
Miniport drivers. The NDIS wrapper provides an abstraction layer between
|
|
the two which allows them to interoperate with each other as long as they
|
|
both adhere to the NDIS interfaces defined for Transports and Miniports.
|
|
|
|
The NDIS wrapper also provides a set of services which isolates NDIS
|
|
drivers from the specifics of the Operating System (Windows 98 vs
|
|
Windows 2000), as well as the platform specifics (Processor, Bus,
|
|
Interrupts). The advantage of using the NDIS wrapper is that the Miniport
|
|
can be easily ported to other Windows environments with little or no
|
|
re-coding.
|
|
|
|
An MCM consists of two, cooperating, drivers contained the the same binary.
|
|
The DATA portion of the driver handles packet transmits and receives. The
|
|
CONNECTION portion handles call setup and tear down.
|
|
|
|
The DATA side of the Miniport is very similar to an NDIS LAN style Miniport,
|
|
except that some of the NDIS interfaces have been modified to support the
|
|
WAN media type. The primary difference from the Miniport's point of view is
|
|
that we use a different set of NDIS requests, and more importantly the line
|
|
can go up and down.
|
|
|
|
The CONNECTION portion of the Miniport adds significant complexity to the
|
|
Miniport. The MCM Miniport must provide a pseudo Telephony Service Provider
|
|
Interface (TSPI) which lives under NDPROXY. The NDPROXY TSPI loads under
|
|
TAPI as the 'real' service provider, and then routes all TAPI events to the
|
|
MCM.
|
|
|
|
NDPROXY can have multiple MCM's living under its TSPI interface. And since
|
|
Remote Access Services (RAS) usess the TAPI interface to place and accept
|
|
all calls, any Dial Up Networking (DUN) requests associated with the MCM,
|
|
will end up at the MCM via CONDIS requests from NDPROXY.
|
|
|
|
@topic 1.1 Reference Documents |
|
|
|
|
The most reliable source of information is provided on the Microsoft
|
|
Developer Network CD. These documents will provide you with the complete
|
|
NDIS interface requirements and architectural overviews. In addition,
|
|
there are many addendums and developer notes in the Microsoft Knowledge
|
|
Base. The most important references are:
|
|
|
|
@iex
|
|
Product Documentation\DDKs\Windows 2000 DDK\Network Drivers\
|
|
Design Guide\Part 2: Miniport NIC Drivers
|
|
Chapters 1-7 discuss all the NDIS interface routines.
|
|
Chapters 8 provide details on WAN/TAPI extensions.
|
|
Section 8.7 discuss CoNdis extensions to support TAPI.
|
|
|
|
Product Documentation\SDKs\Platform SDK\Networking and Directory Services\
|
|
Telephone Application Programming Interfaces\TAPI Service Providers
|
|
This section defines the Windows TSPI implementation.
|
|
|
|
@normal
|
|
|
|
@end
|
|
*/
|
|
|
|
/* @doc EXTERNAL INTERNAL
|
|
§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§
|
|
|
|
@topic 2.0 Installing and Configuring the Sample Driver |
|
|
|
|
The sample driver implements a fully functional ISDN style CO-NDIS WAN
|
|
driver. It layers in under NDPROXY which translates the RAS/WAN/TAPI
|
|
interfaces into a more generic CO-NDIS interface. The driver supports
|
|
multiple adapter instances, so you can install it more than once to
|
|
create multiple adapters.
|
|
|
|
Each adapter can emulate multiple ISDN B channels. By default, each
|
|
adapter is setup with 2 channels, but you can modify the "IsdnBChannels"
|
|
and "WanEndPoints" registry entries to creates as many as you'd like.
|
|
Alternatively, you can just modify these values in the INF file before
|
|
you install the adapter. Either way works fine.
|
|
|
|
@topic 2.1 Installation |
|
|
|
|
The driver can be installed as a non-plug-n-play device using the Windows
|
|
device manager interface as follows:
|
|
|
|
1) Right-click the "My Computer" icon on the desktop and select the
|
|
Properties item from the context menu.
|
|
|
|
2) Select the "Hardware" tab on the "System Properties" dialog.
|
|
|
|
3) Click the "Hardware Wizard" button, then click "Next" when the welcome
|
|
dialog appears.
|
|
|
|
4) Click "Next" again to "Add/Troubleshoot a device".
|
|
|
|
5) Select "Add a new device" from the list presented, then click "Next".
|
|
|
|
6) Select "No, I want to select the hardware from a list" radio button,
|
|
then click "Next".
|
|
|
|
7) Select "Network adapters" from the list presented, then click "Next".
|
|
|
|
8) Click the "Have Disk" button, then browse to the location of the driver
|
|
and INF file, then click OK."
|
|
|
|
9) You should now see "TriplePoint COISDN Adapter" on the screen. Click
|
|
"Next" and then "Next" again to install the driver. If Windows warns you
|
|
about an unsigned driver, just click yes to install. If you don't have
|
|
permission to install such drivers, you'll have to exit and logon with the
|
|
proper permissions. You will have to disable the driver signing check on
|
|
your system if it doesn't allow unsigned drivers to be installed.
|
|
|
|
10) Now click "Finish" to load the driver.
|
|
|
|
@topic 2.2 Dial-In Setup |
|
|
|
|
You must install and enable Dial-Up networking before you can accept an
|
|
incoming call with the driver. This can be done using the following
|
|
procedure:
|
|
|
|
1) Right-click the "My Network Places" icon on the desktop and select the
|
|
Properties item from the context menu.
|
|
|
|
2) Double-click the "Make New Connction" icon from the list.
|
|
|
|
3) Select the "Accept incoming connections" radio button, then click "Next".
|
|
|
|
4) Click the check box next to the "TriplePoint COISDN Adapter"(s) to allow
|
|
incoming calls on the adapter. All channels on that adapter are enabled
|
|
for incoming calls. Once you select the adapter(s), click "Next".
|
|
|
|
5) Select "Do not allow virtual private connections", then click "Next".
|
|
|
|
6) Select the users you want to have dial-in access, then click "Next".
|
|
|
|
7) Select the protocols and services you want to support, then click "Next".
|
|
|
|
8) Now click "Finish" to enable the dial-in connections.
|
|
|
|
@topic 2.3 Dial-Out Setup |
|
|
|
|
The sample driver implements the following simple dialing method.
|
|
|
|
A) "0" can be used to connect to any available more on any available
|
|
adapter. This is generally good enough for most testing.
|
|
|
|
B) "N" specifies that the connection should be directed to a specific
|
|
adapter instance. Where N must match the ObjectID assigned to a particular
|
|
adapter when the <f MiniportInitialize> routine is called. Numbers are
|
|
assigned from 1-M based on the adapter initialization order. The call is
|
|
then directed to any available listening channel on the selected adapter.
|
|
|
|
You must create a dial-out connection before you can place call with the
|
|
driver. This can be done using the following procedure:
|
|
|
|
1) Right-click the "My Network Places" icon on the desktop and select the
|
|
Properties item from the context menu.
|
|
|
|
2) Double-click the "Make New Connction" icon from the list.
|
|
|
|
3) Select the "Dial-up to private network" radio button, then click "Next".
|
|
|
|
4) Click the check box next to one or more "TriplePoint COISDN Adapter"
|
|
ISDN Channels to allow outgoing calls on the channel. Make sure you leave
|
|
enough channels available to answer the call when it comes in... You have
|
|
no way to know which driver BChannel is actually going to be used, but that
|
|
doesn't generally matter anyway. Once you select the channel(s), click "Next".
|
|
|
|
5) Walk your way through the rest of the Wizard dialogs to setup the
|
|
connection as you like.
|
|
|
|
6) When you're done click "Finish" to enable the dial-out connection.
|
|
|
|
Now you can double-click the dial-out connection to see how it all works.
|
|
|
|
I suggest you also turn some debug flags in the driver to see how the call
|
|
setup and teardown winds its way through the driver. This can be quite
|
|
useful before starting to modify the driver for your hardware.
|
|
|
|
@end
|
|
*/
|
|
|
|
|
|
/* @doc EXTERNAL INTERNAL
|
|
§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§
|
|
|
|
@topic 4.0 Functional Overview |
|
|
|
|
This section describes the major functional objects defined by the driver.
|
|
|
|
This driver is designed as a generic ISDN device driver. It does not
|
|
support any specific hardware, but does have the basic elements of an ISDN
|
|
device. The network interface is emulated by placing calls between one or
|
|
more of the driver's BChannels. This is accomplished using a set of
|
|
software events that simulate typical network events (i.e MakeCall,
|
|
AnnounceCall, Tranmit, Receive, Hangup, etc).
|
|
|
|
By using this design approach you can compile and test the driver without
|
|
having to purchase specific hardware. The downside is that you cannot
|
|
easily test the data flow because the networking infrastructure does not
|
|
support terminating the endpoint on the local host. However, the data flow
|
|
is not usually very difficult to test once the call manager interfaces are
|
|
reliable. RAS does support connecting to the local host, but the NDIS
|
|
protocols won't normally route traffic through the interface because they
|
|
just loop back before it reaches the driver. The PPP negotiation packets
|
|
are routed through the interface, so this does give some data flow excersise,
|
|
but nothing worth writing home about. The NDISWAN tester has been modified
|
|
to allow it to run over locally terminated connections, so this is the only
|
|
real way to test the data pump.
|
|
|
|
Because this driver does not support real hardware, all the hardware
|
|
resource code has been ifdef'd out. This code has been used in working
|
|
drivers, so I'm pretty sure it will work if you add the corresponding
|
|
compiler options. However, it has not been verified and may require some
|
|
modifications for your environment.
|
|
|
|
There are several other good samples included on the DDK that can be useful
|
|
for using other NDIS features. This sample focuses primarily on the
|
|
CO-NDIS call manager interfaces.
|
|
|
|
@end
|
|
*/
|
|
|
|
#ifndef _MPDMAIN_H
|
|
#define _MPDMAIN_H
|
|
|
|
#define MINIPORT_DRIVER_OBJECT_TYPE ((ULONG)'D')+\
|
|
((ULONG)'R'<<8)+\
|
|
((ULONG)'V'<<16)+\
|
|
((ULONG)'R'<<24)
|
|
|
|
#define INTERRUPT_OBJECT_TYPE ((ULONG)'I')+\
|
|
((ULONG)'N'<<8)+\
|
|
((ULONG)'T'<<16)+\
|
|
((ULONG)'R'<<24)
|
|
|
|
#define RECEIVE_OBJECT_TYPE ((ULONG)'R')+\
|
|
((ULONG)'E'<<8)+\
|
|
((ULONG)'C'<<16)+\
|
|
((ULONG)'V'<<24)
|
|
|
|
#define TRANSMIT_OBJECT_TYPE ((ULONG)'T')+\
|
|
((ULONG)'R'<<8)+\
|
|
((ULONG)'A'<<16)+\
|
|
((ULONG)'N'<<24)
|
|
|
|
#define REQUEST_OBJECT_TYPE ((ULONG)'R')+\
|
|
((ULONG)'Q'<<8)+\
|
|
((ULONG)'S'<<16)+\
|
|
((ULONG)'T'<<24)
|
|
|
|
/*
|
|
// NDIS_MINIPORT_DRIVER and BINARY_COMPATIBLE must be defined before the
|
|
// NDIS include files. Normally, it is defined on the command line by
|
|
// setting the C_DEFINES variable in the SOURCES build file.
|
|
*/
|
|
#include <ndis.h>
|
|
#include <ndiswan.h>
|
|
#include <ndistapi.h>
|
|
#include "vTarget.h"
|
|
#include "TpiDebug.h"
|
|
|
|
#if !defined(IRP_MN_KERNEL_CALL) && !defined(PCI_SUBCLASS_DASP_OTHER)
|
|
// This should be defined in the NTDDK 5.0 ndis.h, but it's not.
|
|
// So I copied this here from ntddk.h to use with NdisQueryBufferSafe().
|
|
typedef enum _MM_PAGE_PRIORITY {
|
|
LowPagePriority,
|
|
NormalPagePriority = 16,
|
|
HighPagePriority = 32
|
|
} MM_PAGE_PRIORITY;
|
|
#endif
|
|
|
|
// Figure out which DDK we're building with.
|
|
#if defined(NDIS_LCODE)
|
|
# if defined(NDIS_DOS)
|
|
# define USING_WFW_DDK
|
|
# define NDIS_MAJOR_VERSION 0x03
|
|
# define NDIS_MINOR_VERSION 0x00
|
|
# elif defined(OID_WAN_GET_INFO)
|
|
# define USING_WIN98_DDK
|
|
# elif defined(NDIS_WIN)
|
|
# define USING_WIN95_DDK
|
|
# else
|
|
# error "BUILDING WITH UNKNOWN 9X DDK"
|
|
# endif
|
|
#elif defined(NDIS_NT)
|
|
# if defined(OID_GEN_MACHINE_NAME)
|
|
# define USING_NT51_DDK
|
|
# elif defined(OID_GEN_SUPPORTED_GUIDS)
|
|
# define USING_NT50_DDK
|
|
# elif defined(OID_GEN_MEDIA_CONNECT_STATUS)
|
|
# define USING_NT40_DDK
|
|
# elif defined(OID_WAN_GET_INFO)
|
|
# define USING_NT351_DDK
|
|
# else
|
|
# define USING_NT31_DDK
|
|
# endif
|
|
#else
|
|
# error "BUILDING WITH UNKNOWN DDK"
|
|
#endif
|
|
|
|
// Figure out which DDK we should be building with.
|
|
#if defined(NDIS51) || defined(NDIS51_MINIPORT)
|
|
# if defined(USING_NT51_DDK)
|
|
# define NDIS_MAJOR_VERSION 0x05
|
|
# define NDIS_MINOR_VERSION 0x01
|
|
# else
|
|
# error "YOU MUST BUILD WITH THE NT 5.1 DDK"
|
|
# endif
|
|
#elif defined(NDIS50) || defined(NDIS50_MINIPORT)
|
|
# if defined(USING_NT50_DDK) || defined(USING_NT51_DDK)
|
|
# define NDIS_MAJOR_VERSION 0x05
|
|
# define NDIS_MINOR_VERSION 0x00
|
|
# else
|
|
# error "YOU MUST BUILD WITH THE NT 5.0 DDK"
|
|
# endif
|
|
#elif defined(NDIS40) || defined(NDIS40_MINIPORT)
|
|
# if defined(USING_NT40_DDK) || defined(USING_NT50_DDK) || defined(USING_NT51_DDK)
|
|
# define NDIS_MAJOR_VERSION 0x04
|
|
# define NDIS_MINOR_VERSION 0x00
|
|
# else
|
|
# error "YOU MUST BUILD WITH THE NT 4.0 or 5.0 DDK"
|
|
# endif
|
|
#elif defined(NDIS_MINIPORT_DRIVER)
|
|
# if defined(USING_NT351_DDK) || defined(USING_NT40_DDK) || defined(USING_NT50_DDK) || defined(USING_NT51_DDK)
|
|
# define NDIS_MAJOR_VERSION 0x03
|
|
# define NDIS_MINOR_VERSION 0x00
|
|
# else
|
|
# error "YOU MUST BUILD WITH THE NT 3.51, 4.0, or 5.0 DDK"
|
|
# endif
|
|
#elif !defined(NDIS_MAJOR_VERSION) || !defined(NDIS_MINOR_VERSION)
|
|
// Must be FULL MAC
|
|
# define NDIS_MAJOR_VERSION 0x03
|
|
# define NDIS_MINOR_VERSION 0x00
|
|
#endif
|
|
|
|
// Gotta nest NDIS_STRING_CONST or compiler/preprocessor won't be able to
|
|
// handle L##DEFINED_STRING.
|
|
#define INIT_STRING_CONST(name) NDIS_STRING_CONST(name)
|
|
#define DECLARE_WIDE_STRING(name) L##name
|
|
#define INIT_WIDE_STRING(name) DECLARE_WIDE_STRING(name)
|
|
|
|
typedef struct MINIPORT_ADAPTER_OBJECT *PMINIPORT_ADAPTER_OBJECT;
|
|
typedef struct BCHANNEL_OBJECT *PBCHANNEL_OBJECT;
|
|
typedef struct DCHANNEL_OBJECT *PDCHANNEL_OBJECT;
|
|
typedef struct CARD_OBJECT *PCARD_OBJECT;
|
|
typedef struct PORT_OBJECT *PPORT_OBJECT;
|
|
|
|
/*
|
|
// The <t NDIS_MAC_LINE_UP> structure is confusing, so I redefine the
|
|
// field name to be what makes sense.
|
|
*/
|
|
#define MiniportLinkContext NdisLinkHandle
|
|
|
|
#if defined(_VXD_) && !defined(NDIS_LCODE)
|
|
# define NDIS_LCODE code_seg("_LTEXT", "LCODE")
|
|
# define NDIS_LDATA data_seg("_LDATA", "LCODE")
|
|
#endif
|
|
|
|
/*
|
|
// The link speeds we support.
|
|
*/
|
|
#define _64KBPS 64000
|
|
#define _56KBPS 56000
|
|
|
|
#define MICROSECONDS (1)
|
|
#define MILLISECONDS (1000*MICROSECONDS)
|
|
#define SECONDS (1000*MILLISECONDS)
|
|
|
|
#define TSPI_ADDRESS_ID 0
|
|
|
|
/*
|
|
// Include everything here so the driver modules can just include this
|
|
// file and get all they need.
|
|
*/
|
|
#include "Keywords.h"
|
|
#include "Card.h"
|
|
#include "Adapter.h"
|
|
#include "BChannel.h"
|
|
#include "CallMgr.h"
|
|
#include "DChannel.h"
|
|
#include "Port.h"
|
|
#include "TpiParam.h"
|
|
#include "TpiMem.h"
|
|
|
|
/***************************************************************************
|
|
// These routines are defined in Miniport.c
|
|
*/
|
|
|
|
NTSTATUS DriverEntry(
|
|
IN PDRIVER_OBJECT DriverObject,
|
|
IN PUNICODE_STRING RegistryPath
|
|
);
|
|
|
|
NDIS_STATUS MiniportInitialize(
|
|
OUT PNDIS_STATUS OpenErrorStatus,
|
|
OUT PUINT SelectedMediumIndex,
|
|
IN PNDIS_MEDIUM MediumArray,
|
|
IN UINT MediumArraySize,
|
|
IN NDIS_HANDLE MiniportAdapterHandle,
|
|
IN NDIS_HANDLE WrapperConfigurationContext
|
|
);
|
|
|
|
void MiniportHalt(
|
|
IN PMINIPORT_ADAPTER_OBJECT pAdapter
|
|
);
|
|
|
|
void MiniportShutdown(
|
|
IN PMINIPORT_ADAPTER_OBJECT pAdapter
|
|
);
|
|
|
|
NDIS_STATUS MiniportReset(
|
|
OUT PBOOLEAN AddressingReset,
|
|
IN PMINIPORT_ADAPTER_OBJECT pAdapter
|
|
);
|
|
|
|
/***************************************************************************
|
|
// These routines are defined in interrup.c
|
|
*/
|
|
BOOLEAN MiniportCheckForHang(
|
|
IN PMINIPORT_ADAPTER_OBJECT pAdapter
|
|
);
|
|
|
|
void MiniportDisableInterrupt(
|
|
IN PMINIPORT_ADAPTER_OBJECT pAdapter
|
|
);
|
|
|
|
void MiniportEnableInterrupt(
|
|
IN PMINIPORT_ADAPTER_OBJECT pAdapter
|
|
);
|
|
|
|
void MiniportHandleInterrupt(
|
|
IN PMINIPORT_ADAPTER_OBJECT pAdapter
|
|
);
|
|
|
|
void MiniportISR(
|
|
OUT PBOOLEAN InterruptRecognized,
|
|
OUT PBOOLEAN QueueMiniportHandleInterrupt,
|
|
IN PMINIPORT_ADAPTER_OBJECT pAdapter
|
|
);
|
|
|
|
void MiniportTimer(
|
|
IN PVOID SystemSpecific1,
|
|
IN PMINIPORT_ADAPTER_OBJECT pAdapter,
|
|
IN PVOID SystemSpecific2,
|
|
IN PVOID SystemSpecific3
|
|
);
|
|
|
|
/***************************************************************************
|
|
// These routines are defined in receive.c
|
|
*/
|
|
void ReceivePacketHandler(
|
|
IN PBCHANNEL_OBJECT pBChannel,
|
|
IN PNDIS_BUFFER pNdisBuffer,
|
|
IN ULONG BytesReceived
|
|
);
|
|
|
|
VOID MiniportReturnPacket(
|
|
IN PMINIPORT_ADAPTER_OBJECT pAdapter,
|
|
IN PNDIS_PACKET pNdisPacket
|
|
);
|
|
|
|
/***************************************************************************
|
|
// These routines are defined in request.c
|
|
*/
|
|
NDIS_STATUS MiniportCoRequest(
|
|
IN PMINIPORT_ADAPTER_OBJECT pAdapter,
|
|
IN PBCHANNEL_OBJECT pBChannel,
|
|
IN OUT PNDIS_REQUEST NdisRequest
|
|
);
|
|
|
|
/***************************************************************************
|
|
// These routines are defined in transmit.c
|
|
*/
|
|
VOID MiniportCoSendPackets(
|
|
IN PBCHANNEL_OBJECT pBChannel,
|
|
IN PPNDIS_PACKET PacketArray,
|
|
IN UINT NumberOfPackets
|
|
);
|
|
|
|
void TransmitCompleteHandler(
|
|
IN PMINIPORT_ADAPTER_OBJECT pAdapter
|
|
);
|
|
|
|
void FlushSendPackets(
|
|
IN PMINIPORT_ADAPTER_OBJECT pAdapter,
|
|
IN PBCHANNEL_OBJECT pBChannel
|
|
);
|
|
|
|
#endif // _MPDMAIN_H
|
|
|