1 /* Part of libhgfs - (c) 2009, D.C. van Moolenbroek */
2
3 #include "inc.h"
4
5 char rpc_buf[RPC_BUF_SIZE];
6 char *rpc_ptr;
7
8 static struct channel rpc_chan;
9
10 /*===========================================================================*
11 * rpc_open *
12 *===========================================================================*/
rpc_open(void)13 int rpc_open(void)
14 {
15 /* Open a HGFS RPC backdoor channel to the VMware host, and make sure that it
16 * is working. Return OK upon success, or a negative error code otherwise; in
17 * particular, return EAGAIN if shared folders are disabled.
18 */
19 int r;
20
21 if ((r = channel_open(&rpc_chan, CH_OUT)) != OK)
22 return r;
23
24 r = rpc_test();
25
26 if (r != OK)
27 channel_close(&rpc_chan);
28
29 return r;
30 }
31
32 /*===========================================================================*
33 * rpc_query *
34 *===========================================================================*/
rpc_query(void)35 int rpc_query(void)
36 {
37 /* Send a HGFS RPC query over the backdoor channel. Return OK upon success, or
38 * a negative error code otherwise; EAGAIN is returned if shared folders are
39 * disabled. In general, we make the assumption that the sender (= VMware)
40 * speaks the protocol correctly. Hence, the callers of this function do not
41 * check for lengths.
42 */
43 int r, len, err;
44
45 len = RPC_LEN;
46
47 /* A more robust version of this call could reopen the channel and
48 * retry the request upon low-level failure.
49 */
50 r = channel_send(&rpc_chan, rpc_buf, len);
51 if (r < 0) return r;
52
53 r = channel_recv(&rpc_chan, rpc_buf, sizeof(rpc_buf));
54 if (r < 0) return r;
55 if (r < 2 || (len > 2 && r < 10)) return EIO;
56
57 RPC_RESET;
58
59 if (RPC_NEXT8 != '1') return EAGAIN;
60 if (RPC_NEXT8 != ' ') return EAGAIN;
61
62 if (len <= 2) return OK;
63
64 RPC_ADVANCE(sizeof(u32_t)); /* Skip over id field. */
65 err = RPC_NEXT32;
66
67 return error_convert(err);
68 }
69
70 /*===========================================================================*
71 * rpc_test *
72 *===========================================================================*/
rpc_test(void)73 int rpc_test(void)
74 {
75 /* Test whether HGFS communication is working. Return OK on success, EAGAIN if
76 * shared folders are disabled, or another negative error code upon error.
77 */
78
79 RPC_RESET;
80 RPC_NEXT8 = 'f';
81 RPC_NEXT8 = ' ';
82
83 return rpc_query();
84 }
85
86 /*===========================================================================*
87 * rpc_close *
88 *===========================================================================*/
rpc_close(void)89 void rpc_close(void)
90 {
91 /* Close the HGFS RPC backdoor channel.
92 */
93
94 channel_close(&rpc_chan);
95 }
96