Keep track of per-column information inside the listview.
[wine] / dlls / rpcrt4 / rpc_message.c
1 /*
2  * RPC messages
3  *
4  * Copyright 2001-2002 Ove Kåven, TransGaming Technologies
5  *
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.
10  *
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.
15  *
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
19  *
20  * TODO:
21  *  - figure out whether we *really* got this right
22  *  - check for errors and throw exceptions
23  *  - decide if OVERLAPPED_WORKS
24  */
25
26 #include <stdio.h>
27 #include <string.h>
28
29 #include "windef.h"
30 #include "winbase.h"
31 #include "winerror.h"
32 #include "winreg.h"
33
34 #include "rpc.h"
35 #include "rpcdcep.h"
36
37 #include "wine/debug.h"
38
39 #include "rpc_binding.h"
40 #include "rpc_defs.h"
41
42 WINE_DEFAULT_DEBUG_CHANNEL(ole);
43
44 /***********************************************************************
45  *           I_RpcGetBuffer [RPCRT4.@]
46  */
47 RPC_STATUS WINAPI I_RpcGetBuffer(PRPC_MESSAGE pMsg)
48 {
49   void* buf;
50
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;
56 }
57
58 /***********************************************************************
59  *           I_RpcFreeBuffer [RPCRT4.@]
60  */
61 RPC_STATUS WINAPI I_RpcFreeBuffer(PRPC_MESSAGE pMsg)
62 {
63   TRACE("(%p)\n", pMsg);
64   HeapFree(GetProcessHeap(), 0, pMsg->Buffer);
65   pMsg->Buffer = NULL;
66   return S_OK;
67 }
68
69 /***********************************************************************
70  *           I_RpcSend [RPCRT4.@]
71  */
72 RPC_STATUS WINAPI I_RpcSend(PRPC_MESSAGE pMsg)
73 {
74   RpcBinding* bind = (RpcBinding*)pMsg->Handle;
75   RPC_CLIENT_INTERFACE* cif;
76   RPC_STATUS status;
77   RpcPktHdr hdr;
78
79   TRACE("(%p)\n", pMsg);
80   if (!bind) return RPC_S_INVALID_BINDING;
81
82   /* I'll only implement this for client handles for now */
83   if (bind->server) return RPC_S_WRONG_KIND_OF_BINDING;
84
85   cif = pMsg->RpcInterfaceInformation;
86   if (!cif) return RPC_S_INTERFACE_NOT_FOUND; /* ? */
87
88   status = RPCRT4_OpenBinding(bind);
89   if (status != RPC_S_OK) return status;
90
91   /* initialize packet header */
92   memset(&hdr, 0, sizeof(hdr));
93   hdr.rpc_ver = 4;
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;
101
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();
107
108   /* success */
109   return RPC_S_OK;
110 }
111
112 /***********************************************************************
113  *           I_RpcReceive [RPCRT4.@]
114  */
115 RPC_STATUS WINAPI I_RpcReceive(PRPC_MESSAGE pMsg)
116 {
117   RpcBinding* bind = (RpcBinding*)pMsg->Handle;
118   RPC_STATUS status;
119   RpcPktHdr hdr;
120   DWORD dwRead;
121
122   TRACE("(%p)\n", pMsg);
123   if (!bind) return RPC_S_INVALID_BINDING;
124
125   /* I'll only implement this for client handles for now */
126   if (bind->server) return RPC_S_WRONG_KIND_OF_BINDING;
127
128   status = RPCRT4_OpenBinding(bind);
129   if (status != RPC_S_OK) return status;
130
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) {
136       return err;
137     }
138     if (!GetOverlappedResult(bind->conn, &bind->ovl, &dwRead, TRUE)) return GetLastError();
139   }
140 #else
141   if (!ReadFile(bind->conn, &hdr, sizeof(hdr), &dwRead, NULL))
142     return GetLastError();
143 #endif
144   if (dwRead != sizeof(hdr)) return RPC_S_PROTOCOL_ERROR;
145
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) {
154       return err;
155     }
156     if (!GetOverlappedResult(bind->conn, &bind->ovl, &dwRead, TRUE)) return GetLastError();
157   }
158 #else
159   if (!ReadFile(bind->conn, pMsg->Buffer, hdr.len, &dwRead, NULL))
160     return GetLastError();
161 #endif
162   if (dwRead != hdr.len) return RPC_S_PROTOCOL_ERROR;
163
164   /* success */
165   return RPC_S_OK;
166 }
167
168 /***********************************************************************
169  *           I_RpcSendReceive [RPCRT4.@]
170  */
171 RPC_STATUS WINAPI I_RpcSendReceive(PRPC_MESSAGE pMsg)
172 {
173   RPC_STATUS status;
174
175   TRACE("(%p)\n", pMsg);
176   status = I_RpcSend(pMsg);
177   if (status == RPC_S_OK)
178     status = I_RpcReceive(pMsg);
179   return status;
180 }