Exemplo n.º 1
0
/*****************************************************************************
 * GdipGetRegionData [GDIPLUS.@]
 *
 * Returns the header, followed by combining ops and region elements.
 *
 * PARAMS
 *  region  [I] region to retrieve from
 *  buffer  [O] buffer to hold the resulting data
 *  size    [I] size of the buffer
 *  needed  [O] (optional) how much data was written
 *
 * RETURNS
 *  SUCCESS: Ok
 *  FAILURE: InvalidParameter
 *
 * NOTES
 *  The header contains the size, a checksum, a version string, and the number
 *  of children. The size does not count itself or the checksum.
 *  Version is always something like 0xdbc01001 or 0xdbc01002
 *
 *  An element is a RECT, or PATH; Combining ops are stored as their
 *  CombineMode value. Special regions (infinite, empty) emit just their
 *  op-code; GpRectFs emit their code followed by their points; GpPaths emit
 *  their code followed by a second header for the path followed by the actual
 *  path data. Followed by the flags for each point. The pathheader contains
 *  the size of the data to follow, a version number again, followed by a count
 *  of how many points, and any special flags which may apply. 0x4000 means it's
 *  a path of shorts instead of FLOAT.
 *
 *  Combining Ops are stored in reverse order from when they were constructed;
 *  the output is a tree where the left side combining area is always taken
 *  first.
 */
GpStatus WINGDIPAPI GdipGetRegionData(GpRegion *region, BYTE *buffer, UINT size,
        UINT *needed)
{
    struct region_data_header *region_data_header;
    UINT required;

    TRACE("%p, %p, %d, %p\n", region, buffer, size, needed);

    if (!region || !buffer || !size)
        return InvalidParameter;

    required = FIELD_OFFSET(struct region_data_header, header) + write_region_data(region, NULL);
    if (size < required)
    {
        if (needed) *needed = size;
        return InsufficientBuffer;
    }

    region_data_header = (struct region_data_header *)buffer;
    region_data_header->size = write_region_data(region, &region_data_header->header);
    region_data_header->checksum = 0;

    if (needed)
        *needed = required;

    return Ok;
}
Exemplo n.º 2
0
/*****************************************************************************
 * GdipGetRegionDataSize [GDIPLUS.@]
 */
GpStatus WINGDIPAPI GdipGetRegionDataSize(GpRegion *region, UINT *needed)
{
    TRACE("%p, %p\n", region, needed);

    if (!(region && needed))
        return InvalidParameter;

    /* header.size doesn't count header.size and header.checksum */
    *needed = FIELD_OFFSET(struct region_data_header, header) + write_region_data(region, NULL);

    return Ok;
}
Exemplo n.º 3
0
void myformat(int size) {
  // Do not touch or move this function
  dcreate_connect();

  /* 3600: FILL IN CODE HERE.  YOU SHOULD INITIALIZE ANY ON-DISK
           STRUCTURES TO THEIR INITIAL VALUE, AS YOU ARE FORMATTING
           A BLANK DISK.  YOUR DISK SHOULD BE size BLOCKS IN SIZE. */
  vcb *vol_ctrl_blk = (vcb *) calloc(1, sizeof(vcb));
  if (vol_ctrl_blk == NULL) {
    printf("Error: Failed to allocate the volume control block.\n");
  }
  vol_ctrl_blk->magic_num = MAGIC_NUM;
  vol_ctrl_blk->blocksize = BLOCKSIZE;
  vol_ctrl_blk->de_start = 1; // next block
  vol_ctrl_blk->de_length = NUM_DIRENTS; // allocate 100 files at start
  vol_ctrl_blk->fat_start = vol_ctrl_blk->de_start + vol_ctrl_blk->de_length; // next available block
  vol_ctrl_blk->fat_length = floor((size - (vol_ctrl_blk->de_length+1))/(NUM_FATENTS_PER_BLOCK + 1));
  vol_ctrl_blk->db_start = 1 + vol_ctrl_blk->de_length + vol_ctrl_blk->fat_length;
  vol_ctrl_blk->volume_size = size;
  vol_ctrl_blk->user = getuid();
  vol_ctrl_blk->group = getgid();
  vol_ctrl_blk->mode = 0777;
  struct timespec time;
  clock_gettime(CLOCK_REALTIME, &time);
  vol_ctrl_blk->access_time = vol_ctrl_blk->modify_time = vol_ctrl_blk->create_time = time;

  // Initialize our disk cache to store all disk changes before flushing all at end.
  init_cache(vol_ctrl_blk);

  write_data(0, vol_ctrl_blk);

  // write empty_dirent to dirent blocks
  dirent empty_dirent;
  empty_dirent.valid = 0;
  write_region_data(vol_ctrl_blk->de_start, vol_ctrl_blk->de_start + vol_ctrl_blk->de_length, &empty_dirent);

  // Create empty fatent
  fatent empty_fatent;
  empty_fatent.used = 0;
  empty_fatent.eof = 0;
  empty_fatent.next = 0;
  fatent empty_fatents[NUM_FATENTS_PER_BLOCK];
  for (unsigned int i=0; i < NUM_FATENTS_PER_BLOCK; i++) { // initialize the array to have NUM_FATENTS_PER_BLOCK in each block
    empty_fatents[i] = empty_fatent; // all empty
  }
  // write empty fatents to fatent blocks
  write_region_data(vol_ctrl_blk->fat_start, vol_ctrl_blk->fat_start + vol_ctrl_blk->fat_length, empty_fatents);
  
  // create a zero-ed out array of memory  
  char *tmp = (char *) malloc(BLOCKSIZE);
  memset(tmp, 0, BLOCKSIZE);
  // write 0's to data blocks
  write_region_data(vol_ctrl_blk->db_start, size, tmp);
  free(tmp);

  // Flush our changes from the cache to disk
  flush_cache(vol_ctrl_blk);
  free(vol_ctrl_blk);

  // Do not touch or move this function
  dunconnect();
}