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

📄 rpc_transport.c

📁 这是一个开放源代码的与WINNT/WIN2K/WIN2003兼容的操作系统
💻 C
📖 第 1 页 / 共 4 页
字号:
    smb_floor = (twr_empty_floor_t *)tower_data;    tower_data += sizeof(*smb_floor);    smb_floor->count_lhs = sizeof(smb_floor->protid);    smb_floor->protid = EPM_PROTOCOL_SMB;    smb_floor->count_rhs = endpoint_size;    memcpy(tower_data, endpoint, endpoint_size);    tower_data += endpoint_size;    nb_floor = (twr_empty_floor_t *)tower_data;    tower_data += sizeof(*nb_floor);    nb_floor->count_lhs = sizeof(nb_floor->protid);    nb_floor->protid = EPM_PROTOCOL_NETBIOS;    nb_floor->count_rhs = networkaddr_size;    memcpy(tower_data, networkaddr, networkaddr_size);    tower_data += networkaddr_size;    return size;}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;}typedef struct _RpcServerProtseq_np{    RpcServerProtseq common;    HANDLE mgr_event;} RpcServerProtseq_np;static RpcServerProtseq *rpcrt4_protseq_np_alloc(void){    RpcServerProtseq_np *ps = HeapAlloc(GetProcessHeap(), 0, sizeof(*ps));    if (ps)        ps->mgr_event = CreateEventW(NULL, FALSE, FALSE, NULL);    return &ps->common;}static void rpcrt4_protseq_np_signal_state_changed(RpcServerProtseq *protseq){    RpcServerProtseq_np *npps = CONTAINING_RECORD(protseq, RpcServerProtseq_np, common);    SetEvent(npps->mgr_event);}static void *rpcrt4_protseq_np_get_wait_array(RpcServerProtseq *protseq, void *prev_array, unsigned int *count){    HANDLE *objs = prev_array;    RpcConnection_np *conn;    RpcServerProtseq_np *npps = CONTAINING_RECORD(protseq, RpcServerProtseq_np, common);        EnterCriticalSection(&protseq->cs);        /* open and count connections */    *count = 1;    conn = CONTAINING_RECORD(protseq->conn, RpcConnection_np, common);    while (conn) {        rpcrt4_conn_listen_pipe(conn);        if (conn->ovl.hEvent)            (*count)++;        conn = CONTAINING_RECORD(conn->common.Next, RpcConnection_np, common);    }        /* make array of connections */    if (objs)        objs = HeapReAlloc(GetProcessHeap(), 0, objs, *count*sizeof(HANDLE));    else        objs = HeapAlloc(GetProcessHeap(), 0, *count*sizeof(HANDLE));    if (!objs)    {        ERR("couldn't allocate objs\n");        LeaveCriticalSection(&protseq->cs);        return NULL;    }        objs[0] = npps->mgr_event;    *count = 1;    conn = CONTAINING_RECORD(protseq->conn, RpcConnection_np, common);    while (conn) {        if ((objs[*count] = conn->ovl.hEvent))            (*count)++;        conn = CONTAINING_RECORD(conn->common.Next, RpcConnection_np, common);    }    LeaveCriticalSection(&protseq->cs);    return objs;}static void rpcrt4_protseq_np_free_wait_array(RpcServerProtseq *protseq, void *array){    HeapFree(GetProcessHeap(), 0, array);}static int rpcrt4_protseq_np_wait_for_new_connection(RpcServerProtseq *protseq, unsigned int count, void *wait_array){    HANDLE b_handle;    HANDLE *objs = wait_array;    DWORD res;    RpcConnection *cconn;    RpcConnection_np *conn;        if (!objs)        return -1;        res = WaitForMultipleObjects(count, objs, FALSE, INFINITE);    if (res == WAIT_OBJECT_0)        return 0;    else if (res == WAIT_FAILED)    {        ERR("wait failed with error %d\n", GetLastError());        return -1;    }    else    {        b_handle = objs[res - WAIT_OBJECT_0];        /* find which connection got a RPC */        EnterCriticalSection(&protseq->cs);        conn = CONTAINING_RECORD(protseq->conn, RpcConnection_np, common);        while (conn) {            if (b_handle == conn->ovl.hEvent) break;            conn = CONTAINING_RECORD(conn->common.Next, RpcConnection_np, common);        }        cconn = NULL;        if (conn)            RPCRT4_SpawnConnection(&cconn, &conn->common);        else            ERR("failed to locate connection for handle %p\n", b_handle);        LeaveCriticalSection(&protseq->cs);        if (cconn)        {            RPCRT4_new_client(cconn);            return 1;        }        else return -1;    }}static size_t rpcrt4_ncalrpc_get_top_of_tower(unsigned char *tower_data,                                              const char *networkaddr,                                              const char *endpoint){    twr_empty_floor_t *pipe_floor;    size_t size;    size_t endpoint_size;    TRACE("(%p, %s, %s)\n", tower_data, networkaddr, endpoint);    endpoint_size = strlen(networkaddr) + 1;    size = sizeof(*pipe_floor) + endpoint_size;    if (!tower_data)        return size;    pipe_floor = (twr_empty_floor_t *)tower_data;    tower_data += sizeof(*pipe_floor);    pipe_floor->count_lhs = sizeof(pipe_floor->protid);    pipe_floor->protid = EPM_PROTOCOL_SMB;    pipe_floor->count_rhs = endpoint_size;    memcpy(tower_data, endpoint, endpoint_size);    tower_data += endpoint_size;    return size;}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;}/**** ncacn_ip_tcp support ****/typedef struct _RpcConnection_tcp{  RpcConnection common;  int sock;} RpcConnection_tcp;static RpcConnection *rpcrt4_conn_tcp_alloc(void){  RpcConnection_tcp *tcpc;  tcpc = HeapAlloc(GetProcessHeap(), 0, sizeof(RpcConnection_tcp));  if (tcpc == NULL)    return NULL;  tcpc->sock = -1;  return &tcpc->common;}static RPC_STATUS rpcrt4_ncacn_ip_tcp_open(RpcConnection* Connection){  RpcConnection_tcp *tcpc = (RpcConnection_tcp *) Connection;  int sock;  int ret;  struct addrinfo *ai;  struct addrinfo *ai_cur;  struct addrinfo hints;  TRACE("(%s, %s)\n", Connection->NetworkAddr, Connection->Endpoint);  if (tcpc->sock != -1)    return RPC_S_OK;  hints.ai_flags          = 0;  hints.ai_family         = PF_UNSPEC;  hints.ai_socktype       = SOCK_STREAM;  hints.ai_protocol       = IPPROTO_TCP;  hints.ai_addrlen        = 0;  hints.ai_addr           = NULL;  hints.ai_canonname      = NULL;  hints.ai_next           = NULL;  ret = getaddrinfo(Connection->NetworkAddr, Connection->Endpoint, &hints, &ai);  if (ret)  {    ERR("getaddrinfo for %s:%s failed: %s\n", Connection->NetworkAddr,      Connection->Endpoint, gai_strerror(ret));    return RPC_S_SERVER_UNAVAILABLE;  }  for (ai_cur = ai; ai_cur; ai_cur = ai_cur->ai_next)  {    int val;    if (TRACE_ON(rpc))    {      char host[256];      char service[256];      getnameinfo(ai_cur->ai_addr, ai_cur->ai_addrlen,        host, sizeof(host), service, sizeof(service),        NI_NUMERICHOST | NI_NUMERICSERV);      TRACE("trying %s:%s\n", host, service);    }    sock = socket(ai_cur->ai_family, ai_cur->ai_socktype, ai_cur->ai_protocol);    if (sock < 0)    {      WARN("socket() failed: %s\n", strerror(errno));      continue;    }    if (0>connect(sock, ai_cur->ai_addr, ai_cur->ai_addrlen))    {      WARN("connect() failed: %s\n", strerror(errno));      close(sock);      continue;    }    /* RPC depends on having minimal latency so disable the Nagle algorithm */    val = 1;    setsockopt(sock, SOL_TCP, TCP_NODELAY, (char *)&val, sizeof(val));    tcpc->sock = sock;    freeaddrinfo(ai);    TRACE("connected\n");    return RPC_S_OK;  }  freeaddrinfo(ai);  ERR("couldn't connect to %s:%s\n", Connection->NetworkAddr, Connection->Endpoint);  return RPC_S_SERVER_UNAVAILABLE;}static RPC_STATUS rpcrt4_protseq_ncacn_ip_tcp_open_endpoint(RpcServerProtseq *protseq, LPSTR endpoint){    RPC_STATUS status = RPC_S_CANT_CREATE_ENDPOINT;    int sock;    int ret;    struct addrinfo *ai;    struct addrinfo *ai_cur;    struct addrinfo hints;    RpcConnection *first_connection = NULL;    u_long blocking;    TRACE("(%p, %s)\n", protseq, endpoint);    hints.ai_flags          = AI_PASSIVE /* for non-localhost addresses */;    hints.ai_family         = PF_UNSPEC;    hints.ai_socktype       = SOCK_STREAM;    hints.ai_protocol       = IPPROTO_TCP;    hints.ai_addrlen        = 0;    hints.ai_addr           = NULL;    hints.ai_canonname      = NULL;    hints.ai_next           = NULL;    ret = getaddrinfo(NULL, endpoint, &hints, &ai);    if (ret)    {        ERR("getaddrinfo for port %s failed: %s\n", endpoint,            gai_strerror(ret));        if ((ret == EAI_SERVICE) || (ret == EAI_NONAME))            return RPC_S_INVALID_ENDPOINT_FORMAT;        return RPC_S_CANT_CREATE_ENDPOINT;    }    for (ai_cur = ai; ai_cur; ai_cur = ai_cur->ai_next)    {        RpcConnection_tcp *tcpc;        RPC_STATUS create_status;        if (TRACE_ON(rpc))        {            char host[256];            char service[256];            getnameinfo(ai_cur->ai_addr, ai_cur->ai_addrlen,                        host, sizeof(host), service, sizeof(service),                        NI_NUMERICHOST | NI_NUMERICSERV);            TRACE("trying %s:%s\n", host, service);        }        sock = socket(ai_cur->ai_family, ai_cur->ai_socktype, ai_cur->ai_protocol);        if (sock < 0)        {            WARN("socket() failed: %s\n", strerror(errno));            status = RPC_S_CANT_CREATE_ENDPOINT;            continue;        }        ret = bind(sock, ai_cur->ai_addr, ai_cur->ai_addrlen);        if (ret < 0)        {            WARN("bind failed: %s\n", strerror(errno));            close(sock);            if (errno == WSAEADDRINUSE)              status = RPC_S_DUPLICATE_ENDPOINT;            else              status = RPC_S_CANT_CREATE_ENDPOINT;            continue;        }        create_status = RPCRT4_CreateConnection((RpcConnection **)&tcpc, TRUE,                                                protseq->Protseq, NULL,                                                endpoint, NULL, NULL, NULL);        if (create_status != RPC_S_OK)        {            close(sock);            status = create_status;            continue;        }        tcpc->sock = sock;        ret = listen(sock, protseq->MaxCalls);        if (ret < 0)        {            WARN("listen failed: %s\n", strerror(errno));            RPCRT4_DestroyConnection(&tcpc->common);            status = RPC_S_OUT_OF_RESOURCES;            continue;        }

⌨️ 快捷键说明

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