Пример #1
0
int dc_fill_disk_info(dev_hook *hook)
{
	PARTITION_INFORMATION    pti;
	PARTITION_INFORMATION_EX ptix;
	DISK_GEOMETRY_EX         dgx;
	DISK_GEOMETRY            dg;
	u64                      d_size;

	if (hook->pnp_state != Started) {
		return ST_RW_ERR;
	}
	if (hook->flags & F_CDROM)
	{
		if (io_hook_ioctl(hook, IOCTL_CDROM_GET_DRIVE_GEOMETRY, NULL, 0, &dg, sizeof(dg)) != ST_OK) {
			return ST_RW_ERR;
		}
		if (io_hook_ioctl(hook, IOCTL_CDROM_GET_DRIVE_GEOMETRY_EX, NULL, 0, &dgx, sizeof(dgx)) == ST_OK) {
			d_size = dgx.DiskSize.QuadPart;
		} else {
			d_size = d64(dg.Cylinders.QuadPart) * d64(dg.TracksPerCylinder) * 
				     d64(dg.SectorsPerTrack) * d64(dg.BytesPerSector);
		}
	} else
	{
		if (io_hook_ioctl(hook, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0, &dg, sizeof(dg)) != ST_OK) {
			return ST_RW_ERR;
		}
		if (io_hook_ioctl(hook, IOCTL_DISK_GET_PARTITION_INFO_EX, NULL, 0, &ptix, sizeof(ptix)) != ST_OK)
		{
			if (io_hook_ioctl(hook, IOCTL_DISK_GET_PARTITION_INFO, NULL, 0, &pti, sizeof(pti)) != ST_OK) {
				return ST_RW_ERR;
			}
			d_size = pti.PartitionLength.QuadPart;
		} else {
			d_size = ptix.PartitionLength.QuadPart;
		}
	}
	if ( (hook->flags & F_REMOVABLE) && (dc_verify_device(hook) == ST_NO_MEDIA) ) {
		return ST_NO_MEDIA;
	}
	hook->dsk_size   = d_size;
	hook->bps        = dg.BytesPerSector;
	hook->chg_last_v = hook->chg_count;
	hook->max_chunk  = dc_get_device_mtl(hook);
	hook->head_len   = max(sizeof(dc_header), hook->bps);

	if ( (hook->flags & (F_REMOVABLE | F_CDROM)) == 0 ) {
		if (dc_is_this_ssd(hook) != 0) hook->flags |= F_SSD;
	}	
	return ST_OK;
}
Пример #2
0
static NTSTATUS dc_trim_irp(dev_hook *hook, PIRP irp)
{
	PIO_STACK_LOCATION                 irp_sp = IoGetCurrentIrpStackLocation(irp);
	PDEVICE_MANAGE_DATA_SET_ATTRIBUTES p_set  = irp->AssociatedIrp.SystemBuffer;
	u32                                length = irp_sp->Parameters.DeviceIoControl.InputBufferLength;	
	u64                                offset, rnglen;
	PDEVICE_DATA_SET_RANGE             range;
	PDEVICE_MANAGE_DATA_SET_ATTRIBUTES n_set;
	u64                                off1, off2;
	u64                                len1, len2;
	u32                                i;

	if ( (length < sizeof(DEVICE_MANAGE_DATA_SET_ATTRIBUTES)) ||
		 (p_set->Action != DeviceDsmAction_Trim) ||
		 (length < d64(p_set->DataSetRangesOffset) + d64(p_set->DataSetRangesLength)) )
	{
		return dc_forward_irp(hook, irp);
	}
	if (dc_conf_flags & CONF_DISABLE_TRIM)
	{
		return dc_release_irp(hook, irp, STATUS_SUCCESS);
	}
	if ( (n_set = mm_pool_alloc(TRIM_BUFF_MAX(p_set))) == NULL )
	{
		return dc_release_irp(hook, irp, STATUS_INSUFFICIENT_RESOURCES);
	}
	n_set->Size = sizeof(DEVICE_MANAGE_DATA_SET_ATTRIBUTES);
	n_set->Action = DeviceDsmAction_Trim;
	n_set->Flags = 0;
	n_set->ParameterBlockOffset = 0;
	n_set->ParameterBlockLength = 0;
	n_set->DataSetRangesOffset = _align(sizeof(DEVICE_MANAGE_DATA_SET_ATTRIBUTES), sizeof(DEVICE_DATA_SET_RANGE));
	n_set->DataSetRangesLength = 0;

	if (p_set->Flags & DEVICE_DSM_FLAG_ENTIRE_DATA_SET_RANGE)
	{
		if (hook->flags & F_NO_REDIRECT) {
			TRIM_ADD_RANGE(n_set, hook->head_len, hook->dsk_size - hook->head_len);
		} else {
			TRIM_ADD_RANGE(n_set, hook->head_len, LEN_BEFORE_STORAGE(hook));
			TRIM_ADD_RANGE(n_set, OFF_END_OF_STORAGE(hook), LEN_AFTER_STORAGE(hook));
		}
	} else
	{
		for (i = 0, range = addof(p_set, p_set->DataSetRangesOffset);
			 i < p_set->DataSetRangesLength / sizeof(DEVICE_DATA_SET_RANGE); i++, range++)
		{
			if ( (offset = range->StartingOffset) + (rnglen = range->LengthInBytes) > hook->use_size ) {
				continue;
			}
			if (hook->flags & F_NO_REDIRECT) {
				TRIM_ADD_RANGE(n_set, offset + hook->head_len, min(rnglen, hook->use_size - offset));
				continue;
			}
			len1 = intersect(&off1, offset, rnglen, hook->head_len, LEN_BEFORE_STORAGE(hook));
			len2 = intersect(&off2, offset, rnglen, OFF_END_OF_STORAGE(hook), LEN_AFTER_STORAGE(hook));

			TRIM_ADD_RANGE(n_set, off1, len1);
			TRIM_ADD_RANGE(n_set, off2, len2);
		}
	}
	if (n_set->DataSetRangesLength != 0) {
		io_hook_ioctl(hook, IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES, n_set, TRIM_BUFF_LENGTH(n_set), NULL, 0);
	}
	mm_pool_free(n_set);

	return dc_release_irp(hook, irp, STATUS_SUCCESS);
}
Пример #3
0
//!
//! Update the value part.
//!
void StringPair::setV(double v)
{
    D64 d64(v);
    v_ = d64.toString();
}
Пример #4
0
//!
//! Return the value part.
//!
double StringPair::vAsD64() const
{
    D64 d64(v_);
    return d64;
}
Пример #5
0
int main(int argc, char **argv) {
  int restart = 0;
  const char *fn = NULL;
  struct stat st;
  int fd;
  char *buf = NULL;
  uint64_t nblocks = 0, nbytes = 0;
  const char *hlp;
  dump_stump_t stump = NULL, tstump = NULL;
  double t0, t1;
  int c;

  (void)ts();

  /* Arguments */
  hlp = strrchr(argv[0], '/');
  if (hlp == NULL)
    av0 = argv[0];
  else
    av0 = hlp + 1;
  opterr = 0;
  while ((c = getopt(argc, argv, "+rS:")) > 0) {
      switch (c) {
      case 'r':
	restart = 1;
	break;
      case 'S':
	tstump = dump_stump_parse(optarg);
	if (tstump == NULL) {
	  dprintf(2, "%s: Invalid stump spec in option '%c'. Must be <offset>:<string>\n", av0, optopt);
	  dprintf(2, "Usage: %s [ -r ] <destination device or file>\n", av0);
	  fsync(2);
	  exit(1);
	}
	tstump->next = stump;
	stump = tstump;
	tstump = NULL;
	break;
      default:
	dprintf(2, "%s: Invalid option '%c'.\n", av0, optopt);
	dprintf(2, "Usage: %s [ -r ] <destination device or file>\n", av0);
	fsync(2);
	exit(1);
      }
  }
  argc -= optind;
  argv += optind;

  if (argc == 1) {
    fn = argv[0];
  } else {
    dprintf(2, "Usage: %s [ -r ] <destination device or file>\n", av0);
    fsync(2);
    exit(1);
  }

  if (lstat(fn, &st) != 0) {
    dprintf(2, "Can't stat destination \"%s\"\n", fn);
    fsync(2);
    exit(1);
  }

  /* Output type check */
  if (S_ISREG(st.st_mode)) {
    dprintf(1, "Destination is a regular file.\n");
    fsync(1);
  } else if (S_ISCHR(st.st_mode)) {
    dprintf(1, "Destination is a character device.\n");
    fsync(1);
  } else if (S_ISBLK(st.st_mode)) {
    dprintf(1, "Destination is a block device.\n");
    fsync(1);
  } else {
    dprintf(2, "Destination \"%s\" is not regular file or device node\n", fn);
    fsync(2);
    exit(1);
  }

  /* Buffer */
  if (! (buf = malloc(FBUF_LEN))) {
    dprintf(2, "Out of memory\n");
    fsync(2);
    exit(1);
  }

  /* Read and check magic */
  if (r(0, buf, 8) != 8) {
    dprintf(2, "Read error (magic)\n");
    fsync(2);
    exit(1);
  } 
  if (d64(buf) != DUMP_FILE_MAGIC) {
    dprintf(2, "Bad magic\n");
    fsync(2);
    exit(1);
  }

  /* Open output */
  fd = open(fn, O_WRONLY | /*O_SYNC |*/ O_NOFOLLOW, 0);
  if (fd < 0) {
    dprintf(2, "Destination \"%s\" open for writing failed\n", fn);
    fsync(2);
    exit(1);
  }

  /* Main loop */
  while (1) {
    uint64_t off, len;
    if (r(0, buf, 16) != 16) {
      dprintf(2, "Read error (header)\n");
      fsync(2);
      exit(1);
    } 
    off = d64(buf);
    len = d64(buf + 8);
    if ((off == 0) && (len == 0)) {
      dprintf(1, "End of input reached.\n");
      fsync(1);
      break;
    }
    nblocks++;
    dprintf(1, "block=%lu, offset=%lu, length=%lu\n", (unsigned long)nblocks, (unsigned long)off, (unsigned long)len);
    fsync(1);
    if (off != (off_t)off) {
      dprintf(2, "Bad offset\n");
      fsync(2);
      exit(1);
    }
    if (lseek(fd, (off_t)off, SEEK_SET) != (off_t)off) {
      dprintf(2, "Can't seek output\n");
      fsync(2);
      exit(1);
    }
    t0 = ts();
    while (len > 0) {
      size_t cl = (len <= FBUF_LEN) ? len : FBUF_LEN;
      if (r(0, buf, cl) != cl) {
	dprintf(2, "Read error (content)\n");
	fsync(2);
	exit(1);
      }
      if (w(fd, buf, cl) != cl) {
	dprintf(2, "Write error\n");
	fsync(2);
	exit(1);
      }
      write(1, ".", 1);
      fsync(1);
      len -= cl;
      nbytes += cl;
    }
    t1 = ts();
    dprintf(1, "\nblock=%lu ok in %.6fs\n", nblocks, t1 - t0);
    fsync(1);
  }

  /* Write stumps. */
  if (stump != NULL) {
    for (tstump = stump; tstump != NULL; tstump = tstump->next) {
      t0 = ts();
      if (lseek(fd, (off_t)tstump->o, SEEK_SET) != (off_t)tstump->o) {
	dprintf(2, "Can't seek output\n");
	fsync(2);
	exit(1);
      }
      if (w(fd, tstump->s, tstump->l) != tstump->l) {
	dprintf(2, "Write error\n");
	fsync(2);
	exit(1);
      }
      t1 = ts();
      dprintf(1, "stump ok in %.6fs\n", t1 - t0);
      fsync(1);
    }
    if (stump != NULL) {
      dprintf(1, "End of stumps reached.\n");
      fsync(1);
    }
  }

  /* Sync output */
  if (fsync(fd) != 0) {
    dprintf(2, "Destination sync failed\n");
    fsync(2);
    exit(1);
  }

  /* Close output */
  if (close(fd) != 0) {
    dprintf(2, "Closing destination \"%s\" failed\n", fn);
    fsync(2);
    exit(1);
  }

  /* Final report */
  dprintf(1, "Written %lu blocks, %lu bytes total.\n", (unsigned long)nblocks, (unsigned long)nbytes);
  fsync(1);

  /* Cleanup */
  free(buf);
  buf = NULL;
  while (stump != NULL) {
    tstump = stump;
    stump = tstump->next;
    free(tstump->s);
    free(tstump);
  }

  /* Immediate reboot */
  if (restart) {
    dprintf(1, "Attempting to reboot\n");
    fsync(1);
    sleep(1);
    REBOOT_NOW();
    sleep(1);
    dprintf(2, "Reboot failed errno=%d (%s)\n", errno, strerror(errno));
    fsync(2);
    exit(1);
  }
  exit(0);
}