static int HgfsPackCreateSessionRequest(HgfsOp opUsed, // IN: Op to be used HgfsReq *req) // IN/OUT: Packet to write into { switch (opUsed) { case HGFS_OP_CREATE_SESSION_V4: { HgfsRequestCreateSessionV4 *requestV4 = HgfsGetRequestPayload(req); requestV4->numCapabilities = 0; requestV4->maxPacketSize = HGFS_LARGE_PACKET_MAX; requestV4->reserved = 0; req->payloadSize = sizeof(*requestV4) + HgfsGetRequestHeaderSize(); break; } default: LOG(4, ("Unexpected OP type encountered. opUsed = %d\n", opUsed)); return -EPROTO; } /* Fill in header here as payloadSize needs to be there. */ HgfsPackHeader(req, opUsed); return 0; }
static int HgfsPackQueryVolumeRequest(const char *path, // IN: File pointer for this open HgfsOp opUsed, // IN: Op to be used. HgfsReq *req) // IN/OUT: Packet to write into { char *name; uint32 *nameLength; size_t requestSize; int result; ASSERT(req); switch (opUsed) { case HGFS_OP_QUERY_VOLUME_INFO_V3: { HgfsRequestQueryVolumeV3 *requestV3 = HgfsGetRequestPayload(req); /* We'll use these later. */ name = requestV3->fileName.name; nameLength = &requestV3->fileName.length; requestV3->fileName.flags = 0; requestV3->fileName.fid = HGFS_INVALID_HANDLE; requestV3->fileName.caseType = HGFS_FILE_NAME_CASE_SENSITIVE; requestV3->reserved = 0; requestSize = sizeof(*requestV3) + HgfsGetRequestHeaderSize(); break; } case HGFS_OP_QUERY_VOLUME_INFO: { HgfsRequestQueryVolume *request; request = (HgfsRequestQueryVolume *)(HGFS_REQ_PAYLOAD(req)); /* We'll use these later. */ name = request->fileName.name; nameLength = &request->fileName.length; requestSize = sizeof *request; break; } default: LOG(4, ("Unexpected OP type encountered. opUsed = %d\n", opUsed)); return -EPROTO; } /* Convert to CP name. */ result = CPName_ConvertTo(path, HGFS_LARGE_PACKET_MAX - (requestSize - 1), name); if (result < 0) { LOG(4, ("CP conversion failed.\n")); return -EINVAL; } *nameLength = (uint32) result; req->payloadSize = requestSize + result; /* Fill in header here as payloadSize needs to be there. */ HgfsPackHeader(req, opUsed); return 0; }
static int HgfsPackDestroySessionRequest(HgfsOp opUsed, // IN: Op to be used HgfsReq *req) // IN/OUT: Packet to write into { switch (opUsed) { case HGFS_OP_DESTROY_SESSION_V4: { HgfsRequestDestroySessionV4 *requestV4 = (HgfsRequestDestroySessionV4*)HgfsGetRequestPayload(req); requestV4->reserved = 0; req->payloadSize = sizeof(HgfsHeader) + sizeof(*requestV4); /* Fill in header here as payloadSize needs to be there. */ HgfsPackHeader(req, opUsed); break; } default: LOG(4, ("Unexpected OP type encountered. opUsed = %d\n", opUsed)); return -EPROTO; } return 0; }
static int HgfsPackOpenRequest(const char *path, // IN: Path to file struct fuse_file_info *fi, // IN: File info structure mode_t permsMode, // IN: Permissions, in this context HgfsOpenValid mask, // IN: Open validation mask HgfsOp opUsed, // IN: Op to use HgfsReq *req) // IN/OUT: Packet to write into { char *name; uint32 *nameLength; size_t reqSize; int result; int openMode, openFlags; ASSERT(path); ASSERT(req); openMode = HgfsGetOpenMode(fi->flags); if (openMode < 0) { LOG(4, ("Failed to get open mode.\n")); return -EINVAL; } openFlags = HgfsGetOpenFlags(fi->flags); if (openFlags < 0) { LOG(4, ("Failed to get open flags.\n")); return -EINVAL; } switch (opUsed) { case HGFS_OP_OPEN_V3: { HgfsRequestOpenV3 *requestV3 = HgfsGetRequestPayload(req); reqSize = sizeof(*requestV3) + HgfsGetRequestHeaderSize(); /* We'll use these later. */ name = requestV3->fileName.name; nameLength = &requestV3->fileName.length; /* Linux clients need case-sensitive lookups. */ requestV3->fileName.flags = 0; requestV3->fileName.caseType = HGFS_FILE_NAME_CASE_SENSITIVE; requestV3->fileName.fid = HGFS_INVALID_HANDLE; requestV3->mask = mask; requestV3->mode = openMode; requestV3->flags = openFlags; /* Set permissions. */ if (requestV3->mask & HGFS_FILE_OPEN_PERMS) { requestV3->specialPerms = (permsMode & (S_ISUID | S_ISGID | S_ISVTX)) >> 9; requestV3->ownerPerms = (permsMode & S_IRWXU) >> 6; requestV3->groupPerms = (permsMode & S_IRWXG) >> 3; requestV3->otherPerms = (permsMode & S_IRWXO); } /* XXX: Request no lock for now. */ requestV3->desiredLock = HGFS_LOCK_NONE; requestV3->reserved1 = 0; requestV3->reserved2 = 0; break; } case HGFS_OP_OPEN_V2: { HgfsRequestOpenV2 *requestV2; requestV2 = (HgfsRequestOpenV2 *)(HGFS_REQ_PAYLOAD(req)); /* We'll use these later. */ name = requestV2->fileName.name; nameLength = &requestV2->fileName.length; reqSize = sizeof *requestV2; requestV2->mask = mask; requestV2->mode = openMode; requestV2->flags = openFlags; /* Set permissions, requires discussion... default, will set max permission*/ if (requestV2->mask & HGFS_FILE_OPEN_PERMS) { requestV2->specialPerms = (permsMode & (S_ISUID | S_ISGID | S_ISVTX)) >> 9; requestV2->ownerPerms = (permsMode & S_IRWXU) >> 6; requestV2->groupPerms = (permsMode & S_IRWXG) >> 3; requestV2->otherPerms = (permsMode & S_IRWXO); } /* XXX: Request no lock for now. */ requestV2->desiredLock = HGFS_LOCK_NONE; break; }
static int HgfsPackSymlinkCreateRequest(const char* symlink, // IN: path of the link const char *symname, // IN: Target name HgfsOp opUsed, // IN: Op to be used HgfsReq *req) // IN/OUT: Packet to write into { HgfsRequestSymlinkCreateV3 *requestV3 = NULL; HgfsRequestSymlinkCreate *request = NULL; char *symlinkName; uint32 *symlinkNameLength; char *targetName; uint32 *targetNameLength; size_t targetNameBytes; size_t requestSize; int result; switch (opUsed) { case HGFS_OP_CREATE_SYMLINK_V3: { requestV3 = HgfsGetRequestPayload(req); /* We'll use these later. */ symlinkName = requestV3->symlinkName.name; symlinkNameLength = &requestV3->symlinkName.length; requestV3->symlinkName.flags = 0; requestV3->symlinkName.fid = HGFS_INVALID_HANDLE; requestV3->symlinkName.caseType = HGFS_FILE_NAME_CASE_SENSITIVE; requestV3->reserved = 0; requestSize = sizeof(*requestV3) + HgfsGetRequestHeaderSize(); break; } case HGFS_OP_CREATE_SYMLINK: { request = (HgfsRequestSymlinkCreate *)(HGFS_REQ_PAYLOAD(req)); /* We'll use these later. */ symlinkName = request->symlinkName.name; symlinkNameLength = &request->symlinkName.length; requestSize = sizeof *request; break; } default: LOG(4, ("Unexpected OP type encountered. opUsed = %d\n", opUsed)); return -EPROTO; } /* Convert symlink name to CP format. */ result = CPName_ConvertTo(symlink, HGFS_LARGE_PACKET_MAX - (requestSize - 1), symlinkName); if (result < 0) { LOG(4, ("SymlinkName CP conversion failed.\n")); return -EINVAL; } *symlinkNameLength = result; req->payloadSize = requestSize + result; /* * Note the different buffer length. This is because HgfsRequestSymlink * contains two filenames, and once we place the first into the packet we * must account for it when determining the amount of buffer available for * the second. * * Also note that targetNameBytes accounts for the NUL character. Once * we've converted it to CP name, it won't be NUL-terminated and the length * of the string in the packet itself won't account for it. */ if (opUsed == HGFS_OP_CREATE_SYMLINK_V3) { HgfsFileNameV3 *fileNameP; fileNameP = (HgfsFileNameV3 *)((char *)&requestV3->symlinkName + sizeof requestV3->symlinkName + result); targetName = fileNameP->name; targetNameLength = &fileNameP->length; fileNameP->flags = 0; fileNameP->fid = HGFS_INVALID_HANDLE; fileNameP->caseType = HGFS_FILE_NAME_CASE_SENSITIVE; } else { HgfsFileName *fileNameP; fileNameP = (HgfsFileName *)((char *)&request->symlinkName + sizeof request->symlinkName + result); targetName = fileNameP->name; targetNameLength = &fileNameP->length; } targetNameBytes = strlen(symname) + 1; /* Copy target name into request packet. */ if (targetNameBytes > HGFS_LARGE_PACKET_MAX - (requestSize - 1)) { LOG(4, ("Target name is too long.\n")); return -EINVAL; } memcpy(targetName, symname, targetNameBytes); LOG(6, ("Target name: \"%s\"\n", targetName)); /* Convert target name to CPName-lite format. */ CPNameLite_ConvertTo(targetName, targetNameBytes - 1, '/'); *targetNameLength = targetNameBytes - 1; req->payloadSize += targetNameBytes - 1; /* Fill in header here as payloadSize needs to be there. */ HgfsPackHeader(req, opUsed); return 0; }