4 * Copyright 2001-2002 Ove Kåven, TransGaming Technologies
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 * - figure out whether we *really* got this right
22 * - check for errors and throw exceptions
23 * - decide if OVERLAPPED_WORKS
37 #include "wine/debug.h"
39 #include "rpc_binding.h"
42 WINE_DEFAULT_DEBUG_CHANNEL(ole);
44 /***********************************************************************
45 * I_RpcGetBuffer [RPCRT4.@]
47 RPC_STATUS WINAPI I_RpcGetBuffer(PRPC_MESSAGE pMsg)
51 TRACE("(%p)\n", pMsg);
52 buf = HeapReAlloc(GetProcessHeap(), 0, pMsg->Buffer, pMsg->BufferLength);
53 if (buf) pMsg->Buffer = buf;
54 /* FIXME: which errors to return? */
55 return buf ? S_OK : E_OUTOFMEMORY;
58 /***********************************************************************
59 * I_RpcFreeBuffer [RPCRT4.@]
61 RPC_STATUS WINAPI I_RpcFreeBuffer(PRPC_MESSAGE pMsg)
63 TRACE("(%p)\n", pMsg);
64 HeapFree(GetProcessHeap(), 0, pMsg->Buffer);
69 /***********************************************************************
70 * I_RpcSend [RPCRT4.@]
72 RPC_STATUS WINAPI I_RpcSend(PRPC_MESSAGE pMsg)
74 RpcBinding* bind = (RpcBinding*)pMsg->Handle;
75 RPC_CLIENT_INTERFACE* cif;
79 TRACE("(%p)\n", pMsg);
80 if (!bind) return RPC_S_INVALID_BINDING;
82 /* I'll only implement this for client handles for now */
83 if (bind->server) return RPC_S_WRONG_KIND_OF_BINDING;
85 cif = pMsg->RpcInterfaceInformation;
86 if (!cif) return RPC_S_INTERFACE_NOT_FOUND; /* ? */
88 status = RPCRT4_OpenBinding(bind);
89 if (status != RPC_S_OK) return status;
91 /* initialize packet header */
92 memset(&hdr, 0, sizeof(hdr));
94 hdr.ptype = PKT_REQUEST;
95 hdr.object = bind->ObjectUuid;
96 hdr.if_id = cif->InterfaceId.SyntaxGUID;
97 hdr.if_vers = MAKELONG(cif->InterfaceId.SyntaxVersion.MinorVersion,
98 cif->InterfaceId.SyntaxVersion.MajorVersion);
99 hdr.opnum = pMsg->ProcNum;
100 hdr.len = pMsg->BufferLength;
102 /* transmit packet */
103 if (!WriteFile(bind->conn, &hdr, sizeof(hdr), NULL, NULL))
104 return GetLastError();
105 if (!WriteFile(bind->conn, pMsg->Buffer, pMsg->BufferLength, NULL, NULL))
106 return GetLastError();
112 /***********************************************************************
113 * I_RpcReceive [RPCRT4.@]
115 RPC_STATUS WINAPI I_RpcReceive(PRPC_MESSAGE pMsg)
117 RpcBinding* bind = (RpcBinding*)pMsg->Handle;
122 TRACE("(%p)\n", pMsg);
123 if (!bind) return RPC_S_INVALID_BINDING;
125 /* I'll only implement this for client handles for now */
126 if (bind->server) return RPC_S_WRONG_KIND_OF_BINDING;
128 status = RPCRT4_OpenBinding(bind);
129 if (status != RPC_S_OK) return status;
131 /* read packet header */
132 #ifdef OVERLAPPED_WORKS
133 if (!ReadFile(bind->conn, &hdr, sizeof(hdr), &dwRead, &bind->ovl)) {
134 DWORD err = GetLastError();
135 if (err != ERROR_IO_PENDING) {
138 if (!GetOverlappedResult(bind->conn, &bind->ovl, &dwRead, TRUE)) return GetLastError();
141 if (!ReadFile(bind->conn, &hdr, sizeof(hdr), &dwRead, NULL))
142 return GetLastError();
144 if (dwRead != sizeof(hdr)) return RPC_S_PROTOCOL_ERROR;
146 /* read packet body */
147 pMsg->BufferLength = hdr.len;
148 status = I_RpcGetBuffer(pMsg);
149 if (status != RPC_S_OK) return status;
150 #ifdef OVERLAPPED_WORKS
151 if (!ReadFile(bind->conn, pMsg->Buffer, hdr.len, &dwRead, &bind->ovl)) {
152 DWORD err = GetLastError();
153 if (err != ERROR_IO_PENDING) {
156 if (!GetOverlappedResult(bind->conn, &bind->ovl, &dwRead, TRUE)) return GetLastError();
159 if (!ReadFile(bind->conn, pMsg->Buffer, hdr.len, &dwRead, NULL))
160 return GetLastError();
162 if (dwRead != hdr.len) return RPC_S_PROTOCOL_ERROR;
168 /***********************************************************************
169 * I_RpcSendReceive [RPCRT4.@]
171 RPC_STATUS WINAPI I_RpcSendReceive(PRPC_MESSAGE pMsg)
175 TRACE("(%p)\n", pMsg);
176 status = I_RpcSend(pMsg);
177 if (status == RPC_S_OK)
178 status = I_RpcReceive(pMsg);