Networking APIs





Networking APIs

Windows 2000 implements multiple networking APIs to provide support for legacy applications and compatibility with industry standards. In this section, we'll briefly look at the networking APIs and describe how applications use them. It's important to keep in mind that the decision about which API an application uses depends on characteristics of the API, such as which protocols the API can layer over, whether the API supports reliable or bidirectional communication, and the API's portability to other Windows platforms the application might run on. We'll discuss the following networking APIs:

  • Named pipes and mailslots
  • Windows Sockets (Winsock)
  • Remote procedure call (RPC)
  • Common Internet File System (CIFS)
  • NetBIOS

In addition, we'll briefly describe several APIs that build on the APIs listed here and that are widely used on a typical Windows 2000 system.

Named Pipes and Mailslots

Named pipes and mailslots are programming APIs that Microsoft originally developed for OS/2 LAN Manager and then ported to Windows NT. Named pipes provide for reliable bidirectional communications, whereas mailslots provide unreliable unidirectional data transmission. An advantage of mailslots is that they support broadcast capability. In Windows 2000, both APIs take advantage of Windows 2000 security, which allows a server to control precisely which clients can connect to it.

The names servers assign to named pipes and clients conform to the Windows 2000 Universal Naming Convention (UNC), which is a protocol-independent way to identify resources on a Windows network. The implementation of UNC names is described later in the chapter.

Named Pipe Operation

Named pipe communication consists of a named pipe server and a named pipe client. A named pipe server is an application that creates a named pipe to which clients can connect. A named pipe's name has the format \\Server\Pipe\PipeName. The Server component of the name specifies the computer on which the named pipe server is executing (a named pipe server can't create a named pipe on a remote system), and the name can be a DNS name (for example, mspress.microsoft.com), a NetBIOS name (mspress), or an IP address (255.0.0.0). The Pipe component of the name must be the string "Pipe," and PipeName is the unique name assigned to a named pipe. The unique portion of the named pipe's name can include subdirectories; an example of a named pipe name with a subdirectory is \\MyComputer\Pipe\MyServerApp\ConnectionPipe.

A named pipe server uses the CreateNamedPipe Win32 function to create a named pipe. One of the function's input parameters is a pointer to the named pipe name, in the form\\.\Pipe\PipeName. The "\\.\" is a Win32-defined alias for "this computer." Other parameters the function accepts include an optional security descriptor that protects access to the named pipe, a flag that specifies whether the pipe should be bidirectional or unidirectional, a value indicating the maximum number of simultaneous connections the pipe supports, and a flag specifying whether the pipe should operate in byte mode or message mode.

Most networking APIs operate only in byte mode, which means that a message sent with one send function might require the receiver to perform multiple receives, building up the complete message from fragments. Named pipes operated in message mode simplify the implementation of a receiver because there is a one-to-one correspondence between sends and receives. A receiver therefore obtains an entire message each time it completes a receive and doesn't have to concern itself with keeping track of message fragments.

The first call to CreateNamedPipe for a particular name creates the first instance of that name and establishes the behavior of all named pipe instances having that name. A server creates additional instances, up to the maximum specified in the first call, with additional calls to CreateNamedPipe. After creating at least one named pipe instance, a server executes the ConnectNamedPipe Win32 function, which enables the named pipe the server created to establish connections with clients. ConnectNamedPipe can be executed synchronously or asynchronously, and it doesn't complete until a client establishes a connection with the instance (or an error occurs).

A named pipe client uses the Win32 CreateFile or CallNamedPipe function, specifying the name of the pipe a server has created, to connect to a server. If the server has performed a ConnectNamedPipe call, the client's security profile and the access it requests to the pipe (read, write) are validated against the named pipe's security descriptor. (See Chapter 8 for more information on the security-check algorithms Windows 2000 uses.) If the client is granted access to a named pipe, it receives a handle representing the client side of a named pipe connection and the server's call to ConnectNamedPipe completes.

After a named pipe connection is established, the client and server can use the ReadFile and WriteFile Win32 functions to read from and write to the pipe. Named pipes support both synchronous and asynchronous operation for message transmittal. Figure shows a server and client communicating through a named pipe instance.

Click to view at full size.

Figure Named pipe communications

A unique characteristic of the named pipe networking API is that it allows a server to impersonate a client by using the ImpersonateNamedPipeClient function. See the section "Impersonation" in Chapter 8 for a discussion of how impersonation is used in client/server applications.

Mailslot Operation

Mailslots provide an unreliable unidirectional broadcast mechanism. One example of an application that can use this type of communication is a time synchronization service, which might broadcast a source time across the domain every few seconds. Receiving the source-time message isn't crucial for every computer on the network and is therefore a good candidate for the use of mailslots.

Like named pipes, mailslots are integrated with the Win32 API. A mailslot server creates a mailslot by using the CreateMailslot function. CreateMailslot accepts a name of the form "\\.\Mailslot\MailslotName" as an input parameter. Again like named pipes, a mailslot server can create mailslots only on the machine it's executing on, and the name it assigns to a mailslot can include subdirectories. CreateMailslot also takes a security descriptor that controls client access to the mailslot. The handles returned by CreateMailslot are overlapped, which means that operations performed on the handles, such as sending and receiving messages, are asynchronous.

Because mailslots are unidirectional and unreliable, CreateMailslot doesn't take many of the parameters that CreateNamedPipe does. After it creates a mailslot, a server simply listens for incoming client messages by executing the ReadFile function on the handle representing the mailslot.

Mailslot clients use a naming format similar to that used by named pipe clients, but with variations that make it possible to broadcast messages to all the mailslots of a given name within the client's domain or a specified domain. To send a message to a particular instance of a mailslot, the client calls CreateFile, specifying the computer-specific name. An example of such a name is "\\Server\Mailslot\MailslotName." (The client can specify "\\.\" to represent the local computer.) If the client wants to obtain a handle representing all the mailslots of a given name on the domain it's a member of, it specifies the name in the format "\\*\Mailslot\MailslotName," and if the client wants to broadcast to all the mailslots of a given name within a different domain, the format it uses is "\\DomainName\Mailslot\MailslotName."

After obtaining a handle representing the client side of a mailslot, the client sends messages by calling WriteFile. Because of the way mailslots are implemented, only messages smaller than 425 bytes can be broadcast. If a message is larger than 425 bytes, the mailslot implementation uses a reliable communications mechanism that requires a one-to-one client/server connection, which precludes broadcast capability. Also, a quirk of the mailslot implementation causes messages of 425 or 426 bytes to be truncated to 424 bytes. These limitations make mailslots generally unsuitable for messages larger than 424 bytes. Figure shows an example of a client broadcasting to multiple mailslot servers within a domain.

Click to view at full size.

Figure Mailslot broadcast

Named Pipe and Mailslot Implementation

As evidence of their tight integration with Win32, named pipe and mailslot functions are all implemented in the Kernel32.dll Win32 client-side DLL. ReadFile and WriteFile, which are the functions applications use to send and receive messages using named pipes and mailslots, are the primary Win32 I/O routines. The CreateFile function, which a client uses to open either a named pipe or a mailslot, is also a standard Win32 I/O routine. However, the names specified by named pipe and mailslot applications specify file system namespaces managed by the named pipe file system driver (\Winnt\System32\Drivers\Npfs.sys) and the mailslot file system driver (\Winnt\System32\Drivers\Msfs.sys), as shown in Figure. The named pipe file system driver creates a device object named \Device\NamedPipe and a symbolic link to that object named \??\Pipe, and the mailslot file system driver creates a device object named \Device\Mailslot and a symbolic link named \??\Mailslot that points to that object. (See Chapter 3 for an explanation of the \?? object manager directory.) Names passed to CreateFile of the form \\.\Pipe\… and \\.\Mailslot\… have their prefix of \\.\ translated to \??\ so that the names resolve through a symbolic link to a device object. The special functions CreateNamedPipe and CreateMailslot use the corresponding native functions NtCreateNamedPipeFile and NtCreateMailslotFile.

Click to view at full size.

Figure Named pipe and mailslot implementation

Later in the chapter, we'll discuss how the redirector file system driver is involved when a name that specifies a remote named pipe or mailslot resolves to a remote system. However, when a named pipe or mailslot is created by a server or opened by a client, the appropriate file system driver (FSD) on the machine where the named pipe or mailslot is located is eventually invoked. There are several reasons why FSDs in kernel mode implement named pipes and mailslots, the main one being that they integrate with the object manager namespace and can use file objects to represent opened named pipes and mailslots. This integration results in several benefits:

  • The FSDs use kernel-mode security functions to implement standard Windows 2000 security for named pipes and mailslots.
  • Applications can use CreateFile to open a named pipe or mailslot because FSDs integrate with the object manager namespace.
  • Applications can use Win32 functions such as ReadFile and WriteFile to interact with named pipes and mailslots.
  • The FSDs rely on the object manager to track handle and reference counts for file objects representing named pipes and mailslots.
  • The FSDs can implement their own named pipe and mailslot namespaces, complete with subdirectories.

Because named pipes and mailslot name resolution uses the redirector FSD to communicate across the network, they indirectly rely on the CIFS protocol (described later). CIFS works by using the IPX, TCP/IP, and NetBEUI protocols, so applications running on systems that have at least one of these in common can use named pipes and mailslots.

EXPERIMENT
Listing the Named Pipe Namespace and Watching Named Pipe Activity

It's not possible to use the Win32 API to open the root of the named pipe FSD and perform a directory listing, but you can do this by using native API services. The PipeList tool (on the companion CD as \Sysint\Pipelist.exe) shows you the names of the named pipes defined on a computer as well as the number of instances that have been created for a name and the maximum number of instances as defined by a server's call to CreateNamedPipe. Here's an example of PipeList output:

C:\>pipelist
PipeList v1.01
by Mark Russinovich
http://www.sysinternals.com

Pipe Name                          Instances       Max Instances
------------------
InitShutdown                            2               -1
lsass                                   3               -1
ntsvcs                                 32               -1
scerpc                                  2               -1
net\NtControlPipe1                      1                1
DhcpClient                              1               -1
net\NtControlPipe2                      1                1
Winsock2\CatalogChangeListener-184-0    1                1
net\NtControlPipe3                      1                1
spoolss                                 2               -1
net\NtControlPipe4                      1                1
net\NtControlPipe5                      1                1
net\NtControlPipe0                      1                1
net\NtControlPipe6                      1                1
net\NtControlPipe7                      1                1
winreg                                  2               -1
Winsock2\CatalogChangeListener-208-0    1                1
atsvc                                   2               -1
net\NtControlPipe8                      1                1
SecondaryLogon                          1               10
SfcApi                                  2               -1
ProfMapApi                              2               -1
winlogonrpc                             2               -1
Winsock2\CatalogChangeListener-d8-0     1                1
epmapper                                2               -1
POLICYAGENT                             2               -1
WMIEP_e4                                2               -1
WMIEP_1d4                               2               -1
tapsrv                                  2               -1
ROUTER                                  9               -1
WMIEP_3c4                               2               -1
WMIEP_3d0                               2               -1
WMIEP_3ec                               2               -1

It's clear from this output that several system components use named pipes as their communications mechanism. For example, the InitShutdown pipe is created by Winlogon to accept remote shutdown commands, and the SecondaryLogon pipe is created by the Runas service to perform logon operations on behalf of the Runas utility. You can determine what process has each of these pipes open by using the object search facility in HandleEx (on the companion CD as \Sysint\Handleex.exe). Note that a Max Instances value of -1 means that there is no upper limit on the number of instances for the given name.

The Filemon file system filter driver (on the companion CD as \Sysint\Filemon.exe) is able to attach to either the Npfs.sys or Msfs.sys file system drivers and to therefore see all named pipe or mailslot activity occurring on a system. Select the Named Pipes or Mail Slots menu entries from Filemon's Drives menu to have Filemon attach to the corresponding driver. The following screen shot shows Filemon capturing the named pipe activity generated when the My Network Places icon on the desktop was opened. Notice the messages transmitted through the Lsass and workstation service named pipes.

Click to view at full size.

Windows Sockets

Windows Sockets (Winsock) is Microsoft's implementation of BSD (Berkeley Software Distribution) Sockets, a programming API that became the standard by which UNIX systems have communicated over the Internet since the 1980s. Support for sockets on Windows 2000 makes the task of porting UNIX networking applications to Windows 2000 relatively straightforward. Winsock includes most of the functionality of BSD Sockets but also includes Microsoft-specific enhancements, which continue to evolve. Winsock supports reliable-connection-oriented communication as well as unreliable-connectionless communication. Windows 2000 provides Winsock 2.2, which is also either included with or available as an add-on for all versions of Consumer Windows.

Winsock includes the following features:

  • Support for scatter-gather and asynchronous application I/O.
  • Quality of service (QoS) conventions so that applications can negotiate latency and bandwidth requirements when the underlying network supports QoS.
  • Extensibility so that Winsock can be used with protocols other than those Windows 2000 requires it to support.
  • Support for integrated namespaces other than those defined by a protocol an application is using with Winsock. A server can publish its name in Active Directory, for example, and using namespace extensions, a client can look up the server's address in Active Directory.
  • Support for multipoint messages where messages transmit to multiple receivers simultaneously.

We'll examine typical Winsock operation and then describe ways that Winsock can be extended.

Winsock Operation

After initializing the Winsock API with a call to an initialization function, the first step a Winsock application takes is to create a socket that will represent a communications endpoint. A socket must be bound to an address on the local computer, so binding is the second step the application performs. Winsock is a protocol-independent API, so an address can be specified for any protocol installed on the system over which Winsock operates (NetBEUI, TCP/IP, IPX). After binding is complete, the steps taken by a server and client diverge, as do steps for connection-oriented and connectionless socket operation.

A connection-oriented Winsock server performs a listen operation on the socket, indicating the number of connections that it can support for the socket. Then it performs an accept operation to allow a client to connect to the socket. If there is a pending connection request, the accept call completes immediately; otherwise, it completes when a connection request arrives. When a connection is made, the accept function returns a new socket that represents the server's end of the connection. The server can perform receive and send operations by using functions such as recv and send.

Connection-oriented clients connect to a server by using the Winsock connect function that specifies a remote address. When a connection is established, the client can send and receive messages over its socket. Figure shows connection-oriented communication between a Winsock client and server.

Click to view at full size.

Figure Connection-oriented Winsock operation

After binding an address, a connectionless server is no different from a connectionless client: it can send and receive messages over the socket simply by specifying the remote address with each message. When using connectionless messages, which are also called datagrams, a sender learns that a message wasn't received when the sender obtains an error code the next time a receive operation is performed.

Winsock Extensions

A powerful feature from a Windows programming point of view is that the Winsock API is integrated with Windows messages. A Winsock application can take advantage of this feature to perform asynchronous socket operations and receive notification of an operation's completion via a standard Windows message or through the execution of a callback function. This capability simplifies the design of a Windows application because the application doesn't need to be multithreaded or manage synchronization objects to both perform network I/O and respond to user input or requests from the window manager to update the application windows. The names of message-based versions of BSD-style Winsock functions usually begin with the prefix WSA—for example, WSAAccept.

In addition to supporting functions that correspond directly to those implemented in BSD Sockets, Microsoft has added a handful of functions that aren't part of the Winsock standard. Two of these functions, AcceptEx and TransmitFile, are worth describing because many Web servers on Windows 2000 use them to achieve high performance. AcceptEx is a version of the accept function that, in the process of establishing a connection with a client, returns the client's address and the client's first message. With this function, a Web server avoids executing multiple Winsock functions that would otherwise be required.

After establishing a connection with a client, a Web server usually sends a file, such as a Web page, to the client. The TransmitFile function's implementation is integrated with the Windows 2000 cache manager so that a client can send a file directly from the file system cache. Sending data in this way is called zero-copy because the server doesn't have to touch the file data to send it: it simply specifies a handle to a file and the range(s) of the file to send. In addition, TransmitFile allows a server to prepend or append data to the file's data so that the server can send header information, which might include the name of the Web server and a field that indicates to the client the size of the message the server is sending. Internet Information Services (IIS) 5.0, which is bundled with Windows 2000, uses both AcceptEx and TransmitFile.

Extending Winsock

Winsock is an extensible API on Windows 2000 because third parties can add a transport service provider that interfaces Winsock with other protocols as well as a namespace service provider to augment Winsock's name-resolution facilities. Service providers plug in to Winsock using the Winsock service provider interface (SPI). When a transport service provider is registered with Winsock, Winsock uses the transport service provider to implement socket functions, such as connect and accept, for the address types that the provider indicates it implements. There are no restrictions on how the transport service provider implements the functions, but the implementation usually involves communicating with a transport driver in kernel mode.

A requirement of any Winsock client/server application is for the server to make its address available to clients so that the clients can connect to the server. Standard services that execute on the TCP/IP protocol use "well-known addresses" to make their addresses available. As long as a browser knows the name of the computer a Web server is running on, it can connect to the Web server by specifying the well-known Web server address (the IP address of the server concatenated with :80, the port number used for HTTP). Namespace service providers make it possible for servers to register their presence in other ways. For example, one namespace service provider might on the server side register the server's address in Active Directory, and on the client side look up the server's address in Active Directory. Namespace service providers supply this functionality to Winsock by implementing standard Winsock name-resolution functions such as gethostbyaddr, getservbyname, and getservbyport.

EXPERIMENT
Looking at Winsock Service Providers

The Windows Sockets Configuration utility (Sporder.exe) included with the Platform SDK shows the registered Winsock transport and namespace providers and allows you to change the order in which transport service providers are enumerated. For example, if there are two TCP/IP transport service providers, the first one listed is the default provider for Winsock applications using the TCP/IP protocol. Here's a screen shot from Sporder showing the registered transport service providers:

Click to view at full size.

Winsock Implementation

Winsock's implementation is shown in Figure. Its application interface consists of an API DLL, Ws2_32.dll (\Winnt\System32\Ws2_32.dll), which provides applications access to Winsock functions. Ws2_32.dll calls on the services of namespace and transport service providers to carry out name and message operations. The Msafd.dll library acts as a transport service provider for the protocols Microsoft provides support for in Winsock, and Msafd.dll uses Winsock Helper libraries that are protocol specific to communicate with kernel-mode protocol drivers. For example, Wshtcpip.dll is the TCP/IP helper, and Wshnetbs.dll is the NetBEUI helper. Mswsock.dll (\Winnt\System32\Mswsock.dll) implements the Microsoft Winsock extension functions, such as TransmitFile, AcceptEx, and WSARecvEx. Windows 2000 ships with helper DLLs for TCP/IP, NetBEUI, AppleTalk, IPX/SPX, ATM, and IrDA (Infrared Data Association) and namespace service providers for DNS (TCP/IP), Active Directory, and IPX/SPX.

Click to view at full size.

Figure Winsock implementation

Like the named pipe and mailslot APIs, Winsock integrates with the Win32 I/O model and uses file handles to represent sockets. This support requires the aid of a kernel-mode file system driver, so Msafd.dll uses the services of the Ancillary Function Driver (AFD - \Winnt\System32\Drivers\Afd.sys) to implement socket-based functions. AFD is a TDI client and executes network socket operations, such as sending and receiving messages, by sending TDI IRPs to protocol drivers. AFD isn't coded to use particular protocol drivers; instead, Msafd.dll informs AFD of the name of the protocol used for each socket so that AFD can open the device object representing the protocol.

Remote Procedure Call

Remote procedure call (RPC) is a network programming standard originally developed in the early 1980s. The Open Software Foundation (now The Open Group) made RPC part of the distributed computing environment (DCE) distributed computing standard. Although there is a second RPC standard, SunRPC, the Microsoft RPC implementation is compatible with the OSF/DCE standard. RPC builds on other networking APIs, such as named pipes or Winsock, to provide an alternate programming model that in some sense hides the details of networking programming from an application developer.

RPC Operation

An RPC facility is one that allows a programmer to create an application consisting of any number of procedures, some that execute locally and others that execute on remote computers via a network. It provides a procedural view of networked operations rather than a transport-centered view, thus simplifying the development of distributed applications.

Networking software is traditionally structured around an I/O model of processing. In Windows 2000, for example, a network operation is initiated when an application issues a remote I/O request. The operating system processes it accordingly by forwarding it to a redirector, which acts as a remote file system by making the client interaction with the remote file system invisible to the client. The redirector passes the operation to the remote file system, and after the remote system fills the request and returns the results, the local network card interrupts. The kernel handles the interrupt, and the original I/O operation completes, returning results to the caller.

RPC takes a different approach altogether. RPC applications are like other structured applications, with a main program that calls procedures or procedure libraries to perform specific tasks. The difference between RPC applications and regular applications, however, is that some of the procedure libraries in an RPC application execute on remote computers, as shown in Figure, whereas others execute locally.

Click to view at full size.

Figure RPC operation

To the RPC application, all the procedures appear to execute locally. In other words, instead of making a programmer actively write code to transmit computational or I/O-related requests across a network, handle network protocols, deal with network errors, wait for results, and so forth, RPC software handles these tasks automatically. And the Windows 2000 RPC facility can operate over any available transports loaded into the system.

To write an RPC application, the programmer decides which procedures will execute locally and which will execute remotely. For example, suppose an ordinary workstation has a network connection to a Cray supercomputer or to a machine designed specifically for high-speed vector operations. If the programmer were writing an application that manipulated large matrices, it would make sense from a performance point of view to offload the mathematical calculations to the remote computer by writing the program as an RPC application.

RPC applications work like this: As an application runs, it calls local procedures as well as procedures that aren't present on the local machine. To handle the latter case, the application is linked to a local static-link library or DLL that contains stub procedures, one for each remote procedure. For simple applications, the stub procedures are statically linked with the application, but for bigger components the stubs are included in separate DLLs. In DCOM, covered later in the chapter, the latter method is typically used. The stub procedures have the same name and use the same interface as the remote procedures, but instead of performing the required operations, the stub takes the parameters passed to it and marshals them for transmission across the network. Marshaling parameters means ordering and packaging them in a particular way to suit a network link, such as resolving references and picking up a copy of any data structures that a pointer refers to.

The stub then calls RPC run-time procedures that locate the computer where the remote procedure resides, determine which transport mechanisms that computer uses, and send the request to it using local transport software. When the remote server receives the RPC request, it unmarshals the parameters (the reverse of marshaling them), reconstructs the original procedure call, and calls the procedure. When the server finishes, it performs the reverse sequence to return results to the caller.

In addition to the synchronous function-call-based interface described here, Windows 2000 RPC also supports asynchronous RPC. Asynchronous RPC lets an RPC application execute a function but not wait until the function completes to continue processing. Instead, the application can execute other code and later, when a response has arrived from the server, the RPC run time signals an event object the client associates with the asynchronous call. The client can use standard Win32 functions, such as WaitForSingleObject, to learn of the function's completion.

Besides the RPC run time, Microsoft's RPC facility includes a compiler, called the Microsoft Interface Definition Language (MIDL) compiler. The MIDL compiler simplifies the creation of an RPC application. The programmer writes a series of ordinary function prototypes (assuming a C or C++ application) that describe the remote routines and then places the routines in a file. The programmer then adds some additional information to these prototypes, such as a network-unique identifier for the package of routines and a version number, plus attributes that specify whether the parameters are input, output, or both. The embellished prototypes form the developer's Interface Definition Language (IDL) file.

Once the IDL file is created, the programmer compiles it with the MIDL compiler, which produces both client-side and server-side stub routines, mentioned previously, as well as header files to be included in the application. When the client-side application is linked to the stub routines file, all remote procedure references are resolved. The remote procedures are then installed, using a similar process, on the server machine. A programmer who wants to call an existing RPC application need only write the client side of the software and link the application to the local RPC run-time facility.

The RPC run time uses a generic RPC transport provider interface to talk to a transport protocol. The provider interface acts as a thin layer between the RPC facility and the transport, mapping RPC operations onto the functions provided by the transport. The Windows 2000 RPC facility implements transport provider DLLs for named pipes, NetBIOS, and TCP/IP. You can write new provider DLLs to support additional transports. In a similar fashion, the RPC facility is designed to work with different network security facilities.

Most of the Windows 2000 networking services are RPC applications, which means that both local processes and processes on remote computers can call them. Thus, a remote client computer can call the server service to list shares, open files, write to print queues, or activate users on your server, or it can call the messenger service to direct messages to you (all subject to security constraints, of course).

Server name publishing, which is the ability of a server to register its name in a location accessible for client lookup, is in RPC and is integrated with Active Directory. If Active Directory isn't installed, the RPC name locator services fall back on NetBIOS broadcast. This behavior ensures interoperability with Windows NT 4 systems and allows RPC to function on stand-alone servers and workstations.

RPC Security

Windows 2000 RPC includes integration with security support providers (SSPs) so that RPC clients and servers can use authenticated or encrypted communications. When an RPC server wants secure communication, it must register its SSP-specific principal name with an SSP. A client registers its security credentials when it binds to a server, specifying the server's principal name. At the time of the binding, the client also specifies the authentication level it wants. Various authentication levels exist to ensure that only authorized clients connect to a server, verify that each message a server receives originates at an authorized client, check the integrity of RPC messages to detect manipulation, and even encrypt RPC message data. Obviously, higher authentication levels require more processing.

An SSP handles the details of performing network communication authentication and encryption, not only for RPC but also for Winsock. Windows 2000 includes a number of built-in SSPs, including a Kerberos SSP to implement Kerberos version 5 authentication, and Secure Channel (SChannel), which implements Secure Sockets Layer (SSL), Transport Layer Security (TLS) protocol, and private communication technology (PCT). In the absence of a specified SSP, RPC software uses the built-in security of named pipes.

Another feature of RPC security is the ability of a server to impersonate the security identity of a client with the RpcImpersonateClient function. After a server has finished performing impersonated operations on behalf a client, it returns to its own security identity by calling RpcRevertToSelf or RpcRevertToSelfEx. (See Chapter 8 for more information on impersonation.)

RPC Implementation

RPC implementation is depicted in Figure, which shows that an RPC-based application links with the RPC run-time DLL (\Winnt\System32\Rpcrt4.dll). The RPC run-time DLL provides marshaling and unmarshaling functions for use by an application's RPC function stubs as well as functions for sending and receiving marshaled data. The RPC run-time DLL includes support routines to handle RPC over a network as well as a form of RPC called local RPC. Local RPC can be used for communication between two processes located on the same system, and the RPC run-time DLL uses the local procedure call (LPC) facilities in kernel mode as the local networking API. (See Chapter 3 for more information on LPCs.) When RPC is based on nonlocal communication mechanisms, the RPC run-time DLL uses the Winsock, named pipe, or Message Queuing (described shortly) APIs.

Click to view at full size.

Figure RPC implementation

For name registry and lookup, RPC applications link with the RPC name services DLL (\Winnt\System32\Rpcns4.dll). The DLL communicates with the RPC Subsystem (RPCSS - \Winnt\System32\Rpcss.dll), which is implemented as a Win32 service. RPCSS is itself an RPC application that communicates with instances of itself on other systems to perform name lookup and registration. (For clarity, Figure doesn't show RPCSS link with the RPC run-time DLL.)

Common Internet File System (CIFS)

Common Internet File System (CIFS) is an enhanced form of the Server Message Block (SMB) protocol, which is the protocol Windows 2000 uses to implement file sharing. Because applications access remote files using standard Win32 file I/O functions, applications don't directly use the CIFS protocol, but the protocol is used to process the I/O request. CIFS defines printer-sharing conventions, so Windows 2000 uses CIFS for that as well. Although CIFS isn't itself an API, we cover it in this section because file and printer sharing is built on CIFS and is exposed to applications via the Win32 API.

CIFS is a published Microsoft standard (documented in the Platform SDK) that allows third parties to interoperate with Windows 2000 file servers and with Windows 2000 file sharing clients. For example, the Samba shareware suite allows UNIX systems to serve files to Windows 2000 clients and for UNIX applications to access files served by Windows 2000 systems. Other platforms that support CIFS include DEC VMS and Apple Macintosh.

File sharing on Windows 2000 is based on a redirector FSD (redirector, for short) executing on a client machine that communicates with a server FSD executing on the server. The redirector FSD intercepts Win32 file I/O directed at files residing on the server and transmits CIFS messages to the server file system to execute client requests. The server receives CIFS messages and translates them back to I/O operations that it issues to local FSDs, such as NTFS, running on the server. Figure shows a redirector and server communicating with one another.

Click to view at full size.

Figure CIFS file sharing

Because they are integrated with the Windows 2000 I/O system, redirector and server FSDs have several advantages over alternate user-space implementations of file servers:

  • They can interact directly with TDI transports and local FSDs.
  • They can integrate with the cache manager to seamlessly cache server file data on client systems. (The caching protocol Windows 2000 uses is described shortly.)
  • Applications can use standard Win32 file I/O functions, such as CreateFile, ReadFile, and WriteFile to access remote files.

Windows 2000 redirector and server FSDs rely on standard network-resource naming conventions that all kernel-mode file servers and client software use. If a remote file share is connected using a drive letter, network file names are specified in the same way as local names. However, redirector also supports UNC names. Network-resource name resolution is described in the section "Network-Resource Name Resolution" later in this chapter.

CIFS Implementation

The redirector FSD on Windows 2000 is implemented in a port/miniport model common to many other device driver types. (See Chapter 9 for information on device drivers.) Microsoft provides a redirector library named \Winnt\System32\Drivers\Rdbss.sys to which developers can write a redirector miniport. The redirector library hides many details of implementing a redirector, such as integrating with the cache manager, the memory manager, and TDI transports. The CIFS miniport driver is named \Winnt\System32\Drivers\Mrxsmb.sys.

Rdbss uses the cache manager services described in Chapter 11 and Chapter 12 to cache file data and to take advantage of intelligent read-ahead. The CIFS miniport driver sends CIFS commands to a remote server by way of the TDI API. It can use any transport that supports the TDI interface, such as NetBEUI, NetBT (NetBIOS over TCP/IP), and TCP/IP.

On a system acting as a file server, the server (\Winnt\System32\Drivers\Srv.sys) FSD listens for CIFS commands originating on client machines and acts as a surrogate interface to the local FSD on which accessed files reside. The server FSD uses file system interfaces implemented by native Windows 2000 FSDs to implement zero-copy send capability. The interfaces allow for the server FSD to obtain a memory descriptor list (MDL) description of a file's data residing in the file system cache of the server and to pass the MDL to a TDI transport for transmission across the network using a network adapter driver. (See Chapter 7 for more information on MDLs.) Without the support of local FSDs and the cache manager, the server FSD would have to copy file data into its own buffers that it would subsequently pass to TDI transports.

Both the server FSD and the redirector have corresponding Win32 services, Server and Workstation, that execute in the service control manager (SCM) process to provide administrative management interfaces to the drivers.

Distributed File Caching

If a single client accesses a file on a server, it's obvious that the client can safely cache the file's data on the client system. When two clients access the same file, however, steps must be taken to provide a consistent view of the file between the two clients and the server. The Windows 2000 solution to this problem, which is known as distributed cache coherency, is implemented through a mechanism called an opportunistic lock (oplock). When a client wants to access a server file, it must first request an oplock. The type of oplock that the server grants the client dictates the kind of caching that the client can perform.

There are three main types of oplock:

  • A Level I oplock is granted when a client has exclusive access to a file. A client holding this type of oplock for a file can cache both reads and writes on the client system.
  • A Level II oplock represents a shared file lock. Clients that hold a Level II oplock can cache reads, but writing to the file invalidates the Level II oplock.
  • A Batch oplock is the most permissive kind of oplock. A client with this oplock can cache both reads and writes to the file as well as open and close the file without requesting additional oplocks. Batch oplocks are typically used only to support the execution of batch files, which can open and close a file repeatedly as they execute.

If a client has no oplock, it can cache neither read or write data locally and instead must retrieve data from the server and send all modifications directly to the server.

An example, shown in Figure, will help illustrate oplock operation. The server automatically grants a Level I oplock to the first client to open a server file for access. The redirector on the client caches the file data for both reads and writes in the file cache of the client machine. If a second client opens the file, it too requests a Level I oplock. However, because there are now two clients accessing the same file, the server must take steps to present a consistent view of the file's data to both clients. If the first client has written to the file, as is the case in Figure, the server revokes its oplock and grants neither client an oplock. When the first client's oplock is revoked, or broken, the client flushes any data it has cached for the file back to the server.

If the first client hadn't written to the file, the first client's oplock would have been broken to a Level II oplock, which is the same type of oplock the server grants to the second client. Now both clients can cache reads, but if either writes to the file, the server revokes their oplocks so that noncached operation commences. Once oplocks are broken, they aren't granted again for the same open instance of a file. However, if a client closes a file and then reopens it, the server reassesses what level of oplock to grant the client based on what other clients have the file open and whether or not at least one of them has written to the file.

Click to view at full size.

Figure Oplock example

NetBIOS

Until the 1990s, the Network Basic Input/Output System (NetBIOS) programming API had been the most widely used programming API on PCs. NetBIOS allows for both reliable-connection-oriented and unreliable-connectionless communication. Windows 2000 supports NetBIOS for its legacy applications. Microsoft discourages application developers from using NetBIOS because other APIs, such as named pipes and Winsock, are much more flexible and portable. NetBIOS is supported by the TCP/IP, NetBEUI, and IPX/SPX protocols on Windows 2000.

NetBIOS Names

NetBIOS relies on a naming convention whereby computers and network services are assigned a 16-byte name called a NetBIOS name. The 16th byte of a NetBIOS name is treated as a modifier that can specify a name as unique or as part of a group. Only one instance of a unique NetBIOS name can be assigned to a network, but multiple applications can assign the same group name. A client can broadcast messages by sending them to a group name.

To support interoperability with Windows NT 4 systems as well as Consumer Windows, Windows 2000 automatically defines a NetBIOS name for a domain that is the first 15 bytes of the Domain Name System (DNS) name that an administrator assigns to the domain. For example, if a domain were named mspress.microsoft.com, the NetBIOS name of the domain would be mspress. Similarly, Windows 2000 requires an administrator to assign each computer a NetBIOS name at the time of installation.

Another concept used by NetBIOS is that of LAN adapter (LANA) numbers. A LANA number is assigned to every NetBIOS-compatible protocol that layers above a network adapter. For example, if a computer has two network adapters and TCP/IP and NetBEUI can use either adapter, there would be four LANA numbers. LANA numbers are important because a NetBIOS application must explicitly assign its service name to each LANA through which it's willing to accept client connections. If the application listens for client connections on a particular name, clients can access the name only via protocols on the network adapters for which the name is registered.

A networking service called Windows Internet Name Service (WINS) maintains the mapping between NetBIOS names and TCP/IP protocol addresses. If WINS isn't installed, NetBIOS uses name broadcasting to propagate names within a Windows network. Note that NetBIOS names are secondary to DNS names: computer names are registered and resolved first through DNS, with Windows 2000 falling back on NetBIOS names only if DNS name resolution fails. (DNS name resolution is described in the section "Network-Resource Name Resolution" later in this chapter.)

NetBIOS Operation

A NetBIOS server application uses the NetBIOS API to enumerate the LANAs present on a system and assign a NetBIOS name representing the application's service to each LANA. If the server is connection oriented, it performs a NetBIOS listen command to wait for client connection attempts. After a client is connected, the server executes NetBIOS functions to send and receive data. Connectionless communication is similar, but the server simply reads messages without establishing connections.

A connection-oriented client uses NetBIOS functions to establish a connection with a NetBIOS server and then executes further NetBIOS functions to send and receive data. An established NetBIOS connection is also known as a session. If the client wants to send connectionless messages, it simply specifies the NetBIOS name of the server with the send function.

NetBIOS consists of a number of functions, but they all route through the same interface: Netbios. This routing scheme is the result of a legacy left over from the time when NetBIOS was implemented on MS-DOS as an MS-DOS interrupt service. A NetBIOS application would execute an MS-DOS interrupt and pass a data structure to the NetBIOS implementation that specified every aspect of the command being executed. As a result, the Netbios function in Windows 2000 takes a single parameter, which is a data structure that contains the parameters specific to the service the application requests.

EXPERIMENT
Using Nbtstat to See NetBIOS Names

You can use the Nbtstat command, which is included with Windows 2000, to list the active sessions on a system, the NetBIOS-to-TCP/IP name mappings cached on a computer, and the NetBIOS names defined on a computer. Here's an example of the Nbtstat command with the -n option, which lists the NetBIOS names defined on the computer:

C:\>nbtstat -n
Local Area Connection:
Node IpAddress: [10.0.0.5] Scope Id: []

                NetBIOS Local Name Table

       Name               Type         Status
---------------------------------------------
    MARKLAP        <00>  UNIQUE      Registered
    MARKLAP        <20>  UNIQUE      Registered
    MARK           <00>  GROUP       Registered
    MARK           <1E>  GROUP       Registered

\Device\NetBT_Tcpip_{0A546AD9-3AD1-4A89-858B-1ADBF9AC5620}:
Node IpAddress: [32.100.225.5] Scope Id: []

                NetBIOS Local Name Table

       Name               Type         Status
    ---------------------------------------------
    MARKLAP        <00>  UNIQUE      Registered
    MARK           <00>  GROUP       Registered
    MARK           <1E>  GROUP       Registered

NetBIOS API Implementation

The components that implement the NetBIOS API are shown in Figure. The Netbios function is exported to applications by \Winnt\System32\Netapi32.dll. Netapi32.dll opens a handle to the kernel-mode driver named the NetBIOS emulator (\Winnt\System32\Drivers\Netbios.sys) and issues Win32 DeviceIoControl file commands on behalf of an application. The NetBIOS emulator translates NetBIOS commands issued by an application into TDI commands that it sends to protocol drivers.

Click to view at full size.

Figure NetBIOS API implementation

If an application wants to use NetBIOS over the TCP/IP protocol, the NetBIOS emulator requires the presence of the NetBT driver (\Winnt\System32\Drivers\Netbt.sys). NetBT is known as the NetBIOS over TCP/IP driver and is responsible for supporting NetBIOS semantics that are inherent to the NetBEUI protocol (described later in this chapter), but not the TCP/IP protocol. For example, NetBIOS relies on NetBEUI's message-mode transmission and NetBIOS name resolution facilities, so the NetBT driver implements them on top of the TCP/IP protocol. Similarly, the NwLinkNB driver implements NetBIOS semantics over the IPX/SPX protocol.

Other Networking APIs

Windows 2000 includes other networking APIs that are used less frequently or are layered on the APIs already described (and outside the scope of this book). Three of these, however, Telephony API (TAPI), Distributed Component Object Model (DCOM), and Message Queuing, are important enough to the operation of a Windows 2000 system and many applications to merit brief descriptions.

Telephony API (TAPI)

Telephony integrates computers with communications devices such as telephones and modems. In Windows 2000, telephony also encompasses applications such as Voice over Internet Protocol (VoIP), multicast multimedia conferencing, and real-time collaboration (RTC). Windows 2000 includes the Telephony API (TAPI) for applications that want to communicate over telephony-supported devices. TAPI abstracts the details of device management so that TAPI applications can work over different devices without change. Windows 2000 ships with two versions of TAPI, TAPI 2.2 for C applications and TAPI 3.0 for COM applications.

TAPI can be broken down into subset APIs for device, session, and media control. Device control interfaces allow TAPI to communicate device characteristics and changes to those characteristics to a TAPI application and for a TAPI application to query the device's characteristics. Characteristics include lines, address identifiers, device events, and media types. Session control interfaces let an application establish a connection between two or more addresses. Session control operations are similar to the ones supported by sophisticated telephones and include session initiation, answer, accept, forward, park, transfer, and drop. Finally, media control interfaces allow a TAPI application to perform operations such as tone-detection and dialing.

The Microsoft Telephony architecture, shown in Figure, is centered on the TAPI service (\Winnt\System32\Tapisrv.dll), which runs as a Win32 service in a Service Host process. (See Chapter 5 for more information on Win32 services.) TAPI applications use the TAPI client-side DLL (\Winnt\System32\Tapi32.dll) to communicate via RPCs with the TAPI service.

Click to view at full size.

Figure TAPI architecture

To support device abstraction, the TAPI service loads TAPI service providers (TSPs) that provide interfaces to a particular device or class of devices. For example, the Unimodem TSP interfaces the TAPI service with most types of modems. TAPI also includes Media Service Providers (MSPs) that allow a TAPI application enhanced media-specific control over a medium. An MSP DLL loaded by the application has a corresponding TSP in the TAPI server. Other TSPs that come with Windows 2000 include the following:

  • Remote TSP provides access to remote communications resources such as modem pools.
  • H.323 TSP allows TAPI applications to make and receive video and audio calls according to the H.323 telephony protocol.
  • NDIS Proxy TSP (NDPTSP) presents NDIS 5 miniports (described later in the chapter) as TAPI lines.
  • Kernel-Mode Device Driver (KMDD) TSP presents legacy NDIS 4 miniports for WAN devices as TAPI lines.
  • IP Conference TSP supports conferencing over TCP/IP connections.

The TAPI architecture and documentation also make it possible for third parties to develop their own TAPI TSPs.

DCOM

Microsoft's COM API lets applications consist of different components, each component being a replaceable self-contained module. A COM object exports an object-oriented interface to methods for manipulating the data within the object. Because COM objects present well-defined interfaces, developers can implement new objects to extend existing interfaces and dynamically update applications with the new support.

DCOM extends COM by letting an application's components reside on different computers, which means that applications don't need to be concerned that one COM object might be on the local computer and another might be across the LAN. DCOM thus provides location transparency, which simplifies developing distributed applications. DCOM isn't a self-contained API but relies on RPC to carry out its work.

Message Queuing

Microsoft's newest networking service, Message Queuing, was introduced in Windows NT 4 Enterprise Edition. Message Queuing is a general-purpose platform for developing distributed applications that take advantage of loosely coupled messaging. Message Queuing is therefore an API and a messaging infrastructure. Its flexibility comes from the fact that its queues serve as message repositories in which senders can queue messages for receivers, and receivers can dequeue the messages at their discretion. Senders and receivers do not need to establish connections to use Message Queuing, nor do they even need to be executing at the same time, which allows for disconnected asynchronous message exchange.

A notable feature of Message Queuing is that it is integrated with Microsoft Transaction Server (MTS) and SQL Server, so it can participate in Microsoft Distributed Transaction Coordinator (MS DTC) coordinated transactions. Using MS DTC with Message Queuing allows you to develop reliable transaction functionality to three-tier applications.


The CHM file was converted to HTM by Trial version of ChmDecompiler.
Download ChmDecompiler at: http://www.zipghost.com

 Python   SQL   Java   php   Perl 
 game development   web development   internet   *nix   graphics   hardware 
 telecommunications   C++ 
 Flash   Active Directory   Windows