Inside Microsoft Windows 2000, Third Edition (Microsoft Programming Series)
A local procedure call (LPC) is an interprocess communication facility for high-speed message passing. It is not directly available through the Win32 API; it is an internal mechanism available only to Windows 2000 operating system components. Here are some examples of where LPCs are used:
- Win32 applications that use remote procedure calls (RPCs), a documented API, indirectly use LPCs when they specify local-RPC, a form of RPC used to communicate between processes on the same system.
- A few Win32 APIs result in sending messages to the Win32 subsystem process.
- Winlogon uses LPCs to communicate with the local security authentication server process, Lsass.
- The security reference monitor (an executive component explained in Chapter 8) uses LPCs to communicate with the Lsass process.
EXPERIMENT
Viewing LPC Port Objects
You can see named LPC port objects with the Object Viewer utility included on this book's companion CD. Run \Sysint\Winobj.exe, and select the root directory. A plug icon identifies the port objects, as shown here:
To see the LPC port objects used by RPC, select the \RPC Control directory, as shown here:
You can also view LPC port objects by using the !lpc kernel debugger command. The command accepts parameters that direct it to show LPC ports, LPC messages, and threads that are waiting or sending LPC messages. To view the Lsass authentication port (the port that Winlogon sends logon requests to), first obtain a list of the ports on the system:
kd> !lpc Usage: !lpc - Display this help !lpc message [MessageId] - Display the message with a given ID and all related information If MessageId is not specified, dump all messages !lpc port [PortAddress] - Display the port information !lpc scan PortAddress - Search this port and any connected port !lpc thread [ThreadAddr] - Search the thread in rundown port queues and display the port info If ThreadAddr is missing, display all threads marked as doing some lpc operations kd> !lpc port Scanning 206 objects 1 Port: 0xe1360320 Connection: 0xe1360320 Communication: 0x00000000 'SeRmCommandPort' 1 Port: 0xe136bc20 Connection: 0xe136bc20 Communication: 0x00000000 'SmApiPort' 1 Port: 0xe133ba80 Connection: 0xe133ba80 Communication: 0x00000000 'DbgSsApiPort' 1 Port: 0xe13606e0 Connection: 0xe13606e0 Communication: 0x00000000 'DbgUiApiPort' |
Locate the port named LsaAuthenticationPort in the output and then examine it by passing its address to the !lpc command:
kd> !lpc port 0xe205f040 Server connection port e205f040 Name: LsaAuthenticationPort Handles: 1 References: 37 Server process : ff7d56c0 (lsass.exe) Queue semaphore : ff7bfcc8 Semaphore state 0 (0x0) The message queue is empty The LpcDataInfoChainHead queue is empty |
Typically, LPCs are used between a server process and one or more client processes of that server. An LPC connection can be established between two user-mode processes or between a kernel-mode component and a user-mode process. For example, as noted in Chapter 2, Win32 processes send occasional messages to the Win32 subsystem by using LPCs. Also, some system processes use LPCs to communicate, such as Winlogon and Lsass. An example of a kernel-mode component using an LPC to talk to a user process is the communication between the security reference monitor and the Lsass process.
LPCs are designed to allow three methods of exchanging messages:
- A message that is shorter than 256 bytes can be sent by calling the LPC with a buffer containing the message. This message is then copied from the address space of the sending process into system address space, and from there to the address space of the receiving process.
- If a client and a server want to exchange more than 256 bytes of data, they can choose to use a shared section to which both are mapped. The sender places message data in the shared section and then sends a small message to the receiver with pointers to where the data is to be found in the shared section.
- When a server wants to read or write larger amounts of data than will fit in a shared section, data can be directly read from or written to a client's address space. The LPC component supplies two functions that a server can use to accomplish this. A message sent by the first function is used to synchronize the message passing.
An LPC exports a single executive object called the port object to maintain the state needed for communication. Although an LPC uses a single object type, it has several kinds of ports:
- Server connection port A named port that is a server connection request point. Clients can connect to the server by connecting to this port.
- Server communication port An unnamed port a server uses to communicate with a particular client. The server has one such port per active client.
- Client communication port An unnamed port a particular client thread uses to communicate with a particular server.
- Unnamed communication port An unnamed port created for use by two threads in the same process.
LPCs are typically used as follows: A server creates a named server connection port object. A client makes a connect request to this port. If the request is granted, two new unnamed ports, a client communication port and a server communication port, are created. The client gets a handle to the client communication port, and the server gets a handle to the server communication port. The client and the server will then use these new ports for their communication.
A completed connection between a client and a server is shown in Figure 3-24.
Figure 3-24 Use of LPC ports