服务端
DWORD WINAPI ServerThread1(LPVOID)
{
SECURITY_DESCRIPTOR sd;
OBJECT_ATTRIBUTES ObjAttr; // Object attributes for the name
UNICODE_STRING PortName;
NTSTATUS Status;
HANDLE LpcPortHandle = NULL;
BYTE RequestBuffer[sizeof(PORT_MESSAGE) + MAX_LPC_DATA];
BOOL WeHaveToStop = FALSE;
int nError;
__try // try-finally
{
//
// Initialize security descriptor that will be set to
// "Everyone has the full access"
//
if(!InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION))
{
nError = GetLastError();
__leave;
}
//
// Set the empty DACL to the security descriptor
//
if(!SetSecurityDescriptorDacl(&sd, TRUE, NULL, FALSE))
{
nError = GetLastError();
__leave;
}
//
// Initialize attributes for the port and create it
//
RtlInitUnicodeString(&PortName, LpcPortName);
InitializeObjectAttributes(&ObjAttr, &PortName, 0, NULL, &sd);
_tprintf(_T("Server: Creating LPC port \"%s\" (NtCreatePort) ...\n"), LpcPortName);
Status = NtCreatePort(&LpcPortHandle,
&ObjAttr,
NULL,
sizeof(PORT_MESSAGE) + MAX_LPC_DATA,
0);
_tprintf(_T("Server: NtCreatePort result 0x%08lX\n"), Status);
if(!NT_SUCCESS(Status))
__leave;
//
// Process all incoming LPC messages
//
while(WeHaveToStop == FALSE)
{
PTRANSFERRED_MESSAGE LpcMessage = NULL;
HANDLE ServerHandle = NULL;
//
// Create the data buffer for the request
//
LpcMessage = (PTRANSFERRED_MESSAGE)RequestBuffer;
_tprintf(_T("Server: ------------- Begin loop ----------------------0x%x\n"), Status);
//
// Listen to the port. This call is blocking, and cannot be interrupted,
// even if the handle is closed. The only way how to stop the block is to send
// an LPC request which will be recognized by server thread as "Stop" command
//
if(NT_SUCCESS(Status))
{
_tprintf(_T("Server: Listening to LPC port (NtListenPort) ...%s\n"), LpcPortName);
//监听客户端连接 在此阻塞
Status = NtListenPort(LpcPortHandle,
&LpcMessage->Header);
_tprintf(_T("Server: NtListenPort result 0x%08lX\n"), Status);
}
//
// Accept the port connection
//
if(NT_SUCCESS(Status))
{
_tprintf(_T("Server: Accepting LPC connection (NtAcceptConnectPort)%s ...\n"), LpcPortName);
//该函数执行完毕客户端NtConnectPort 结束阻塞
Status = NtAcceptConnectPort(&ServerHandle,
NULL,
&LpcMessage->Header,
TRUE,
NULL,
NULL);
_tprintf(_T("Server: NtAcceptConnectPort result 0x%08lX\n"), Status);
}
//
// Complete the connection
//
if(NT_SUCCESS(Status))
{
_tprintf(_T("Server: Completing LPC connection (NtCompleteConnectPort) %s...\n"), LpcPortName);
Status = NtCompleteConnectPort(ServerHandle);
_tprintf(_T("Server: NtCompleteConnectPort result 0x%08lX\n"), Status);
}
//
// Now accept the data request coming from the port.
//
if(NT_SUCCESS(Status))
{
_tprintf(_T("Server: Receiving LPC data (NtReplyWaitReceivePort)%s ...\n"), LpcPortName);
//等待 客户端调用NtRequestPort 或者 NtRequestWaitReplyPort 发送消息过来
Status = NtReplyWaitReceivePort(ServerHandle,
NULL,
NULL,
&LpcMessage->Header);
_tprintf(_T("Server: NtReplyWaitReceivePort result 0x%08lX\n"), Status);
}
//
// Get the data sent by the client
//
if(NT_SUCCESS(Status))
{
// If a request has been received, answer to it.
switch(LpcMessage->Command)
{
case LPC_COMMAND_REQUEST_NOREPLY:
//第一次通信,客户端发送了一段内容,服务器接收.服务器没有向客户端回复内容
_tprintf(_T("Server: Received request \"%s\"\n"), LpcMessage->MessageText);
break; // Nothing more to do
case LPC_COMMAND_REQUEST_REPLY:
_tprintf(_T("Server: Received request \"%s\"\n"), LpcMessage->MessageText);
_tprintf(_T("Server: Sending reply (NtReplyPort) %s...\n"), LpcPortName);
Status = NtReplyPort(LpcPortHandle, &LpcMessage->Header);
_tprintf(_T("Server: NtReplyPort result 0x%08lX\n"), Status);
break;
case LPC_COMMAND_STOP: // Stop the work
_tprintf(_T("Server: Stopping ...\n"));
WeHaveToStop = TRUE;
break;
}
}
//
// Close the server connection handle
//
if(ServerHandle != NULL)
{
_tprintf(_T("Server: Closing the request handle (NtClose) %s...\n"), LpcPortName);
Status = NtClose(ServerHandle);
_tprintf(_T("Server: NtClose result 0x%08lX\n"), Status);
}
_tprintf(_T("Server: ------------- End loop ---------------------- %x\n"), Status);
}
}
__finally
{
if(LpcPortHandle != NULL)
NtClose(LpcPortHandle);
}
return 0;
}
客户端
DWORD WINAPI ServerThread1(LPVOID)
{
SECURITY_DESCRIPTOR sd;
OBJECT_ATTRIBUTES ObjAttr; // Object attributes for the name
UNICODE_STRING PortName;
NTSTATUS Status;
HANDLE LpcPortHandle = NULL;
BYTE RequestBuffer[sizeof(PORT_MESSAGE) + MAX_LPC_DATA];
BOOL WeHaveToStop = FALSE;
int nError;
__try // try-finally
{
//
// Initialize security descriptor that will be set to
// "Everyone has the full access"
//
if(!InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION))
{
nError = GetLastError();
__leave;
}
//
// Set the empty DACL to the security descriptor
//
if(!SetSecurityDescriptorDacl(&sd, TRUE, NULL, FALSE))
{
nError = GetLastError();
__leave;
}
//
// Initialize attributes for the port and create it
//
RtlInitUnicodeString(&PortName, LpcPortName);
InitializeObjectAttributes(&ObjAttr, &PortName, 0, NULL, &sd);
_tprintf(_T("Server: Creating LPC port \"%s\" (NtCreatePort) ...\n"), LpcPortName);
Status = NtCreatePort(&LpcPortHandle,
&ObjAttr,
NULL,
sizeof(PORT_MESSAGE) + MAX_LPC_DATA,
0);
_tprintf(_T("Server: NtCreatePort result 0x%08lX\n"), Status);
if(!NT_SUCCESS(Status))
__leave;
//
// Process all incoming LPC messages
//
while(WeHaveToStop == FALSE)
{
PTRANSFERRED_MESSAGE LpcMessage = NULL;
HANDLE ServerHandle = NULL;
//
// Create the data buffer for the request
//
LpcMessage = (PTRANSFERRED_MESSAGE)RequestBuffer;
_tprintf(_T("Server: ------------- Begin loop ----------------------0x%x\n"), Status);
//
// Listen to the port. This call is blocking, and cannot be interrupted,
// even if the handle is closed. The only way how to stop the block is to send
// an LPC request which will be recognized by server thread as "Stop" command
//
if(NT_SUCCESS(Status))
{
_tprintf(_T("Server: Listening to LPC port (NtListenPort) ...%s\n"), LpcPortName);
Status = NtListenPort(LpcPortHandle,
&LpcMessage->Header);
_tprintf(_T("Server: NtListenPort result 0x%08lX\n"), Status);
}
//
// Accept the port connection
//
if(NT_SUCCESS(Status))
{
_tprintf(_T("Server: Accepting LPC connection (NtAcceptConnectPort)%s ...\n"), LpcPortName);
Status = NtAcceptConnectPort(&ServerHandle,
NULL,
&LpcMessage->Header,
TRUE,
NULL,
NULL);
_tprintf(_T("Server: NtAcceptConnectPort result 0x%08lX\n"), Status);
}
//
// Complete the connection
//
if(NT_SUCCESS(Status))
{
_tprintf(_T("Server: Completing LPC connection (NtCompleteConnectPort) %s...\n"), LpcPortName);
Status = NtCompleteConnectPort(ServerHandle);
_tprintf(_T("Server: NtCompleteConnectPort result 0x%08lX\n"), Status);
}
//
// Now accept the data request coming from the port.
//
if(NT_SUCCESS(Status))
{
_tprintf(_T("Server: Receiving LPC data (NtReplyWaitReceivePort)%s ...\n"), LpcPortName);
Status = NtReplyWaitReceivePort(ServerHandle,
NULL,
NULL,
&LpcMessage->Header);
_tprintf(_T("Server: NtReplyWaitReceivePort result 0x%08lX\n"), Status);
}
//
// Get the data sent by the client
//
if(NT_SUCCESS(Status))
{
// If a request has been received, answer to it.
switch(LpcMessage->Command)
{
case LPC_COMMAND_REQUEST_NOREPLY:
_tprintf(_T("Server: Received request \"%s\"\n"), LpcMessage->MessageText);
break; // Nothing more to do
case LPC_COMMAND_REQUEST_REPLY:
_tprintf(_T("Server: Received request \"%s\"\n"), LpcMessage->MessageText);
_tprintf(_T("Server: Sending reply (NtReplyPort) %s...\n"), LpcPortName);
Status = NtReplyPort(LpcPortHandle, &LpcMessage->Header);
_tprintf(_T("Server: NtReplyPort result 0x%08lX\n"), Status);
break;
case LPC_COMMAND_STOP: // Stop the work
_tprintf(_T("Server: Stopping ...\n"));
WeHaveToStop = TRUE;
break;
}
}
//
// Close the server connection handle
//
if(ServerHandle != NULL)
{
_tprintf(_T("Server: Closing the request handle (NtClose) %s...\n"), LpcPortName);
Status = NtClose(ServerHandle);
_tprintf(_T("Server: NtClose result 0x%08lX\n"), Status);
}
_tprintf(_T("Server: ------------- End loop ---------------------- %x\n"), Status);
}
}
__finally
{
if(LpcPortHandle != NULL)
NtClose(LpcPortHandle);
}
return 0;
}