Windows IT Pro
Windows IT Library
  - Advertise        
Windows IT Pro Logo

  Home  |   Books  |   Chapters  |   Topics  |   Authors  |   Book Reviews  |   Whitepapers  |   About Us  |   Contact Us  |   ITTV  |   IT Jobs

search for  on    power search   help
 






Local Procedure Call
View the book table of contents
Author: Prasad Dabak
Milind Borate
Sandeep Phadke
Published: October 1999
Copyright: 1999
Publisher: M&T Books
 


Abstract
A local procedure call (LPC) is the communication mechanism used by Windows NT subsystems. This chapter introduces subsystems and then provides a detailed discussion on the undocumented LPC mechanism.

MICROSOFT DESIGNED THE local procedure call (LPC) facility to enable efficient communication with what Windows NT calls the subsystems. Although you do not need to know about subsystems before understanding the LPC mechanism, it is certainly interesting and advisable. In this chapter, we discuss the subsystems and then shed some light on the undocumented LPC mechanism.


THE ORIGIN OF THE SUBSYSTEMS

Although Microsoft never stated what “NT” stood for, one popular theory suggests that it refers to “New Technology.” That’s not to say everything that goes inside Windows NT is new. Windows NT has borrowed several concepts from earlier operating systems. For example, the NTFS (New Technology File System) borrows a lot from the HPFS (High Performance File System) of IBM’s OS/2. The Win32 API itself is an extension of the Windows 16-bit API. The Windows NT 3.51 user interface comes from Windows 3.1 and Windows NT 4.0 inherits its interface from Windows 95. Windows 2000 (Beta 3) maintains more or less the same user interface as Windows NT 4.0. In this section, we discuss the overall architecture of Windows NT, which Microsoft borrowed from the MACH operating system, originally developed at Carnegie Mellon University.

DOS and Unix variants dominated the operating systems world in the 1980s. DOS has a monolithic architecture, composed of a single lump of code. Unix follows the layered architecture, where the operating system divides into layers such that each layer uses only the interface provided by the lower layers. The MACH operating system follows a new client-server approach. The initial versions of MACH were based on BSD Unix 4.3.

The MACH team focused on two major goals. First, they wanted to have a more structured code than BSD 4.3. Second, they wanted to support different variants of the Unix API. They achieved both these goals by pushing the execution of kernel code to user-mode processes, which acted as servers. The MACH kernel appears very small, providing only the basic system services common to all Unix APIs. Therefore, we call it a micro-kernel. The server processes run in user mode and provide a sophisticated API interface. The normal application processes are clients of these server processes. When a client process invokes an API function, the emulation library, which links with the client code, transparently passes on the call to the server process. You can accomplish this using a facility similar to RPC (remote procedure call). The server process, after carrying out any necessary processing, returns the results to the client.

To support a new API in the MACH environment, you need to write a server process and emulation library, which support the new API. Not all server processes provide a different API. Some provide generic functionality such as memory management or TTY management.

The Windows NT design team sought goals similar to that of MACH’s developers. They wanted to support Win32, OS/2, and POSIX APIs, while keeping room for future APIs. Client-server architecture proved a natural choice.

The servers are called as the protected subsystems in Windows NT. Subsystems are user-mode processes running in a local system security context. We call them protected subsystems because they are separate processes operating in separate address spaces and hence are protected from client access/modification. There are two types of subsystems:
  • Integral subsystems
  • Environment subsystems
Integral Subsystems
An integral subsystem performs some essential operating system task. For Windows NT, this group includes the Local Security Authority (lsass.exe), the Security Accounts Manager, the Session Manager (smss.exe), and the network server. The Local Security Authority (LSA) subsystem manages security access tokens for users. The Security Accounts Manager (SAM) subsystem maintains a database of information on user accounts, including passwords, any account groups a given user belongs to, the access rights each user is allowed, and any special privileges a given user has. The Session Manager subsystem starts and keeps track of NT logon sessions and serves as an intermediary among protected subsystems.

Environment Subsystems
An environment subsystem is a server that appears to perform operating system functions for its native applications by calling system services. An environment subsystem runs in user mode and its interface to end-users emulates another operating system, such as OS/2 or POSIX–on top of Windows NT. Even the Win32 API implements through a subsystem process under Windows NT 3.51.

Note: Not all the API functions in the client-side DLLs need to pass the call to the subsystem process. For example, most of the KERNEL32.DLL calls can directly map onto the system services provided by the kernel. Such API functions invoke the system services via NTDLL.DLL. Most of the USER32.DLL functions and GDI32.DLL functions pass on the call to the subsystem process. (In Windows NT 4.0, Microsoft moved the Win32 subsystem inside the kernel for performance reasons.)

The system call interface provided by the Windows NT kernel is called as the native API. The Win32 subsystem uses the native API for implementing the Win32 API. Generally, user programs make calls to an API provided by some subsystem, avoiding the use of a cumbersome, native API. We refer to the user programs as the clients of the subsystem that provides the API used by these programs.

The communication between the client processes and the subsystem happens through a mechanism called local procedure call (LPC), specially designed by Microsoft for that purpose. For unknown reasons, Microsoft prefers to keep the LPC interface undocumented. There is no reason why LPC cannot function as an Inter-Process Communication (IPC) mechanism. Microsoft provides a RPC kit for client-server communication across machines. Windows NT optimizes the RPCs by converting them to LPCs, in case the client and the server reside on the same machine. However, RPC has its own overheads. LPC proves most efficient in the raw form, and the subsystems also use it in that form only. Apart from that, RPC does not provide access to the fastest form of LPC–the Quick LPC. For these reasons, we provide you with useful information on the LPC interface.


LOCAL PROCEDURE CALL

In Windows NT, client-subsystem communication happens in a fashion similar to that in the MACH operating system. Each subsystem contains a client-side DLL that links with the client executable. The DLL contains stub functions for the subsystem’s API. Whenever a client process–an application using the subsystem interface–makes an API call, the corresponding stub function in the DLL passes on the call to the subsystem process. The subsystem process, after the necessary processing, returns the results to the client DLL. The stub function in the DLL waits for the subsystem to return the results and, in turn, passes the results to the caller. The client process simply resembles calling a normal procedure in its own code. In the case of RPC, the client actually calls a procedure sitting in some remote server over the network–hence the name remote procedure call. In Windows NT, the server runs on the same machine; hence the mechanism is called as a local procedure call.

There are three types of LPC. The first type sends small messages up to 304 bytes. The second type sends larger messages. The third type of LPC is called as Quick LPC and used by the Win32 subsystem in Windows NT 3.51.

The first two types of LPC use port objects for communication. Ports resemble the sockets or named pipes in Unix. A port is a bidirectional communication channel between two processes. However, unlike sockets, the data passed through ports is not streamed. The ports preserve the message boundaries. Simply put, you can send and receive messages using ports. The subsystems create ports with well-known names. The client processes that need to invoke services from the subsystems open the corresponding port using the well-known name. After opening the port, the client can communicate, with the server, over the port.

Short Message Communication
The client-subsystem communication via a port happens as follows. The server/subsystem creates a port using the NtCreatePort() function. The name of the port is well published and known to the clients (or, rather, to the client-side DLL). The NtCreatePort() function returns a port handle used by the subsystem to wait and accept requests using the NtListenPort() function. Any process can send connection requests on this port and get a port handle for communication. The subsystem receives the request messages, processes them, and sends back the replies over the port to the client.

The client sends a connection request to a waiting subsystem using the NtConnectPort() function. When the subsystem receives the connect request, it comes out of the NtListenPort() function and accepts the connection using the NtAcceptConnectPort() function. The NtAcceptConnectPort returns a new port handle specific to the client requesting the connection. The server can break the communication link with the particular client by closing this handle. The subsystem completes the connection protocol using the NtCompleteConnectPort() function. Now, the client also returns from the NtConnectPort() function and gets a handle to the communication port. This handle is private to the client process. The child processes do not inherit the port handles so the children need to open the subsystem port again.

After completing this connection protocol, the client and the subsystem can start communicating over this port. The client sends a request to the subsystem using the NtRequestPort() function. When the NtRequestPort() function sends datagram messages to the subsystem, the client does not receive any acknowledgment for the sent messages. In case the client expects a reply to its request, the client can use the NtRequestWaitReplyPort() function, which sends the request to the subsystem and waits for a reply from the subsystem. The subsystem receives request messages using the NtReplyWaitReceive() function and sends reply messages using the NtReplyPort() function. The subsystem can optimize by replying to the previous request and waiting for the next request using a single call to the NtReplyWaitReceivePort() function. Figure 8-1 displays this entire process of communication.

A subsystem may receive/reply to messages from more than one client using the same port. The message contains fields, which identify the client process and thread. The kernel fills in the process ID and the thread ID in the messages. Therefore, the subsystems can rely on this information, and the LPC forms a secure and reliable communication mechanism because the sender of the messages can be reliably identified.

Shared Section Communication
You can send only short messages–up to 304 bytes–via ports. You need to use a shared region of memory for passing larger messages. If clients want to pass messages via shared memory, they have to do some extra processing before calling NtConnectPort(). A client creates a section object of required size, using CreateFileMapping()–a documented function. The size of the message is restricted only by the size of the section. The client need not map the section onto the address space; the port connection procedure takes care of that. But the client has to pass the section handle to the NtConnectPort() call. The function returns the addresses where the section is mapped in the client’s as well as the server’s address spaces. Now, whenever the client wants to invoke the server, it simply copies the parameters to the shared section and sends a message over the port. This message simply acts as an indication of the client request because the actual parameters pass via the shared section.

Generally, as a part of the port message, the client specifies the server space address of the shared section and the offset of the copied parameters within the shared section. If the server uses this information, it should first validate it if the client process proves unreliable. After processing the request, the server also sends back the results via the shared section. Apart from the additional processing, the shared section LPC essentially uses the same set of port APIs as the short message communication. The sequence of operations also resembles that of the short message communication with one exception–in addition to handling the message port, the client must create the shared section and perform the parameter copying. The sequence of operations shown in Figure 8-1 applies to the shared section LPC as well.


PORT-RELATED FUNCTIONS

In this section, we discuss the port-related functions and parameters passed to them in detail. We prepared sample programs demonstrating short message passing and shared section memory message passing. We discuss these programs next.

NtCreatePort
int _stdcall

NtCreatePort(

PHANDLE PortHandle,

POBJECT_ATTRIBUTES ObjectAttributes,

DWORD MaxConnectInfoLength,

DWORD MaxDataLength,

DWORD Unknown);
This function creates a new port for communication. The name of the port and the parent directory in the object hierarchy pass through the ObjectAttributes parameter. The MaxConnectInfoLength parameter specifies the maximum size of information that can pass on to a connection request. (Later in this section, we discuss the connection information.) The MaxDataLength parameter is the maximum size of the message that can pass through the port. Both these parameters are ignored. The operating system always sets the connection information length to 260 bytes and the data length to 328 bytes, which are the maximum allowed values for these parameters. Just make sure that you pass values less than the maximum allowed values because the function returns an error otherwise. The unknown fifth parameter can pass as zero. A handle to the newly created port returns in PortHandle. The server process uses this port handle to accept connection requests from clients.



Page: 1, 2, 3, 4, 5, 6

next page



ADS BY GOOGLE SPONSORED LINKS FEATURED LINKS

WinConnections Conference Fall 2008
Don’t miss the premier event for Microsoft IT Professionals in Las Vegas, November 10-13. Register and book your room by August 25 and receive a FREE room night (based on a three night minimum stay).

Maximize your SharePoint Investment – 8 Cities
Discover best practices and tips for both architecting and administering SharePoint. Early Bird Price of $99 through Sept 15th.

Find a new job now on the all new IT Job Hound!
Search jobs, post your resume, and set up job e-mail alerts!

Master SharePoint with 3 eLearning Seminars
Learn how to build a better SharePoint infrastructure and enable powerful collaboration with MVPs Dan Holme and Michael Noel. Register today!

Top Tools for Virtualization Disaster Recovery & Replication
View this web seminar on August 14th to learn about two tools that will result in faster backup and restore with P2V disaster recovery.

SharePointConnections Conference Fall 2008
Don’t miss the premier event for Microsoft IT Professionals in Las Vegas, November 10-13. Register and book your room by August 25 and receive a FREE room night (based on a three night minimum stay).

VMworld 2008 - Sign Up Today!
Join your peers on September 15-18 at The Venetian Hotel in Las Vegas as VMware hosts VMworld 2008, the leading Virtualization event.



When managing just VMware isn’t enough
Plan/Manage/Secure – NetIQ VMware management. Download whitepaper.

What’s up with your network? Find out with ipMonitor
Availability monitoring for servers, applications and networks – FREE trial

Microsoft® Tech•Ed EMEA 2008 IT Professionals
Advance your thinking with new ideas and practical real-world solutions at Microsoft’s FIVE day technical infrastructure conference 3-7 Nov., 2008. Register before 26 September 2008 to save €300.

Order Your Fundamentals CD Today!
Gain an introduction to Exchange, learn server security requirements, and understand how unified communications can play a role in your messaging strategies with this free Exchange CD.

Are You Really Compliant with Software Regulations?
View this web seminar that will help you with compliance best practices and check out a management solution to assure that you won’t be in jeopardy of an audit.

Virtualization Congress Oct. 14-16 in London
Don't miss Virtualization Congress, the premiere EMEA conference dedicated to hardware, OS and application virtualization. Oct. 14-16 in London.
Windows IT Pro Home Register FAQ for Windows WinInfo News
Europe Edition About Us Contact Us/Customer Service Media Kit Affiliates / Licensing  
SQL Server Magazine Office & SharePoint Pro Windows Dev Pro IT Job Hound ITTV
IT Library Technical Resources Directory Connected Home Windows Excavator Windows SuperSite 
 
 Windows IT Pro is a Division of Penton Media Inc.
 Copyright © 2008 Penton Media, Inc., All rights reserved. Terms and Use | Privacy Statement | Reprints and Licensing