⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rpc_message.c

📁 这是一个开放源代码的与WINNT/WIN2K/WIN2003兼容的操作系统
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * RPC messages * * Copyright 2001-2002 Ove K鍁en, TransGaming Technologies * Copyright 2004 Filip Navara * Copyright 2006 CodeWeavers * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */#include <stdarg.h>#include <stdio.h>#include <string.h>#include "windef.h"#include "winbase.h"#include "winerror.h"#include "rpc.h"#include "rpcndr.h"#include "rpcdcep.h"#include "wine/debug.h"#include "rpc_binding.h"#include "rpc_defs.h"#include "rpc_message.h"#include "ncastatus.h"WINE_DEFAULT_DEBUG_CHANNEL(rpc);/* note: the DCE/RPC spec says the alignment amount should be 4, but * MS/RPC servers seem to always use 16 */#define AUTH_ALIGNMENT 16/* gets the amount needed to round a value up to the specified alignment */#define ROUND_UP_AMOUNT(value, alignment) \    (((alignment) - (((value) % (alignment)))) % (alignment))#define ROUND_UP(value, alignment) (((value) + ((alignment) - 1)) & ~((alignment)-1))enum secure_packet_direction{  SECURE_PACKET_SEND,  SECURE_PACKET_RECEIVE};static RPC_STATUS I_RpcReAllocateBuffer(PRPC_MESSAGE pMsg);static DWORD RPCRT4_GetHeaderSize(const RpcPktHdr *Header){  static const DWORD header_sizes[] = {    sizeof(Header->request), 0, sizeof(Header->response),    sizeof(Header->fault), 0, 0, 0, 0, 0, 0, 0, sizeof(Header->bind),    sizeof(Header->bind_ack), sizeof(Header->bind_nack),    0, 0, 0, 0, 0  };  ULONG ret = 0;    if (Header->common.ptype < sizeof(header_sizes) / sizeof(header_sizes[0])) {    ret = header_sizes[Header->common.ptype];    if (ret == 0)      FIXME("unhandled packet type\n");    if (Header->common.flags & RPC_FLG_OBJECT_UUID)      ret += sizeof(UUID);  } else {    TRACE("invalid packet type\n");  }  return ret;}static int packet_has_body(const RpcPktHdr *Header){    return (Header->common.ptype == PKT_FAULT) ||           (Header->common.ptype == PKT_REQUEST) ||           (Header->common.ptype == PKT_RESPONSE);}static int packet_has_auth_verifier(const RpcPktHdr *Header){    return !(Header->common.ptype == PKT_BIND_NACK) &&           !(Header->common.ptype == PKT_SHUTDOWN);}static VOID RPCRT4_BuildCommonHeader(RpcPktHdr *Header, unsigned char PacketType,                              unsigned long DataRepresentation){  Header->common.rpc_ver = RPC_VER_MAJOR;  Header->common.rpc_ver_minor = RPC_VER_MINOR;  Header->common.ptype = PacketType;  Header->common.drep[0] = LOBYTE(LOWORD(DataRepresentation));  Header->common.drep[1] = HIBYTE(LOWORD(DataRepresentation));  Header->common.drep[2] = LOBYTE(HIWORD(DataRepresentation));  Header->common.drep[3] = HIBYTE(HIWORD(DataRepresentation));  Header->common.auth_len = 0;  Header->common.call_id = 1;  Header->common.flags = 0;  /* Flags and fragment length are computed in RPCRT4_Send. */}                              static RpcPktHdr *RPCRT4_BuildRequestHeader(unsigned long DataRepresentation,                                     unsigned long BufferLength,                                     unsigned short ProcNum,                                     UUID *ObjectUuid){  RpcPktHdr *header;  BOOL has_object;  RPC_STATUS status;  has_object = (ObjectUuid != NULL && !UuidIsNil(ObjectUuid, &status));  header = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,                     sizeof(header->request) + (has_object ? sizeof(UUID) : 0));  if (header == NULL) {    return NULL;  }  RPCRT4_BuildCommonHeader(header, PKT_REQUEST, DataRepresentation);  header->common.frag_len = sizeof(header->request);  header->request.alloc_hint = BufferLength;  header->request.context_id = 0;  header->request.opnum = ProcNum;  if (has_object) {    header->common.flags |= RPC_FLG_OBJECT_UUID;    header->common.frag_len += sizeof(UUID);    memcpy(&header->request + 1, ObjectUuid, sizeof(UUID));  }  return header;}RpcPktHdr *RPCRT4_BuildResponseHeader(unsigned long DataRepresentation,                                      unsigned long BufferLength){  RpcPktHdr *header;  header = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(header->response));  if (header == NULL) {    return NULL;  }  RPCRT4_BuildCommonHeader(header, PKT_RESPONSE, DataRepresentation);  header->common.frag_len = sizeof(header->response);  header->response.alloc_hint = BufferLength;  return header;}RpcPktHdr *RPCRT4_BuildFaultHeader(unsigned long DataRepresentation,                                   RPC_STATUS Status){  RpcPktHdr *header;  header = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(header->fault));  if (header == NULL) {    return NULL;  }  RPCRT4_BuildCommonHeader(header, PKT_FAULT, DataRepresentation);  header->common.frag_len = sizeof(header->fault);  header->fault.status = Status;  return header;}RpcPktHdr *RPCRT4_BuildBindHeader(unsigned long DataRepresentation,                                  unsigned short MaxTransmissionSize,                                  unsigned short MaxReceiveSize,                                  unsigned long  AssocGroupId,                                  const RPC_SYNTAX_IDENTIFIER *AbstractId,                                  const RPC_SYNTAX_IDENTIFIER *TransferId){  RpcPktHdr *header;  header = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(header->bind));  if (header == NULL) {    return NULL;  }  RPCRT4_BuildCommonHeader(header, PKT_BIND, DataRepresentation);  header->common.frag_len = sizeof(header->bind);  header->bind.max_tsize = MaxTransmissionSize;  header->bind.max_rsize = MaxReceiveSize;  header->bind.assoc_gid = AssocGroupId;  header->bind.num_elements = 1;  header->bind.num_syntaxes = 1;  memcpy(&header->bind.abstract, AbstractId, sizeof(RPC_SYNTAX_IDENTIFIER));  memcpy(&header->bind.transfer, TransferId, sizeof(RPC_SYNTAX_IDENTIFIER));  return header;}static RpcPktHdr *RPCRT4_BuildAuthHeader(unsigned long DataRepresentation){  RpcPktHdr *header;  header = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,                     sizeof(header->common) + 12);  if (header == NULL)    return NULL;  RPCRT4_BuildCommonHeader(header, PKT_AUTH3, DataRepresentation);  header->common.frag_len = 0x14;  header->common.auth_len = 0;  return header;}RpcPktHdr *RPCRT4_BuildBindNackHeader(unsigned long DataRepresentation,                                      unsigned char RpcVersion,                                      unsigned char RpcVersionMinor){  RpcPktHdr *header;  header = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(header->bind_nack));  if (header == NULL) {    return NULL;  }  RPCRT4_BuildCommonHeader(header, PKT_BIND_NACK, DataRepresentation);  header->common.frag_len = sizeof(header->bind_nack);  header->bind_nack.protocols_count = 1;  header->bind_nack.protocols[0].rpc_ver = RpcVersion;  header->bind_nack.protocols[0].rpc_ver_minor = RpcVersionMinor;  return header;}RpcPktHdr *RPCRT4_BuildBindAckHeader(unsigned long DataRepresentation,                                     unsigned short MaxTransmissionSize,                                     unsigned short MaxReceiveSize,                                     LPCSTR ServerAddress,                                     unsigned long Result,                                     unsigned long Reason,                                     const RPC_SYNTAX_IDENTIFIER *TransferId){  RpcPktHdr *header;  unsigned long header_size;  RpcAddressString *server_address;  RpcResults *results;  RPC_SYNTAX_IDENTIFIER *transfer_id;  header_size = sizeof(header->bind_ack) +                ROUND_UP(FIELD_OFFSET(RpcAddressString, string[strlen(ServerAddress) + 1]), 4) +                sizeof(RpcResults) +                sizeof(RPC_SYNTAX_IDENTIFIER);  header = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, header_size);  if (header == NULL) {    return NULL;  }  RPCRT4_BuildCommonHeader(header, PKT_BIND_ACK, DataRepresentation);  header->common.frag_len = header_size;  header->bind_ack.max_tsize = MaxTransmissionSize;  header->bind_ack.max_rsize = MaxReceiveSize;  server_address = (RpcAddressString*)(&header->bind_ack + 1);  server_address->length = strlen(ServerAddress) + 1;  strcpy(server_address->string, ServerAddress);  /* results is 4-byte aligned */  results = (RpcResults*)((ULONG_PTR)server_address + ROUND_UP(FIELD_OFFSET(RpcAddressString, string[server_address->length]), 4));  results->num_results = 1;  results->results[0].result = Result;  results->results[0].reason = Reason;  transfer_id = (RPC_SYNTAX_IDENTIFIER*)(results + 1);  memcpy(transfer_id, TransferId, sizeof(RPC_SYNTAX_IDENTIFIER));  return header;}VOID RPCRT4_FreeHeader(RpcPktHdr *Header){  HeapFree(GetProcessHeap(), 0, Header);}NCA_STATUS RPC2NCA_STATUS(RPC_STATUS status){    switch (status)    {    case ERROR_INVALID_HANDLE:              return NCA_S_FAULT_CONTEXT_MISMATCH;    case ERROR_OUTOFMEMORY:                 return NCA_S_FAULT_REMOTE_NO_MEMORY;    case RPC_S_NOT_LISTENING:               return NCA_S_SERVER_TOO_BUSY;    case RPC_S_UNKNOWN_IF:                  return NCA_S_UNK_IF;    case RPC_S_SERVER_TOO_BUSY:             return NCA_S_SERVER_TOO_BUSY;    case RPC_S_CALL_FAILED:                 return NCA_S_FAULT_UNSPEC;    case RPC_S_CALL_FAILED_DNE:             return NCA_S_MANAGER_NOT_ENTERED;    case RPC_S_PROTOCOL_ERROR:              return NCA_S_PROTO_ERROR;    case RPC_S_UNSUPPORTED_TYPE:            return NCA_S_UNSUPPORTED_TYPE;    case RPC_S_INVALID_TAG:                 return NCA_S_FAULT_INVALID_TAG;    case RPC_S_INVALID_BOUND:               return NCA_S_FAULT_INVALID_BOUND;    case RPC_S_PROCNUM_OUT_OF_RANGE:        return NCA_S_OP_RNG_ERROR;    case RPC_X_SS_HANDLES_MISMATCH:         return NCA_S_FAULT_CONTEXT_MISMATCH;    case STATUS_FLOAT_DIVIDE_BY_ZERO:       return NCA_S_FAULT_FP_DIV_ZERO;    case STATUS_FLOAT_INVALID_OPERATION:    return NCA_S_FAULT_FP_ERROR;    case STATUS_FLOAT_OVERFLOW:             return NCA_S_FAULT_FP_OVERFLOW;    case STATUS_FLOAT_UNDERFLOW:            return NCA_S_FAULT_FP_UNDERFLOW;    case STATUS_INTEGER_DIVIDE_BY_ZERO:     return NCA_S_FAULT_INT_DIV_BY_ZERO;    case STATUS_INTEGER_OVERFLOW:           return NCA_S_FAULT_INT_OVERFLOW;    default:                                return status;    }}RPC_STATUS NCA2RPC_STATUS(NCA_STATUS status){    switch (status)    {    case NCA_S_COMM_FAILURE:            return RPC_S_COMM_FAILURE;    case NCA_S_OP_RNG_ERROR:            return RPC_S_PROCNUM_OUT_OF_RANGE;    case NCA_S_UNK_IF:                  return RPC_S_UNKNOWN_IF;    case NCA_S_YOU_CRASHED:             return RPC_S_CALL_FAILED;    case NCA_S_PROTO_ERROR:             return RPC_S_PROTOCOL_ERROR;    case NCA_S_OUT_ARGS_TOO_BIG:        return ERROR_NOT_ENOUGH_SERVER_MEMORY;    case NCA_S_SERVER_TOO_BUSY:         return RPC_S_SERVER_TOO_BUSY;    case NCA_S_UNSUPPORTED_TYPE:        return RPC_S_UNSUPPORTED_TYPE;    case NCA_S_FAULT_INT_DIV_BY_ZERO:   return RPC_S_ZERO_DIVIDE;    case NCA_S_FAULT_ADDR_ERROR:        return RPC_S_ADDRESS_ERROR;    case NCA_S_FAULT_FP_DIV_ZERO:       return RPC_S_FP_DIV_ZERO;    case NCA_S_FAULT_FP_UNDERFLOW:      return RPC_S_FP_UNDERFLOW;    case NCA_S_FAULT_FP_OVERFLOW:       return RPC_S_FP_OVERFLOW;    case NCA_S_FAULT_INVALID_TAG:       return RPC_S_INVALID_TAG;    case NCA_S_FAULT_INVALID_BOUND:     return RPC_S_INVALID_BOUND;    case NCA_S_RPC_VERSION_MISMATCH:    return RPC_S_PROTOCOL_ERROR;    case NCA_S_UNSPEC_REJECT:           return RPC_S_CALL_FAILED_DNE;    case NCA_S_BAD_ACTID:               return RPC_S_CALL_FAILED_DNE;    case NCA_S_WHO_ARE_YOU_FAILED:      return RPC_S_CALL_FAILED;    case NCA_S_MANAGER_NOT_ENTERED:     return RPC_S_CALL_FAILED_DNE;    case NCA_S_FAULT_CANCEL:            return RPC_S_CALL_CANCELLED;    case NCA_S_FAULT_ILL_INST:          return RPC_S_ADDRESS_ERROR;    case NCA_S_FAULT_FP_ERROR:          return RPC_S_FP_OVERFLOW;    case NCA_S_FAULT_INT_OVERFLOW:      return RPC_S_ADDRESS_ERROR;    case NCA_S_FAULT_UNSPEC:            return RPC_S_CALL_FAILED;    case NCA_S_FAULT_PIPE_EMPTY:        return RPC_X_PIPE_EMPTY;    case NCA_S_FAULT_PIPE_CLOSED:       return RPC_X_PIPE_CLOSED;    case NCA_S_FAULT_PIPE_ORDER:        return RPC_X_WRONG_PIPE_ORDER;    case NCA_S_FAULT_PIPE_DISCIPLINE:   return RPC_X_PIPE_DISCIPLINE_ERROR;    case NCA_S_FAULT_PIPE_COMM_ERROR:   return RPC_S_COMM_FAILURE;    case NCA_S_FAULT_PIPE_MEMORY:       return ERROR_OUTOFMEMORY;    case NCA_S_FAULT_CONTEXT_MISMATCH:  return ERROR_INVALID_HANDLE;    case NCA_S_FAULT_REMOTE_NO_MEMORY:  return ERROR_NOT_ENOUGH_SERVER_MEMORY;    default:                            return status;    }}static RPC_STATUS RPCRT4_SecurePacket(RpcConnection *Connection,    enum secure_packet_direction dir,    RpcPktHdr *hdr, unsigned int hdr_size,    unsigned char *stub_data, unsigned int stub_data_size,    RpcAuthVerifier *auth_hdr,    unsigned char *auth_value, unsigned int auth_value_size){    SecBufferDesc message;    SecBuffer buffers[4];    SECURITY_STATUS sec_status;    message.ulVersion = SECBUFFER_VERSION;    message.cBuffers = sizeof(buffers)/sizeof(buffers[0]);    message.pBuffers = buffers;    buffers[0].cbBuffer = hdr_size;    buffers[0].BufferType = SECBUFFER_DATA|SECBUFFER_READONLY_WITH_CHECKSUM;    buffers[0].pvBuffer = hdr;    buffers[1].cbBuffer = stub_data_size;    buffers[1].BufferType = SECBUFFER_DATA;    buffers[1].pvBuffer = stub_data;    buffers[2].cbBuffer = sizeof(*auth_hdr);    buffers[2].BufferType = SECBUFFER_DATA|SECBUFFER_READONLY_WITH_CHECKSUM;    buffers[2].pvBuffer = auth_hdr;    buffers[3].cbBuffer = auth_value_size;    buffers[3].BufferType = SECBUFFER_TOKEN;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -