/*********************************************************************** * I_RpcGetBuffer [RPCRT4.@] * * Allocates a buffer for use by I_RpcSend or I_RpcSendReceive and binds to the * server interface. * * PARAMS * pMsg [I/O] RPC message information. * * RETURNS * Success: RPC_S_OK. * Failure: RPC_S_INVALID_BINDING if pMsg->Handle is invalid. * RPC_S_SERVER_UNAVAILABLE if unable to connect to server. * ERROR_OUTOFMEMORY if buffer allocation failed. * * NOTES * The pMsg->BufferLength field determines the size of the buffer to allocate, * in bytes. * * Use I_RpcFreeBuffer() to unbind from the server and free the message buffer. * * SEE ALSO * I_RpcFreeBuffer(), I_RpcSend(), I_RpcReceive(), I_RpcSendReceive(). */ RPC_STATUS WINAPI I_RpcGetBuffer(PRPC_MESSAGE pMsg) { RPC_STATUS status; RpcBinding* bind = (RpcBinding*)pMsg->Handle; FB_TRACE("> (%p): BufferLength=%d\n", pMsg, pMsg->BufferLength); if (!bind) { FE_ERR("< no binding\n"); return RPC_S_INVALID_BINDING; } pMsg->Buffer = I_RpcAllocate(pMsg->BufferLength); TRACE("Buffer=%p\n", pMsg->Buffer); if (!pMsg->Buffer) return ERROR_OUTOFMEMORY; if (!bind->server) { status = I_RpcNegotiateTransferSyntax(pMsg); if (status != RPC_S_OK) I_RpcFree(pMsg->Buffer); } else status = RPC_S_OK; FE_TRACE("< status:%lu\n",status); return status; }
static RPC_STATUS rpcrt4_protseq_ncacn_np_open_endpoint(RpcServerProtseq *protseq, LPSTR endpoint) { static const char prefix[] = "\\\\."; RPC_STATUS r; LPSTR pname; RpcConnection *Connection; r = RPCRT4_CreateConnection(&Connection, TRUE, protseq->Protseq, NULL, endpoint, NULL, NULL, NULL); if (r != RPC_S_OK) return r; /* protseq=ncacn_np: named pipes */ pname = I_RpcAllocate(strlen(prefix) + strlen(Connection->Endpoint) + 1); strcat(strcpy(pname, prefix), Connection->Endpoint); r = rpcrt4_conn_create_pipe(Connection, pname); I_RpcFree(pname); EnterCriticalSection(&protseq->cs); Connection->Next = protseq->conn; protseq->conn = Connection; LeaveCriticalSection(&protseq->cs); return r; }
static RPC_STATUS rpcrt4_ncalrpc_parse_top_of_tower(const unsigned char *tower_data, size_t tower_size, char **networkaddr, char **endpoint) { const twr_empty_floor_t *pipe_floor = (const twr_empty_floor_t *)tower_data; TRACE("(%p, %d, %p, %p)\n", tower_data, (int)tower_size, networkaddr, endpoint); *networkaddr = NULL; *endpoint = NULL; if (tower_size < sizeof(*pipe_floor)) return EPT_S_NOT_REGISTERED; tower_data += sizeof(*pipe_floor); tower_size -= sizeof(*pipe_floor); if ((pipe_floor->count_lhs != sizeof(pipe_floor->protid)) || (pipe_floor->protid != EPM_PROTOCOL_SMB) || (pipe_floor->count_rhs > tower_size)) return EPT_S_NOT_REGISTERED; if (endpoint) { *endpoint = I_RpcAllocate(pipe_floor->count_rhs); if (!*endpoint) return RPC_S_OUT_OF_RESOURCES; memcpy(*endpoint, tower_data, pipe_floor->count_rhs); } return RPC_S_OK; }
static RPC_STATUS rpcrt4_protseq_ncalrpc_open_endpoint(RpcServerProtseq* protseq, LPSTR endpoint) { static const char prefix[] = "\\\\.\\pipe\\lrpc\\"; RPC_STATUS r; LPSTR pname; RpcConnection *Connection; r = RPCRT4_CreateConnection(&Connection, TRUE, protseq->Protseq, NULL, endpoint, NULL, NULL, NULL); if (r != RPC_S_OK) return r; /* protseq=ncalrpc: supposed to use NT LPC ports, * but we'll implement it with named pipes for now */ pname = I_RpcAllocate(strlen(prefix) + strlen(Connection->Endpoint) + 1); strcat(strcpy(pname, prefix), Connection->Endpoint); r = rpcrt4_conn_create_pipe(Connection, pname); I_RpcFree(pname); EnterCriticalSection(&protseq->cs); Connection->Next = protseq->conn; protseq->conn = Connection; LeaveCriticalSection(&protseq->cs); return r; }
RPC_STATUS RpcTransport_ParseTopOfTower(const unsigned char *tower_data, size_t tower_size, char **protseq, char **networkaddr, char **endpoint) { const twr_empty_floor_t *protocol_floor; const twr_empty_floor_t *floor4; const struct connection_ops *protseq_ops = NULL; RPC_STATUS status; int i; if (tower_size < sizeof(*protocol_floor)) return EPT_S_NOT_REGISTERED; protocol_floor = (const twr_empty_floor_t *)tower_data; tower_data += sizeof(*protocol_floor); tower_size -= sizeof(*protocol_floor); if ((protocol_floor->count_lhs != sizeof(protocol_floor->protid)) || (protocol_floor->count_rhs > tower_size)) return EPT_S_NOT_REGISTERED; tower_data += protocol_floor->count_rhs; tower_size -= protocol_floor->count_rhs; floor4 = (const twr_empty_floor_t *)tower_data; if ((tower_size < sizeof(*floor4)) || (floor4->count_lhs != sizeof(floor4->protid))) return EPT_S_NOT_REGISTERED; for(i = 0; i < ARRAYSIZE(conn_protseq_list); i++) if ((protocol_floor->protid == conn_protseq_list[i].epm_protocols[0]) && (floor4->protid == conn_protseq_list[i].epm_protocols[1])) { protseq_ops = &conn_protseq_list[i]; break; } if (!protseq_ops) return EPT_S_NOT_REGISTERED; status = protseq_ops->parse_top_of_tower(tower_data, tower_size, networkaddr, endpoint); if ((status == RPC_S_OK) && protseq) { *protseq = I_RpcAllocate(strlen(protseq_ops->name) + 1); strcpy(*protseq, protseq_ops->name); } return status; }
static RPC_STATUS rpcrt4_ncacn_np_handoff(RpcConnection *old_conn, RpcConnection *new_conn) { RPC_STATUS status; LPSTR pname; static const char prefix[] = "\\\\."; rpcrt4_conn_np_handoff((RpcConnection_np *)old_conn, (RpcConnection_np *)new_conn); pname = I_RpcAllocate(strlen(prefix) + strlen(old_conn->Endpoint) + 1); strcat(strcpy(pname, prefix), old_conn->Endpoint); status = rpcrt4_conn_create_pipe(old_conn, pname); I_RpcFree(pname); return status; }
static RPC_STATUS rpcrt4_ncacn_np_open(RpcConnection* Connection) { RpcConnection_np *npc = (RpcConnection_np *) Connection; static const char prefix[] = "\\\\."; RPC_STATUS r; LPSTR pname; /* already connected? */ if (npc->pipe) return RPC_S_OK; /* protseq=ncacn_np: named pipes */ pname = I_RpcAllocate(strlen(prefix) + strlen(Connection->Endpoint) + 1); strcat(strcpy(pname, prefix), Connection->Endpoint); r = rpcrt4_conn_open_pipe(Connection, pname, FALSE); I_RpcFree(pname); return r; }
static RPC_STATUS rpcrt4_ncalrpc_open(RpcConnection* Connection) { RpcConnection_np *npc = (RpcConnection_np *) Connection; static const char prefix[] = "\\\\.\\pipe\\lrpc\\"; RPC_STATUS r; LPSTR pname; /* already connected? */ if (npc->pipe) return RPC_S_OK; /* protseq=ncalrpc: supposed to use NT LPC ports, * but we'll implement it with named pipes for now */ pname = I_RpcAllocate(strlen(prefix) + strlen(Connection->Endpoint) + 1); strcat(strcpy(pname, prefix), Connection->Endpoint); r = rpcrt4_conn_open_pipe(Connection, pname, TRUE); I_RpcFree(pname); return r; }
static RPC_STATUS rpcrt4_ncacn_np_parse_top_of_tower(const unsigned char *tower_data, size_t tower_size, char **networkaddr, char **endpoint) { const twr_empty_floor_t *smb_floor = (const twr_empty_floor_t *)tower_data; const twr_empty_floor_t *nb_floor; TRACE("(%p, %d, %p, %p)\n", tower_data, (int)tower_size, networkaddr, endpoint); if (tower_size < sizeof(*smb_floor)) return EPT_S_NOT_REGISTERED; tower_data += sizeof(*smb_floor); tower_size -= sizeof(*smb_floor); if ((smb_floor->count_lhs != sizeof(smb_floor->protid)) || (smb_floor->protid != EPM_PROTOCOL_SMB) || (smb_floor->count_rhs > tower_size)) return EPT_S_NOT_REGISTERED; if (endpoint) { *endpoint = I_RpcAllocate(smb_floor->count_rhs); if (!*endpoint) return RPC_S_OUT_OF_RESOURCES; memcpy(*endpoint, tower_data, smb_floor->count_rhs); } tower_data += smb_floor->count_rhs; tower_size -= smb_floor->count_rhs; if (tower_size < sizeof(*nb_floor)) return EPT_S_NOT_REGISTERED; nb_floor = (const twr_empty_floor_t *)tower_data; tower_data += sizeof(*nb_floor); tower_size -= sizeof(*nb_floor); if ((nb_floor->count_lhs != sizeof(nb_floor->protid)) || (nb_floor->protid != EPM_PROTOCOL_NETBIOS) || (nb_floor->count_rhs > tower_size)) return EPT_S_NOT_REGISTERED; if (networkaddr) { *networkaddr = I_RpcAllocate(nb_floor->count_rhs); if (!*networkaddr) { if (endpoint) { I_RpcFree(*endpoint); *endpoint = NULL; } return RPC_S_OUT_OF_RESOURCES; } memcpy(*networkaddr, tower_data, nb_floor->count_rhs); } return RPC_S_OK; }
static RPC_STATUS rpcrt4_ncacn_ip_tcp_parse_top_of_tower(const unsigned char *tower_data, size_t tower_size, char **networkaddr, char **endpoint) { const twr_tcp_floor_t *tcp_floor = (const twr_tcp_floor_t *)tower_data; const twr_ipv4_floor_t *ipv4_floor; struct in_addr in_addr; TRACE("(%p, %d, %p, %p)\n", tower_data, (int)tower_size, networkaddr, endpoint); if (tower_size < sizeof(*tcp_floor)) return EPT_S_NOT_REGISTERED; tower_data += sizeof(*tcp_floor); tower_size -= sizeof(*tcp_floor); if (tower_size < sizeof(*ipv4_floor)) return EPT_S_NOT_REGISTERED; ipv4_floor = (const twr_ipv4_floor_t *)tower_data; if ((tcp_floor->count_lhs != sizeof(tcp_floor->protid)) || (tcp_floor->protid != EPM_PROTOCOL_TCP) || (tcp_floor->count_rhs != sizeof(tcp_floor->port)) || (ipv4_floor->count_lhs != sizeof(ipv4_floor->protid)) || (ipv4_floor->protid != EPM_PROTOCOL_IP) || (ipv4_floor->count_rhs != sizeof(ipv4_floor->ipv4addr))) return EPT_S_NOT_REGISTERED; if (endpoint) { *endpoint = I_RpcAllocate(6 /* sizeof("65535") + 1 */); if (!*endpoint) return RPC_S_OUT_OF_RESOURCES; sprintf(*endpoint, "%u", ntohs(tcp_floor->port)); } if (networkaddr) { *networkaddr = I_RpcAllocate(INET_ADDRSTRLEN); if (!*networkaddr) { if (endpoint) { I_RpcFree(*endpoint); *endpoint = NULL; } return RPC_S_OUT_OF_RESOURCES; } in_addr.s_addr = ipv4_floor->ipv4addr; if (!inet_ntop(AF_INET, &in_addr, *networkaddr, INET_ADDRSTRLEN)) { ERR("inet_ntop: %s\n", strerror(errno)); I_RpcFree(*networkaddr); *networkaddr = NULL; if (endpoint) { I_RpcFree(*endpoint); *endpoint = NULL; } return EPT_S_NOT_REGISTERED; } } return RPC_S_OK; }