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 HgfsPackOpenRequest(struct inode *inode, // IN: Inode of the file to open struct file *file, // IN: File pointer for this open HgfsOp opUsed, // IN: Op to use HgfsReq *req) // IN/OUT: Packet to write into { char *name; uint32 *nameLength; size_t requestSize; int result; ASSERT(inode); ASSERT(file); ASSERT(req); switch (opUsed) { case HGFS_OP_OPEN_V3: { HgfsRequest *requestHeader; HgfsRequestOpenV3 *requestV3; requestHeader = (HgfsRequest *)HGFS_REQ_PAYLOAD(req); requestHeader->op = opUsed; requestHeader->id = req->id; requestV3 = (HgfsRequestOpenV3 *)HGFS_REQ_PAYLOAD_V3(req); requestSize = HGFS_REQ_PAYLOAD_SIZE_V3(requestV3); /* We'll use these later. */ name = requestV3->fileName.name; nameLength = &requestV3->fileName.length; requestV3->mask = HGFS_FILE_OPEN_MASK; /* Linux clients need case-sensitive lookups. */ requestV3->fileName.flags = 0; requestV3->fileName.caseType = HGFS_FILE_NAME_CASE_SENSITIVE; requestV3->fileName.fid = HGFS_INVALID_HANDLE; /* Set mode. */ result = HgfsGetOpenMode(file->f_flags); if (result < 0) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsPackOpenRequest: failed to get " "open mode\n")); return -EINVAL; } requestV3->mode = result; /* Set flags. */ result = HgfsGetOpenFlags(file->f_flags); if (result < 0) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsPackOpenRequest: failed to get " "open flags\n")); return -EINVAL; } requestV3->flags = result; /* Set permissions. */ requestV3->specialPerms = (inode->i_mode & (S_ISUID | S_ISGID | S_ISVTX)) >> 9; requestV3->ownerPerms = (inode->i_mode & S_IRWXU) >> 6; requestV3->groupPerms = (inode->i_mode & S_IRWXG) >> 3; requestV3->otherPerms = (inode->i_mode & 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)); requestV2->header.op = opUsed; requestV2->header.id = req->id; /* We'll use these later. */ name = requestV2->fileName.name; nameLength = &requestV2->fileName.length; requestSize = sizeof *requestV2; requestV2->mask = HGFS_FILE_OPEN_MASK; /* Set mode. */ result = HgfsGetOpenMode(file->f_flags); if (result < 0) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsPackOpenRequest: failed to get " "open mode\n")); return -EINVAL; } requestV2->mode = result; /* Set flags. */ result = HgfsGetOpenFlags(file->f_flags); if (result < 0) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsPackOpenRequest: failed to get " "open flags\n")); return -EINVAL; } requestV2->flags = result; /* Set permissions. */ requestV2->specialPerms = (inode->i_mode & (S_ISUID | S_ISGID | S_ISVTX)) >> 9; requestV2->ownerPerms = (inode->i_mode & S_IRWXU) >> 6; requestV2->groupPerms = (inode->i_mode & S_IRWXG) >> 3; requestV2->otherPerms = (inode->i_mode & S_IRWXO); /* XXX: Request no lock for now. */ requestV2->desiredLock = HGFS_LOCK_NONE; break; } case HGFS_OP_OPEN: { HgfsRequestOpen *request; request = (HgfsRequestOpen *)(HGFS_REQ_PAYLOAD(req)); request->header.op = opUsed; request->header.id = req->id; /* We'll use these later. */ name = request->fileName.name; nameLength = &request->fileName.length; requestSize = sizeof *request; /* Set mode. */ result = HgfsGetOpenMode(file->f_flags); if (result < 0) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsPackOpenRequest: failed to get " "open mode\n")); return -EINVAL; } request->mode = result; /* Set flags. */ result = HgfsGetOpenFlags(file->f_flags); if (result < 0) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsPackOpenRequest: failed to get " "open flags\n")); return -EINVAL; } request->flags = result; /* Set permissions. */ request->permissions = (inode->i_mode & S_IRWXU) >> 6; break; } default: LOG(4, (KERN_DEBUG "VMware hgfs: HgfsPackOpenRequest: unexpected " "OP type encountered\n")); return -EPROTO; } /* Build full name to send to server. */ if (HgfsBuildPath(name, req->bufferSize - (requestSize - 1), file->f_dentry) < 0) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsPackOpenRequest: build path " "failed\n")); return -EINVAL; } LOG(6, (KERN_DEBUG "VMware hgfs: HgfsPackOpenRequest: opening \"%s\", " "flags %o, create perms %o\n", name, file->f_flags, file->f_mode)); /* Convert to CP name. */ result = CPName_ConvertTo(name, req->bufferSize - (requestSize - 1), name); if (result < 0) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsPackOpenRequest: CP conversion " "failed\n")); return -EINVAL; } *nameLength = (uint32) result; req->payloadSize = requestSize + result; return 0; }
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; }
static int HgfsPackDirOpenRequest(struct file *file, // 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(file); ASSERT(req); switch (opUsed) { case HGFS_OP_SEARCH_OPEN_V3: { HgfsRequest *requestHeader; HgfsRequestSearchOpenV3 *requestV3; requestHeader = (HgfsRequest *)(HGFS_REQ_PAYLOAD(req)); requestHeader->op = opUsed; requestHeader->id = req->id; requestV3 = (HgfsRequestSearchOpenV3 *)HGFS_REQ_PAYLOAD_V3(req); /* We'll use these later. */ name = requestV3->dirName.name; nameLength = &requestV3->dirName.length; requestV3->dirName.flags = 0; requestV3->dirName.caseType = HGFS_FILE_NAME_CASE_SENSITIVE; requestV3->dirName.fid = HGFS_INVALID_HANDLE; requestV3->reserved = 0; requestSize = HGFS_REQ_PAYLOAD_SIZE_V3(requestV3); break; } case HGFS_OP_SEARCH_OPEN: { HgfsRequestSearchOpen *request; request = (HgfsRequestSearchOpen *)(HGFS_REQ_PAYLOAD(req)); request->header.op = opUsed; request->header.id = req->id; /* We'll use these later. */ name = request->dirName.name; nameLength = &request->dirName.length; requestSize = sizeof *request; break; } default: LOG(4, (KERN_DEBUG "VMware hgfs: HgfsPackDirOpenRequest: unexpected " "OP type encountered\n")); return -EPROTO; } /* Build full name to send to server. */ #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 19, 0) if (HgfsBuildPath(name, req->bufferSize - (requestSize - 1), file->f_dentry) < 0) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsPackDirOpenRequest: build path failed\n")); return -EINVAL; } #else if (HgfsBuildPath(name, req->bufferSize - (requestSize - 1), file->f_path.dentry) < 0) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsPackDirOpenRequest: build path failed\n")); return -EINVAL; } #endif LOG(4, (KERN_DEBUG "VMware hgfs: HgfsPackDirOpenRequest: opening \"%s\"\n", name)); /* Convert to CP name. */ result = CPName_ConvertTo(name, req->bufferSize - (requestSize - 1), name); if (result < 0) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsPackDirOpenRequest: CP conversion failed\n")); return -EINVAL; } *nameLength = (uint32) result; req->payloadSize = requestSize + result; return 0; }