b48b037fbe
servers/hgfs/hgfs_server => servers/hgfs servers/hgfs/libhgfs => lib/libhgfs servers/rs/service => commands/service drivers/memory/memory_driver => drivers/memory drivers/memory/ramdisk => drivers/ramdisk
146 lines
3.8 KiB
C
146 lines
3.8 KiB
C
/* Part of libhgfs - (c) 2009, D.C. van Moolenbroek */
|
|
|
|
#include "inc.h"
|
|
|
|
#define CMD_XFER 0x1E /* vmware backdoor transfer command */
|
|
|
|
enum {
|
|
XFER_OPEN, /* open transfer channel */
|
|
XFER_SENDLEN, /* specify length of data to send */
|
|
XFER_SEND, /* send data */
|
|
XFER_RECVLEN, /* get length of data to receive */
|
|
XFER_RECV, /* receive data */
|
|
XFER_RECVACK, /* acknowledge receipt of data */
|
|
XFER_CLOSE /* close transfer channel */
|
|
};
|
|
|
|
#define STATUS(p) (HIWORD((p)[2]) & 0xff)
|
|
|
|
/*===========================================================================*
|
|
* channel_open *
|
|
*===========================================================================*/
|
|
PUBLIC int channel_open(ch, type)
|
|
struct channel *ch; /* struct describing the new channel */
|
|
u32_t type; /* channel type: CH_IN or CH_OUT */
|
|
{
|
|
/* Open a new backdoor channel. Upon success, the given channel structure will
|
|
* be filled with information and can be used in subsequent channel calls.
|
|
* Return OK on success, or a negative error code on error.
|
|
*/
|
|
u32_t ptr[6];
|
|
|
|
ptr[1] = type | 0x80000000;
|
|
ptr[2] = MAKELONG(CMD_XFER, XFER_OPEN);
|
|
|
|
backdoor(ptr);
|
|
|
|
if ((STATUS(ptr) & 1) == 0) return EIO;
|
|
|
|
ch->id = HIWORD(ptr[3]);
|
|
ch->cookie1 = ptr[4];
|
|
ch->cookie2 = ptr[5];
|
|
|
|
return OK;
|
|
}
|
|
|
|
/*===========================================================================*
|
|
* channel_close *
|
|
*===========================================================================*/
|
|
PUBLIC void channel_close(ch)
|
|
struct channel *ch; /* backdoor channel to close */
|
|
{
|
|
/* Close a previously opened backdoor channel.
|
|
*/
|
|
u32_t ptr[6];
|
|
|
|
ptr[2] = MAKELONG(CMD_XFER, XFER_CLOSE);
|
|
ptr[3] = MAKELONG(0, ch->id);
|
|
ptr[4] = ch->cookie1;
|
|
ptr[5] = ch->cookie2;
|
|
|
|
backdoor(ptr);
|
|
}
|
|
|
|
/*===========================================================================*
|
|
* channel_send *
|
|
*===========================================================================*/
|
|
PUBLIC int channel_send(ch, buf, len)
|
|
struct channel *ch; /* backdoor channel to send to */
|
|
char *buf; /* buffer to send data from */
|
|
int len; /* size of the data to send */
|
|
{
|
|
/* Receive data over a backdoor channel. Return OK on success, or a negative
|
|
* error code on error.
|
|
*/
|
|
u32_t ptr[7];
|
|
|
|
ptr[1] = len;
|
|
ptr[2] = MAKELONG(CMD_XFER, XFER_SENDLEN);
|
|
ptr[3] = MAKELONG(0, ch->id);
|
|
ptr[4] = ch->cookie1;
|
|
ptr[5] = ch->cookie2;
|
|
|
|
backdoor(ptr);
|
|
|
|
if ((STATUS(ptr) & 1) == 0) return EIO;
|
|
|
|
if (len == 0) return OK;
|
|
|
|
ptr[1] = MAKELONG(0, 1);
|
|
ptr[2] = len;
|
|
ptr[3] = MAKELONG(0, ch->id);
|
|
ptr[4] = (u32_t)buf;
|
|
ptr[5] = ch->cookie2;
|
|
ptr[6] = ch->cookie1;
|
|
|
|
backdoor_out(ptr);
|
|
|
|
return OK;
|
|
}
|
|
|
|
/*===========================================================================*
|
|
* channel_recv *
|
|
*===========================================================================*/
|
|
PUBLIC int channel_recv(ch, buf, max)
|
|
struct channel *ch; /* backdoor channel to receive from */
|
|
char *buf; /* buffer to receive data into */
|
|
int max; /* size of the buffer */
|
|
{
|
|
/* Receive data on a backdoor channel. Return the number of bytes received, or
|
|
* a negative error code on error.
|
|
*/
|
|
u32_t ptr[7];
|
|
int len;
|
|
|
|
ptr[2] = MAKELONG(CMD_XFER, XFER_RECVLEN);
|
|
ptr[3] = MAKELONG(0, ch->id);
|
|
ptr[4] = ch->cookie1;
|
|
ptr[5] = ch->cookie2;
|
|
|
|
backdoor(ptr);
|
|
|
|
if ((STATUS(ptr) & 0x81) == 0) return EIO;
|
|
|
|
if ((len = ptr[1]) == 0 || (STATUS(ptr) & 3) == 1) return 0;
|
|
|
|
if (len > max) return E2BIG;
|
|
|
|
ptr[1] = MAKELONG(0, 1);
|
|
ptr[2] = len;
|
|
ptr[3] = MAKELONG(0, ch->id);
|
|
ptr[4] = ch->cookie1;
|
|
ptr[5] = (u32_t)buf;
|
|
ptr[6] = ch->cookie2;
|
|
|
|
backdoor_in(ptr);
|
|
|
|
ptr[1] = 1;
|
|
ptr[2] = MAKELONG(CMD_XFER, XFER_RECVACK);
|
|
ptr[3] = MAKELONG(0, ch->id);
|
|
ptr[4] = ch->cookie1;
|
|
ptr[5] = ch->cookie2;
|
|
|
|
backdoor(ptr);
|
|
|
|
return len;
|
|
}
|