📄 visopsys_io.c
字号:
saveBuff = buff; if (fd->position % (s64) fd->disk.sectorSize) sectorCount += 1; if ((fd->position + count) % (s64) fd->disk.sectorSize) sectorCount += 1; buff = malloc(sectorCount * fd->disk.sectorSize); if (buff == NULL) { ntfs_log_trace("Memory allocation failure\n"); errno = ntfs_visopsys_errno(ERR_MEMORY); return (status = -1); } } // Read sectors status = diskReadSectors(fd->disk.name, (unsigned) startSector, (unsigned) sectorCount, buff); if (status < 0) { ntfs_log_trace("Error %d doing disk read\n", status); errno = ntfs_visopsys_errno(status); return (status = -1); } if (saveBuff) { memcpy(saveBuff, (buff + (fd->position % (s64) fd->disk.sectorSize)), count); free(buff); } br = count; fd->position += count; return (br);}static s64 ntfs_device_visopsys_write(struct ntfs_device *dev, const void *buff, s64 count){ // Write bytes to an ntfs device // dev: ntfs device obtained via ->open // buff: pointer to the data to write // count: how many bytes should be written // On success returns the number of bytes actually written. // On error returns -1 with errno set. int status = 0; visopsys_fd *fd = NULL; s64 startSector = 0; s64 sectorCount = 0; void *saveBuff = NULL; s64 br = 0; //Vdebug("WRITE\n"); // Check params if ((dev == NULL) || (buff == NULL) || (count <= 0)) { ntfs_log_trace("NULL parameter\n"); errno = ntfs_visopsys_errno(ERR_NULLPARAMETER); return (status = -1); } if (NDevReadOnly(dev)) { ntfs_log_trace("Device is read-only\n"); errno = EROFS; return (status = -1); } fd = (visopsys_fd *) dev->d_private; startSector = (fd->position / (s64) fd->disk.sectorSize); sectorCount = (count / (s64) fd->disk.sectorSize); if ((fd->position % (s64) fd->disk.sectorSize) || (count % (s64) fd->disk.sectorSize)) { Vdebug("Doing off-kilter write"); saveBuff = (void *) buff; if (fd->position % (s64) fd->disk.sectorSize) sectorCount += 1; if ((fd->position + count) % (s64) fd->disk.sectorSize) sectorCount += 1; buff = malloc(sectorCount * fd->disk.sectorSize); if (buff == NULL) { ntfs_log_trace("Memory allocation failure\n"); errno = ntfs_visopsys_errno(ERR_MEMORY); return (status = -1); } if (fd->position % (s64) fd->disk.sectorSize) { // The current position is not a multiple of the sector size. // Read the first sector into the buffer status = diskReadSectors(fd->disk.name, (unsigned) startSector, 1, (void *) buff); if (status < 0) { ntfs_log_trace("Error %d doing disk read\n", status); free((void *) buff); errno = ntfs_visopsys_errno(status); return (status = -1); } } if ((fd->position + count) % (s64) fd->disk.sectorSize) { // The count is not a multiple of the sector size. Read the last // sector into the buffer s64 lastSector = (startSector + (sectorCount - 1)); status = diskReadSectors(fd->disk.name, (unsigned) lastSector, 1, (void *) (buff + ((lastSector - startSector) * fd->disk.sectorSize))); if (status < 0) { ntfs_log_trace("Error %d doing disk read\n", status); free((void *) buff); errno = ntfs_visopsys_errno(status); return (status = -1); } } // Copy the caller-supplied data into the appropriate place in the buffer memcpy((void *) (buff + (fd->position % (s64) fd->disk.sectorSize)), saveBuff, count); } NDevSetDirty(dev); // Write sectors status = diskWriteSectors(fd->disk.name, (unsigned) startSector, (unsigned) sectorCount, buff); if (saveBuff) free((void *) buff); if (status < 0) { ntfs_log_trace("Error %d doing disk write\n", status); errno = ntfs_visopsys_errno(status); return (status = -1); } br = count; fd->position += count; return (br);}static s64 ntfs_device_visopsys_pread(struct ntfs_device *dev, void *b, s64 count, s64 offset){ //Vdebug("PREAD\n"); return (ntfs_pread(dev, offset, count, b));}static s64 ntfs_device_visopsys_pwrite(struct ntfs_device *dev, const void *b, s64 count, s64 offset){ //Vdebug("PWRITE\n"); NDevSetDirty(dev); return (ntfs_pwrite(dev, offset, count, b));}static int ntfs_device_visopsys_sync(struct ntfs_device *dev){ // Flush write buffers to disk // dev: ntfs device obtained via ->open // Return 0 if o.k. // -1 if not, and errno set. int status = 0; visopsys_fd *fd = NULL; Vdebug("SYNC\n"); // Check params if (dev == NULL) { ntfs_log_trace("NULL device parameter\n"); errno = ntfs_visopsys_errno(ERR_NULLPARAMETER); return (status = -1); } fd = (visopsys_fd *) dev->d_private; if (!NDevReadOnly(dev) && NDevDirty(dev)) { status = diskSync(fd->disk.name); if (status < 0) { ntfs_log_trace("Error syncing disk\n"); errno = ntfs_visopsys_errno(errno); return (status = -1); } NDevClearDirty(dev); } return (status = 0);}static int ntfs_device_visopsys_stat(struct ntfs_device *dev, struct stat *buff){ // Get a unix-like stat structure for an ntfs device // dev: ntfs device obtained via ->open // buf: pointer to the stat structure to fill // Note: Only st_mode, st_size, and st_blocks are filled. // Return 0 if o.k. // -1 if not and errno set. in this case handle is trashed. int status = 0; visopsys_fd *fd = NULL; Vdebug("STAT\n"); // Check params if ((dev == NULL) || (buff == NULL)) { errno = ntfs_visopsys_errno(ERR_NULLPARAMETER); return (status = -1); } fd = (visopsys_fd *) dev->d_private; ntfs_log_trace("stat() operation not implemented\n"); errno = ntfs_visopsys_errno(ERR_NOTIMPLEMENTED); return (status = -1);}static int ntfs_device_visopsys_ioctl(struct ntfs_device *dev, int request, void *argp){ int status = 0; visopsys_fd *fd = NULL; Vdebug("IOCTL %x\n", request); // Check params if ((dev == NULL) || (argp == NULL)) { ntfs_log_trace("NULL parameter\n"); errno = ntfs_visopsys_errno(ERR_NULLPARAMETER); return (status = -1); } fd = (visopsys_fd *) dev->d_private; switch (request) { case BLKGETSIZE: // Get the size of the device in sectors *((int *) argp) = fd->disk.numSectors; break; case BLKGETSIZE64: // Get the size of the device in bytes *((s64 *) argp) = fd->partLength; break; case HDIO_GETGEO: ((struct hd_geometry *) argp)->heads = fd->disk.heads; ((struct hd_geometry *) argp)->sectors = fd->disk.sectorsPerCylinder; ((struct hd_geometry *) argp)->cylinders = fd->disk.cylinders; ((struct hd_geometry *) argp)->start = 0; break; case BLKSSZGET: *((int *) argp) = fd->disk.sectorSize; break; case BLKBSZSET: // Set the device sector size. Not applicable. break; default: ntfs_log_trace("IOCTL %x not implemented\n", request); errno = ntfs_visopsys_errno(ERR_NOTIMPLEMENTED); return (status = -1); } return 0;}struct ntfs_device_operations ntfs_device_visopsys_io_ops = { .open = ntfs_device_visopsys_open, .close = ntfs_device_visopsys_close, .seek = ntfs_device_visopsys_seek, .read = ntfs_device_visopsys_read, .write = ntfs_device_visopsys_write, .pread = ntfs_device_visopsys_pread, .pwrite = ntfs_device_visopsys_pwrite, .sync = ntfs_device_visopsys_sync, .stat = ntfs_device_visopsys_stat, .ioctl = ntfs_device_visopsys_ioctl};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -