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;
}
Exemple #2
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;
}
Exemple #3
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;
}
Exemple #4
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;
}