 03514ba605
			
		
	
	
		03514ba605
		
	
	
	
	
		
			
			Patch submitted by hoefnix. Ref. https://groups.google.com/d/msg/minix-dev/sHQDVJRyx1c/eJjrYOqk5bgJ Change-Id: I2fcdf4cf119ef252ccc7df06849baf37ffd08440
		
			
				
	
	
		
			151 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			151 lines
		
	
	
		
			3.7 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				     *
 | |
|  *===========================================================================*/
 | |
| int channel_open(
 | |
| 	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				     *
 | |
|  *===========================================================================*/
 | |
| void channel_close(
 | |
| 	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				     *
 | |
|  *===========================================================================*/
 | |
| int channel_send(
 | |
| 	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				     *
 | |
|  *===========================================================================*/
 | |
| int channel_recv(
 | |
| 	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;
 | |
| }
 |