1433d6423SLionel Sambuc /* Part of libhgfs - (c) 2009, D.C. van Moolenbroek */
2433d6423SLionel Sambuc
3433d6423SLionel Sambuc #include "inc.h"
4433d6423SLionel Sambuc
5433d6423SLionel Sambuc char rpc_buf[RPC_BUF_SIZE];
6433d6423SLionel Sambuc char *rpc_ptr;
7433d6423SLionel Sambuc
8433d6423SLionel Sambuc static struct channel rpc_chan;
9433d6423SLionel Sambuc
10433d6423SLionel Sambuc /*===========================================================================*
11433d6423SLionel Sambuc * rpc_open *
12433d6423SLionel Sambuc *===========================================================================*/
rpc_open(void)13433d6423SLionel Sambuc int rpc_open(void)
14433d6423SLionel Sambuc {
15433d6423SLionel Sambuc /* Open a HGFS RPC backdoor channel to the VMware host, and make sure that it
16433d6423SLionel Sambuc * is working. Return OK upon success, or a negative error code otherwise; in
17433d6423SLionel Sambuc * particular, return EAGAIN if shared folders are disabled.
18433d6423SLionel Sambuc */
19433d6423SLionel Sambuc int r;
20433d6423SLionel Sambuc
21433d6423SLionel Sambuc if ((r = channel_open(&rpc_chan, CH_OUT)) != OK)
22433d6423SLionel Sambuc return r;
23433d6423SLionel Sambuc
24433d6423SLionel Sambuc r = rpc_test();
25433d6423SLionel Sambuc
26433d6423SLionel Sambuc if (r != OK)
27433d6423SLionel Sambuc channel_close(&rpc_chan);
28433d6423SLionel Sambuc
29433d6423SLionel Sambuc return r;
30433d6423SLionel Sambuc }
31433d6423SLionel Sambuc
32433d6423SLionel Sambuc /*===========================================================================*
33433d6423SLionel Sambuc * rpc_query *
34433d6423SLionel Sambuc *===========================================================================*/
rpc_query(void)35433d6423SLionel Sambuc int rpc_query(void)
36433d6423SLionel Sambuc {
37433d6423SLionel Sambuc /* Send a HGFS RPC query over the backdoor channel. Return OK upon success, or
38433d6423SLionel Sambuc * a negative error code otherwise; EAGAIN is returned if shared folders are
39433d6423SLionel Sambuc * disabled. In general, we make the assumption that the sender (= VMware)
40433d6423SLionel Sambuc * speaks the protocol correctly. Hence, the callers of this function do not
41433d6423SLionel Sambuc * check for lengths.
42433d6423SLionel Sambuc */
43*0a6a1f1dSLionel Sambuc int r, len, err;
44433d6423SLionel Sambuc
45433d6423SLionel Sambuc len = RPC_LEN;
46433d6423SLionel Sambuc
47433d6423SLionel Sambuc /* A more robust version of this call could reopen the channel and
48433d6423SLionel Sambuc * retry the request upon low-level failure.
49433d6423SLionel Sambuc */
50433d6423SLionel Sambuc r = channel_send(&rpc_chan, rpc_buf, len);
51433d6423SLionel Sambuc if (r < 0) return r;
52433d6423SLionel Sambuc
53433d6423SLionel Sambuc r = channel_recv(&rpc_chan, rpc_buf, sizeof(rpc_buf));
54433d6423SLionel Sambuc if (r < 0) return r;
55433d6423SLionel Sambuc if (r < 2 || (len > 2 && r < 10)) return EIO;
56433d6423SLionel Sambuc
57433d6423SLionel Sambuc RPC_RESET;
58433d6423SLionel Sambuc
59433d6423SLionel Sambuc if (RPC_NEXT8 != '1') return EAGAIN;
60433d6423SLionel Sambuc if (RPC_NEXT8 != ' ') return EAGAIN;
61433d6423SLionel Sambuc
62433d6423SLionel Sambuc if (len <= 2) return OK;
63433d6423SLionel Sambuc
64*0a6a1f1dSLionel Sambuc RPC_ADVANCE(sizeof(u32_t)); /* Skip over id field. */
65433d6423SLionel Sambuc err = RPC_NEXT32;
66433d6423SLionel Sambuc
67433d6423SLionel Sambuc return error_convert(err);
68433d6423SLionel Sambuc }
69433d6423SLionel Sambuc
70433d6423SLionel Sambuc /*===========================================================================*
71433d6423SLionel Sambuc * rpc_test *
72433d6423SLionel Sambuc *===========================================================================*/
rpc_test(void)73433d6423SLionel Sambuc int rpc_test(void)
74433d6423SLionel Sambuc {
75433d6423SLionel Sambuc /* Test whether HGFS communication is working. Return OK on success, EAGAIN if
76433d6423SLionel Sambuc * shared folders are disabled, or another negative error code upon error.
77433d6423SLionel Sambuc */
78433d6423SLionel Sambuc
79433d6423SLionel Sambuc RPC_RESET;
80433d6423SLionel Sambuc RPC_NEXT8 = 'f';
81433d6423SLionel Sambuc RPC_NEXT8 = ' ';
82433d6423SLionel Sambuc
83433d6423SLionel Sambuc return rpc_query();
84433d6423SLionel Sambuc }
85433d6423SLionel Sambuc
86433d6423SLionel Sambuc /*===========================================================================*
87433d6423SLionel Sambuc * rpc_close *
88433d6423SLionel Sambuc *===========================================================================*/
rpc_close(void)89433d6423SLionel Sambuc void rpc_close(void)
90433d6423SLionel Sambuc {
91433d6423SLionel Sambuc /* Close the HGFS RPC backdoor channel.
92433d6423SLionel Sambuc */
93433d6423SLionel Sambuc
94433d6423SLionel Sambuc channel_close(&rpc_chan);
95433d6423SLionel Sambuc }
96