static Bool HgfsClient_Close(HgfsHandle rootHandle) // IN: Handle to root directory { HgfsRequestSearchClose *searchCloseReq; HgfsReplySearchClose *searchCloseRep; int err; char const *replyPacket; size_t packetSize; /* Create a SearchClose and send it. */ searchCloseReq = (HgfsRequestSearchClose *)gPacketBuffer; memset(searchCloseReq, 0, sizeof *searchCloseReq); searchCloseReq->header.id = 0; searchCloseReq->header.op = HGFS_OP_SEARCH_CLOSE; searchCloseReq->search = rootHandle; packetSize = sizeof *searchCloseReq; err = HgfsBd_Dispatch(gChannel, (char *)searchCloseReq, &packetSize, &replyPacket); if (err != 0) { Warning("Failed to send search close request.\n"); return FALSE; } /* replyPacket has success/failure. */ searchCloseRep = (HgfsReplySearchClose *)replyPacket; if (searchCloseRep->header.status != HGFS_STATUS_SUCCESS) { Warning("Error closing root directory.\n"); return FALSE; } return TRUE; }
static int HgfsBdChannelSend(HgfsTransportChannel *channel, // IN: Channel HgfsReq *req) // IN: request to send { char const *replyPacket = NULL; size_t payloadSize; int ret; ASSERT(req); ASSERT(req->state == HGFS_REQ_STATE_UNSENT); ASSERT(req->payloadSize <= req->bufferSize); LOG(8, ("VMware hgfs: %s: backdoor sending.\n", __func__)); payloadSize = req->payloadSize; ret = HgfsBd_Dispatch(channel->priv, HGFS_REQ_PAYLOAD(req), &payloadSize, &replyPacket); if (ret == 0) { LOG(8, ("VMware hgfs: %s: Backdoor reply received.\n", __func__)); /* Request sent successfully. Copy the reply and wake the client. */ ASSERT(replyPacket); ASSERT(payloadSize <= req->bufferSize); memcpy(HGFS_REQ_PAYLOAD(req), replyPacket, payloadSize); req->payloadSize = payloadSize; HgfsCompleteReq(req); } return ret; }
int HgfsBackdoorSendRequest(HgfsReq *req) // IN/OUT: Request to be sent { char const *replyPacket; size_t packetSize; ASSERT(req->state == HGFS_REQ_SUBMITTED); ASSERT(req->packetSize <= HGFS_PACKET_MAX); bcopy(req->packet, packetBuffer, req->packetSize); packetSize = req->packetSize; DEBUG(VM_DEBUG_COMM, "HgfsBackdoorSendRequest: Sending packet over backdoor\n"); /* * We should attempt to reopen the backdoor channel with every request, * because the HGFS server in the host can be enabled or disabled at any * time. */ if (!HgfsBd_OpenBackdoor(&hgfsRpcOut)) { DEBUG(VM_DEBUG_COMM, "HgfsBackdoorSendRequest: HGFS is disabled in the host\n"); req->state = HGFS_REQ_ERROR; return ENOSYS; } else if (HgfsBd_Dispatch(hgfsRpcOut, packetBuffer, &packetSize, &replyPacket) == 0) { DEBUG(VM_DEBUG_COMM, "HgfsBackdoorSendRequest: backdoor reply received\n"); /* Request was sent successfully. Copy the reply and return to the client. */ ASSERT(packetSize <= HGFS_PACKET_MAX); bcopy(replyPacket, req->packet, packetSize); req->packetSize = packetSize; req->state = HGFS_REQ_COMPLETED; } else { DEBUG(VM_DEBUG_COMM, "HgfsBackdoorSendRequest: backdoor error\n"); /* Pass the error into the request. */ req->state = HGFS_REQ_ERROR; /* * If the channel was previously open, make sure it's dead and gone * now. We do this because subsequent requests deserve a chance to * reopen it. */ HgfsBd_CloseBackdoor(&hgfsRpcOut); } return 0; }
static Bool HgfsClient_Open(HgfsHandle *rootHandle) // OUT: Handle to root directory { Bool success = FALSE; HgfsRequestSearchOpen *searchOpenReq; HgfsReplySearchOpen *searchOpenRep = NULL; int err; char const *replyPacket; size_t packetSize; /* Create a SearchOpen and send it. */ searchOpenReq = (HgfsRequestSearchOpen *)gPacketBuffer; memset(searchOpenReq, 0, sizeof *searchOpenReq); searchOpenReq->header.id = 0; searchOpenReq->header.op = HGFS_OP_SEARCH_OPEN; searchOpenReq->dirName.length = 0; searchOpenReq->dirName.name[0] = 0; packetSize = sizeof *searchOpenReq; err = HgfsBd_Dispatch(gChannel, (char *)searchOpenReq, &packetSize, &replyPacket); if (err != 0) { Warning("Failed to send search open request.\n"); goto out; } /* replyPacket has our search handle. */ searchOpenRep = (HgfsReplySearchOpen *)replyPacket; if (searchOpenRep->header.status != HGFS_STATUS_SUCCESS) { Warning("Error in opening root directory.\n"); goto out; } success = TRUE; out: /* We got the root handle. */ if (success) { *rootHandle = searchOpenRep->search; } return success; }
static HgfsFileName * HgfsClient_Read(HgfsHandle rootHandle, // IN: Handle to root directory int offset) // IN: Offset of dirent to read { HgfsFileName *shareName = NULL; HgfsRequestSearchRead *searchReadReq; HgfsReplySearchRead *searchReadRep; int err; char const *replyPacket; size_t packetSize; /* Create searchRead and send it. */ searchReadReq = (HgfsRequestSearchRead *)gPacketBuffer; memset(searchReadReq, 0, sizeof *searchReadReq); searchReadReq->header.id = 0; searchReadReq->header.op = HGFS_OP_SEARCH_READ; searchReadReq->search = rootHandle; searchReadReq->offset = offset; packetSize = sizeof *searchReadReq; err = HgfsBd_Dispatch(gChannel, (char *)searchReadReq, &packetSize, &replyPacket); if (err != 0) { Warning("Failed to send search read request.\n"); goto out; } /* replyPacket has our share name. */ searchReadRep = (HgfsReplySearchRead *)replyPacket; if (searchReadRep->header.status != HGFS_STATUS_SUCCESS) { Warning("Error in getting share name.\n"); goto out; } /* We got the share name. */ shareName = &searchReadRep->fileName; out: return shareName; }
static int HgfsBdChannelSend(HgfsTransportChannel *channel, // IN: Channel HgfsReq *req) // IN: request to send { char const *replyPacket = NULL; size_t payloadSize; int ret; ASSERT(req); ASSERT(req->state == HGFS_REQ_STATE_UNSENT); ASSERT(req->payloadSize <= HGFS_LARGE_PACKET_MAX); pthread_mutex_lock(&channel->connLock); if (channel->status != HGFS_CHANNEL_CONNECTED) { LOG(6, ("Backdoor not opened.\n")); pthread_mutex_unlock(&channel->connLock); return -ENOTCONN; } payloadSize = req->payloadSize; LOG(8, ("Backdoor sending.\n")); ret = HgfsBd_Dispatch(channel->priv, HGFS_REQ_PAYLOAD(req), &payloadSize, &replyPacket); if (ret == 0) { LOG(8, ("Backdoor reply received.\n")); /* Request sent successfully. Copy the reply and wake the client. */ ASSERT(replyPacket); HgfsCompleteReq(req, replyPacket, payloadSize); } else { /* Map rpc failure to EIO. */ ret = -EIO; } pthread_mutex_unlock(&channel->connLock); return ret; }