Пример #1
0
  IDE::buffer_t IDE::read_sync(block_t blk)
  {
    if (blk >= _nb_blk) {
      // avoid reading past the disk boundaries
      return buffer_t();
    }

    set_irq_mode(false);
    set_drive(0xE0 | _drive | ((blk >> 24) & 0x0F));
    set_nbsectors(1);
    set_blocknum(blk);
    set_command(IDE_CMD_READ);

    auto* buffer = new uint8_t[block_size()];

    wait_status_flags(IDE_DRDY, false);
  
    uint16_t* wptr = (uint16_t*) buffer;
    uint16_t* wend = (uint16_t*)&buffer[block_size()];
    while (wptr < wend)
      *(wptr++) = inw(IDE_DATA);
  
    // return a shared_ptr wrapper for the buffer
    return buffer_t(buffer, std::default_delete<uint8_t[]>());
  }
Пример #2
0
 void FAT::readFile(const Dirent& ent, on_read_func callback)
 {
   // cluster -> sector
   uint32_t sector = this->cl_to_sector(ent.block);
   // number of sectors to read ahead
   size_t chunks = ent.size / sector_size + 1;
   // allocate buffer
   auto* buffer = new uint8_t[chunks * sector_size];
   // at which sector we will stop
   size_t total   = chunks;
   size_t current = 0;
   
   typedef std::function<void(uint32_t, size_t, size_t)> next_func_t;
   auto* next = new next_func_t;
   
   *next = 
   [this, buffer, ent, callback, next] (uint32_t sector, size_t current, size_t total)
   {
     if (unlikely(current == total))
     {
       // report back to HQ
       debug("DONE SIZE: %lu  (current=%lu, total=%lu)\n", 
           ent.size, current, total);
       // create shared buffer
       auto buffer_ptr = buffer_t(buffer, std::default_delete<uint8_t[]>());
       // notify caller
       callback(no_error, buffer_ptr, ent.size);
       // cleanup (after callback)
       delete next;
       return;
     }
     device.read(sector,
     [this, current, total, buffer, ent, &callback, sector, next] (buffer_t data)
     {
       if (!data)
       {
         // general I/O error occurred
         debug("Failed to read sector %u for read()", sector);
         // cleanup
         delete next;
         delete[] buffer;
         callback(true, buffer_t(), 0);
         return;
       }
       
       // copy over data
       memcpy(buffer + current * sector_size, data.get(), sector_size);
       // continue reading next sector
       (*next)(sector+1, current+1, total);
     });
   };
   
   // start!
   (*next)(sector, current, total);
 }
Пример #3
0
MemDisk::buffer_t MemDisk::read_sync(block_t blk)
{
  auto* loc = ((char*) image_start) + blk * block_size();
  // Disallow reading memory past disk image
  if (unlikely(loc >= image_end))
    return buffer_t();
  
  auto* buffer = new uint8_t[block_size()];
  assert( memcpy(buffer, loc, block_size()) == buffer );
  
  return buffer_t(buffer, std::default_delete<uint8_t[]>());
}
Пример #4
0
void MemDisk::read(block_t blk, on_read_func callback) {
  auto* sector_loc = ((char*) image_start) + blk * block_size();
  // Disallow reading memory past disk image
  if (unlikely(sector_loc >= image_end))
  {
    callback(buffer_t()); return;
  }
  
  auto* buffer = new uint8_t[block_size()];
  assert( memcpy(buffer, sector_loc, block_size()) == buffer );
  
  callback( buffer_t(buffer, std::default_delete<uint8_t[]>()) );
}
Пример #5
0
void MemDisk::read(block_t start, block_t count, on_read_func callback) {
  auto* start_loc = ((char*) image_start) + start * block_size();
  auto* end_loc   = start_loc + count * block_size();
  // Disallow reading memory past disk image
  if (unlikely(end_loc >= image_end))
  {
    callback(buffer_t()); return;
  }
  
  auto* buffer = new uint8_t[count * block_size()];
  assert( memcpy(buffer, start_loc, count * block_size()) == buffer );
  
  callback( buffer_t(buffer, std::default_delete<uint8_t[]>()) );
}
int test_sz(int n, TCHAR value[i]) {
  printf("=== test %i ===\n", n);
  int ret = 0;
  TCHAR empty[4096];
  memset(empty, 0xCC, sizeof(empty));
  buffer_t buffer((LPBYTE)empty, sizeof(empty));
  valueList_t v = ParseValues(buffer_t((LPBYTE)value, sizeof(TCHAR)*i), REG_SZ);
  if (memcmp(v.begin()->p, value, (i + 1) * sizeof(TCHAR))) {
    printf("list: got ?? expected %S [%i]\n", value, (i + 1) * sizeof(TCHAR));
    ++ret;
  }
  MakeMultiSzRegString(buffer, v);
  if (buffer.cbBytes != sizeof(TCHAR) * (i + 1)) {
    printf("got %i bytes, expected %i\n", buffer.cbBytes, sizeof(TCHAR) * (i + 1));
    ++ret;
  }
  if (memcmp(empty, value, (i + 1) * sizeof(TCHAR))) {
    printf("got ?? expected %S [%i]\n", value, (i + 1) * sizeof(TCHAR));
    ++ret;
  }
  if (ret) {
    for (int i = 0; i < 30; ++i) {
      printf("%02x ", ((char*)empty)[i]& 0xFF);
    }
    printf("\n");
    for (int i = 0; i < 30; ++i) {
      printf("%2c ", (((char*)empty)[i] ? ((char*)empty)[i] : ' '));
    }
    printf("\n");
  }
  return ret;
}
Пример #7
0
 scanline_read_iterator( Reader& reader
                       , int     pos = 0
                       )
 : _pos( pos )
 , _read_scanline( true )
 , _skip_scanline( true )
 , _reader( reader )
 {
     _buffer = boost::make_shared<  buffer_t >( buffer_t( _reader._scanline_length ));
     _buffer_start = &_buffer->front();
 }
Пример #8
0
void VirtioBlk::read (block_t blk, size_t cnt, on_read_func func) {

  // create big buffer for collecting all the disk data
  buffer_t bigbuf { new uint8_t[block_size() * cnt], std::default_delete<uint8_t[]>() };
  // (initialized) boolean array of partial jobs
  auto results = std::make_shared<size_t> (cnt);
  bool shipped = false;
  //printf("virtioblk: Enqueue blk %llu cnt %u\n", blk, cnt);

  //for (int i = cnt-1; i >= 0; i--)
  for (size_t i = 0; i < cnt; i++)
  {
    // create a special request where we collect all the data
    auto* vbr = new request_t(
      blk + i,
      on_read_func::make_packed(
      [this, i, func, results, bigbuf] (buffer_t buffer) {
        // if the job was already completed, return early
        if (*results == 0) {
          printf("Job cancelled? results == 0,  blk=%u\n", i);
          return;
        }
        // validate partial result
        if (buffer) {
          *results -= 1;
          // copy partial block
          memcpy(bigbuf.get() + i * block_size(), buffer.get(), block_size());
          // check if we have all blocks
          if (*results == 0) {
            // finally, call user-provided callback
            func(bigbuf);
          }
        }
        else {
          (*this->errors)++;
          // if the partial result failed, cancel all
          *results = 0;
          // callback with no data
          func(buffer_t());
        }
      })
    );
    //printf("virtioblk: Enqueue blk %llu\n", blk + i);
    //
    if (free_space()) {
      shipit(vbr);
      shipped = true;
    }
    else
      jobs.push_back(vbr);
  }
  // kick when we have enqueued stuff
  if (shipped) req.kick();
}
Пример #9
0
void VirtioBlk::handle(request_t* hdr) {
  // check request response
  blk_resp_t& resp = hdr->resp;
  // only call handler with data when the request was fullfilled
  //printf("response: status %u blk %llu  func %p  buff %p\n",
  //      resp.status, hdr->hdr.sector, resp.handler.get_ptr(), hdr->io.sector);

  if (resp.status == 0) {
    // give the whole request to user:
    // packaged as buffer, but deleted as request
    auto buf = buffer_t(hdr->io.sector, [] (uint8_t* buffer) {
      delete (request_t*) (buffer -  sizeof(scsi_header_t));
    });
    // call handler with buffer only as size is implicit
    resp.handler(buf);
  }
  else {
    // return empty shared ptr
    resp.handler(buffer_t());
  }
}
Пример #10
0
 MemDisk::buffer_t MemDisk::read_block(block_t blk)
 {
   FILE* f = fopen(image.c_str(), "r");
   if (!f)
   {
     return buffer_t();
   }
   
   fseek(f, blk * block_size(), SEEK_SET);
   
   auto* buffer = new uint8_t[block_size()];
   int res = fread(buffer, block_size(), 1, f);
   // fail when not reading block size
   if (res < 0)
   {
     printf("read_block (blk=%lu) fread failed: %s\n", blk, strerror(errno));
     return buffer_t();
   }
   // call event handler for successful block read
   return buffer_t(buffer, std::default_delete<uint8_t[]>());
 }
Пример #11
0
  void FAT::read(const Dirent& ent, uint64_t pos, uint64_t n, on_read_func callback)
  {
    // when n=0 roundup() will return an invalid value
    if (n == 0) {
      callback({ error_t::E_IO, "Zero read length" }, buffer_t(), 0);
      return;
    }
    // bounds check the read position and length
    uint32_t stapos = std::min(ent.size(), pos);
    uint32_t endpos = std::min(ent.size(), pos + n);
    // new length
    n = endpos - stapos;
    // calculate start and length in sectors
    uint32_t sector = stapos / this->sector_size;
    uint32_t nsect = roundup(endpos, sector_size) / sector_size - sector;
    uint32_t internal_ofs = stapos % device.block_size();

    // cluster -> sector + position
    device.read(this->cl_to_sector(ent.block) + sector, nsect,
    [pos, n, callback, internal_ofs] (buffer_t data) {

      if (!data) {
        // general I/O error occurred
        debug("Failed to read sector %u for read()", sector);
        callback({ error_t::E_IO, "Unable to read file" }, buffer_t(), 0);
        return;
      }

      // when the offset is non-zero we aren't on a sector boundary
      if (internal_ofs != 0) {
        // so, we need to copy offset data to data buffer
        auto* result = new uint8_t[n];
        memcpy(result, data.get() + internal_ofs, n);
        data = buffer_t(result, std::default_delete<uint8_t[]>());
      }

      callback(no_error, data, n);
    });
  }
Пример #12
0
  void IDE::read(block_t blk, on_read_func callback) {
    if (blk >= _nb_blk) {
      // avoid reading past the disk boundaries
      callback(buffer_t());
      return;
    }

    set_irq_mode(true);
    set_drive(0xE0 | _drive | ((blk >> 24) & 0x0F));
    set_nbsectors(1);
    set_blocknum(blk);
    set_command(IDE_CMD_READ);

    _current_callback = callback;
    _nb_irqs = 1;
  }
Пример #13
0
 MemDisk::buffer_t MemDisk::read_sync(block_t blk)
 {
   // check for existing entry in cache
   for (auto& entry : cache)
   if (entry.block == blk)
   {
     return entry.data;
   }
   // make room if needed
   while (cache.size() >= CACHE_SIZE)
       free_entry();
   // retrieve block from disk
   auto data = read_block(blk);
   if (!data)
   {
     printf("Failed to read block %lu\n", blk);
     return buffer_t();
   }
   // save for later
   cache.emplace_back(blk, data);
   return data;
 }
int test_multi(int n, TCHAR *data, DWORD dataLen, TCHAR** ref, int refLen) {
  printf("=== test %i ===\n", n);
  int ret = 0;
  TCHAR empty[4096];
  memset(empty, 0xCC, sizeof(empty));
  buffer_t buffer((LPBYTE)empty, sizeof(empty));
  valueList_t v = ParseValues(buffer_t((LPBYTE)data, dataLen), REG_MULTI_SZ);
  MakeMultiSzRegString(buffer, v);
  if (v.size() != refLen) {
    printf("got %i items, expected %i\n", v.size(), refLen);
    ++ret;
  }
  int i = 0;
  for (valueList_t::const_iterator it = v.begin();
       i < refLen && it != v.end();
       ++it, ++i)
  {
    if (_tcscmp(it->p, ref[i])) {
      printf("got mismatch at position %i\n", i);
      ++ret;
    }
  }
  if (memcmp(empty, data, dataLen)) {
    printf("mismatch in raw buffer\n");
    ++ret;
  }
  if (ret) {
    for (int i = 0; i < dataLen + 2; ++i) {
      printf("%02x ", ((char*)empty)[i]& 0xFF);
    }
    printf("\n");
    for (int i = 0; i < dataLen + 2; ++i) {
      printf("%2c ", (((char*)empty)[i] ? ((char*)empty)[i] : ' '));
    }
    printf("\n");
  }
  return ret;
}
Пример #15
0
 void EXT4::readFile(const std::string& strpath, on_read_func callback)
 {
   (void) strpath;
   callback(true, buffer_t(), 0);
 }
Пример #16
0
 Buffer EXT4::readFile(const std::string&)
 {
   return Buffer({ error_t::E_IO, "Not implemented" }, buffer_t(), 0);
 }
Пример #17
0
 void EXT4::readFile(const std::string& strpath, on_read_func callback)
 {
   (void) strpath;
   callback({ error_t::E_IO, "Not implemented" }, buffer_t(), 0);
 }
Пример #18
0
 IDE::buffer_t IDE::read_sync(block_t blk, size_t cnt) {
   (void) blk;
   (void) cnt;
   // not yet implemented
   return buffer_t();
 }
	auto allocate_secondary_buffer() const {
		std::unique_lock<std::mutex> l(shared_data.m);
		return buffer_t(this, pool.get().get().allocate_secondary_buffer());
	}
Пример #20
0
 void EXT4::readFile(const Dirent&, on_read_func callback)
 {
   callback(true, buffer_t(), 0);
 }