示例#1
0
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;
}
示例#2
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;
}
示例#3
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;
}
示例#4
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;
   }
示例#5
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;
}