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 /* FIXME: pfnAllocate? */
53 buf
= HeapReAlloc(GetProcessHeap(), 0, pMsg
->Buffer
, pMsg
->BufferLength
);
54 if (buf
) pMsg
->Buffer
= buf
;
55 /* FIXME: which errors to return? */
56 return buf
? S_OK
: E_OUTOFMEMORY
;
59 /***********************************************************************
60 * I_RpcFreeBuffer [RPCRT4.@]
62 RPC_STATUS WINAPI
I_RpcFreeBuffer(PRPC_MESSAGE pMsg
)
64 TRACE("(%p)\n", pMsg
);
66 HeapFree(GetProcessHeap(), 0, pMsg
->Buffer
);
71 /***********************************************************************
72 * I_RpcSend [RPCRT4.@]
74 RPC_STATUS WINAPI
I_RpcSend(PRPC_MESSAGE pMsg
)
76 RpcBinding
* bind
= (RpcBinding
*)pMsg
->Handle
;
77 RPC_CLIENT_INTERFACE
* cif
= NULL
;
78 RPC_SERVER_INTERFACE
* sif
= NULL
;
82 TRACE("(%p)\n", pMsg
);
83 if (!bind
) return RPC_S_INVALID_BINDING
;
86 sif
= pMsg
->RpcInterfaceInformation
;
87 if (!sif
) return RPC_S_INTERFACE_NOT_FOUND
; /* ? */
89 cif
= pMsg
->RpcInterfaceInformation
;
90 if (!cif
) return RPC_S_INTERFACE_NOT_FOUND
; /* ? */
93 status
= RPCRT4_OpenBinding(bind
);
94 if (status
!= RPC_S_OK
) return status
;
96 /* initialize packet header */
97 memset(&hdr
, 0, sizeof(hdr
));
99 hdr
.ptype
= PKT_REQUEST
;
100 hdr
.object
= bind
->ObjectUuid
; /* FIXME: IIRC iff no object, the header structure excludes this elt */
101 hdr
.if_id
= (bind
->server
) ? sif
->InterfaceId
.SyntaxGUID
: cif
->InterfaceId
.SyntaxGUID
;
104 MAKELONG(sif
->InterfaceId
.SyntaxVersion
.MinorVersion
, sif
->InterfaceId
.SyntaxVersion
.MajorVersion
) :
105 MAKELONG(cif
->InterfaceId
.SyntaxVersion
.MinorVersion
, cif
->InterfaceId
.SyntaxVersion
.MajorVersion
);
106 hdr
.opnum
= pMsg
->ProcNum
;
107 /* only the low-order 3 octets of the DataRepresentation go in the header */
108 hdr
.drep
[0] = LOBYTE(LOWORD(pMsg
->DataRepresentation
));
109 hdr
.drep
[1] = HIBYTE(LOWORD(pMsg
->DataRepresentation
));
110 hdr
.drep
[2] = LOBYTE(HIWORD(pMsg
->DataRepresentation
));
111 hdr
.len
= pMsg
->BufferLength
;
113 /* transmit packet */
114 if (!WriteFile(bind
->conn
, &hdr
, sizeof(hdr
), NULL
, NULL
))
115 return GetLastError();
116 if (!WriteFile(bind
->conn
, pMsg
->Buffer
, pMsg
->BufferLength
, NULL
, NULL
))
117 return GetLastError();
123 /***********************************************************************
124 * I_RpcReceive [RPCRT4.@]
126 RPC_STATUS WINAPI
I_RpcReceive(PRPC_MESSAGE pMsg
)
128 RpcBinding
* bind
= (RpcBinding
*)pMsg
->Handle
;
133 TRACE("(%p)\n", pMsg
);
134 if (!bind
) return RPC_S_INVALID_BINDING
;
136 status
= RPCRT4_OpenBinding(bind
);
137 if (status
!= RPC_S_OK
) return status
;
139 /* read packet header */
140 #ifdef OVERLAPPED_WORKS
141 if (!ReadFile(bind
->conn
, &hdr
, sizeof(hdr
), &dwRead
, &bind
->ovl
)) {
142 DWORD err
= GetLastError();
143 if (err
!= ERROR_IO_PENDING
) {
146 if (!GetOverlappedResult(bind
->conn
, &bind
->ovl
, &dwRead
, TRUE
)) return GetLastError();
149 if (!ReadFile(bind
->conn
, &hdr
, sizeof(hdr
), &dwRead
, NULL
))
150 return GetLastError();
152 if (dwRead
!= sizeof(hdr
)) return RPC_S_PROTOCOL_ERROR
;
154 /* read packet body */
155 pMsg
->BufferLength
= hdr
.len
;
156 status
= I_RpcGetBuffer(pMsg
);
157 if (status
!= RPC_S_OK
) return status
;
158 #ifdef OVERLAPPED_WORKS
159 if (!ReadFile(bind
->conn
, pMsg
->Buffer
, hdr
.len
, &dwRead
, &bind
->ovl
)) {
160 DWORD err
= GetLastError();
161 if (err
!= ERROR_IO_PENDING
) {
164 if (!GetOverlappedResult(bind
->conn
, &bind
->ovl
, &dwRead
, TRUE
)) return GetLastError();
167 if (!ReadFile(bind
->conn
, pMsg
->Buffer
, hdr
.len
, &dwRead
, NULL
))
168 return GetLastError();
170 if (dwRead
!= hdr
.len
) return RPC_S_PROTOCOL_ERROR
;
176 /***********************************************************************
177 * I_RpcSendReceive [RPCRT4.@]
179 RPC_STATUS WINAPI
I_RpcSendReceive(PRPC_MESSAGE pMsg
)
183 TRACE("(%p)\n", pMsg
);
184 status
= I_RpcSend(pMsg
);
185 if (status
== RPC_S_OK
)
186 status
= I_RpcReceive(pMsg
);