357 lines
9.0 KiB
C++
357 lines
9.0 KiB
C++
/*++
|
|
|
|
Copyright (C) Microsoft Corporation, 1992 - 1999
|
|
|
|
Module Name:
|
|
|
|
wmsgpack.hxx
|
|
|
|
Abstract:
|
|
|
|
This file contains the definitions of the packet formats used by
|
|
RPC on LPC.
|
|
|
|
Author:
|
|
|
|
Steven Zeck (stevez) 11/12/91
|
|
|
|
Revision History:
|
|
|
|
15-Dec-1992 mikemon
|
|
|
|
Rewrote the majority of the code.
|
|
|
|
... implemented WMSG protocol
|
|
|
|
05-15-96 merged LRPC / WMSG into a single protocol
|
|
|
|
Kamen Moutafov (KamenM) Mar-2000 Support for extended error info
|
|
|
|
--*/
|
|
|
|
#ifndef __LPCPACK_HXX__
|
|
#define __LPCPACK_HXX__
|
|
|
|
#define LRPC_DIRECTORY_NAME L##"\\RPC Control\\"
|
|
#define MINIMUM_PARTIAL_BUFFLEN 10240
|
|
#define PORT_NAME_LEN 64
|
|
#define BIND_BACK_PORT_NAME_LEN 128
|
|
#define LRPC_TIMEOUT 100
|
|
#define LRPC_THRESHOLD_SIZE (MINIMUM_PARTIAL_BUFFLEN * 3)
|
|
|
|
#define BIND_BACK_FLAG 1
|
|
#define NEW_SECURITY_CONTEXT_FLAG 2
|
|
#define NEW_PRESENTATION_CONTEXT_FLAG 4
|
|
#define EXTENDED_ERROR_INFO_PRESENT 8
|
|
#define DEFAULT_LOGONID_FLAG (0x10)
|
|
#define SERVER_BIND_EXCH_RESP (0x20)
|
|
|
|
#define TS_NDR20_FLAG 1
|
|
#define TS_NDR64_FLAG 2
|
|
#define TS_NDRTEST_FLAG 4
|
|
|
|
typedef struct _LRPC_BIND_EXCHANGE
|
|
{
|
|
INT ConnectType ;
|
|
DWORD AssocKey ;
|
|
RPC_SYNTAX_IDENTIFIER InterfaceId;
|
|
// can be any of TS_NDR20_FLAG, TS_NDR64_FLAG
|
|
unsigned int TransferSyntaxSet;
|
|
RPC_STATUS RpcStatus;
|
|
// can be: BIND_BACK_FLAG, NEW_SECURITY_CONTEXT_FLAG, NEW_PRESENTATION_CONTEXT_FLAG
|
|
// EXTENDED_ERROR_INFO_PRESENT, SERVER_BIND_EXCH_RESP on return from the server
|
|
unsigned short Flags;
|
|
// the first is always the presentation context id for NDR20,
|
|
// and the second is for NDR64. The third can be NDRTest - that's
|
|
// why the + 1
|
|
unsigned short PresentationContext[MaximumNumberOfTransferSyntaxes + 1];
|
|
unsigned long SecurityContextId;
|
|
union
|
|
{
|
|
char szPortName[PORT_NAME_LEN] ;
|
|
struct
|
|
{
|
|
// provide 8 byte alignment
|
|
unsigned char Pad2[4];
|
|
unsigned char Buffer[4];
|
|
};
|
|
};
|
|
} LRPC_BIND_EXCHANGE;
|
|
|
|
|
|
// message types
|
|
#define LRPC_MSG_BIND 0
|
|
#define LRPC_MSG_REQUEST 1
|
|
#define LRPC_MSG_RESPONSE 2
|
|
#define LRPC_MSG_CALLBACK 3
|
|
#define LRPC_MSG_FAULT 4
|
|
#define LRPC_MSG_CLOSE 5
|
|
#define LRPC_MSG_ACK 6
|
|
#define LRPC_BIND_ACK 7
|
|
#define LRPC_MSG_COPY 8
|
|
#define LRPC_MSG_PUSH 9
|
|
#define LRPC_MSG_CANCEL 10
|
|
#define LRPC_MSG_BIND_BACK 11
|
|
#define LRPC_ASYNC_REQUEST 12
|
|
#define LRPC_PARTIAL_REQUEST 13
|
|
#define LRPC_CLIENT_SEND_MORE 14
|
|
#define LRPC_SERVER_SEND_MORE 15
|
|
#define LRPC_MSG_FAULT2 16
|
|
|
|
#define MAX_LRPC_MSG 16
|
|
|
|
// connect types
|
|
#define LRPC_CONNECT_REQUEST 0
|
|
#define LRPC_CONNECT_RESPONSE 1
|
|
#define LRPC_CONNECT_TICKLE 2
|
|
|
|
#define MAX_LRPC_CONTEXTS ((PORT_MAXIMUM_MESSAGE_LENGTH - sizeof(LRPC_BIND_MESSAGE)) / sizeof(DWORD))
|
|
|
|
typedef struct _OLD_SECURITY_CONTEXTS
|
|
{
|
|
DWORD NumContexts;
|
|
DWORD SecurityContextId[1];
|
|
} OLD_SECURITY_CONTEXTS;
|
|
|
|
#define BIND_NAK_PICKLE_BUFFER_OFFSET (FIELD_OFFSET(LRPC_BIND_EXCHANGE, Buffer) \
|
|
+ FIELD_OFFSET(LRPC_BIND_MESSAGE, BindExchange))
|
|
#define MAX_BIND_NAK (PORT_MAXIMUM_MESSAGE_LENGTH - BIND_NAK_PICKLE_BUFFER_OFFSET)
|
|
|
|
typedef struct _LRPC_BIND_MESSAGE
|
|
{
|
|
PORT_MESSAGE LpcHeader;
|
|
unsigned char MessageType;
|
|
unsigned char Pad[3];
|
|
LRPC_BIND_EXCHANGE BindExchange;
|
|
OLD_SECURITY_CONTEXTS OldSecurityContexts;
|
|
} LRPC_BIND_MESSAGE;
|
|
|
|
typedef struct _LRPC_BIND_BACK_MESSAGE
|
|
{
|
|
PORT_MESSAGE LpcHeader;
|
|
unsigned char MessageType;
|
|
unsigned char Pad[3];
|
|
DWORD AssocKey ;
|
|
char szPortName[BIND_BACK_PORT_NAME_LEN] ;
|
|
} LRPC_BIND_BACK_MESSAGE;
|
|
|
|
// buffer flags
|
|
#define LRPC_BUFFER_IMMEDIATE 0x0001
|
|
#define LRPC_BUFFER_REQUEST 0x0002
|
|
#define LRPC_BUFFER_SERVER 0x0004
|
|
|
|
// misc flags
|
|
#define LRPC_SYNC_CLIENT 0x0040
|
|
#define LRPC_BUFFER_PARTIAL 0x0080
|
|
#define LRPC_OBJECT_UUID 0x0100
|
|
#define LRPC_NON_PIPE 0x0200
|
|
#define LRPC_CAUSAL 0x0400
|
|
#define LRPC_EEINFO_PRESENT 0x0800
|
|
|
|
typedef struct _LRPC_RPC_HEADER
|
|
{
|
|
unsigned char MessageType;
|
|
unsigned short PresentContext;
|
|
unsigned short Flags ;
|
|
unsigned short ProcedureNumber;
|
|
UUID ObjectUuid;
|
|
unsigned long SecurityContextId;
|
|
unsigned long CallId;
|
|
} LRPC_RPC_HEADER;
|
|
|
|
typedef struct _LRPC_SERVER_BUFFER
|
|
{
|
|
unsigned int Length;
|
|
LPC_PVOID Buffer;
|
|
} LRPC_SERVER_BUFFER;
|
|
|
|
#define MAXIMUM_MESSAGE_BUFFER \
|
|
(PORT_MAXIMUM_MESSAGE_LENGTH - sizeof(PORT_MESSAGE) \
|
|
- sizeof(LRPC_RPC_HEADER))
|
|
|
|
typedef struct _LRPC_CONNECT_MESSAGE
|
|
{
|
|
PORT_MESSAGE LpcHeader;
|
|
LRPC_BIND_EXCHANGE BindExchange;
|
|
} LRPC_CONNECT_MESSAGE;
|
|
|
|
typedef struct _LRPC_RPC_MESSAGE
|
|
{
|
|
PORT_MESSAGE LpcHeader;
|
|
LRPC_RPC_HEADER RpcHeader;
|
|
union
|
|
{
|
|
unsigned char Buffer[MAXIMUM_MESSAGE_BUFFER];
|
|
PORT_DATA_INFORMATION Request;
|
|
LRPC_SERVER_BUFFER Server;
|
|
};
|
|
} LRPC_RPC_MESSAGE;
|
|
|
|
typedef struct _LRPC_FAULT_MESSAGE
|
|
{
|
|
PORT_MESSAGE LpcHeader;
|
|
LRPC_RPC_HEADER RpcHeader ;
|
|
RPC_STATUS RpcStatus;
|
|
// align the Buffer on 8 bytes - required for pickling
|
|
DWORD Padding1;
|
|
// the actual length has to be retrieved
|
|
// from LpcHeader.u1.s1.DataLength/TotalLength
|
|
unsigned char Buffer[4];
|
|
} LRPC_FAULT_MESSAGE;
|
|
|
|
#define MAXIMUM_FAULT_MESSAGE \
|
|
(PORT_MAXIMUM_MESSAGE_LENGTH - sizeof(LRPC_FAULT_MESSAGE))
|
|
|
|
// N.B. The layout of fault2 must match the layout of
|
|
// LRPC_RPC_MESSAGE up to and including the union of
|
|
// Request/Server. This is so because many code paths
|
|
// will operate on both, and having the same layout
|
|
// allows us to avoid special casing those
|
|
typedef struct _LRPC_FAULT2_MESSAGE
|
|
{
|
|
PORT_MESSAGE LpcHeader;
|
|
LRPC_RPC_HEADER RpcHeader ;
|
|
union
|
|
{
|
|
PORT_DATA_INFORMATION Request;
|
|
LRPC_SERVER_BUFFER Server;
|
|
};
|
|
RPC_STATUS RpcStatus;
|
|
} LRPC_FAULT2_MESSAGE;
|
|
|
|
typedef struct _LRPC_CLOSE_MESSAGE
|
|
{
|
|
PORT_MESSAGE LpcHeader;
|
|
unsigned char MessageType;
|
|
unsigned char Pad[3];
|
|
} LRPC_CLOSE_MESSAGE;
|
|
|
|
typedef struct _LRPC_PUSH_MESSAGE
|
|
{
|
|
PORT_MESSAGE LpcHeader;
|
|
LRPC_RPC_HEADER RpcHeader;
|
|
PORT_DATA_INFORMATION Response;
|
|
RPC_STATUS RpcStatus;
|
|
} LRPC_PUSH_MESSAGE;
|
|
|
|
#define ACK_BUFFER_COMPLETE 0x01
|
|
|
|
typedef struct _LRPC_ACK_MESSAGE
|
|
{
|
|
PORT_MESSAGE LpcHeader;
|
|
unsigned char MessageType;
|
|
unsigned char Pad ;
|
|
short Shutup ;
|
|
RPC_STATUS RpcStatus;
|
|
int ValidDataSize ;
|
|
int Flags ;
|
|
} LRPC_ACK_MESSAGE;
|
|
|
|
typedef struct _LRPC_COPY_MESSAGE
|
|
{
|
|
PORT_MESSAGE LpcHeader;
|
|
LRPC_RPC_HEADER RpcHeader ;
|
|
PORT_DATA_INFORMATION Request;
|
|
LRPC_SERVER_BUFFER Server;
|
|
RPC_STATUS RpcStatus;
|
|
int IsPartial ;
|
|
} LRPC_COPY_MESSAGE;
|
|
|
|
typedef struct _LRPC_PARTIAL_MESSAGE
|
|
{
|
|
PORT_MESSAGE LpcHeader;
|
|
LRPC_RPC_HEADER RpcHeader ;
|
|
PORT_DATA_INFORMATION Request;
|
|
RPC_STATUS RpcStatus;
|
|
int IsPartial ;
|
|
} LRPC_PARTIAL_MESSAGE;
|
|
|
|
typedef union _LRPC_MESSAGE
|
|
{
|
|
LRPC_CONNECT_MESSAGE Connect;
|
|
LRPC_BIND_MESSAGE Bind;
|
|
LRPC_RPC_MESSAGE Rpc;
|
|
LRPC_FAULT_MESSAGE Fault;
|
|
LRPC_FAULT2_MESSAGE Fault2;
|
|
LRPC_CLOSE_MESSAGE Close;
|
|
PORT_MESSAGE LpcHeader;
|
|
LRPC_ACK_MESSAGE Ack ;
|
|
LRPC_PUSH_MESSAGE Push ;
|
|
LRPC_BIND_BACK_MESSAGE BindBack ;
|
|
LRPC_PARTIAL_MESSAGE Partial ;
|
|
} LRPC_MESSAGE;
|
|
|
|
//
|
|
// Conversion functions to use the 64bit LPC structures when built 32bit on 64bit NT(wow64).
|
|
|
|
#if defined(BUILD_WOW6432)
|
|
|
|
inline
|
|
CLIENT_ID
|
|
MsgClientIdToClientId(const CLIENT_ID64 & s) {
|
|
CLIENT_ID d;
|
|
d.UniqueProcess = (HANDLE)s.UniqueProcess;
|
|
d.UniqueThread = (HANDLE)s.UniqueThread;
|
|
return d;
|
|
}
|
|
|
|
inline
|
|
CLIENT_ID64
|
|
ClientIdToMsgClientId(const CLIENT_ID & s) {
|
|
CLIENT_ID64 d;
|
|
d.UniqueProcess = (ULONGLONG)s.UniqueProcess;
|
|
d.UniqueThread = (ULONGLONG)s.UniqueThread;
|
|
return d;
|
|
}
|
|
|
|
inline
|
|
ULONGLONG
|
|
PtrToMsgPtr(void * s) {
|
|
return (ULONGLONG)s;
|
|
}
|
|
|
|
inline
|
|
void *
|
|
MsgPtrToPtr(ULONGLONG s) {
|
|
return (void *)s;
|
|
}
|
|
|
|
#else
|
|
|
|
inline
|
|
CLIENT_ID
|
|
MsgClientIdToClientId(const CLIENT_ID & s) {
|
|
return s;
|
|
}
|
|
|
|
inline
|
|
CLIENT_ID
|
|
ClientIdToMsgClientId(const CLIENT_ID s) {
|
|
return s;
|
|
}
|
|
|
|
inline
|
|
PVOID
|
|
PtrToMsgPtr(PVOID s) {
|
|
return s;
|
|
}
|
|
|
|
inline
|
|
void *
|
|
MsgPtrToPtr(void *s) {
|
|
return s;
|
|
}
|
|
|
|
#endif
|
|
|
|
RPC_STATUS
|
|
LrpcMapRpcStatus (
|
|
IN RPC_STATUS RpcStatus
|
|
);
|
|
|
|
void
|
|
ShutdownLrpcClient (
|
|
) ;
|
|
|
|
#endif // __LPCPACK_HXX__
|