MORE INFORMATION
The Win32 DLC API has been designed to be as compatible with the IBM OS/2
DLC API for OS/2 1.xx as possible. The limits to compatibility are those
imposed by the operating system functions (such as Event vs. Semaphores),
and the differing memory models (flat vs. segmented).
The API is described herein as differences from the Command Control Block
(CCB) interface in the IBM LAN Technical Reference, Fourth Edition (Dec,
1990). Areas addressed in the IBM documentation are generally not repeated
here.
Differences between the Win32 and OS/2 DLC API
The following is a list of the differences between IBM OS/2 DLC and the
Win32 DLC API.
- All 16-bit segment offsets in CCBs and parameter tables have been
replaced by 32-bit flat pointers.
- The buffer pool is managed by the DLC driver. Applications can no
longer define the segment size of the buffer pool or add new buffers to
the pool. The application must, however, always check the size field in
the buffer header.
- The application ID and application key code fields in the CCB structure
have been rendered obsolete by the ability to provide an optional
security descriptor when an adapter is opened.
- The IBM Token-Ring hardware-specific parameter fields that cannot be
supported by other common token-ring adapters have been removed. These
fields are not available on Ethernet adapters and applications should
in general, avoid using them.
- Win32 Events are used instead of OS/2 system semaphores to signal the
completion of asycnhronous requests.
- All global resources like functional address, group address on
Ethernet, link, sap and direct stations, which were shared by all active
applications are now available to each application separately.
- Ethernet type codes are supported when sending DIRECT frames.
- Applications may define a 48-bit multicast address on Ethernet
adapters. This address overwrites the 32-bit broadcast address set by
DIR.SET.GROUP.ADDRESS
- Applications can send several frames with the TRANSMIT.FRAMES command
from a DLC station.
Differences between the Win32 and DOS/2 DLC API
- The post routines of DOS DLC have been replaced by a READ request.
- The receive buffers are compatible with OS/2 1.xx DLC API and are
different from the DOS DLC receive headers.
- The parameter tables use OS/2 specific parameter fields.
- No DOS-specific functions have been implemented.
Win32 DLC API
In general, most of the functions and their parameter blocks are identical
to those of the IBM DLC API for OS/2 1.xx, with the pointers being changed
from 16-bit offsets to 32-bit flat addresses.
Because of the compatibility with the IBM DLC specification, all Ethernet
network and broadcast addresses in the functions and data structures that
are common to Ethernet and token-ring networks, use the token-ring Net
headers and have swapped bit order in the addresses. The functions and data
structures that are only possible on the Ethernet use the normal Ethernet
Net headers and bit order. For example, DIX Ethernet frames use the
Ethernet order in the receive and transmit buffer Net headers.
DIR.SET.MULTICAST.ADDRESS also uses the Ethernet order.
The data types, constants and error codes mentioned in the following
sections are documented in the DLCAPI.H file, which ships with Microsoft
Visual C++ version 4.0, or the Win32 SDK.
API Call
The Win32 DLC services are provided by a single entry point of
ASCLAN_STATUS Acslan(PLLC_CCB pCCB, PLLC_CCB * ppBadCCB);
where:
pCCB - Command Control Block, defines the function type and its
input parameters.
pBadCCB - Returns the address of the invalid CCB, if server CCBs were
queued together and one of them failed. The parameter may be
NULL if the application only specifies one command.
Return code: ASCLAN status code. The DLC error or success status is
always returned in the CCB status field.
The Command Control Block (CCB) defines parameters common for all DLC
requests. The request-specific parameters are either in an external
parameter table or in four bytes reserved for them in the Win32 CCB.
For example:
//
// LLC_CCB - the Command Control Block structure from DLCAPI.H
//
typedef struct _LLC_CCB {
UCHAR uchAdapterNumber; // Adapter
UCHAR uchDlcCommand; // DLC command
UCHAR uchDlcStatus; // DLC command completion code
UCHAR uchReserved1; // reserved for DLC DLL
struct _LLC_CCB* pNext; // CCB chain
ULONG ulCompletionFlag; // used in command completion
CCB_PARMS u; // parameters
HANDLE hCompletionEvent; // event for command completion
UCHAR uchReserved2; // reserved for DLC DLL
UCHAR uchReadFlag; // set when special READ CCB chained
USHORT usReserved3; // reserved for DLC DLL
} LLC_CCB, *PLLC_CCB;
where:
uchAdapterNumber - Network adapter number, 0, 1, 2.. 255
uchCommand - Function code, mostly compatible with IBM spec.
uchDlcStatus - DLC return status
pNext - Used to chain CCBs. Several Canceled commands or
completed TRANSMIT CCBs may be chained with this
field. It can also provide a READ command to
complete the current command.
ulCompletionFlag - Optional flag set by READ when the command is
completed. The DLC API driver does not use the
parameter if it was set to 0 before the call.
u - Function-dependent parameter table.
hCompletionEvent - Event handle which can be used to wait for command
completion. This must be created with the Win32 API
CreateEvent.
uchReadFlag - This should be set if a READ CCB is chained in this
command.
Most DLC commands may only be executed synchronously, with the status and
the optional output parameters being returned immediately. The network I/O
commands may be executed sychronously or asynchronously.
Command Completion
The NT DLC command can be completed in two ways:
Waiting on the event handle defined in the CCB.
Setting a completion flag in the CCB and reading the command completion
with the READ command.
The method of polling on the status code in the CCB is unreliable in
Windows NT and should not be used. The status field may be updated before
the other returned parameters have been set, and should not be polled for
completion.
Ethernet Type Support
The DLC API specification for the direct interface only allows data
encapsulated in 802.5 or 802.3 frames. This makes it impossible to receive
other Ethernet types. The new direct station ids 0004H and 0005H can
receive all Ethernet types.
Users may also specify a specific Ethernet frame type in the new parameter
field of the DIR.OPEN.STATION command. The direct station then only
receives frames which have that specific Ethernet frame type. The received
frame type is returned in the DLC header field of the non-contiguous frame
header.
Received DIX Ethernet frames always include the frame padding, if the frame
length is less than 64 bytes.
The Ethernet NET header is used whenever an application is sending or
receiving Ethernet type frames.
Buffer Management
The buffer allocation and management methods in the Win32 DLC API are quite
different from the DOS or OS/2 1.xx methods. The buffer headers, however,
are as defined in the specifications.
The DLC buffers of Win32 are allocated from a single virtual memory block
and the DLC driver defines the buffer segment sizes. For each received
frame it allocates a minimal combination of 256, 512, 1024, 2048 and 4096
buffer segments (at most one of each size). The algorithm minimizes the
non-paged memory needed for different buffer segment headers (DLC headers,
internal segment header and MDL). It also allocates the minimal number of
buffers for the received frames. Applications may request the fixed size
buffers or an optimal number of buffers for a frame size.
The DLC buffers pools are dynamically expanded from the
application-specified minimum size threshold if the size of free buffers is
less than this value during a READ, DLC.FLOW.CONTROL or BUFFER.GET command.
The buffer pool cannot, however, be increased beyond its maximum size.
An application may use its own transmit buffers or send data directly from
the buffer pool. Because the DLC driver locks all the transmit buffers that
are not in the buffer pool, applications should avoid using too many small
transmit buffers.
Use the following methods to obtain better performance:
- Allocate transmit buffers from the buffer pool. Data may be copied to
these buffers from the user buffers.
- The negotiated maximum frame size should fit into a single DLC buffer
(e.g., 2048 or 4096 bytes minus the frame and buffer headers).
- Receive several frames with the READ command.
- Use the CCBs defined in the LLC_READ_COMMAND structure.
DLC API Functions
The following section itemizes the functions in the Win32 DLC set that are
different from the CCB2 interface of the IBM LAN Technical Reference. Other
functions are identical to the specification, except that pointers are
32-bit flat pointers.
1. BUFFER.CREATE
This function creates a new DLC buffer pool and returns its handle. All SAP
stations and the direct station on the same adapter number use the same
buffer pool. The same buffer pool may also be shared by different adapters
owned by the same application. For example:
typedef struct _LLC_BUFFER_CREATE_PARMS {
OUT HANDLE hBufferPoolHandle;
IN PVOID pBuffer;
IN ULONG cbBufferSize;
IN ULONG cbMinimumSizeThreshold;
} LLC_BUFFER_CREATE_PARMS, *PLLC_UFFER_CREATE_PARMS;
LLC_BUFFER_CREATE_PARMS Structure
hBufferPoolHandle - Handle of the created buffer pool. This handle can
be used by the same process to share a single
buffer pool by several adapter contexts. This
handle may be given in the extended parameter
table of another DIR.OPEN.ADAPTER command.
pBuffer - The application must provide this buffer to
the DLC buffer manager. The buffer may be static
or allocated from the heap. The buffer manager
allocates all DLC buffers from this virtual
buffer. This buffer area must not be used for
anything else.
cbBufferSize - The total size of the buffer. This must be the
maximum size of the buffer pool. 0x2000 (hex) is
the minimum buffer size, because the buffer manager
only uses the full 4K pages.
cbMinimumSizeThreshold - The buffer manager tries to keep at least this
much free space in the buffer pool. The
buffer pool is extended by READ, BUFFER.GET
and DLC.FLOW.CONTROL commands. This
parameter should be big enough to hold all
data received between two sequential READ
commands. The buffer manager also releases
(unlocks) the extra buffer space after a
constant time.
All buffer segments in a DLC buffer pool are allocated from a single
virtual memory block. Its size is also the maximum size of the buffer pool.
This command returns an error if it cannot lock the given minimum buffer
size. At least one adapter must be open before buffer pool can be created.
The RECEIVE command fails if a buffer pool has not been defined
for the adapter.
Windows/Windows NT DLC applications should very carefully select the total
and minimum buffer pool sizes, because the memory manager of
Windows/Windows NT has a dynamic quota available pages for each process. A
DLC application may not work at all if it tries to allocate too large a
buffer pool in low memory conditions. The transmit commands using buffers
outside of the buffer pool may fail for the same reason.
DLC applications should minimize the time that the buffers returned by the
data receive or by the BUFFER.GET request are held, because those buffers
are still locked in the memory. DLC applications should also be able to
recover if the DLC device driver runs out of the buffers, because it may
not be able to add new memory to the buffer pool (if the entire system is
running out of memory).
In any case, there always is at least the minimal free buffer space if the
BUFFER.CREATE request has been completed successfully.
2. BUFFER.FREE
This request returns one or more buffers to the adapter's pool. It cannot
be used to add new virtual memory blocks to the existing pool. The buffers
must have been obtained with BUFFER.GET
3. BUFFER.GET
This command returns the requested buffers. The command can be used both
to get several buffers of the same size or to get an optimal set of buffers
for the given frame size.
In the first case below, cBufferToGet includes the number the returned
buffers and cbBufferSize is the size of the returned buffer segment. The
size is rounded up to next available buffer size (256, 512, 1024, 2048 or
4096).
In the second case the number of returned buffers must be 0 and
cbBufferSize includes the size of the actual frame that is copied to
buffers. The buffer manager returns enough buffers to contain the
whole frame including its buffer headers. cbBuffersLeft returns the size
of free locked memory in 256 bytes blocks or 65536 if the actual size is
above 1MB. For example:
typedef struct _LLC_BUFFER_GET_PARMS {
IN USHORT usReserved;
IN USHORT cBuffersLeft;
IN USHORT cBufferToGet;
IN USHORT cbBufferSize;
OUT PLLC_BUFFER pFirstBuffer;
} LLC_BUFFER_GET_PARMS, *PLLC_BUFFER_GET_PARMS;
4. DLC.FLOW.CONTROL
A Windows NT application should issue this command immediately when a link
station enters a local busy state. The driver clears the busy state when
there are enough free buffers to receive more frames in the buffer pool.
5. DIR.CLOSE.ADAPTER
This command closes the adapter logically, release all its resource and
cancels any outstanding commands. Open SAP or link stations are reset
prior to completion of this command. The canceled commands return error
code 0x62. If the application has previously set bits of the functional
address, the adapter support software resets the bits.
6. DIR.INITIALIZE
This command resets the network adapter. Only the BRING_UPS field in the
parameter block is returned. All other fields are reserved. For security
reasons, the command resets the adapter physically only if the adapter was
not functioning normally when the command was issued.
See the "IBM LAN Technical Reference" for further information.
7. DIR.INTERRUPT
This command does not do anything in Windows NT.
8. DIR.OPEN.ADAPTER
This command must be completed successfully before any network
communication can start. It does not usually open the physical adapter, but
results in a logical open. This is because multiple applications and
drivers may be accessing the same DLC driver.
Applications may have to provide the security descriptor parameter in the
parameter table.
All fields specific to the IBM Token Ring hardware or the DOS NETBIOS
interface have been removed from the parameter tables. The DOS security and
direct interface buffer pool parameters are also obsolete.
The bring-up diagnostic result is returned (it is not defined in CCB1).
Otherwise, the CCB1 parameter tables and parameters are used.
DIR_OPEN_ADAPTER_PARMS Structure
typedef struct _LLC_DIR_OPEN_ADAPTER_PARMS {
PDIR_ADAPTER_PARMS pAdapterParms;
PLLC_EXTENDED_ADAPTER_PARMS pExtendedParms;
PLLC_PARMS pDlcParms;
PVOID Reserved1;
} LLC_DIR_OPEN_ADAPTER_PARMS, *PLLC_DIR_OPEN_ADAPTER_PARMS;
pExtendedParms - Pointer to new open parameters.
pAdapterParameters - Pointer to adapter parameter table.
pDlcParameters - Pointer to DLC parameter table, see IBM
documentation for further information.
EXTENDED_ADAPTER_PARMS Structure
typedef struct _LLC_EXTENDED_ADAPTER_PARMS {
HANDLE hBufferPoolHandle;
PVOID pSecurityDescriptor;
} LLC_EXTENDED_ADAPTER_PARMS, *PLLC_EXTENDED_ADAPTER_PARMS;
hBufferPoolHandle - Buffer pool handle returned by a
BUFFER.CREATE command.
pSecurityDescriptor - Windows/Windows NT security descriptor used by
all open commands on the adapter.
See "IBM Local Area Network Technical Reference" for further information.
9. DIR.OPEN.DIRECT
The fields that define the buffer pool in the IBM specification are not
used. Windows NT provides an extension to receive frames of specific
Ethernet types using the direct station when the usEthernetType field has
a valid Ethernet type (>1500).
The protocol type mask, match and offset can be used to receive frames for
a particular subprotocol type or socket. The optional parameters are
ignored if the ulProtocolTypeMask is zero. The offset defines the distance
of the protocol type from the beginning of the protocol header (offset 14
in the frame header). The mask is used to bitwise AND the data and the
result must be equal to the match.
That is, the packet is received whenever:
(*(PULONG)((PUCHAR)pFrame + 14 + offset) & mask) == match)
typedef struct _LLC_DIR_OPEN_DIRECT_PARMS {
IN USHORT usReserved[4];
IN USHORT usOpenOptions;
IN USHORT usEthernetType;
IN ULONG ulProtocolTypeMask OPTIONAL;
IN ULONG ulProtocolTypeMatch OPTIONAL;
IN USHORT usProtocolTypeOffset OPTIONAL;
} LLC_DIR_OPEN_DIRECT_PARMS, *PLLC_DIR_OPEN_DIRECT_PARMS;
10. DIR.READ.LOG
All parameter fields of this function may not be supported by some network
adapters because the implementation of error counters is optional in NDIS
3.0. These fields are supported by Microsoft-provided NDIS 3.0 drivers,
including IBM Token Ring.
11. DIR.SET.FUNCTIONAL.ADDRESS
On Ethernet, each bit set in the token-ring functional addresses causes a
mapping to an Ethernet-multicast address. Please see the "IBM LAN Technical
Reference" for more information.
12. DIR.SET.MULTICAST.ADDRESS
This command sets a 48-bit multicast address for the currently open DLC
adapter context. A zero value removes the previous multicast address. This
command is only supported on Ethernet networks and is an alternative to the
DIR.SET.GROUP.ADDRESS function that can only set the lowest 32 bits of a
multicast address. This operation may fail if the Ethernet adapter does not
have a multicast address available.
The bit order of the multicast address is the normal Ethernet bit order.
13. DIR.SET.GROUP.ADDRESS
Only one application may set a group address for a token ring adapter. This
operation may also fail if the Ethernet adapter does not have available
multicast addresses.
14. READ
As in the IBM specification, except that all the fields in the parameter
table are naturally aligned. The not contiguous buffer is also aligned. The
data and the optional header begin at offset 64.
15.READ.CANCEL
As in the CCB2 specification, except that the pParameter field in the CCB
of the command is used to specify the CCB pointer of the canceled command.
16. RECEIVE
The receive option 5 (BREAK) is not supported.
17. RECEIVE.CANCEL
Uses the pParameter field of the CCB to point to the CCB pointer of the
canceled command.
Unsupported DOS Commands
The following DOS DLC commands are not supported by Windows NT:
- DIR.SET.USER.APPENDAGE
- RECEIVE.MODIFY
- DIR.RESTORE.OPEN.PARMS
- DIR.MODIFY.OPEN.PARMS
WOW/DOS DLC
DLC services are made available to DOS applications running in the DOS/WOW
environment on Windows NT. The API is directly compatible with existing IBM
emulators using the DOS DLC API in DOS.
Windows applications that communicate with DOS terminate-and-stay-resident
(TSR) applications to access DLC services should also work unmodified on
WOW.