ID: Q156081
The information in this article applies to:
- Microsoft Windows NT version 3.51
This article describes the major differences between the Win32 Data Link Control (DLC) API and the DOS DLC interface. It assumes familiarity with the DLC protocol and the relevant specification documents. Where appropriate, differences from the IBM OS/2 DLC interface are also described.
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.
The following is a list of the differences between IBM OS/2 DLC and the 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.
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.
The NT DLC command can be completed in two ways:
Waiting on the event handle defined in the CCB.
-or-
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.
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.
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:
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.
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;
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.
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
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;
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.
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.
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.
This command does not do anything in Windows NT.
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.
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.
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.
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;
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.
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.
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.
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.
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.
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.
The receive option 5 (BREAK) is not supported.
Uses the pParameter field of the CCB to point to the CCB pointer of the canceled command.
The following DOS DLC commands are not supported by Windows NT:
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.
Keywords : kbnetwork kbAPI kbDLC kbNTOS350 kbSDKPlatform kbWinOS95 kbGrpNet
Issue type : kbinfo
Last Reviewed: January 1, 1999