uint64_t read_uint64(const uint8_t ** buffer) {
    return (((uint64_t) read_uint32(buffer)) << 32) |
            ((uint64_t) read_uint32(buffer));
}
Beispiel #2
0
/* Open dmg image */
int dmg_open(int fd, bdev_desc_t *bdev)
{
    u32 count;
    u32 max_compressed_size=1,max_sectors_per_chunk=1,i;
    bdev->priv = malloc(sizeof(BDRVDMGState));
    if(bdev->priv == NULL)
        goto fail;
    BDRVDMGState *s = DMG_PRIV(bdev);
    CLEAR(*s);

    off_t info_begin,info_end,last_in_offset,last_out_offset;

    /* Init the bdev struct */
    bdev->fd = fd;
    bdev->read = &wrap_read;
    bdev->real_read = &dmg_read;
    bdev->write = NULL;
    bdev->seek = &dmg_seek;
    bdev->close = &dmg_close;

    s->fd = fd;
    /* RO */
    bdev->flags &= ~BF_ENABLE_WRITE;
    s->n_chunks = 0;
    s->offsets = s->lengths = s->sectors = s->sectorcounts = 0;

    /* read offset of info blocks */
    if(lseek(s->fd,-0x1d8,SEEK_END)<0)
	goto fail;
    info_begin=read_off(s->fd);
    if(info_begin==0)
	goto fail;
    if(lseek(s->fd,info_begin,SEEK_SET)<0)
	goto fail;
    if(read_uint32(s->fd)!=0x100)
	goto fail;
    if((count = read_uint32(s->fd))==0)
	goto fail;
    info_end = info_begin+count;
    if(lseek(s->fd,0xf8,SEEK_CUR)<0)
	goto fail;

    /* read offsets */
    last_in_offset = last_out_offset = 0;
    while(lseek(s->fd,0,SEEK_CUR)<info_end) {
        u32 type;

	count = read_uint32(s->fd);
	if(count==0)
		goto fail;
	type = read_uint32(s->fd);
	if(type!=0x6d697368 || count<244)
	    lseek(s->fd,count-4,SEEK_CUR);
	else {
	    int new_size, chunk_count;
	    if(lseek(s->fd,200,SEEK_CUR)<0)
		goto fail;
	    chunk_count = (count-204)/40;
	    new_size = sizeof(u64) * (s->n_chunks + chunk_count);
	    s->types = realloc(s->types, new_size/2);
	    s->offsets = realloc(s->offsets, new_size);
	    s->lengths = realloc(s->lengths, new_size);
	    s->sectors = realloc(s->sectors, new_size);
	    s->sectorcounts = realloc(s->sectorcounts, new_size);

	    for(i=s->n_chunks;i<s->n_chunks+chunk_count;i++) {
		s->types[i] = read_uint32(s->fd);
		if(s->types[i]!=0x80000005 && s->types[i]!=1 && s->types[i]!=2) {
		    if(s->types[i]==0xffffffff) {
			last_in_offset = s->offsets[i-1]+s->lengths[i-1];
			last_out_offset = s->sectors[i-1]+s->sectorcounts[i-1];
		    }
		    chunk_count--;
		    i--;
		    if(lseek(s->fd,36,SEEK_CUR)<0)
			goto fail;
		    continue;
		}
		read_uint32(s->fd);
		s->sectors[i] = last_out_offset+read_off(s->fd);
		s->sectorcounts[i] = read_off(s->fd);
		s->offsets[i] = last_in_offset+read_off(s->fd);
		s->lengths[i] = read_off(s->fd);
		if(s->lengths[i]>max_compressed_size)
		    max_compressed_size = s->lengths[i];
		if(s->sectorcounts[i]>max_sectors_per_chunk)
		    max_sectors_per_chunk = s->sectorcounts[i];
	    }
	    s->n_chunks+=chunk_count;
	}
    }
    bdev->size = s->n_chunks * 512;

    /* initialize zlib engine */
    if(!(s->compressed_chunk=(char*)malloc(max_compressed_size+1)))
	goto fail;
    if(!(s->uncompressed_chunk=(char*)malloc(512*max_sectors_per_chunk)))
	goto fail;
    if(inflateInit(&s->zstream) != Z_OK)
	goto fail;

    s->current_chunk = s->n_chunks;
    
    return 0;

fail:
    return -1;
    
}
Beispiel #3
0
/* Reads a property of type 'prop_type' from 'data', and puts the
 * result 'out'. Returns 0 upon success, a negative value otherwise */
static int read_ply_property(struct file_data *data, const int prop_type, 
                             const int swap_bytes, void *out) 
{
  int c, rcode=0;
  /* Just local pointers to copy the result from the 'read_[type]'
   * functions into... */
  t_int8 *tmp_int8;
  t_uint8 *tmp_uint8;
  t_int16 *tmp_int16;
  t_uint16 *tmp_uint16;
  t_int32 *tmp_int32;
  t_uint32 *tmp_uint32;
  float *tmp_float32;
  double *tmp_float64;

  switch(prop_type) {
  case uint8:
    c = getc(data);
    if (c == EOF) 
      rcode = EOF;
    else {
      tmp_uint8 = out;
      *tmp_uint8 = (t_uint8)c;
    }
    break;
  case int8:
    c = getc(data);
    if (c == EOF) 
      rcode = EOF;
    else {
      tmp_int8= out;
      *tmp_int8 = (t_int8)c;
    }
    break;
  case uint16:
    tmp_uint16 = out;
    rcode = read_uint16(data, swap_bytes, tmp_uint16);
    break;
  case int16:
    tmp_int16 = out;
    rcode = read_int16(data, swap_bytes, tmp_int16);
    break;
  case uint32:
    tmp_uint32 = out;
    rcode = read_uint32(data, swap_bytes, tmp_uint32);
    break;
  case int32:
    tmp_int32 = out;
    rcode = read_int32(data, swap_bytes, tmp_int32);
    break;
  case float32:
    tmp_float32 = out;
    rcode = read_float32(data, swap_bytes, tmp_float32);
    break;
  case float64:
    tmp_float64 = out;
    rcode = read_float64(data, swap_bytes, tmp_float64);
    break;
  default:
    rcode = MESH_CORRUPTED;
    break;
  }

  return rcode;
}
Beispiel #4
0
static bmp_result bmp_analyse_header(bmp_image *bmp, uint8_t *data) {
	uint32_t header_size;
	uint32_t i;
	uint8_t j;
	int32_t width, height;
	uint8_t palette_size;
	unsigned int flags = 0;

	/* a variety of different bitmap headers can follow, depending
	 * on the BMP variant. A full description of the various headers
	 * can be found at
	 * http://msdn.microsoft.com/en-us/library/ms532301(VS.85).aspx
	 */
	header_size = read_uint32(data, 0);
	if (bmp->buffer_size < (14 + header_size))
		return BMP_INSUFFICIENT_DATA;
	if (header_size == 12) {
		/* the following header is for os/2 and windows 2.x and consists of:
		 *
		 *	+0	UINT32	size of this header (in bytes)
		 *	+4	INT16	image width (in pixels)
		 *	+6	INT16	image height (in pixels)
		 *	+8	UINT16	number of colour planes (always 1)
		 *	+10	UINT16	number of bits per pixel
		 */
		width = read_int16(data, 4);
		height = read_int16(data, 6);
		if ((width <= 0) || (height == 0))
			return BMP_DATA_ERROR;
		if (height < 0) {
			bmp->reversed = true;
			height = -height;
		}
		/* ICOs only support 256*256 resolutions
		 * In the case of the ICO header, the height is actually the added
		 * height of XOR-Bitmap and AND-Bitmap (double the visible height)
		 * Technically we could remove this check and ICOs with bitmaps
		 * of any size could be processed; this is to conform to the spec.
		 */
		if (bmp->ico) {
			if ((width > 256) || (height > 512)) {
				return BMP_DATA_ERROR;
			} else {
				bmp->width = width;
				bmp->height = height / 2;
			}
		} else {
			bmp->width = width;
			bmp->height = height;
		}
		if (read_uint16(data, 8) != 1)
			return BMP_DATA_ERROR;
		bmp->bpp = read_uint16(data, 10);
		/**
		 * The bpp value should be in the range 1-32, but the only
		 * values considered legal are:
		 * RGB ENCODING: 1, 4, 8, 16, 24 and 32
		 */
		if ((bmp->bpp != 1) && (bmp->bpp != 4) &&
				(bmp->bpp != 8) &&
				(bmp->bpp != 16) &&
				(bmp->bpp != 24) &&
				(bmp->bpp != 32))
			return BMP_DATA_ERROR;
		bmp->colours = (1 << bmp->bpp);
		palette_size = 3;
	} else if (header_size < 40) {
		return BMP_DATA_ERROR;
	} else {
		/* the following header is for windows 3.x and onwards. it is a
		 * minimum of 40 bytes and (as of Windows 95) a maximum of 108 bytes.
		 *
		 *	+0	UINT32	size of this header (in bytes)
		 *	+4	INT32	image width (in pixels)
		 *	+8	INT32	image height (in pixels)
 		 *	+12	UINT16	number of colour planes (always 1)
		 *	+14	UINT16	number of bits per pixel
		 *	+16	UINT32	compression methods used
		 *	+20	UINT32	size of bitmap (in bytes)
		 *	+24	UINT32	horizontal resolution (in pixels per meter)
		 *	+28	UINT32	vertical resolution (in pixels per meter)
		 *	+32	UINT32	number of colours in the image
		 *	+36	UINT32	number of important colours
		 *	+40	UINT32	mask identifying bits of red component
		 *	+44	UINT32	mask identifying bits of green component
		 *	+48	UINT32	mask identifying bits of blue component
		 *	+52	UINT32	mask identifying bits of alpha component
		 *	+56	UINT32	color space type
		 *	+60	UINT32	x coordinate of red endpoint
		 *	+64	UINT32	y coordinate of red endpoint
		 *	+68	UINT32	z coordinate of red endpoint
		 *	+72	UINT32	x coordinate of green endpoint
		 *	+76	UINT32	y coordinate of green endpoint
		 *	+80	UINT32	z coordinate of green endpoint
		 *	+84	UINT32	x coordinate of blue endpoint
		 *	+88	UINT32	y coordinate of blue endpoint
		 *	+92	UINT32	z coordinate of blue endpoint
		 *	+96	UINT32	gamma red coordinate scale value
		 *	+100	UINT32	gamma green coordinate scale value
		 *	+104	UINT32	gamma blue coordinate scale value
		 */
		width = read_int32(data, 4);
		height = read_int32(data, 8);
		if ((width <= 0) || (height == 0))
			return BMP_DATA_ERROR;
		if (height < 0) {
			bmp->reversed = true;
			height = -height;
		}
		/* ICOs only support 256*256 resolutions
		 * In the case of the ICO header, the height is actually the added
		 * height of XOR-Bitmap and AND-Bitmap (double the visible height)
		 * Technically we could remove this check and ICOs with bitmaps
		 * of any size could be processed; this is to conform to the spec.
		 */
		if (bmp->ico) {
			if ((width > 256) || (height > 512)) {
				return BMP_DATA_ERROR;
			} else {
				bmp->width = width;
				bmp->height = height / 2;
			}
		} else {
			bmp->width = width;
			bmp->height = height;
		}
		if (read_uint16(data, 12) != 1)
			return BMP_DATA_ERROR;
		bmp->bpp = read_uint16(data, 14);
		if (bmp->bpp == 0)
			bmp->bpp = 8;
		bmp->encoding = read_uint32(data, 16);
		/**
		 * The bpp value should be in the range 1-32, but the only
		 * values considered legal are:
		 * RGB ENCODING: 1, 4, 8, 16, 24 and 32
		 * RLE4 ENCODING: 4
		 * RLE8 ENCODING: 8
		 * BITFIELD ENCODING: 16 and 32
		 */
		switch (bmp->encoding) {
			case BMP_ENCODING_RGB:
				if ((bmp->bpp != 1) && (bmp->bpp != 4) &&
						(bmp->bpp != 8) &&
						(bmp->bpp != 16) &&
						(bmp->bpp != 24) &&
						(bmp->bpp != 32))
					return BMP_DATA_ERROR;
				break;
			case BMP_ENCODING_RLE8:
				if (bmp->bpp != 8)
					return BMP_DATA_ERROR;
				break;
			case BMP_ENCODING_RLE4:
				if (bmp->bpp != 4)
					return BMP_DATA_ERROR;
				break;
			case BMP_ENCODING_BITFIELDS:
				if ((bmp->bpp != 16) && (bmp->bpp != 32))
					return BMP_DATA_ERROR;
				break;
			/* invalid encoding */
			default:
				return BMP_DATA_ERROR;
				break;
		}
		/* Bitfield encoding means we have red, green, blue, and alpha masks.
		 * Here we aquire the masks and determine the required bit shift to
		 * align them in our 24-bit color 8-bit alpha format.
		 */
		if (bmp->encoding == BMP_ENCODING_BITFIELDS) {
			if (header_size == 40) {
				header_size += 12;
				if (bmp->buffer_size < (14 + header_size))
					return BMP_INSUFFICIENT_DATA;
				for (i = 0; i < 3; i++)
					bmp->mask[i] = read_uint32(data, 40 + (i << 2));
			} else {
				for (i = 0; i < 4; i++)
					bmp->mask[i] = read_uint32(data, 40 + (i << 2));
			}
			for (i = 0; i < 4; i++) {
				if (bmp->mask[i] == 0)
					break;
				for (j = 31; j > 0; j--)
					if (bmp->mask[i] & (1 << j)) {
					  	if ((j - 7) > 0)
					  		bmp->mask[i] &= 0xff << (j - 7);
					  	else
					  		bmp->mask[i] &= 0xff >> (-(j - 7));
					  	bmp->shift[i] = (i << 3) - (j - 7);
						break;
					}
			}
		}
		bmp->colours = read_uint32(data, 32);
		if (bmp->colours == 0)
			bmp->colours = (1 << bmp->bpp);
		palette_size = 4;
	}
	data += header_size;

	/* if there's no alpha mask, flag the bmp opaque */
	if ((!bmp->ico) && (bmp->mask[3] == 0)) {
		flags |= BMP_OPAQUE;
		bmp->opaque = true;
	}

	/* we only have a palette for <16bpp */
	if (bmp->bpp < 16) {
		/* we now have a series of palette entries of the format:
		 *
		 *	+0	BYTE	blue
		 *	+1	BYTE	green
		 *	+2	BYTE	red
		 *
		 * if the palette is from an OS/2 or Win2.x file then the entries
		 * are padded with an extra byte.
		 */

		/* boundary checking */
		if (bmp->buffer_size < (14 + header_size + ((uint64_t)4 * bmp->colours)))
			return BMP_INSUFFICIENT_DATA;

		/* create the colour table */
		bmp->colour_table = (uint32_t *)malloc(bmp->colours * 4);
		if (!bmp->colour_table)
			return BMP_INSUFFICIENT_MEMORY;
		for (i = 0; i < bmp->colours; i++) {
			bmp->colour_table[i] = data[2] | (data[1] << 8) | (data[0] << 16);
			if (bmp->opaque)
				bmp->colour_table[i] |= (0xff << 24);
			data += palette_size;
			bmp->colour_table[i] = read_uint32((uint8_t *)&bmp->colour_table[i],0);
		}
	}

	/* create our bitmap */
	flags |= BMP_NEW | BMP_CLEAR_MEMORY;
	bmp->bitmap = bmp->bitmap_callbacks.bitmap_create(bmp->width, bmp->height, flags);
	if (!bmp->bitmap) {
		if (bmp->colour_table)
			free(bmp->colour_table);
		bmp->colour_table = NULL;
		return BMP_INSUFFICIENT_MEMORY;
	}
	/* BMPs within ICOs don't have BMP file headers, so the image data should
	 * always be right after the colour table.
	 */
	if (bmp->ico)
		bmp->bitmap_offset = (intptr_t)data - (intptr_t)bmp->bmp_data;
	return BMP_OK;
}
Beispiel #5
0
/* state->src and state->src_size contain the freshly read bytes
   we must accumulate any partial state between calls.
*/
int slip_decode(struct slip_decode_state *state)
{
  switch(state->encapsulator) {
  case SLIP_FORMAT_SLIP:
    {
      /*
       Examine received bytes for end of packet marker.
       The challenge is that we need to make sure that the packet encapsulation
       is self-synchronising in the event that a data error occurs (including
       failure to receive an arbitrary number of bytes).
       */
      while(state->src_offset < state->src_size){
	// clear the valid bit flag if we hit the end of the destination buffer
	if (state->dst_offset >= sizeof state->dst)
	  state->state&=~DC_VALID;
	
	if (state->state&DC_ESC){
	  // clear escape bit
	  state->state&=~DC_ESC;
	  switch(state->src[state->src_offset]) {
	    case SLIP_ESC_END: // escaped END byte
	      state->dst[state->dst_offset++]=SLIP_END;
	      break;
	    case SLIP_ESC_ESC: // escaped escape character
	      state->dst[state->dst_offset++]=SLIP_ESC;
	      break;
	    case SLIP_ESC_0a:
	      state->dst[state->dst_offset++]=SLIP_0a;
	      break;
	    case SLIP_ESC_0d:
	      state->dst[state->dst_offset++]=SLIP_0d;
	      break;
	    case SLIP_ESC_0f:
	      state->dst[state->dst_offset++]=SLIP_0f;
	      break;
	    case SLIP_ESC_1b:
	      state->dst[state->dst_offset++]=SLIP_1b;
	      break;
	    default: /* Unknown escape character. This is an error. */
	      if (config.debug.packetradio)
		WARNF("Packet radio stream contained illegal escaped byte 0x%02x -- resetting parser.",state->src[state->src_offset]);
	      state->dst_offset=0;
	      // skip everything until the next SLIP_END
	      state->state=0;
	  }
	}else{
	  // non-escape character
	  switch(state->src[state->src_offset]) {
	    case SLIP_ESC:
	      // set escape bit
	      state->state|=DC_ESC; 
	      break;
	    case SLIP_END:
	      if (state->dst_offset>4){
		
		uint32_t src_crc = read_uint32(state->dst + state->dst_offset -4);
		uint32_t crc=Crc32_ComputeBuf( 0, state->dst, state->dst_offset -4);
		
		if (src_crc != crc){
		  DEBUGF("Dropping frame due to CRC failure (%08x vs %08x)", src_crc, crc);
		  dump("frame", state->dst, state->dst_offset);
		  state->dst_offset=0;
		  state->state=0;
		  break;
		}
		// return once we've successfully parsed a valid packet that isn't empty
		state->packet_length=state->dst_offset -4;
		return 1;
	      }
	      // set the valid flag to begin parsing the next packet
	      state->state=DC_VALID;
	      break;
	    default:
	      if (state->state&DC_VALID)
		state->dst[state->dst_offset++]=state->src[state->src_offset];
	  }
	}
	state->src_offset++;
      }
      return 0;
    }
  case SLIP_FORMAT_UPPER7:
    {
      if (config.debug.slip) {
	if (state->rssi_len>=RSSI_TEXT_SIZE) state->rssi_len=RSSI_TEXT_SIZE-1;
	state->rssi_text[state->rssi_len]=0;
	DEBUGF("RX state=%d, rssi_len=%u, rssi_text='%s',src=%p, src_size=%u",
	       state->state,state->rssi_len,state->rssi_text,
	       state->src,state->src_size);
      }
     while(state->src_offset<state->src_size) {
	if (upper7_decode(state,state->src[state->src_offset++])==1) {
	  if (config.debug.slip) {
	    dump("de-slipped packet",state->dst,state->packet_length);
          }
	 
	  // Check that CRC matches
	  uint32_t crc=Crc32_ComputeBuf( 0, state->dst, state->packet_length);
	  if (crc!=state->crc) {
	    if (config.debug.packetradio||config.debug.rejecteddata)
	      DEBUGF("Rejected packet of %u bytes due to CRC mis-match (%08x vs %08x)",
		     state->packet_length,crc,state->crc);
	    if (config.debug.rejecteddata) {
	      dump("bad packet",state->dst,state->packet_length);
	    }
	  } else {
	    if (config.debug.packetradio) 
	      DEBUGF("Accepted packet of %u bytes (CRC ok)",state->packet_length);
	    return 1;
	  }
	}
      }
    }
    return 0;
  default:
    return WHYF("Unknown SLIP encapsulation format #%d",state->encapsulator);
  }
}
Beispiel #6
0
Datei: dmg.c Projekt: heiher/qemu
static int dmg_read_resource_fork(BlockDriverState *bs, DmgHeaderState *ds,
                                  uint64_t info_begin, uint64_t info_length)
{
    BDRVDMGState *s = bs->opaque;
    int ret;
    uint32_t count, rsrc_data_offset;
    uint8_t *buffer = NULL;
    uint64_t info_end;
    uint64_t offset;

    /* read offset from begin of resource fork (info_begin) to resource data */
    ret = read_uint32(bs, info_begin, &rsrc_data_offset);
    if (ret < 0) {
        goto fail;
    } else if (rsrc_data_offset > info_length) {
        ret = -EINVAL;
        goto fail;
    }

    /* read length of resource data */
    ret = read_uint32(bs, info_begin + 8, &count);
    if (ret < 0) {
        goto fail;
    } else if (count == 0 || rsrc_data_offset + count > info_length) {
        ret = -EINVAL;
        goto fail;
    }

    /* begin of resource data (consisting of one or more resources) */
    offset = info_begin + rsrc_data_offset;

    /* end of resource data (there is possibly a following resource map
     * which will be ignored). */
    info_end = offset + count;

    /* read offsets (mish blocks) from one or more resources in resource data */
    while (offset < info_end) {
        /* size of following resource */
        ret = read_uint32(bs, offset, &count);
        if (ret < 0) {
            goto fail;
        } else if (count == 0 || count > info_end - offset) {
            ret = -EINVAL;
            goto fail;
        }
        offset += 4;

        buffer = g_realloc(buffer, count);
        ret = bdrv_pread(bs->file, offset, buffer, count);
        if (ret < 0) {
            goto fail;
        }

        ret = dmg_read_mish_block(s, ds, buffer, count);
        if (ret < 0) {
            goto fail;
        }
        /* advance offset by size of resource */
        offset += count;
    }
    ret = 0;

fail:
    g_free(buffer);
    return ret;
}
Beispiel #7
0
uint64_t
read_uint64(unsigned char *p) {
  uint32_t v1 = read_uint32(p);
  uint32_t v2 = read_uint32(p+4);
  return (uint64_t)(v1 + ((uint64_t)v2<<32));
}
Beispiel #8
0
void *read_pipe_(void* a)
{
	*((int*)a) = read_uint32("outpipe");
}
Beispiel #9
0
void pok_loader_load_partition (const uint32_t part_id, uint32_t *entry)
{
	(void) part_id;
	uint32_t part_entry;
    uint32_t segments;
    if(read_uint32(&part_entry) != sizeof(uint32_t))
    {
#ifdef POK_NEEDS_ERROR_HANDLING
		pok_partition_error (part_id, POK_ERROR_KIND_PARTITION_CONFIGURATION);
#else
#ifdef POK_NEEDS_DEBUG
#include <core/debug.h>
#include <stdio.h>
		pok_fatal ("No partition entry\n");
#endif
#endif
    }

    if(read_uint32(&segments) != sizeof(uint32_t))
    {
#ifdef POK_NEEDS_ERROR_HANDLING
		pok_partition_error (part_id, POK_ERROR_KIND_PARTITION_CONFIGURATION);
#else
#ifdef POK_NEEDS_DEBUG
#include <core/debug.h>
#include <stdio.h>
		pok_fatal ("No partition size\n");
#endif
#endif
    }

#ifdef POK_NEEDS_DEBUG
    printf("[DEBUG]\t [Reading partition %d] Entry address: %p\n", part_id, (void*)(part_entry));
    printf("[DEBUG]\t [Reading partition %d] Segments number: %d\n", part_id, segments);
#endif

    unsigned int segment = 0;
    unsigned int part_size = 0;
    while (segment < segments) 
    {
	    uint32_t segment_address;
	    uint32_t segment_size;

     	if (read_uint32(&segment_address) != sizeof(uint32_t))
     	{
#ifdef POK_NEEDS_ERROR_HANDLING
			pok_partition_error (part_id, POK_ERROR_KIND_PARTITION_CONFIGURATION);
#else
#ifdef POK_NEEDS_DEBUG
#include <core/debug.h>
#include <stdio.h>
			pok_fatal ("No segment address\n");
#endif
#endif
      	}

#ifdef POK_NEEDS_DEBUG
      	printf("[DEBUG]\t [Reading partition %d] Segment %d address: %p\n", part_id, segment, (void*)segment_address);
#endif

      	if (read_uint32(&segment_size) != sizeof(uint32_t))
      	{
#ifdef POK_NEEDS_ERROR_HANDLING
			pok_partition_error (part_id, POK_ERROR_KIND_PARTITION_CONFIGURATION);
#else
#ifdef POK_NEEDS_DEBUG
#include <core/debug.h>
#include <stdio.h>
			pok_fatal ("No segment size\n");
#endif
#endif
      	}
#ifdef POK_NEEDS_DEBUG
      	printf("[DEBUG]\t [Reading partition %d] Segment %d size: %d\n", part_id, segment, segment_size);
#endif

      	if (read_data(segment_size, (char*)(segment_address)) != segment_size) {
#ifdef POK_NEEDS_ERROR_HANDLING
			pok_partition_error (part_id, POK_ERROR_KIND_PARTITION_CONFIGURATION);
#else
#ifdef POK_NEEDS_DEBUG
#include <core/debug.h>
#include <stdio.h>
			printf("No segment data\n");
#endif
#endif
      	}
        part_size = part_size + segment_size;

#ifdef POK_NEEDS_DEBUG
      	printf("[DEBUG]\t [Reading partition %d] Segment %d loaded\n", part_id, segment);
#endif

      	segment++;
    }

    *entry = (uint32_t) (part_entry);
}
Beispiel #10
0
int ape_parseheader(int fd, struct ape_ctx_t* ape_ctx)
{
    int i,n;

    /* TODO: Skip any leading junk such as id3v2 tags */
    ape_ctx->junklength = 0;

    lseek(fd,ape_ctx->junklength,SEEK_SET);

    n = read(fd,&ape_ctx->magic,4);
    if (n != 4) return -1;

    if (memcmp(ape_ctx->magic,"MAC ",4)!=0)
    {
        return -1;
    }

    if (read_int16(fd,&ape_ctx->fileversion) < 0)
        return -1;

    if (ape_ctx->fileversion >= 3980)
    {
        if (read_int16(fd,&ape_ctx->padding1) < 0)
            return -1;
        if (read_uint32(fd,&ape_ctx->descriptorlength) < 0)
            return -1;
        if (read_uint32(fd,&ape_ctx->headerlength) < 0)
            return -1;
        if (read_uint32(fd,&ape_ctx->seektablelength) < 0)
            return -1;
        if (read_uint32(fd,&ape_ctx->wavheaderlength) < 0)
            return -1;
        if (read_uint32(fd,&ape_ctx->audiodatalength) < 0)
            return -1;
        if (read_uint32(fd,&ape_ctx->audiodatalength_high) < 0)
            return -1;
        if (read_uint32(fd,&ape_ctx->wavtaillength) < 0)
            return -1;
        if (read(fd,&ape_ctx->md5,16) != 16)
            return -1;

        /* Skip any unknown bytes at the end of the descriptor.  This is for future
           compatibility */
        if (ape_ctx->descriptorlength > 52)
            lseek(fd,ape_ctx->descriptorlength - 52, SEEK_CUR);

        /* Read header data */
        if (read_uint16(fd,&ape_ctx->compressiontype) < 0)
            return -1;
        if (read_uint16(fd,&ape_ctx->formatflags) < 0)
            return -1;
        if (read_uint32(fd,&ape_ctx->blocksperframe) < 0)
            return -1;
        if (read_uint32(fd,&ape_ctx->finalframeblocks) < 0)
            return -1;
        if (read_uint32(fd,&ape_ctx->totalframes) < 0)
            return -1;
        if (read_uint16(fd,&ape_ctx->bps) < 0)
            return -1;
        if (read_uint16(fd,&ape_ctx->channels) < 0)
            return -1;
        if (read_uint32(fd,&ape_ctx->samplerate) < 0)
            return -1;
    } else {
        ape_ctx->descriptorlength = 0;
        ape_ctx->headerlength = 32;

        if (read_uint16(fd,&ape_ctx->compressiontype) < 0)
            return -1;
        if (read_uint16(fd,&ape_ctx->formatflags) < 0)
            return -1;
        if (read_uint16(fd,&ape_ctx->channels) < 0)
            return -1;
        if (read_uint32(fd,&ape_ctx->samplerate) < 0)
            return -1;
        if (read_uint32(fd,&ape_ctx->wavheaderlength) < 0)
            return -1;
        if (read_uint32(fd,&ape_ctx->wavtaillength) < 0)
            return -1;
        if (read_uint32(fd,&ape_ctx->totalframes) < 0)
            return -1;
        if (read_uint32(fd,&ape_ctx->finalframeblocks) < 0)
            return -1;

        if (ape_ctx->formatflags & MAC_FORMAT_FLAG_HAS_PEAK_LEVEL)
        {
            lseek(fd, 4, SEEK_CUR);   /* Skip the peak level */
            ape_ctx->headerlength += 4;
        }

        if (ape_ctx->formatflags & MAC_FORMAT_FLAG_HAS_SEEK_ELEMENTS)
        {
            if (read_uint32(fd,&ape_ctx->seektablelength) < 0)
                return -1;
            ape_ctx->headerlength += 4;
            ape_ctx->seektablelength *= sizeof(int32_t);
        } else {
            ape_ctx->seektablelength = ape_ctx->totalframes * sizeof(int32_t);
        }

        if (ape_ctx->formatflags & MAC_FORMAT_FLAG_8_BIT)
            ape_ctx->bps = 8;
        else if (ape_ctx->formatflags & MAC_FORMAT_FLAG_24_BIT)
            ape_ctx->bps = 24;
        else
            ape_ctx->bps = 16;

        if (ape_ctx->fileversion >= 3950)
            ape_ctx->blocksperframe = 73728 * 4;
        else if ((ape_ctx->fileversion >= 3900) || (ape_ctx->fileversion >= 3800 && ape_ctx->compressiontype >= 4000))
            ape_ctx->blocksperframe = 73728;
        else
            ape_ctx->blocksperframe = 9216;

        /* Skip any stored wav header */
        if (!(ape_ctx->formatflags & MAC_FORMAT_FLAG_CREATE_WAV_HEADER))
        {
            lseek(fd, ape_ctx->wavheaderlength, SEEK_CUR);
        }
    }

    ape_ctx->totalsamples = ape_ctx->finalframeblocks;
    if (ape_ctx->totalframes > 1)
        ape_ctx->totalsamples += ape_ctx->blocksperframe * (ape_ctx->totalframes-1);

    if (ape_ctx->seektablelength > 0)
    {
        ape_ctx->seektable = malloc(ape_ctx->seektablelength);
        if (ape_ctx->seektable == NULL)
            return -1;
        for (i=0; i < ape_ctx->seektablelength / sizeof(uint32_t); i++)
        {
            if (read_uint32(fd,&ape_ctx->seektable[i]) < 0)
            {
                 free(ape_ctx->seektable);
                 return -1;
            }
        }
    }

    ape_ctx->firstframe = ape_ctx->junklength + ape_ctx->descriptorlength +
                           ape_ctx->headerlength + ape_ctx->seektablelength +
                           ape_ctx->wavheaderlength;

    return 0;
}
Beispiel #11
0
int main(int argc, char *argv[]) {
	// set scpi lib debug level: 0 for no debug info, 10 for lots
	const int scsi_verbose = 2;
	char *dev_name;

	switch (argc) {
	case 1:
		fputs(
			"\nUsage: stlink-access-test /dev/sg0, sg1, ...\n"
				"\n*** Notice: The stlink firmware violates the USB standard.\n"
				"*** If you plug-in the discovery's stlink, wait a several\n"
				"*** minutes to let the kernel driver swallow the broken device.\n"
				"*** Watch:\ntail -f /var/log/messages\n"
				"*** This command sequence can shorten the waiting time and fix some issues.\n"
				"*** Unplug the stlink and execute once as root:\n"
				"modprobe -r usb-storage && modprobe usb-storage quirks=483:3744:lrwsro\n\n",
			stderr);
		return EXIT_FAILURE;
	case 2:
		dev_name = argv[1];
		break;
	default:
		return EXIT_FAILURE;
	}

	fputs("*** stlink access test ***\n", stderr);
	fprintf(stderr, "Using sg_lib %s : scsi_pt %s\n", sg_lib_version(),
		scsi_pt_version());

	stlink_t *sl = stlink_quirk_open(dev_name, scsi_verbose);
	if (sl == NULL)
		return EXIT_FAILURE;

	// we are in mass mode, go to swd
	stlink_enter_swd_mode(sl);
	stlink_current_mode(sl);
	stlink_core_id(sl);
	//----------------------------------------------------------------------

	stlink_status(sl);
	//stlink_force_debug(sl);
	stlink_reset(sl);
	stlink_status(sl);
#if 0
	// core system control block
	stlink_read_mem32(sl, 0xe000ed00, 4);
	DD(sl, "cpu id base register: SCB_CPUID = got 0x%08x expect 0x411fc231", read_uint32(sl->q_buf, 0));
	// no MPU
	stlink_read_mem32(sl, 0xe000ed90, 4);
	DD(sl, "mpu type register: MPU_TYPER = got 0x%08x expect 0x0", read_uint32(sl->q_buf, 0));

	stlink_read_mem32(sl, 0xe000edf0, 4);
	DD(sl, "DHCSR = 0x%08x", read_uint32(sl->q_buf, 0));

	stlink_read_mem32(sl, 0x4001100c, 4);
	DD(sl, "GPIOC_ODR = 0x%08x", read_uint32(sl->q_buf, 0));
#endif
#if 0
	// happy new year 2011: let blink all the leds
	// see "RM0041 Reference manual - STM32F100xx advanced ARM-based 32-bit MCUs"

#define GPIOC		0x40011000 // port C
#define GPIOC_CRH	(GPIOC + 0x04) // port configuration register high
#define GPIOC_ODR	(GPIOC + 0x0c) // port output data register
#define LED_BLUE	(1<<8) // pin 8
#define LED_GREEN	(1<<9) // pin 9
	stlink_read_mem32(sl, GPIOC_CRH, 4);
	uint32_t io_conf = read_uint32(sl->q_buf, 0);
	DD(sl, "GPIOC_CRH = 0x%08x", io_conf);

	// set: general purpose output push-pull, output mode, max speed 10 MHz.
	write_uint32(sl->q_buf, 0x44444411);
	stlink_write_mem32(sl, GPIOC_CRH, 4);

	clear_buf(sl);
	for (int i = 0; i < 100; i++) {
		write_uint32(sl->q_buf, LED_BLUE | LED_GREEN);
		stlink_write_mem32(sl, GPIOC_ODR, 4);
		/* stlink_read_mem32(sl, 0x4001100c, 4); */
		/* DD(sl, "GPIOC_ODR = 0x%08x", read_uint32(sl->q_buf, 0)); */
		delay(100);

		clear_buf(sl);
		stlink_write_mem32(sl, GPIOC_ODR, 4); // PC lo
		delay(100);
	}
	write_uint32(sl->q_buf, io_conf); // set old state

#endif
#if 0
	// TODO rtfm: stlink doesn't have flash write routines
	// writing to the flash area confuses the fw for the next read access

	//stlink_read_mem32(sl, 0, 1024*6);
	// flash 0x08000000 128kB
	fputs("++++++++++ read a flash at 0x0800 0000\n", stderr);
	stlink_read_mem32(sl, 0x08000000, 1024 * 6); //max 6kB
	clear_buf(sl);
	stlink_read_mem32(sl, 0x08000c00, 5);
	stlink_read_mem32(sl, 0x08000c00, 4);
	mark_buf(sl);
	stlink_write_mem32(sl, 0x08000c00, 4);
	stlink_read_mem32(sl, 0x08000c00, 256);
	stlink_read_mem32(sl, 0x08000c00, 256);
#endif
#if 0
	// sram 0x20000000 8kB
	fputs("\n++++++++++ read/write 8bit, sram at 0x2000 0000 ++++++++++++++++\n\n", stderr);
	clear_buf(sl);
	stlink_write_mem8(sl, 0x20000000, 16);

	mark_buf(sl);
	stlink_write_mem8(sl, 0x20000000, 1);
	stlink_write_mem8(sl, 0x20000001, 1);
	stlink_write_mem8(sl, 0x2000000b, 3);
	stlink_read_mem32(sl, 0x20000000, 16);
#endif
#if 0
	// a not aligned mem32 access doesn't work indeed
	fputs("\n++++++++++ read/write 32bit, sram at 0x2000 0000 ++++++++++++++++\n\n", stderr);
	clear_buf(sl);
	stlink_write_mem8(sl, 0x20000000, 32);

	mark_buf(sl);
	stlink_write_mem32(sl, 0x20000000, 1);
	stlink_read_mem32(sl, 0x20000000, 16);
	mark_buf(sl);
	stlink_write_mem32(sl, 0x20000001, 1);
	stlink_read_mem32(sl, 0x20000000, 16);
	mark_buf(sl);
	stlink_write_mem32(sl, 0x2000000b, 3);
	stlink_read_mem32(sl, 0x20000000, 16);

	mark_buf(sl);
	stlink_write_mem32(sl, 0x20000000, 17);
	stlink_read_mem32(sl, 0x20000000, 32);
#endif
#if 0
	// sram 0x20000000 8kB
	fputs("++++++++++ read/write 32bit, sram at 0x2000 0000 ++++++++++++\n", stderr);
	mark_buf(sl);
	stlink_write_mem8(sl, 0x20000000, 64);
	stlink_read_mem32(sl, 0x20000000, 64);

	mark_buf(sl);
	stlink_write_mem32(sl, 0x20000000, 1024 * 8); //8kB
	stlink_read_mem32(sl, 0x20000000, 1024 * 6);
	stlink_read_mem32(sl, 0x20000000 + 1024 * 6, 1024 * 2);
#endif
#if 0
	stlink_read_all_regs(sl);
	stlink_step(sl);
	fputs("++++++++++ write r0 = 0x12345678\n", stderr);
	stlink_write_reg(sl, 0x12345678, 0);
	stlink_read_reg(sl, 0);
	stlink_read_all_regs(sl);
#endif
#if 0
	stlink_run(sl);
	stlink_status(sl);

	stlink_force_debug(sl);
	stlink_status(sl);
#endif
#if 1 /* read the system bootloader */
	fputs("\n++++++++++ reading bootloader ++++++++++++++++\n\n", stderr);
	stlink_fread(sl, "/tmp/barfoo", sl->sys_base, sl->sys_size);
#endif
#if 0 /* read the flash memory */
	fputs("\n+++++++ read flash memory\n\n", stderr);
	/* mark_buf(sl); */
	stlink_read_mem32(sl, 0x08000000, 4);
#endif
#if 0 /* flash programming */
	fputs("\n+++++++ program flash memory\n\n", stderr);
	stlink_fwrite_flash(sl, "/tmp/foobar", 0x08000000);
#endif
#if 0 /* check file contents */
	fputs("\n+++++++ check flash memory\n\n", stderr);
	{
	  const int res = stlink_fcheck_flash(sl, "/tmp/foobar", 0x08000000);
	  printf("_____ stlink_fcheck_flash() == %d\n", res);
	}
#endif
#if 0
	fputs("\n+++++++ sram write and execute\n\n", stderr);
	stlink_fwrite_sram(sl, "/tmp/foobar", sl->sram_base);
	stlink_run_at(sl, sl->sram_base);
#endif

	stlink_run(sl);
	stlink_status(sl);
	//----------------------------------------------------------------------
	// back to mass mode, just in case ...
	stlink_exit_debug_mode(sl);
	stlink_current_mode(sl);
	stlink_close(sl);

	//fflush(stderr); fflush(stdout);
	return EXIT_SUCCESS;
}
Beispiel #12
0
bool Indigo::detail::ZipFile::open(const char* filename)
{
	static const OOBase::uint8_t END_OF_CDR[4] = { 0x50, 0x4b, 0x05, 0x06 };
	static const OOBase::uint8_t CDR_HEADER[4] = { 0x50, 0x4b, 0x01, 0x02 };

	int err = m_file.open(filename,false);
	if (err)
		LOG_ERROR_RETURN(("Failed to open file %s: %s",filename,OOBase::system_error_text(err)),false);

	OOBase::uint64_t len = m_file.length();
	if (len == OOBase::uint64_t(-1))
		LOG_ERROR_RETURN(("Failed to get file length: %s",OOBase::system_error_text()),false);

	// Step backwards looking for end of central directory record
	OOBase::uint32_t cdr_size = 0;

	OOBase::ScopedArrayPtr<OOBase::uint8_t,OOBase::ThreadLocalAllocator,256> buf;
	for (OOBase::int64_t offset = len - 256;!cdr_size;)
	{
		if (offset < 0)
			offset = 0;

		OOBase::uint64_t p = m_file.seek(offset,OOBase::File::seek_begin);
		if (p == OOBase::uint64_t(-1))
			LOG_ERROR_RETURN(("Failed to get seek in file: %s",OOBase::system_error_text()),false);

		size_t chunk_len = m_file.read(buf.get(),256);
		if (chunk_len == size_t(-1))
			LOG_ERROR_RETURN(("Failed to read file: %s",OOBase::system_error_text()),false);

		// Scan forwards looking for signatures
		for (OOBase::uint8_t* c = buf.get(); c < buf.get() + chunk_len - 4; ++c)
		{
			if (memcmp(c,END_OF_CDR,4) == 0)
			{
				OOBase::uint64_t eof_cdr = p + (c - buf.get());
				if (len - eof_cdr >= 22 && m_file.seek(eof_cdr,OOBase::File::seek_begin) == eof_cdr)
				{
					m_file.read(buf.get(),22);

					OOBase::uint16_t disk_no = read_uint16(buf,4);
					OOBase::uint16_t cdr_disk_no = read_uint16(buf,6);
					OOBase::uint16_t cdr_entries_disk = read_uint16(buf,8);
					OOBase::uint16_t cdr_entries = read_uint16(buf,10);
					OOBase::uint32_t cdr_size_i = read_uint32(buf,12);
					OOBase::uint32_t cdr_offset = read_uint32(buf,16);
					OOBase::uint16_t comments = read_uint16(buf,20);
					
					if (cdr_size_i >= 46 && (eof_cdr + 22 + comments == len) && 
						(disk_no == 0 && cdr_disk_no == 0 && cdr_entries_disk == cdr_entries) &&
						(cdr_offset + cdr_size_i <= eof_cdr))
					{
						if (m_file.seek(cdr_offset,OOBase::File::seek_begin) == cdr_offset)
						{
							m_file.read(buf.get(),46);
							if (memcmp(buf.get(),CDR_HEADER,4) == 0)
							{
								cdr_size = cdr_size_i;
								break;
							}
						}
					}
				}
			}
		}

		if (offset > 0)
			offset -= 253;
		else
			break;
	}

	if (!cdr_size)
		LOG_ERROR_RETURN(("Failed to find end of central dictionary in zip %s",filename),false);

	// Now loop reading file entries
	for (;;)
	{
		struct Info info = {0};

		info.m_length = read_uint32(buf,24);
		OOBase::uint16_t filename_len = read_uint16(buf,28);
		OOBase::uint16_t extra_len = read_uint16(buf,30);
		OOBase::uint16_t comments = read_uint16(buf,32);
		OOBase::uint16_t disk_no = read_uint16(buf,34);
		info.m_offset = read_uint32(buf,42);

		if (disk_no != 0)
			LOG_ERROR_RETURN(("Multi-disk zip file not supported: %s",filename),false);

		if (filename_len == 0)
			LOG_WARNING(("Ignoring empty filename in %s",filename));
		else
		{
			if (!buf.resize(filename_len))
				LOG_ERROR_RETURN(("Failed to resize buffer: %s",OOBase::system_error_text()),false);

			if (m_file.read(buf.get(),filename_len) != filename_len)
				LOG_ERROR_RETURN(("Failed to read file %s: %s",filename,OOBase::system_error_text()),false);

			OOBase::String strFilename;
			if (!strFilename.assign(reinterpret_cast<char*>(buf.get()),filename_len))
				LOG_ERROR_RETURN(("Failed to assign string: %s",OOBase::system_error_text()),false);

			if (!m_mapFiles.insert(strFilename,info))
				LOG_ERROR_RETURN(("Failed to insert zip entry: %s",OOBase::system_error_text()),false);
		}

		if (cdr_size <= OOBase::uint32_t(filename_len) + extra_len + comments + 46)
			break;

		cdr_size -= 46 + filename_len + extra_len + comments;
		if (m_file.seek(extra_len + comments,OOBase::File::seek_current) == OOBase::uint64_t(-1))
			LOG_ERROR_RETURN(("Failed to get seek in file: %s",OOBase::system_error_text()),false);

		if (m_file.read(buf.get(),46) != 46)
			LOG_ERROR_RETURN(("Failed to read central dictionary header in zip %s",filename),false);

		if (memcmp(buf.get(),CDR_HEADER,4) != 0)
			LOG_ERROR_RETURN(("Invalid central dictionary header in zip %s",filename),false);
	}
	
	return true;
}
Beispiel #13
0
OOBase::SharedPtr<const char> Indigo::detail::ZipFile::load(const OOBase::String& prefix, const char* name)
{
	OOBase::SharedPtr<const char> ret;
	OOBase::String filename(prefix);
	if (!filename.append(name))
		LOG_ERROR_RETURN(("Failed to append string: %s",OOBase::system_error_text()),ret);

	OOBase::Table<OOBase::String,Info>::iterator i=m_mapFiles.find(filename);
	if (!i)
		return ret;

	// Read the local file header
	if (m_file.seek(i->second.m_offset,OOBase::File::seek_begin) == OOBase::uint64_t(-1))
		LOG_ERROR_RETURN(("Failed to get seek in file: %s",OOBase::system_error_text()),ret);

	OOBase::uint8_t header[30];
	if (m_file.read(header,30) != 30)
		LOG_ERROR_RETURN(("Failed to read local file header header in zip"),ret);

	static const OOBase::uint8_t LFR_HEADER[4] = { 0x50, 0x4b, 0x03, 0x04 };
	if (memcmp(header,LFR_HEADER,4) != 0)
		LOG_ERROR_RETURN(("Invalid local file header header in zip"),ret);

	OOBase::uint16_t compression = read_uint16(header,8);
	OOBase::uint32_t compressed_size = read_uint32(header,18);
	size_t offset = 30 + read_uint16(header,26) + read_uint16(header,28);

	OOBase::SharedPtr<const char> mapping = m_file.auto_map<const char>(false,i->second.m_offset + offset,compressed_size);
	if (!mapping)
		LOG_ERROR_RETURN(("Failed to map file content: %s",OOBase::system_error_text()),ret);

	if (compression == 0)
	{
		ret = mapping;
	}
	else if (compression == 8)
	{
		void* p = OOBase::CrtAllocator::allocate(i->second.m_length,1);
		if (!p)
			LOG_ERROR_RETURN(("Failed to allocate: %s",OOBase::system_error_text()),ret);

		if (stbi_zlib_decode_noheader_buffer(static_cast<char*>(p),(int)i->second.m_length,mapping.get(),(int)compressed_size) == -1)
		{
			LOG_ERROR(("Failed to inflate file: %s",stbi_failure_reason()));
			OOBase::CrtAllocator::free(p);
		}
		else
		{
			ret = OOBase::const_pointer_cast<const char>(OOBase::make_shared<char>(static_cast<char*>(p)));
			if (!ret)
			{
				LOG_ERROR(("Failed to allocate: %s",OOBase::system_error_text()));
				OOBase::CrtAllocator::free(p);
			}
		}
	}
	else
		LOG_ERROR(("Unsupported zip compression method: %u",compression));

	return ret;
}
Beispiel #14
0
/* Process the differences file in input stream, starting at offset 8 (the
   header has already been read and verified), creating a new block reference
   list. */
static void process_input(InputStream *is)
{
    FILE *fp;
    uint32_t S;
    uint16_t C, A;
    size_t num_blocks;
    off_t offset;
    BlockRef br;
    uint8_t digest1[DS], digest2[DS];

    fp = tmpfile();
    if (fp == NULL)
    {
        fprintf(stderr, "Couldn't open temporary file!\n");
        exit(EXIT_FAILURE);
    }

    offset = 8;
    num_blocks = 0;

    for (;;)
    {
        S = read_uint32(is);
        C = read_uint16(is);
        A = read_uint16(is);
        offset += 8;

        /* Check for end-of-instructions. */
        if (S == 0xffffffffu && C == 0xffffu && A == 0xffffu) break;

        if ( (C > 0x7fffu || A > 0x7fffu) || (C > 0xffffffffu - S) ||
             (S == 0xffffffffu && C != 0) || (S != 0xffffffffu && C == 0) )
        {
            fprintf(stderr, "Invalid instruction in differences file!\n");
            exit(EXIT_FAILURE);
        }

        while (C--)
        {
            if (last_blocks == NULL)
            {
                br.is = NULL;
                br.offset = BS*S++;
            }
            else
            {
                if (S >= last_num_blocks)
                {
                    fprintf(stderr, "Invalid block index in differences file!\n");
                    exit(EXIT_FAILURE);
                }
                br = last_blocks[S++];
            }
            if (fwrite(&br, sizeof(br), 1, fp) != 1)
            {
                fprintf(stderr, "Write to temporary file failed!\n");
                exit(EXIT_FAILURE);
            }
            ++num_blocks;
        }

        while (A--)
        {
            br.is = is;
            br.offset = offset;
            offset += BS;
            if (fwrite(&br, sizeof(br), 1, fp) != 1)
            {
                fprintf(stderr, "Write to temporary file failed!\n");
                exit(EXIT_FAILURE);
            }
            ++num_blocks;
        }

        is->seek(is, offset);
    }

    /* Verify MD5 digests */
    read_data(is, digest2, DS);
    if (is->read(is, digest1, DS) == DS)
    {
        if (last_blocks == NULL)
        {
            orig_digest_known = true;
            memcpy(orig_digest, digest1, DS);
        }
        else
        if (memcmp(digest1, last_digest, DS) != 0)
        {
            fprintf(stderr, "Invalid sequence of differences files!\n");
            exit(EXIT_FAILURE);
        }
    }
    else
    {
        fprintf(stderr, "WARNING: differences file is missing original file "
                        "digest; patch integrity cannot be guaranteed.\n");
    }
    memcpy(last_digest, digest2, DS);

    /* Unmap old block data */
    if (last_blocks != NULL)
    {
        if (munmap(last_blocks, last_num_blocks*sizeof(BlockRef)) != 0)
        {
            fprintf(stderr, "munmap() failed!\n");
            exit(EXIT_FAILURE);
        }
    }

    /* Map new block data */
    fflush(fp); /* must flush to ensure all data can be mmap()ed */
    last_blocks = mmap( NULL, num_blocks*sizeof(BlockRef), PROT_READ,
                        MAP_SHARED, fileno(fp), 0 );
    if (last_blocks == NULL)
    {
        fprintf(stderr, "mmap() failed!\n");
        exit(EXIT_FAILURE);
    }
    last_num_blocks = num_blocks;
    fclose(fp);
}
Beispiel #15
0
//int ape_parseheader(int fd, struct ape_parser_ctx_t* ape_ctx)
int ape_parseheader(FILE* fp, struct ape_parser_ctx_t* ape_ctx)
{
    int i,n;

    /* Skip any leading junk such as id3v2 tags */
    memset(ape_ctx, 0, sizeof(struct ape_parser_ctx_t));
    while (1) {
        char sync[5];
        if (4 != fread(sync, 1, 4, fp))
            return -1;
        sync[4] = 0;
        if (strcmp(sync,"MAC ") == 0)
            break;
        else if (strcmp(sync + 1,"MAC") == 0) {
            fseek(fp, -1, SEEK_CUR);
            ape_ctx->junklength += 1;
            }
        else if (strcmp(sync + 2, "MA") == 0) {
            fseek(fp, -2, SEEK_CUR);
            ape_ctx->junklength += 2;
            }
        else if (sync[3]=='M') {
            fseek(fp, -3, SEEK_CUR);
            ape_ctx->junklength += 3;
            }
        else {
            ape_ctx->junklength += 4;
            }
        }


    fseek(fp, ape_ctx->junklength, SEEK_SET);

    n = fread(&ape_ctx->magic,1, 4, fp);
    if (n != 4) return -1;

    if (memcmp(ape_ctx->magic,"MAC ",4)!=0)
    {
        return -1;
    }

    if (read_int16(fp,&ape_ctx->fileversion) < 0)
        return -1;

    if (ape_ctx->fileversion >= 3980)
    {
        if (read_int16(fp,&ape_ctx->padding1) < 0)
            return -1;
        if (read_uint32(fp,&ape_ctx->descriptorlength) < 0)
            return -1;
        if (read_uint32(fp,&ape_ctx->headerlength) < 0)
            return -1;
        if (read_uint32(fp,&ape_ctx->seektablelength) < 0)
            return -1;
        if (read_uint32(fp,&ape_ctx->wavheaderlength) < 0)
            return -1;
        if (read_uint32(fp,&ape_ctx->audiodatalength) < 0)
            return -1;
        if (read_uint32(fp,&ape_ctx->audiodatalength_high) < 0)
            return -1;
        if (read_uint32(fp,&ape_ctx->wavtaillength) < 0)
            return -1;
        if (fread(&ape_ctx->md5,1, 16, fp) != 16)
            return -1;

        /* Skip any unknown bytes at the end of the descriptor.  This is for future
           compatibility */
        if (ape_ctx->descriptorlength > 52)
            fseek(fp, ape_ctx->descriptorlength - 52, SEEK_CUR);

        /* Read header data */
        if (read_uint16(fp,&ape_ctx->compressiontype) < 0)
            return -1;
        if (read_uint16(fp,&ape_ctx->formatflags) < 0)
            return -1;
        if (read_uint32(fp,&ape_ctx->blocksperframe) < 0)
            return -1;
        if (read_uint32(fp,&ape_ctx->finalframeblocks) < 0)
            return -1;
        if (read_uint32(fp,&ape_ctx->totalframes) < 0)
            return -1;
        if (read_uint16(fp,&ape_ctx->bps) < 0)
            return -1;
        if (read_uint16(fp,&ape_ctx->channels) < 0)
            return -1;
        if (read_uint32(fp,&ape_ctx->samplerate) < 0)
            return -1;
    } else {
        ape_ctx->descriptorlength = 0;
        ape_ctx->headerlength = 32;

        if (read_uint16(fp,&ape_ctx->compressiontype) < 0)
            return -1;
        if (read_uint16(fp,&ape_ctx->formatflags) < 0)
            return -1;
        if (read_uint16(fp,&ape_ctx->channels) < 0)
            return -1;
        if (read_uint32(fp,&ape_ctx->samplerate) < 0)
            return -1;
        if (read_uint32(fp,&ape_ctx->wavheaderlength) < 0)
            return -1;
        if (read_uint32(fp,&ape_ctx->wavtaillength) < 0)
            return -1;
        if (read_uint32(fp,&ape_ctx->totalframes) < 0)
            return -1;
        if (read_uint32(fp,&ape_ctx->finalframeblocks) < 0)
            return -1;

        if (ape_ctx->formatflags & MAC_FORMAT_FLAG_HAS_PEAK_LEVEL)
        {
            fseek(fp, 4, SEEK_CUR);
            ape_ctx->headerlength += 4;
        }

        if (ape_ctx->formatflags & MAC_FORMAT_FLAG_HAS_SEEK_ELEMENTS)
        {
            if (read_uint32(fp,&ape_ctx->seektablelength) < 0)
                return -1;
            ape_ctx->headerlength += 4;
            ape_ctx->seektablelength *= sizeof(ape_parser_int32_t);
        } else {
            ape_ctx->seektablelength = ape_ctx->totalframes * sizeof(ape_parser_int32_t);
        }

        if (ape_ctx->formatflags & MAC_FORMAT_FLAG_8_BIT)
            ape_ctx->bps = 8;
        else if (ape_ctx->formatflags & MAC_FORMAT_FLAG_24_BIT)
            ape_ctx->bps = 24;
        else
            ape_ctx->bps = 16;

        if (ape_ctx->fileversion >= 3950)
            ape_ctx->blocksperframe = 73728 * 4;
        else if ((ape_ctx->fileversion >= 3900) || (ape_ctx->fileversion >= 3800 && ape_ctx->compressiontype >= 4000))
            ape_ctx->blocksperframe = 73728;
        else
            ape_ctx->blocksperframe = 9216;

        /* Skip any stored wav header */
        if (!(ape_ctx->formatflags & MAC_FORMAT_FLAG_CREATE_WAV_HEADER))
        {
            fseek(fp, ape_ctx->wavheaderlength, SEEK_CUR);
        }
    }

    ape_ctx->totalsamples = ape_ctx->finalframeblocks;
    if (ape_ctx->totalframes > 1)
        ape_ctx->totalsamples += ape_ctx->blocksperframe * (ape_ctx->totalframes-1);

    if (ape_ctx->seektablelength > 0)
    {
        ape_ctx->seektable = malloc(ape_ctx->seektablelength);
        if (ape_ctx->seektable == NULL)
            return -1;
        for (i=0; i < ape_ctx->seektablelength / sizeof(ape_parser_uint32_t); i++)
        {
            if (read_uint32(fp,&ape_ctx->seektable[i]) < 0)
            {
                 free(ape_ctx->seektable);
                 return -1;
            }
        }
    }

    ape_ctx->firstframe = ape_ctx->junklength + ape_ctx->descriptorlength +
                           ape_ctx->headerlength + ape_ctx->seektablelength +
                           ape_ctx->wavheaderlength;

    return 0;
}
Beispiel #16
0
int main ( int argc, char *argv[] )
{
    stlink_t* sl;
    unsigned int ra;
    unsigned int rb;
    unsigned int flen;
    int ret;

    if(argc<2)
    {
        printf(".bin file not specified\n");
        return(1);
    }

    fp=fopen(argv[1],"rb");
    if(fp==NULL)
    {
        printf("Error opening file [%s]\n",argv[1]);
        return(1);
    }
    memset(pdata,0xFF,sizeof(pdata));
    flen=fread(pdata,1,sizeof(pdata),fp);
    flen+=3;
    flen>>=2;
    fclose(fp);

    sl = stlink_open_usb(10);
    if(sl==NULL)
    {
        printf("stlink_open_usb failed\n");
        return(1);
    }

    printf("-- version\n");
    stlink_version(sl);

    printf("mode before doing anything: %d\n", stlink_current_mode(sl));

    if (stlink_current_mode(sl) == STLINK_DEV_DFU_MODE) {
        printf("-- exit_dfu_mode\n");
        stlink_exit_dfu_mode(sl);
    }

    printf("-- enter_swd_mode\n");
    stlink_enter_swd_mode(sl);

    printf("-- mode after entering swd mode: %d\n", stlink_current_mode(sl));

    printf("-- chip id: %#x\n", sl->chip_id);
    printf("-- core_id: %#x\n", sl->core_id);

    cortex_m3_cpuid_t cpuid;
    stlink_cpu_id(sl, &cpuid);
    printf("cpuid:impl_id = %0#x, variant = %#x\n", cpuid.implementer_id, cpuid.variant);
    printf("cpuid:part = %#x, rev = %#x\n", cpuid.part, cpuid.revision);

  //  printf("-- status\n");
    //stlink_status(sl);

    printf("-- reset\n");
    stlink_reset(sl);
    stlink_force_debug(sl);

//    printf("-- status\n");
  //  stlink_status(sl);

#ifdef LOAD_RAM

    printf("-- load\n");

    for(ra=0;ra<flen;ra++)
    {
        write_uint32(sl->q_buf,pdata[ra]);
        stlink_write_mem32(sl, 0x20000000+(ra<<2), 4);
    }

    for(ra=0;ra<8;ra++)
    {
        stlink_read_mem32(sl, 0x20000000+(ra<<2), 4);
        rb=read_uint32(sl->q_buf,0);
        printf("[0x%08X] 0x%08X 0x%08X\n",ra,rb,pdata[ra]);
    }

    printf("-- run\n");

    stlink_write_reg(sl, 0x20020000, 13); /* pc register */
    stlink_write_reg(sl, 0x20000000, 15); /* pc register */

    stlink_run(sl);

    ret =0;

#endif //LOAD_RAM

#ifdef LOAD_FLASH

    ra=0;
    rb=0;
    ret=stlink_write_flash(sl,0x08000000,(unsigned char *)pdata,0x4000);
    if(ret)
    {
        printf("stlink_write_flasin error\n");
    }

#endif //LOAD_FLASH















    printf("-- exit_debug_mode\n");
    stlink_exit_debug_mode(sl);

    stlink_close(sl);

    return 0;
}
Beispiel #17
0
crf1mm_t* crf1mm_new(const char *filename)
{
    FILE *fp = NULL;
    uint8_t* p = NULL;
    crf1mm_t *model = NULL;
    header_t *header = NULL;

    model = (crf1mm_t*)calloc(1, sizeof(crf1mm_t));
    if (model == NULL) {
        goto error_exit;
    }

    fp = fopen(filename, "rb");
    if (fp == NULL) {
        goto error_exit;
    }

    fseek(fp, 0, SEEK_END);
    model->size = (uint32_t)ftell(fp);
    fseek(fp, 0, SEEK_SET);

    model->buffer = model->buffer_orig = (uint8_t*)malloc(model->size + 16);
    while ((uint32_t)model->buffer % 16 != 0) {
        ++model->buffer;
    }

    fread(model->buffer, 1, model->size, fp);
    fclose(fp);

    /* Write the file header. */
    header = (header_t*)calloc(1, sizeof(header_t));

    p = model->buffer;
    p += read_uint8_array(p, header->magic, sizeof(header->magic));
    p += read_uint32(p, &header->size);
    p += read_uint8_array(p, header->type, sizeof(header->type));
    p += read_uint32(p, &header->version);
    p += read_uint32(p, &header->num_features);
    p += read_uint32(p, &header->num_labels);
    p += read_uint32(p, &header->num_attrs);
    p += read_uint32(p, &header->off_features);
    p += read_uint32(p, &header->off_labels);
    p += read_uint32(p, &header->off_attrs);
    p += read_uint32(p, &header->off_labelrefs);
    p += read_uint32(p, &header->off_attrrefs);
    model->header = header;

    model->labels = cqdb_reader(
        model->buffer + header->off_labels,
        model->size - header->off_labels
        );

    model->attrs = cqdb_reader(
        model->buffer + header->off_attrs,
        model->size - header->off_attrs
        );

    return model;

error_exit:
    if (model != NULL) {
        free(model);
    }
    if (fp != NULL) {
        fclose(fp);
    }
    return NULL;
}
Beispiel #18
0
IFS_DATA* load_ifs_file (const char* filename) {
    int infd;
    IFS_DATA* ifs_data = NULL;
    float version;
    char* ifstag = NULL;
    unsigned int i;
    unsigned int nVertices = 0;
    unsigned int nTriangles = 0;
    unsigned int tmp_Index = 0;
    
    if ((infd = open(filename, O_RDONLY)) < 2) {
	fprintf(stderr, "Error opening an input IFS file\n");
	exit(-1);
    }

    ifs_data = (IFS_DATA*) malloc(sizeof(IFS_DATA));
    ifs_data->modelName = NULL;
    ifs_data->numVertices = 0;
    ifs_data->vertices = NULL;
    ifs_data->numTriangles = 0;
    ifs_data->triangles = NULL;
    
    read_string32(infd, &ifstag);
    if (strcmp(ifstag, "IFS") != 0) {
	fprintf(stderr, "Not IFS filetype\n");
	exit(-1);
    }
    free(ifstag); ifstag = NULL;

    read_float32(infd, &version);
    if (version != 1.0) {
	fprintf(stderr, "Invalid version number: %f\n", version);
	exit(-1);
    }

    read_string32(infd, &(ifs_data->modelName));
    
    read_string32(infd, &ifstag);
    if (strcmp(ifstag, "VERTICES") != 0) {
	fprintf(stderr, "Not IFS filetype\n");
	exit(-1);
    }
    free(ifstag); ifstag = NULL;

    read_uint32(infd, &nVertices);
    ifs_data->numVertices = nVertices;

    ifs_data->vertices = (VERTEX*) malloc(nVertices * sizeof(VERTEX));
    for (i =0; i < ifs_data->numVertices; ++i) {
	ifs_data->vertices[i].id = i;
	read_float32(infd, &((ifs_data->vertices)[i].x));
	read_float32(infd, &((ifs_data->vertices)[i].y));
	read_float32(infd, &((ifs_data->vertices)[i].z));
    }
    
    read_string32(infd, &ifstag);
    if (strcmp(ifstag, "TRIANGLES") != 0) {
	fprintf(stderr, "Not IFS filetype\n");
	exit(-1);
    }
    free(ifstag); ifstag = NULL;
	
    read_uint32(infd, &nTriangles);
    ifs_data->numTriangles = nTriangles;
    
    ifs_data->triangles = (TRIANGLE*) malloc(nTriangles * sizeof(TRIANGLE));
    for (i =0; i < ifs_data->numTriangles; ++i) {
	read_uint32(infd, &tmp_Index);
	if (tmp_Index >= nVertices) {
	    fprintf(stderr, "Invalid Vertex index\n");
	    exit(-1);
	}
	ifs_data->triangles[i].a = &((ifs_data->vertices)[tmp_Index]);
	read_uint32(infd, &tmp_Index);
	if (tmp_Index >= nVertices) {
	    fprintf(stderr, "Invalid Vertex index\n");
	    exit(-1);
	}
	ifs_data->triangles[i].b = &((ifs_data->vertices)[tmp_Index]);
	read_uint32(infd, &tmp_Index);
	if (tmp_Index >= nVertices) {
	    fprintf(stderr, "Invalid Vertex index\n");
	    exit(-1);
	}
	ifs_data->triangles[i].c = &((ifs_data->vertices)[tmp_Index]);
    }

    if (close(infd) == -1) {
	fprintf(stderr, "Error closing an input IFS file\n");
	exit(-1);
    }
	
    return ifs_data;
}
Beispiel #19
0
static GHashTable *read_directory(FILE *f, int64_t *diroff,
				  GHashTable *loop_detector,
				  uint16_t endian) {
  int64_t off = *diroff;
  *diroff = 0;
  GHashTable *result = NULL;
  int64_t *key = NULL;
  int64_t nextdiroff = -1;
  int dircount = -1;

  //  g_debug("diroff: %" PRId64, off);

  if (off <= 0) {
    g_warning("Bad offset");
    goto FAIL;
  }

  // loop detection
  if (g_hash_table_lookup_extended(loop_detector, &off, NULL, NULL)) {
    // loop
    g_warning("Loop detected");
    goto FAIL;
  }
  key = g_slice_new(int64_t);
  *key = off;
  g_hash_table_insert(loop_detector, key, NULL);

  // no loop, let's seek
  if (fseeko(f, off, SEEK_SET) != 0) {
    g_warning("Cannot seek to offset");
    goto FAIL;
  }

  // read directory count
  dircount = read_uint16(f, endian);
  if (dircount == -1) {
    g_warning("Cannot read dircount");
    goto FAIL;
  }

  //  g_debug("dircount: %d", dircount);


  // initial checks passed, initialized the hashtable
  result = g_hash_table_new_full(g_int_hash, g_int_equal,
				 g_free, tiffdump_item_destroy);

  // read all directory entries
  for (int i = 0; i < dircount; i++) {
    int32_t tag = read_uint16(f, endian);
    int32_t type = read_uint16(f, endian);
    int64_t count = read_uint32(f, endian);

    if ((tag == -1) || (type == -1) || (count == -1)) {
      g_warning("Cannot read tag, type, and count");
      goto FAIL;
    }

    //    g_debug(" tag: %d, type: %d, count: %" PRId64, tag, type, count);

    // read in the value/offset
    uint8_t value[4];
    if (fread(value, 1, 4, f) != 4) {
      g_warning("Cannot read value/offset");
      goto FAIL;
    }

    uint32_t offset;
    memcpy(&offset, value, 4);
    if (endian == TIFF_BIGENDIAN) {
      offset = GUINT32_FROM_BE(offset);
    } else {
      offset = GUINT32_FROM_LE(offset);
    }

    // allocate the item
    struct _openslide_tiffdump_item *data =
      g_slice_new(struct _openslide_tiffdump_item);
    data->type = (TIFFDataType) type;
    data->count = count;

    // load the value
    switch (type) {
    case TIFF_BYTE:
    case TIFF_ASCII:
    case TIFF_SBYTE:
    case TIFF_UNDEFINED:
      data->value = read_tiff_tag_1(f, count, offset, value);
      break;

    case TIFF_SHORT:
    case TIFF_SSHORT:
      data->value = read_tiff_tag_2(f, count, offset, value, endian);
      break;

    case TIFF_LONG:
    case TIFF_SLONG:
    case TIFF_FLOAT:
    case TIFF_IFD:
      data->value = read_tiff_tag_4(f, count, offset, value, endian);
      break;

    case TIFF_RATIONAL:
    case TIFF_SRATIONAL:
      data->value = read_tiff_tag_4(f, count * 2, offset, value, endian);
      break;

    case TIFF_DOUBLE:
      data->value = read_tiff_tag_8(f, count, offset, endian);
      break;

    default:
      g_warning("Unknown type encountered: %d", type);
      goto FAIL;
    }

    if (data->value == NULL) {
      g_warning("Cannot read value");
      goto FAIL;
    }

    // add this tag to the hashtable
    int *key = g_new(int, 1);
    *key = tag;
    g_hash_table_insert(result, key, data);
  }

  // read the next dir offset
  nextdiroff = read_uint32(f, endian);
  if (nextdiroff == -1) {
    g_warning("Cannot read next directory offset");
    goto FAIL;
  }
  *diroff = nextdiroff;

  // success
  return result;


 FAIL:
  if (result != NULL) {
    g_hash_table_unref(result);
  }
  return NULL;
}
Beispiel #20
0
		address read_v4_address(InIt&& in)
		{
			std::uint32_t const ip = read_uint32(in);
			return address_v4(ip);
		}
Beispiel #21
0
/**
 * Analyse an ICO prior to decoding.
 *
 * This function will scan the data provided and perform simple checks to
 * ensure the data is a valid ICO.
 *
 * This function must be called before ico_find().
 *
 * \param ico	the ICO image to analyse
 * \return BMP_OK on success
 */
bmp_result ico_analyse(ico_collection *ico, size_t size, uint8_t *data) {
	uint16_t count, i;
	bmp_result result;
	int area, max_area = 0;

	/* ensure we aren't already initialised */
	if (ico->first)
		return BMP_OK;

	/* initialize values */
	ico->buffer_size = size;
	ico->ico_data = data;

	/* 6-byte ICO file header is:
	 *
	 *	+0	INT16	Reserved (should be 0)
	 *	+2	UINT16	Type (1 for ICO, 2 for CUR)
	 *	+4	UINT16	Number of BMPs to follow
	 */
	if (ico->buffer_size < ICO_FILE_HEADER_SIZE)
		return BMP_INSUFFICIENT_DATA;
// 	if (read_int16(data, 2) != 0x0000)
// 		return BMP_DATA_ERROR;
	if (read_uint16(data, 2) != 0x0001)
		return BMP_DATA_ERROR;
	count = read_uint16(data, 4);
	if (count == 0)
		return BMP_DATA_ERROR;
	data += ICO_FILE_HEADER_SIZE;

	/* check if we have enough data for the directory */
	if (ico->buffer_size < (uint32_t)(ICO_FILE_HEADER_SIZE + (ICO_DIR_ENTRY_SIZE * count)))
		return BMP_INSUFFICIENT_DATA;

	/* Decode the BMP files.
	 *
	 * 16-byte ICO directory entry is:
	 *
	 *	+0	UINT8	Width (0 for 256 pixels)
	 *	+1	UINT8	Height (0 for 256 pixels)
	 *	+2	UINT8	Colour count (0 if more than 256 colours)
	 *	+3	INT8	Reserved (should be 0, but may not be)
	 *	+4	UINT16	Colour Planes (should be 0 or 1)
	 *	+6	UINT16	Bits Per Pixel
	 *	+8	UINT32	Size of BMP info header + bitmap data in bytes
	 *	+12	UINT32	Offset (points to the BMP info header, not the bitmap data)
	 */
	for (i = 0; i < count; i++) {
		ico_image *image;
		image = calloc(1, sizeof(ico_image));
		if (!image)
			return BMP_INSUFFICIENT_MEMORY;
		result = next_ico_image(ico, image);
		if (result != BMP_OK)
			return result;
		image->bmp.width = read_uint8(data, 0);
		if (image->bmp.width == 0)
			image->bmp.width = 256;
		image->bmp.height = read_uint8(data, 1);
		if (image->bmp.height == 0)
			image->bmp.height = 256;
		image->bmp.buffer_size = read_uint32(data, 8);
		image->bmp.bmp_data = ico->ico_data + read_uint32(data, 12);
		image->bmp.ico = true;
		data += ICO_DIR_ENTRY_SIZE;

		/* Ensure that the bitmap data resides in the buffer */
		if (image->bmp.bmp_data - ico->ico_data >= 0 &&
				(uint32_t)(image->bmp.bmp_data -
				ico->ico_data) >= ico->buffer_size)
			return BMP_DATA_ERROR;

		/* Ensure that we have sufficient data to read the bitmap */
		if (image->bmp.buffer_size - ICO_DIR_ENTRY_SIZE >= 
		    ico->buffer_size - (ico->ico_data - data))
			return BMP_INSUFFICIENT_DATA;

		result = bmp_analyse_header(&image->bmp, image->bmp.bmp_data);
		if (result != BMP_OK)
			return result;

		/* adjust the size based on the images available */
		area = image->bmp.width * image->bmp.height;
		if (area > max_area) {
			ico->width = image->bmp.width;
			ico->height = image->bmp.height;
			max_area = area;
		}
	}
	return BMP_OK;
}
Beispiel #22
0
static enum dlep_status_code parse_session_init_resp_message(const uint8_t* data_items, uint16_t len, uint32_t* heartbeat_interval, enum dlep_status_code* sc)
{
	const uint8_t* data_item = data_items;

	printf("Valid Session Initialization Response message from modem:\n");

	/* The message has been validated so just scan for the relevant data_items */
	while (data_item < data_items + len)
	{
		/* Octets 0 and 1 are the data item type */
		enum dlep_data_item item_id = read_uint16(data_item);

		/* Octets 2 and 3 are the data item length */
		uint16_t item_len = read_uint16(data_item + 2);

		/* Increment data_item to point to the data */
		data_item += 4;

		switch (item_id)
		{
		case DLEP_HEARTBEAT_INTERVAL_DATA_ITEM:
			*heartbeat_interval = read_uint32(data_item);
			printf("  Heartbeat Interval: %ums\n",*heartbeat_interval);
			break;

		case DLEP_PEER_TYPE_DATA_ITEM:
			printf("  Peer Type: '%.*s'%s\n",(int)item_len-1,data_item + 1,data_item[0] ? " - Secured Medium" : "");
			break;

		case DLEP_STATUS_DATA_ITEM:
			*sc = data_item[0];
			printf_status(*sc);
			break;

		case DLEP_MDRR_DATA_ITEM:
			printf("  Default MDDR: %"PRIu64"bps\n",read_uint64(data_item));
			break;

		case DLEP_MDRT_DATA_ITEM:
			printf("  Default MDDT: %"PRIu64"bps\n",read_uint64(data_item));
			break;

		case DLEP_CDRR_DATA_ITEM:
			printf("  Default CDDR: %"PRIu64"bps\n",read_uint64(data_item));
			break;

		case DLEP_CDRT_DATA_ITEM:
			printf("  Default CDDT: %"PRIu64"bps\n",read_uint64(data_item));
			break;

		case DLEP_LATENCY_DATA_ITEM:
			printf("  Default Latency: %"PRIu64"\x03\xBCs\n",read_uint64(data_item));
			break;

		case DLEP_RESOURCES_DATA_ITEM:
			printf("  Default Resources: %u%%\n",data_item[0]);
			break;

		case DLEP_RLQR_DATA_ITEM:
			printf("  Default RLQR: %u\n",data_item[0]);
			break;

		case DLEP_RLQT_DATA_ITEM:
			printf("  Default RLQT: %u\n",data_item[0]);
			break;

		case DLEP_MTU_DATA_ITEM:
			printf("  Default MTU: %"PRIu32"\n",read_uint32(data_item));
			break;

		case DLEP_EXTS_SUPP_DATA_ITEM:
			if (item_len > 0)
			{
				size_t i = 0;
				printf("  Extensions advertised by peer:\n");
				for (; i < item_len; i += 2)
				{
					printf("    Unknown DLEP extension %u (which we don't support)\n",read_uint16(data_item + i));
				}
			}
			break;

		case DLEP_IPV4_ADDRESS_DATA_ITEM:
		case DLEP_IPV6_ADDRESS_DATA_ITEM:
			printf("  Modem ");
			parse_address(data_item,item_len,0);
			break;

		case DLEP_IPV4_ATT_SUBNET_DATA_ITEM:
		case DLEP_IPV6_ATT_SUBNET_DATA_ITEM:
			printf("  Modem ");
			parse_attached_subnet(data_item,item_len,0);
			break;

		default:
			/* Others will be caught by the check function */
			break;
		}

		/* Increment data_item to point to the next data item */
		data_item += item_len;
	}
	return DLEP_SC_SUCCESS;
}
Beispiel #23
0
/**
 * Decode BMP data stored in 24bpp colour.
 *
 * \param bmp	the BMP image to decode
 * \param start	the data to decode, updated to last byte read on success
 * \param bytes	the number of bytes of data available
 * \return	BMP_OK on success
 *		BMP_INSUFFICIENT_DATA if the bitmap data ends unexpectedly;
 *			in this case, the image may be partially viewable
 */
static bmp_result bmp_decode_rgb24(bmp_image *bmp, uint8_t **start, int bytes) {
	uint8_t *top, *bottom, *end, *data;
	uint32_t *scanline;
	uint32_t x, y;
	uint32_t swidth, skip;
	intptr_t addr;
	uint8_t i;
	uint32_t word;

	data = *start;
	swidth = bmp->bitmap_callbacks.bitmap_get_bpp(bmp->bitmap) * bmp->width;
	top = bmp->bitmap_callbacks.bitmap_get_buffer(bmp->bitmap);
	if (!top)
		return BMP_INSUFFICIENT_MEMORY;
	bottom = top + (uint64_t)swidth * (bmp->height - 1);
	end = data + bytes;
	addr = ((intptr_t)data) & 3;
	skip = bmp->bpp >> 3;
	bmp->decoded = true;

	/* Determine transparent index */
	if (bmp->limited_trans) {
		if ((data + skip) > end)
			return BMP_INSUFFICIENT_DATA;
		if (bmp->encoding == BMP_ENCODING_BITFIELDS)
			bmp->transparent_index = read_uint32(data, 0);
		else
			bmp->transparent_index = data[2] | (data[1] << 8) | (data[0] << 16);
	}

	for (y = 0; y < bmp->height; y++) {
		while (addr != (((intptr_t)data) & 3))
			data++;
		if ((data + (skip * bmp->width)) > end)
			return BMP_INSUFFICIENT_DATA;
		if (bmp->reversed)
			scanline = (void *)(top + (y * swidth));
		else
			scanline = (void *)(bottom - (y * swidth));
		if (bmp->encoding == BMP_ENCODING_BITFIELDS) {
			for (x = 0; x < bmp->width; x++) {
				word = read_uint32(data, 0);
				for (i = 0; i < 4; i++)
					if (bmp->shift[i] > 0)
						scanline[x] |= ((word & bmp->mask[i]) << bmp->shift[i]);
					else
						scanline[x] |= ((word & bmp->mask[i]) >> (-bmp->shift[i]));
				/* 32-bit BMPs have alpha masks, but sometimes they're not utilized */
				if (bmp->opaque)
					scanline[x] |= (0xff << 24);
				data += skip;
				scanline[x] = read_uint32((uint8_t *)&scanline[x],0);
			}
		} else {
			for (x = 0; x < bmp->width; x++) {
				scanline[x] = data[2] | (data[1] << 8) | (data[0] << 16);
				if ((bmp->limited_trans) && (scanline[x] == bmp->transparent_index))
					scanline[x] = bmp->trans_colour;
				if (bmp->opaque)
					scanline[x] |= (0xff << 24);
				data += skip;
				scanline[x] = read_uint32((uint8_t *)&scanline[x],0);
			}
		}
	}
Beispiel #24
0
static void parse_destination_update_message(const uint8_t* data_items, uint16_t len)
{
	const uint8_t* data_item = data_items;

	printf("Received Destination Update message from modem:\n");

	/* The message has been validated so just scan for the relevant data_items */
	while (data_item < data_items + len)
	{
		/* Octets 0 and 1 are the data item type */
		enum dlep_data_item item_id = read_uint16(data_item);

		/* Octets 2 and 3 are the data item length */
		uint16_t item_len = read_uint16(data_item + 2);

		/* Increment data_item to point to the data */
		data_item += 4;

		switch (item_id)
		{
		case DLEP_MAC_ADDRESS_DATA_ITEM:
			printf("  MAC Address: %02X:%02X:%02X:%02X:%02X:%02X\n",data_item[0],data_item[1],data_item[2],data_item[3],data_item[4],data_item[5]);
			break;

		case DLEP_IPV4_ADDRESS_DATA_ITEM:
		case DLEP_IPV6_ADDRESS_DATA_ITEM:
			printf("  ");
			parse_address(data_item,item_len,1);
			break;

		case DLEP_IPV4_ATT_SUBNET_DATA_ITEM:
		case DLEP_IPV6_ATT_SUBNET_DATA_ITEM:
			printf("  ");
			parse_attached_subnet(data_item,item_len,1);
			break;

		case DLEP_MDRR_DATA_ITEM:
			printf("  MDDR: %"PRIu64"bps\n",read_uint64(data_item));
			break;

		case DLEP_MDRT_DATA_ITEM:
			printf("  MDDT: %"PRIu64"bps\n",read_uint64(data_item));
			break;

		case DLEP_CDRR_DATA_ITEM:
			printf("  CDDR: %"PRIu64"bps\n",read_uint64(data_item));
			break;

		case DLEP_CDRT_DATA_ITEM:
			printf("  CDDT: %"PRIu64"bps\n",read_uint64(data_item));
			break;

		case DLEP_LATENCY_DATA_ITEM:
			printf("  Latency: %"PRIu64"\x03\xBCs\n",read_uint64(data_item));
			break;

		case DLEP_RESOURCES_DATA_ITEM:
			printf("  Resources (Receive): %u%%\n",data_item[0]);
			break;

		case DLEP_RLQR_DATA_ITEM:
			printf("  RLQR: %u\n",data_item[0]);
			break;

		case DLEP_RLQT_DATA_ITEM:
			printf("  RLQT: %u\n",data_item[0]);
			break;

		case DLEP_MTU_DATA_ITEM:
			printf("  MTU: %"PRIu32"\n",read_uint32(data_item));
			break;

		default:
			/* Others will be caught by the check function */
			break;
		}

		/* Increment data_item to point to the next data item */
		data_item += item_len;
	}
}
Beispiel #25
0
int opus_header_parse(const unsigned char *packet, int len, OpusHeader *h)
{
    char str[9];
    ROPacket p;
    unsigned char ch;
    uint16_t shortval;

    p.data = packet;
    p.maxlen = len;
    p.pos = 0;
    str[8] = 0;
    if (len<19)return 0;
    read_chars(&p, (unsigned char*)str, 8);
    if (memcmp(str, "OpusHead", 8)!=0)
        return 0;

    if (!read_chars(&p, &ch, 1))
        return 0;
    h->version = ch;
    if((h->version&240) != 0) /* Only major version 0 supported. */
        return 0;

    if (!read_chars(&p, &ch, 1))
        return 0;
    h->channels = ch;
    if (h->channels == 0)
        return 0;

    if (!read_uint16(&p, &shortval))
        return 0;
    h->preskip = shortval;

    if (!read_uint32(&p, &h->input_sample_rate))
        return 0;

    if (!read_uint16(&p, &shortval))
        return 0;
    h->gain = (short)shortval;

    if (!read_chars(&p, &ch, 1))
        return 0;
    h->channel_mapping = ch;

    if (h->channel_mapping != 0)
    {
        if (!read_chars(&p, &ch, 1))
            return 0;

        if (ch<1)
            return 0;
        h->nb_streams = ch;

        if (!read_chars(&p, &ch, 1))
            return 0;

        if (ch>h->nb_streams || (ch+h->nb_streams)>255)
            return 0;
        h->nb_coupled = ch;

        /* Multi-stream support */
        for (int i=0;i<h->channels;i++)
        {
            if (!read_chars(&p, &h->stream_map[i], 1))
                return 0;
            if (h->stream_map[i]>(h->nb_streams+h->nb_coupled) && h->stream_map[i]!=255)
                return 0;
        }
    } else {
        if(h->channels>2)
            return 0;
        h->nb_streams = 1;
        h->nb_coupled = h->channels>1;
        h->stream_map[0]=0;
        h->stream_map[1]=1;
    }
    /*For version 0/1 we know there won't be any more data
      so reject any that have data past the end.*/
    if ((h->version==0 || h->version==1) && p.pos != len)
        return 0;
    return 1;
}
Beispiel #26
0
/**
 * Wraps a CDB mass storage command in the appropriate gunk to get it down
 * @param handle
 * @param endpoint
 * @param cdb
 * @param cdb_length
 * @param lun
 * @param flags
 * @param expected_rx_size
 * @return
 */
int send_usb_mass_storage_command(libusb_device_handle *handle, uint8_t endpoint_out,
        uint8_t *cdb, uint8_t cdb_length,
        uint8_t lun, uint8_t flags, uint32_t expected_rx_size) {
    DLOG("Sending usb m-s cmd: cdblen:%d, rxsize=%d\n", cdb_length, expected_rx_size);
    dump_CDB_command(cdb, cdb_length);

    static uint32_t tag;
    if (tag == 0) {
        tag = 1;
    }

    int try = 0;
    int ret = 0;
    int real_transferred;
    int i = 0;

    uint8_t c_buf[STLINK_SG_SIZE];
    // tag is allegedly ignored... TODO - verify
    c_buf[i++] = 'U';
    c_buf[i++] = 'S';
    c_buf[i++] = 'B';
    c_buf[i++] = 'C';
    write_uint32(&c_buf[i], tag);
    uint32_t this_tag = tag++;
    write_uint32(&c_buf[i+4], expected_rx_size);
    i+= 8;
    c_buf[i++] = flags;
    c_buf[i++] = lun;

    c_buf[i++] = cdb_length;

    // Now the actual CDB request
    assert(cdb_length <= CDB_SL);
    memcpy(&(c_buf[i]), cdb, cdb_length);

    int sending_length = STLINK_SG_SIZE;

    // send....
    do {
        ret = libusb_bulk_transfer(handle, endpoint_out, c_buf, sending_length,
                &real_transferred, SG_TIMEOUT_MSEC);
        if (ret == LIBUSB_ERROR_PIPE) {
            libusb_clear_halt(handle, endpoint_out);
        }
        try++;
    } while ((ret == LIBUSB_ERROR_PIPE) && (try < 3));
    if (ret != LIBUSB_SUCCESS) {
        WLOG("sending failed: %d\n", ret);
        return -1;
    }
    return this_tag;
}


/**
 * Straight from stm8 stlink code...
 * @param handle
 * @param endpoint_in
 * @param endpoint_out
 */
    static void
get_sense(libusb_device_handle *handle, uint8_t endpoint_in, uint8_t endpoint_out)
{
    DLOG("Fetching sense...\n");
    uint8_t cdb[16];
    memset(cdb, 0, sizeof(cdb));
#define REQUEST_SENSE 0x03
#define REQUEST_SENSE_LENGTH 18
    cdb[0] = REQUEST_SENSE;
    cdb[4] = REQUEST_SENSE_LENGTH;
    uint32_t tag = send_usb_mass_storage_command(handle, endpoint_out, cdb, sizeof(cdb), 0,
            LIBUSB_ENDPOINT_IN, REQUEST_SENSE_LENGTH);
    if (tag == 0) {
        WLOG("refusing to send request sense with tag 0\n");
        return;
    }
    unsigned char sense[REQUEST_SENSE_LENGTH];
    int transferred;
    int ret;
    int try = 0;
    do {
        ret = libusb_bulk_transfer(handle, endpoint_in, sense, sizeof(sense),
                &transferred, SG_TIMEOUT_MSEC);
        if (ret == LIBUSB_ERROR_PIPE) {
            libusb_clear_halt(handle, endpoint_in);
        }
        try++;
    } while ((ret == LIBUSB_ERROR_PIPE) && (try < 3));
    if (ret != LIBUSB_SUCCESS) {
        WLOG("receiving sense failed: %d\n", ret);
        return;
    }
    if (transferred != sizeof(sense)) {
        WLOG("received unexpected amount of sense: %d != %d\n", transferred, sizeof(sense));
    }
    uint32_t received_tag;
    int status = get_usb_mass_storage_status(handle, endpoint_in, &received_tag);
    if (status != 0) {
        WLOG("receiving sense failed with status: %02x\n", status);
        return;
    }
    if (sense[0] != 0x70 && sense[0] != 0x71) {
        WLOG("No sense data\n");
    } else {
        WLOG("Sense KCQ: %02X %02X %02X\n", sense[2] & 0x0f, sense[12], sense[13]);
    }
}

/**
 * Just send a buffer on an endpoint, no questions asked.
 * Handles repeats, and time outs.  Also handles reading status reports and sense
 * @param handle libusb device *
 * @param endpoint_out sends
 * @param endpoint_in used to read status reports back in
 * @param cbuf  what to send
 * @param length how much to send
 * @return number of bytes actually sent, or -1 for failures.
 */
int send_usb_data_only(libusb_device_handle *handle, unsigned char endpoint_out,
        unsigned char endpoint_in, unsigned char *cbuf, unsigned int length) {
    int ret;
    int real_transferred;
    int try = 0;
    do {
        ret = libusb_bulk_transfer(handle, endpoint_out, cbuf, length,
                &real_transferred, SG_TIMEOUT_MSEC);
        if (ret == LIBUSB_ERROR_PIPE) {
            libusb_clear_halt(handle, endpoint_out);
        }
        try++;
    } while ((ret == LIBUSB_ERROR_PIPE) && (try < 3));
    if (ret != LIBUSB_SUCCESS) {
        WLOG("sending failed: %d\n", ret);
        return -1;
    }

    // now, swallow up the status, so that things behave nicely...
    uint32_t received_tag;
    // -ve is for my errors, 0 is good, +ve is libusb sense status bytes
    int status = get_usb_mass_storage_status(handle, endpoint_in, &received_tag);
    if (status < 0) {
        WLOG("receiving status failed: %d\n", status);
        return -1;
    }
    if (status != 0) {
        WLOG("receiving status not passed :(: %02x\n", status);
    }
    if (status == 1) {
        get_sense(handle, endpoint_in, endpoint_out);
        return -1;
    }

    return real_transferred;
}


int stlink_q(stlink_t *sl) {
    struct stlink_libsg* sg = sl->backend_data;
    //uint8_t cdb_len = 6;  // FIXME varies!!!
    uint8_t cdb_len = 10;  // FIXME varies!!!
    uint8_t lun = 0;  // always zero...
    uint32_t tag = send_usb_mass_storage_command(sg->usb_handle, sg->ep_req,
            sg->cdb_cmd_blk, cdb_len, lun, LIBUSB_ENDPOINT_IN, sl->q_len);


    // now wait for our response...
    // length copied from stlink-usb...
    int rx_length = sl->q_len;
    int try = 0;
    int real_transferred;
    int ret;
    if (rx_length > 0) {
        do {
            ret = libusb_bulk_transfer(sg->usb_handle, sg->ep_rep, sl->q_buf, rx_length,
                    &real_transferred, SG_TIMEOUT_MSEC);
            if (ret == LIBUSB_ERROR_PIPE) {
                libusb_clear_halt(sg->usb_handle, sg->ep_req);
            }
            try++;
        } while ((ret == LIBUSB_ERROR_PIPE) && (try < 3));

        if (ret != LIBUSB_SUCCESS) {
            WLOG("Receiving failed: %d\n", ret);
            return -1;
        }

        if (real_transferred != rx_length) {
            WLOG("received unexpected amount: %d != %d\n", real_transferred, rx_length);
        }
    }

    uint32_t received_tag;
    // -ve is for my errors, 0 is good, +ve is libusb sense status bytes
    int status = get_usb_mass_storage_status(sg->usb_handle, sg->ep_rep, &received_tag);
    if (status < 0) {
        WLOG("receiving status failed: %d\n", status);
        return -1;
    }
    if (status != 0) {
        WLOG("receiving status not passed :(: %02x\n", status);
    }
    if (status == 1) {
        get_sense(sg->usb_handle, sg->ep_rep, sg->ep_req);
        return -1;
    }
    if (received_tag != tag) {
        WLOG("received tag %d but expected %d\n", received_tag, tag);
        //return -1;
    }
    if (rx_length > 0 && real_transferred != rx_length) {
        return -1;
    }
    return 0;
}

// TODO thinking, cleanup

void stlink_stat(stlink_t *stl, char *txt) {
    if (stl->q_len <= 0)
        return;

    stlink_print_data(stl);

    switch (stl->q_buf[0]) {
    case STLINK_OK:
        DLOG("  %s: ok\n", txt);
        return;
    case STLINK_FALSE:
        DLOG("  %s: false\n", txt);
        return;
    default:
        DLOG("  %s: unknown\n", txt);
    }
}


int _stlink_sg_version(stlink_t *stl) {
    struct stlink_libsg *sl = stl->backend_data;
    clear_cdb(sl);
    sl->cdb_cmd_blk[0] = STLINK_GET_VERSION;
    stl->q_len = 6;
    sl->q_addr = 0;
    return stlink_q(stl);
}

// Get stlink mode:
// STLINK_DEV_DFU_MODE || STLINK_DEV_MASS_MODE || STLINK_DEV_DEBUG_MODE
// usb dfu             || usb mass             || jtag or swd

int _stlink_sg_current_mode(stlink_t *stl) {
    struct stlink_libsg *sl = stl->backend_data;
    clear_cdb(sl);
    sl->cdb_cmd_blk[0] = STLINK_GET_CURRENT_MODE;
    stl->q_len = 2;
    sl->q_addr = 0;
    if (stlink_q(stl))
        return -1;

    return stl->q_buf[0];
}

// Exit the mass mode and enter the swd debug mode.

int _stlink_sg_enter_swd_mode(stlink_t *sl) {
    struct stlink_libsg *sg = sl->backend_data;
    clear_cdb(sg);
    sg->cdb_cmd_blk[1] = STLINK_DEBUG_ENTER;
    sg->cdb_cmd_blk[2] = STLINK_DEBUG_ENTER_SWD;
    sl->q_len = 0; // >0 -> aboard
    return stlink_q(sl);
}

// Exit the mass mode and enter the jtag debug mode.
// (jtag is disabled in the discovery's stlink firmware)

int _stlink_sg_enter_jtag_mode(stlink_t *sl) {
    struct stlink_libsg *sg = sl->backend_data;
    DLOG("\n*** stlink_enter_jtag_mode ***\n");
    clear_cdb(sg);
    sg->cdb_cmd_blk[1] = STLINK_DEBUG_ENTER;
    sg->cdb_cmd_blk[2] = STLINK_DEBUG_ENTER_JTAG;
    sl->q_len = 0;
    return stlink_q(sl);
}

// XXX kernel driver performs reset, the device temporally disappears
// Suspect this is no longer the case when we have ignore on? RECHECK
int _stlink_sg_exit_dfu_mode(stlink_t *sl) {
    struct stlink_libsg *sg = sl->backend_data;
    DLOG("\n*** stlink_exit_dfu_mode ***\n");
    clear_cdb(sg);
    sg->cdb_cmd_blk[0] = STLINK_DFU_COMMAND;
    sg->cdb_cmd_blk[1] = STLINK_DFU_EXIT;
    sl->q_len = 0; // ??
    return stlink_q(sl);
    /*
       [135121.844564] sd 19:0:0:0: [sdb] Unhandled error code
       [135121.844569] sd 19:0:0:0: [sdb] Result: hostbyte=DID_ERROR driverbyte=DRIVER_OK
       [135121.844574] sd 19:0:0:0: [sdb] CDB: Read(10): 28 00 00 00 10 00 00 00 08 00
       [135121.844584] end_request: I/O error, dev sdb, sector 4096
       [135121.844590] Buffer I/O error on device sdb, logical block 512
       [135130.122567] usb 6-1: reset full speed USB device using uhci_hcd and address 7
       [135130.274551] usb 6-1: device firmware changed
       [135130.274618] usb 6-1: USB disconnect, address 7
       [135130.275186] VFS: busy inodes on changed media or resized disk sdb
       [135130.275424] VFS: busy inodes on changed media or resized disk sdb
       [135130.286758] VFS: busy inodes on changed media or resized disk sdb
       [135130.292796] VFS: busy inodes on changed media or resized disk sdb
       [135130.301481] VFS: busy inodes on changed media or resized disk sdb
       [135130.304316] VFS: busy inodes on changed media or resized disk sdb
       [135130.431113] usb 6-1: new full speed USB device using uhci_hcd and address 8
       [135130.629444] usb-storage 6-1:1.0: Quirks match for vid 0483 pid 3744: 102a1
       [135130.629492] scsi20 : usb-storage 6-1:1.0
       [135131.625600] scsi 20:0:0:0: Direct-Access     STM32                          PQ: 0 ANSI: 0
       [135131.627010] sd 20:0:0:0: Attached scsi generic sg2 type 0
       [135131.633603] sd 20:0:0:0: [sdb] 64000 512-byte logical blocks: (32.7 MB/31.2 MiB)
       [135131.633613] sd 20:0:0:0: [sdb] Assuming Write Enabled
       [135131.633620] sd 20:0:0:0: [sdb] Assuming drive cache: write through
       [135131.640584] sd 20:0:0:0: [sdb] Assuming Write Enabled
       [135131.640592] sd 20:0:0:0: [sdb] Assuming drive cache: write through
       [135131.640609]  sdb:
       [135131.652634] sd 20:0:0:0: [sdb] Assuming Write Enabled
       [135131.652639] sd 20:0:0:0: [sdb] Assuming drive cache: write through
       [135131.652645] sd 20:0:0:0: [sdb] Attached SCSI removable disk
       [135131.671536] sd 20:0:0:0: [sdb] Result: hostbyte=DID_OK driverbyte=DRIVER_SENSE
       [135131.671548] sd 20:0:0:0: [sdb] Sense Key : Illegal Request [current]
       [135131.671553] sd 20:0:0:0: [sdb] Add. Sense: Logical block address out of range
       [135131.671560] sd 20:0:0:0: [sdb] CDB: Read(10): 28 00 00 00 f9 80 00 00 08 00
       [135131.671570] end_request: I/O error, dev sdb, sector 63872
       [135131.671575] Buffer I/O error on device sdb, logical block 7984
       [135131.678527] sd 20:0:0:0: [sdb] Result: hostbyte=DID_OK driverbyte=DRIVER_SENSE
       [135131.678532] sd 20:0:0:0: [sdb] Sense Key : Illegal Request [current]
       [135131.678537] sd 20:0:0:0: [sdb] Add. Sense: Logical block address out of range
       [135131.678542] sd 20:0:0:0: [sdb] CDB: Read(10): 28 00 00 00 f9 80 00 00 08 00
       [135131.678551] end_request: I/O error, dev sdb, sector 63872
       ...
       [135131.853565] end_request: I/O error, dev sdb, sector 4096
       */
}

int _stlink_sg_core_id(stlink_t *sl) {
    struct stlink_libsg *sg = sl->backend_data;
    int ret;
    clear_cdb(sg);
    sg->cdb_cmd_blk[1] = STLINK_DEBUG_READCOREID;
    sl->q_len = 4;
    sg->q_addr = 0;
    ret = stlink_q(sl);
    if (ret)
        return ret;

    sl->core_id = read_uint32(sl->q_buf, 0);
    return 0;
}

// Arm-core reset -> halted state.

int _stlink_sg_reset(stlink_t *sl) {
    struct stlink_libsg *sg = sl->backend_data;
    clear_cdb(sg);
    sg->cdb_cmd_blk[1] = STLINK_DEBUG_RESETSYS;
    sl->q_len = 2;
    sg->q_addr = 0;
    if (stlink_q(sl))
        return -1;

    stlink_stat(sl, "core reset");
    return 0;
}

// Arm-core reset -> halted state.

int _stlink_sg_jtag_reset(stlink_t *sl, int value) {
    struct stlink_libsg *sg = sl->backend_data;
    clear_cdb(sg);
    sg->cdb_cmd_blk[1] = STLINK_JTAG_DRIVE_NRST;
    sg->cdb_cmd_blk[2] = (value)?0:1;
    sl->q_len = 3;
    sg->q_addr = 2;
    if (stlink_q(sl))
        return -1;

    stlink_stat(sl, "core reset");

    return 0;
}

// Arm-core status: halted or running.

int _stlink_sg_status(stlink_t *sl) {
    struct stlink_libsg *sg = sl->backend_data;
    clear_cdb(sg);
    sg->cdb_cmd_blk[1] = STLINK_DEBUG_GETSTATUS;
    sl->q_len = 2;
    sg->q_addr = 0;
    return stlink_q(sl);
}

// Force the core into the debug mode -> halted state.

int _stlink_sg_force_debug(stlink_t *sl) {
    struct stlink_libsg *sg = sl->backend_data;
    clear_cdb(sg);
    sg->cdb_cmd_blk[1] = STLINK_DEBUG_FORCEDEBUG;
    sl->q_len = 2;
    sg->q_addr = 0;
    if (stlink_q(sl))
        return -1;

    stlink_stat(sl, "force debug");
    return 0;
}

// Read all arm-core registers.

int _stlink_sg_read_all_regs(stlink_t *sl, reg *regp) {
    struct stlink_libsg *sg = sl->backend_data;

    clear_cdb(sg);
    sg->cdb_cmd_blk[1] = STLINK_DEBUG_READALLREGS;
    sl->q_len = 84;
    sg->q_addr = 0;
    if (stlink_q(sl))
        return -1;

    stlink_print_data(sl);

    // TODO - most of this should be re-extracted up....

    // 0-3 | 4-7 | ... | 60-63 | 64-67 | 68-71   | 72-75      | 76-79 | 80-83
    // r0  | r1  | ... | r15   | xpsr  | main_sp | process_sp | rw    | rw2
    for (int i = 0; i < 16; i++) {
        regp->r[i] = read_uint32(sl->q_buf, 4 * i);
        if (sl->verbose > 1)
            DLOG("r%2d = 0x%08x\n", i, regp->r[i]);
    }
    regp->xpsr = read_uint32(sl->q_buf, 64);
    regp->main_sp = read_uint32(sl->q_buf, 68);
    regp->process_sp = read_uint32(sl->q_buf, 72);
    regp->rw = read_uint32(sl->q_buf, 76);
    regp->rw2 = read_uint32(sl->q_buf, 80);
    if (sl->verbose < 2)
        return 0;

    DLOG("xpsr       = 0x%08x\n", regp->xpsr);
    DLOG("main_sp    = 0x%08x\n", regp->main_sp);
    DLOG("process_sp = 0x%08x\n", regp->process_sp);
    DLOG("rw         = 0x%08x\n", regp->rw);
    DLOG("rw2        = 0x%08x\n", regp->rw2);

    return 0;
}

// Read an arm-core register, the index must be in the range 0..20.
//  0  |  1  | ... |  15   |  16   |   17    |   18       |  19   |  20
// r0  | r1  | ... | r15   | xpsr  | main_sp | process_sp | rw    | rw2

int _stlink_sg_read_reg(stlink_t *sl, int r_idx, reg *regp) {
    struct stlink_libsg *sg = sl->backend_data;
    clear_cdb(sg);
    sg->cdb_cmd_blk[1] = STLINK_DEBUG_READREG;
    sg->cdb_cmd_blk[2] = r_idx;
    sl->q_len = 4;
    sg->q_addr = 0;
    if (stlink_q(sl))
        return -1;

    //  0  |  1  | ... |  15   |  16   |   17    |   18       |  19   |  20
    // 0-3 | 4-7 | ... | 60-63 | 64-67 | 68-71   | 72-75      | 76-79 | 80-83
    // r0  | r1  | ... | r15   | xpsr  | main_sp | process_sp | rw    | rw2
    stlink_print_data(sl);

    uint32_t r = read_uint32(sl->q_buf, 0);
    DLOG("r_idx (%2d) = 0x%08x\n", r_idx, r);

    switch (r_idx) {
    case 16:
        regp->xpsr = r;
        break;
    case 17:
        regp->main_sp = r;
        break;
    case 18:
        regp->process_sp = r;
        break;
    case 19:
        regp->rw = r; //XXX ?(primask, basemask etc.)
        break;
    case 20:
        regp->rw2 = r; //XXX ?(primask, basemask etc.)
        break;
    default:
        regp->r[r_idx] = r;
    }

    return 0;
}

// Write an arm-core register. Index:
//  0  |  1  | ... |  15   |  16   |   17    |   18       |  19   |  20
// r0  | r1  | ... | r15   | xpsr  | main_sp | process_sp | rw    | rw2

int _stlink_sg_write_reg(stlink_t *sl, uint32_t reg, int idx) {
    struct stlink_libsg *sg = sl->backend_data;
    clear_cdb(sg);
    sg->cdb_cmd_blk[1] = STLINK_DEBUG_WRITEREG;
    //   2: reg index
    // 3-6: reg content
    sg->cdb_cmd_blk[2] = idx;
    write_uint32(sg->cdb_cmd_blk + 3, reg);
    sl->q_len = 2;
    sg->q_addr = 0;
    if (stlink_q(sl))
        return -1;

    stlink_stat(sl, "write reg");
    return 0;
}

// Write a register of the debug module of the core.
// XXX ?(atomic writes)
// TODO test

void stlink_write_dreg(stlink_t *sl, uint32_t reg, uint32_t addr) {
    struct stlink_libsg *sg = sl->backend_data;
    DLOG("\n*** stlink_write_dreg ***\n");
    clear_cdb(sg);
    sg->cdb_cmd_blk[1] = STLINK_DEBUG_WRITEDEBUGREG;
    // 2-5: address of reg of the debug module
    // 6-9: reg content
    write_uint32(sg->cdb_cmd_blk + 2, addr);
    write_uint32(sg->cdb_cmd_blk + 6, reg);
    sl->q_len = 2;
    sg->q_addr = addr;
    stlink_q(sl);
    stlink_stat(sl, "write debug reg");
}

// Force the core exit the debug mode.

int _stlink_sg_run(stlink_t *sl) {
    struct stlink_libsg *sg = sl->backend_data;
    clear_cdb(sg);
    sg->cdb_cmd_blk[1] = STLINK_DEBUG_RUNCORE;
    sl->q_len = 2;
    sg->q_addr = 0;
    if (stlink_q(sl))
        return -1;

    stlink_stat(sl, "run core");

    return 0;
}

// Step the arm-core.

int _stlink_sg_step(stlink_t *sl) {
    struct stlink_libsg *sg = sl->backend_data;
    clear_cdb(sg);
    sg->cdb_cmd_blk[1] = STLINK_DEBUG_STEPCORE;
    sl->q_len = 2;
    sg->q_addr = 0;
    if (stlink_q(sl))
        return -1;

    stlink_stat(sl, "step core");
    return 0;
}

// TODO test
// see Cortex-M3 Technical Reference Manual
// TODO make delegate!
void stlink_set_hw_bp(stlink_t *sl, int fp_nr, uint32_t addr, int fp) {
    DLOG("\n*** stlink_set_hw_bp ***\n");
    struct stlink_libsg *sg = sl->backend_data;
    clear_cdb(sg);
    sg->cdb_cmd_blk[1] = STLINK_DEBUG_SETFP;
    // 2:The number of the flash patch used to set the breakpoint
    // 3-6: Address of the breakpoint (LSB)
    // 7: FP_ALL (0x02) / FP_UPPER (0x01) / FP_LOWER (0x00)
    sl->q_buf[2] = fp_nr;
    write_uint32(sl->q_buf, addr);
    sl->q_buf[7] = fp;

    sl->q_len = 2;
    stlink_q(sl);
    stlink_stat(sl, "set flash breakpoint");
}

// TODO test

// TODO make delegate!
void stlink_clr_hw_bp(stlink_t *sl, int fp_nr) {
    struct stlink_libsg *sg = sl->backend_data;
    DLOG("\n*** stlink_clr_hw_bp ***\n");
    clear_cdb(sg);
    sg->cdb_cmd_blk[1] = STLINK_DEBUG_CLEARFP;
    sg->cdb_cmd_blk[2] = fp_nr;

    sl->q_len = 2;
    stlink_q(sl);
    stlink_stat(sl, "clear flash breakpoint");
}

// Read a "len" bytes to the sl->q_buf from the memory, max 6kB (6144 bytes)

int _stlink_sg_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len) {
    struct stlink_libsg *sg = sl->backend_data;
    clear_cdb(sg);
    sg->cdb_cmd_blk[1] = STLINK_DEBUG_READMEM_32BIT;
    // 2-5: addr
    // 6-7: len
    write_uint32(sg->cdb_cmd_blk + 2, addr);
    write_uint16(sg->cdb_cmd_blk + 6, len);

    // data_in 0-0x40-len
    // !!! len _and_ q_len must be max 6k,
    //     i.e. >1024 * 6 = 6144 -> aboard)
    // !!! if len < q_len: 64*k, 1024*n, n=1..5  -> aboard
    //     (broken residue issue)
    sl->q_len = len;
    sg->q_addr = addr;
    if (stlink_q(sl))
        return -1;

    stlink_print_data(sl);
    return 0;
}

// Write a "len" bytes from the sl->q_buf to the memory, max 64 Bytes.

int _stlink_sg_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len) {
    struct stlink_libsg *sg = sl->backend_data;
    int ret;

    clear_cdb(sg);
    sg->cdb_cmd_blk[1] = STLINK_DEBUG_WRITEMEM_8BIT;
    // 2-5: addr
    // 6-7: len (>0x40 (64) -> aboard)
    write_uint32(sg->cdb_cmd_blk + 2, addr);
    write_uint16(sg->cdb_cmd_blk + 6, len);

    // this sends the command...
    ret = send_usb_mass_storage_command(sg->usb_handle,
            sg->ep_req, sg->cdb_cmd_blk, CDB_SL, 0, 0, 0);
    if (ret == -1)
        return ret;

    // This sends the data...
    ret = send_usb_data_only(sg->usb_handle,
            sg->ep_req, sg->ep_rep, sl->q_buf, len);
    if (ret == -1)
        return ret;

    stlink_print_data(sl);
    return 0;
}

// Write a "len" bytes from the sl->q_buf to the memory, max Q_BUF_LEN bytes.

int _stlink_sg_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len) {
    struct stlink_libsg *sg = sl->backend_data;
    int ret;

    clear_cdb(sg);
    sg->cdb_cmd_blk[1] = STLINK_DEBUG_WRITEMEM_32BIT;
    // 2-5: addr
    // 6-7: len "unlimited"
    write_uint32(sg->cdb_cmd_blk + 2, addr);
    write_uint16(sg->cdb_cmd_blk + 6, len);

    // this sends the command...
    ret = send_usb_mass_storage_command(sg->usb_handle,
            sg->ep_req, sg->cdb_cmd_blk, CDB_SL, 0, 0, 0);
    if (ret == -1)
        return ret;

    // This sends the data...
    ret = send_usb_data_only(sg->usb_handle,
            sg->ep_req, sg->ep_rep, sl->q_buf, len);
    if (ret == -1)
        return ret;

    stlink_print_data(sl);
    return 0;
}

// Write one DWORD data to memory

int _stlink_sg_write_debug32(stlink_t *sl, uint32_t addr, uint32_t data) {
    struct stlink_libsg *sg = sl->backend_data;
    clear_cdb(sg);
    sg->cdb_cmd_blk[1] = STLINK_JTAG_WRITEDEBUG_32BIT;
    // 2-5: addr
    write_uint32(sg->cdb_cmd_blk + 2, addr);
    write_uint32(sg->cdb_cmd_blk + 6, data);
    sl->q_len = 2;
    return stlink_q(sl);
}

// Read one DWORD data from memory

int _stlink_sg_read_debug32(stlink_t *sl, uint32_t addr, uint32_t *data) {
    struct stlink_libsg *sg = sl->backend_data;
    clear_cdb(sg);
    sg->cdb_cmd_blk[1] = STLINK_JTAG_READDEBUG_32BIT;
    // 2-5: addr
    write_uint32(sg->cdb_cmd_blk + 2, addr);
    sl->q_len = 8;
    if (stlink_q(sl))
        return -1;

    *data = read_uint32(sl->q_buf, 4);
    return 0;
}

// Exit the jtag or swd mode and enter the mass mode.

int _stlink_sg_exit_debug_mode(stlink_t *stl)
{
    if (stl) {
        struct stlink_libsg* sl = stl->backend_data;
        clear_cdb(sl);
        sl->cdb_cmd_blk[1] = STLINK_DEBUG_EXIT;
        stl->q_len = 0; // >0 -> aboard
        return stlink_q(stl);
    }

    return 0;
}


// 1) open a sg device, switch the stlink from dfu to mass mode
// 2) wait 5s until the kernel driver stops reseting the broken device
// 3) reopen the device
// 4) the device driver is now ready for a switch to jtag/swd mode
// TODO thinking, better error handling, wait until the kernel driver stops reseting the plugged-in device

stlink_backend_t _stlink_sg_backend = {
    _stlink_sg_close,
    _stlink_sg_exit_debug_mode,
    _stlink_sg_enter_swd_mode,
    _stlink_sg_enter_jtag_mode,
    _stlink_sg_exit_dfu_mode,
    _stlink_sg_core_id,
    _stlink_sg_reset,
    _stlink_sg_jtag_reset,
    _stlink_sg_run,
    _stlink_sg_status,
    _stlink_sg_version,
    _stlink_sg_read_debug32,
    _stlink_sg_read_mem32,
    _stlink_sg_write_debug32,
    _stlink_sg_write_mem32,
    _stlink_sg_write_mem8,
    _stlink_sg_read_all_regs,
    _stlink_sg_read_reg,
    NULL,                   /* read_all_unsupported_regs */
    NULL,                   /* read_unsupported_regs */
    NULL,                   /* write_unsupported_regs */
    _stlink_sg_write_reg,
    _stlink_sg_step,
    _stlink_sg_current_mode,
    _stlink_sg_force_debug,
    NULL
};

static stlink_t* stlink_open(const int verbose) {

    stlink_t *sl = malloc(sizeof (stlink_t));
    memset(sl, 0, sizeof(stlink_t));
    struct stlink_libsg *slsg = malloc(sizeof (struct stlink_libsg));
    if (sl == NULL || slsg == NULL) {
        WLOG("Couldn't malloc stlink and stlink_sg structures out of memory!\n");
        return NULL;
    }

    if (libusb_init(&(slsg->libusb_ctx))) {
        WLOG("failed to init libusb context, wrong version of libraries?\n");
        free(sl);
        free(slsg);
        return NULL;
    }

    libusb_set_debug(slsg->libusb_ctx, 3);

    slsg->usb_handle = libusb_open_device_with_vid_pid(slsg->libusb_ctx, USB_ST_VID, USB_STLINK_PID);
    if (slsg->usb_handle == NULL) {
        WLOG("Failed to find an stlink v1 by VID:PID\n");
        libusb_close(slsg->usb_handle);
        libusb_exit(slsg->libusb_ctx);
        free(sl);
        free(slsg);
        return NULL;
    }

    // TODO
    // Could read the interface config descriptor, and assert lots of the assumptions

    // assumption: numInterfaces is always 1...
    if (libusb_kernel_driver_active(slsg->usb_handle, 0) == 1) {
        int r = libusb_detach_kernel_driver(slsg->usb_handle, 0);
        if (r < 0) {
            WLOG("libusb_detach_kernel_driver(() error %s\n", strerror(-r));
            libusb_close(slsg->usb_handle);
            libusb_exit(slsg->libusb_ctx);
            free(sl);
            free(slsg);
            return NULL;
        }
        DLOG("Kernel driver was successfully detached\n");
    }

    int config;
    if (libusb_get_configuration(slsg->usb_handle, &config)) {
        /* this may fail for a previous configured device */
        WLOG("libusb_get_configuration()\n");
        libusb_close(slsg->usb_handle);
        libusb_exit(slsg->libusb_ctx);
        free(sl);
        free(slsg);
        return NULL;

    }

    // assumption: bConfigurationValue is always 1
    if (config != 1) {
        WLOG("Your stlink got into a real weird configuration, trying to fix it!\n");
        DLOG("setting new configuration (%d -> 1)\n", config);
        if (libusb_set_configuration(slsg->usb_handle, 1)) {
            /* this may fail for a previous configured device */
            WLOG("libusb_set_configuration() failed\n");
            libusb_close(slsg->usb_handle);
            libusb_exit(slsg->libusb_ctx);
            free(sl);
            free(slsg);
            return NULL;
        }
    }

    if (libusb_claim_interface(slsg->usb_handle, 0)) {
        WLOG("libusb_claim_interface() failed\n");
        libusb_close(slsg->usb_handle);
        libusb_exit(slsg->libusb_ctx);
        free(sl);
        free(slsg);
        return NULL;
    }

    // assumption: endpoint config is fixed mang. really.
    slsg->ep_rep = 1 /* ep rep */ | LIBUSB_ENDPOINT_IN;
    slsg->ep_req = 2 /* ep req */ | LIBUSB_ENDPOINT_OUT;

    DLOG("Successfully opened stlinkv1 by libusb :)\n");

    sl->verbose = verbose;
    sl->backend_data = slsg;
    sl->backend = &_stlink_sg_backend;

    sl->core_stat = STLINK_CORE_STAT_UNKNOWN;
    slsg->q_addr = 0;

    return sl;
}
Beispiel #27
0
vba_project_t *
cli_vba_readdir(const char *dir, struct uniq *U, uint32_t which)
{
	unsigned char *buf;
	const unsigned char vba56_signature[] = { 0xcc, 0x61 };
	uint16_t record_count, buflen, ffff, byte_count;
	uint32_t offset;
	int i, j, fd, big_endian = FALSE;
	vba_project_t *vba_project;
	struct vba56_header v56h;
	off_t seekback;
	char fullname[1024], *hash;

	cli_dbgmsg("in cli_vba_readdir()\n");

	if(dir == NULL)
		return NULL;

	/*
	 * _VBA_PROJECT files are embedded within office documents (OLE2)
	 */
	
	if (!uniq_get(U, "_vba_project", 12, &hash))
		return NULL;
	snprintf(fullname, sizeof(fullname), "%s"PATHSEP"%s_%u", dir, hash, which);
	fullname[sizeof(fullname)-1] = '\0';
	fd = open(fullname, O_RDONLY|O_BINARY);

	if(fd == -1)
		return NULL;

	if(cli_readn(fd, &v56h, sizeof(struct vba56_header)) != sizeof(struct vba56_header)) {
		close(fd);
		return NULL;
	}
	if (memcmp(v56h.magic, vba56_signature, sizeof(v56h.magic)) != 0) {
		close(fd);
		return NULL;
	}

	i = vba_read_project_strings(fd, TRUE);
	if ((seekback = lseek(fd, 0, SEEK_CUR)) == -1) {
		cli_dbgmsg("vba_readdir: lseek() failed. Unable to guess VBA type\n");
		close(fd);
		return NULL;
	}
	if (lseek(fd, sizeof(struct vba56_header), SEEK_SET) == -1) {
		cli_dbgmsg("vba_readdir: lseek() failed. Unable to guess VBA type\n");
		close(fd);
		return NULL;
	}
	j = vba_read_project_strings(fd, FALSE);
	if(!i && !j) {
		close(fd);
		cli_dbgmsg("vba_readdir: Unable to guess VBA type\n");
		return NULL;
	}
	if (i > j) {
		big_endian = TRUE;
		if (lseek(fd, seekback, SEEK_SET) == -1) {
			cli_dbgmsg("vba_readdir: call to lseek() while guessing big-endian has failed\n");
			close(fd);
			return NULL;
		}
		cli_dbgmsg("vba_readdir: Guessing big-endian\n");
	} else {
		cli_dbgmsg("vba_readdir: Guessing little-endian\n");
	}

	/* junk some more stuff */
	do
		if (cli_readn(fd, &ffff, 2) != 2) {
			close(fd);
			return NULL;
		}
	while(ffff != 0xFFFF);

	/* check for alignment error */
	if(!seekandread(fd, -3, SEEK_CUR, &ffff, sizeof(uint16_t))) {
		close(fd);
		return NULL;
	}
	if (ffff != 0xFFFF) {
		if (lseek(fd, 1, SEEK_CUR) == -1) {
            cli_dbgmsg("call to lseek() while checking alignment error has failed\n");
            close(fd);
            return NULL;
        }
    }

	if(!read_uint16(fd, &ffff, big_endian)) {
		close(fd);
		return NULL;
	}

	if(ffff != 0xFFFF) {
		if (lseek(fd, ffff, SEEK_CUR) == -1) {
            cli_dbgmsg("call to lseek() while checking alignment error has failed\n");
            close(fd);
            return NULL;
        }
    }

	if(!read_uint16(fd, &ffff, big_endian)) {
		close(fd);
		return NULL;
	}

	if(ffff == 0xFFFF)
		ffff = 0;

	if (lseek(fd, ffff + 100, SEEK_CUR) == -1) {
        cli_dbgmsg("call to lseek() failed\n");
        close(fd);
        return NULL;
    }

	if(!read_uint16(fd, &record_count, big_endian)) {
		close(fd);
		return NULL;
	}
	cli_dbgmsg("vba_readdir: VBA Record count %d\n", record_count);
	if (record_count == 0) {
		/* No macros, assume clean */
		close(fd);
		return NULL;
	}
	if (record_count > MAX_VBA_COUNT) {
		/* Almost certainly an error */
		cli_dbgmsg("vba_readdir: VBA Record count too big\n");
		close(fd);
		return NULL;
	}

	vba_project = create_vba_project(record_count, dir, U);
	if(vba_project == NULL) {
		close(fd);
		return NULL;
	}
	buf = NULL;
	buflen = 0;
	for(i = 0; i < record_count; i++) {
		uint16_t length;
		char *ptr;

		vba_project->colls[i] = 0;
		if(!read_uint16(fd, &length, big_endian))
			break;

		if (length == 0) {
			cli_dbgmsg("vba_readdir: zero name length\n");
			break;
		}
		if(length > buflen) {
			unsigned char *newbuf = (unsigned char *)cli_realloc(buf, length);
			if(newbuf == NULL)
				break;
			buflen = length;
			buf = newbuf;
		}
		if (cli_readn(fd, buf, length) != length) {
			cli_dbgmsg("vba_readdir: read name failed\n");
			break;
		}
		ptr = get_unicode_name((const char *)buf, length, big_endian);
		if(ptr == NULL) break;
		if (!(vba_project->colls[i]=uniq_get(U, ptr, strlen(ptr), &hash))) {
			cli_dbgmsg("vba_readdir: cannot find project %s (%s)\n", ptr, hash);
			free(ptr);
			break;
		}
		cli_dbgmsg("vba_readdir: project name: %s (%s)\n", ptr, hash);
		free(ptr);
		vba_project->name[i] = hash;
		if(!read_uint16(fd, &length, big_endian))
			break;
		lseek(fd, length, SEEK_CUR);

		if(!read_uint16(fd, &ffff, big_endian))
			break;
		if (ffff == 0xFFFF) {
			lseek(fd, 2, SEEK_CUR);
			if(!read_uint16(fd, &ffff, big_endian))
				break;
			lseek(fd, ffff + 8, SEEK_CUR);
		} else
			lseek(fd, ffff + 10, SEEK_CUR);

		if(!read_uint16(fd, &byte_count, big_endian))
			break;
		lseek(fd, (8 * byte_count) + 5, SEEK_CUR);
		if(!read_uint32(fd, &offset, big_endian))
			break;
		cli_dbgmsg("vba_readdir: offset: %u\n", (unsigned int)offset);
		vba_project->offset[i] = offset;
		lseek(fd, 2, SEEK_CUR);
	}

	if(buf)
		free(buf);

	close(fd);

	if(i < record_count) {
		free(vba_project->name);
		free(vba_project->colls);
		free(vba_project->dir);
		free(vba_project->offset);
		free(vba_project);
		return NULL;
	}

	return vba_project;
}
Beispiel #28
0
		address read_v4_address(InIt& in)
		{
			unsigned long ip = read_uint32(in);
			return address_v4(ip);
		}
Beispiel #29
0
static int dmg_open(BlockDriverState *bs, int flags)
{
    BDRVDMGState *s = bs->opaque;
    uint64_t info_begin,info_end,last_in_offset,last_out_offset;
    uint32_t count, tmp;
    uint32_t max_compressed_size=1,max_sectors_per_chunk=1,i;
    int64_t offset;
    int ret;

    bs->read_only = 1;
    s->n_chunks = 0;
    s->offsets = s->lengths = s->sectors = s->sectorcounts = NULL;

    /* read offset of info blocks */
    offset = bdrv_getlength(bs->file);
    if (offset < 0) {
        ret = offset;
        goto fail;
    }
    offset -= 0x1d8;

    ret = read_uint64(bs, offset, &info_begin);
    if (ret < 0) {
        goto fail;
    } else if (info_begin == 0) {
        ret = -EINVAL;
        goto fail;
    }

    ret = read_uint32(bs, info_begin, &tmp);
    if (ret < 0) {
        goto fail;
    } else if (tmp != 0x100) {
        ret = -EINVAL;
        goto fail;
    }

    ret = read_uint32(bs, info_begin + 4, &count);
    if (ret < 0) {
        goto fail;
    } else if (count == 0) {
        ret = -EINVAL;
        goto fail;
    }
    info_end = info_begin + count;

    offset = info_begin + 0x100;

    /* read offsets */
    last_in_offset = last_out_offset = 0;
    while (offset < info_end) {
        uint32_t type;

        ret = read_uint32(bs, offset, &count);
        if (ret < 0) {
            goto fail;
        } else if (count == 0) {
            ret = -EINVAL;
            goto fail;
        }
        offset += 4;

        ret = read_uint32(bs, offset, &type);
        if (ret < 0) {
            goto fail;
        }

	if (type == 0x6d697368 && count >= 244) {
	    int new_size, chunk_count;

            offset += 4;
            offset += 200;

	    chunk_count = (count-204)/40;
	    new_size = sizeof(uint64_t) * (s->n_chunks + chunk_count);
	    s->types = g_realloc(s->types, new_size/2);
	    s->offsets = g_realloc(s->offsets, new_size);
	    s->lengths = g_realloc(s->lengths, new_size);
	    s->sectors = g_realloc(s->sectors, new_size);
	    s->sectorcounts = g_realloc(s->sectorcounts, new_size);

            for (i = s->n_chunks; i < s->n_chunks + chunk_count; i++) {
                ret = read_uint32(bs, offset, &s->types[i]);
                if (ret < 0) {
                    goto fail;
                }
		offset += 4;
		if(s->types[i]!=0x80000005 && s->types[i]!=1 && s->types[i]!=2) {
		    if(s->types[i]==0xffffffff) {
			last_in_offset = s->offsets[i-1]+s->lengths[i-1];
			last_out_offset = s->sectors[i-1]+s->sectorcounts[i-1];
		    }
		    chunk_count--;
		    i--;
		    offset += 36;
		    continue;
		}
		offset += 4;

                ret = read_uint64(bs, offset, &s->sectors[i]);
                if (ret < 0) {
                    goto fail;
                }
                s->sectors[i] += last_out_offset;
                offset += 8;

                ret = read_uint64(bs, offset, &s->sectorcounts[i]);
                if (ret < 0) {
                    goto fail;
                }
                offset += 8;

                ret = read_uint64(bs, offset, &s->offsets[i]);
                if (ret < 0) {
                    goto fail;
                }
                s->offsets[i] += last_in_offset;
                offset += 8;

                ret = read_uint64(bs, offset, &s->lengths[i]);
                if (ret < 0) {
                    goto fail;
                }
                offset += 8;

		if(s->lengths[i]>max_compressed_size)
		    max_compressed_size = s->lengths[i];
		if(s->sectorcounts[i]>max_sectors_per_chunk)
		    max_sectors_per_chunk = s->sectorcounts[i];
	    }
	    s->n_chunks+=chunk_count;
	}
    }

    /* initialize zlib engine */
    s->compressed_chunk = g_malloc(max_compressed_size+1);
    s->uncompressed_chunk = g_malloc(512*max_sectors_per_chunk);
    if(inflateInit(&s->zstream) != Z_OK) {
        ret = -EINVAL;
        goto fail;
    }

    s->current_chunk = s->n_chunks;

    qemu_co_mutex_init(&s->lock);
    return 0;

fail:
    g_free(s->types);
    g_free(s->offsets);
    g_free(s->lengths);
    g_free(s->sectors);
    g_free(s->sectorcounts);
    g_free(s->compressed_chunk);
    g_free(s->uncompressed_chunk);
    return ret;
}
static uint8_t * parse_msgc_tunnel_service_add(uint8_t *message_start, uint8_t *message_end, int minor, size_t *size, message_destructor_t *free_message)
{
    SPICE_GNUC_UNUSED uint8_t *pos;
    uint8_t *start = message_start;
    uint8_t *data = NULL;
    size_t mem_size, nw_size;
    uint8_t *in, *end;
    SPICE_GNUC_UNUSED intptr_t ptr_size;
    uint32_t n_ptr=0;
    PointerInfo ptr_info[2];
    size_t name__extra_size;
    size_t description__extra_size;
    size_t u__nw_size;
    uint16_t type__value;
    SpiceMsgcTunnelAddGenericService *out;
    uint32_t i;

    { /* name */
        uint32_t name__value;
        uint32_t name__array__nw_size;
        uint32_t name__array__mem_size;
        pos = (start + 14);
        if (SPICE_UNLIKELY(pos + 4 > message_end)) {
            goto error;
        }
        name__value = read_uint32(pos);
        if (SPICE_UNLIKELY(message_start + name__value >= message_end)) {
            goto error;
        }
        name__array__nw_size = spice_strnlen((char *)message_start + name__value, message_end - (message_start + name__value));
        if (SPICE_UNLIKELY(*(message_start + name__value + name__array__nw_size) != 0)) {
            goto error;
        }
        name__array__mem_size = name__array__nw_size;
        /* @nocopy, so no extra size */
        name__extra_size = 0;
    }

    { /* description */
        uint32_t description__value;
        uint32_t description__array__nw_size;
        uint32_t description__array__mem_size;
        pos = (start + 18);
        if (SPICE_UNLIKELY(pos + 4 > message_end)) {
            goto error;
        }
        description__value = read_uint32(pos);
        if (SPICE_UNLIKELY(message_start + description__value >= message_end)) {
            goto error;
        }
        description__array__nw_size = spice_strnlen((char *)message_start + description__value, message_end - (message_start + description__value));
        if (SPICE_UNLIKELY(*(message_start + description__value + description__array__nw_size) != 0)) {
            goto error;
        }
        description__array__mem_size = description__array__nw_size;
        /* @nocopy, so no extra size */
        description__extra_size = 0;
    }

    { /* u */
        pos = start + 0;
        if (SPICE_UNLIKELY(pos + 2 > message_end)) {
            goto error;
        }
        type__value = read_uint16(pos);
        if (type__value == SPICE_TUNNEL_SERVICE_TYPE_IPP) {
            SPICE_GNUC_UNUSED uint8_t *start2 = (start + 22);
            size_t u__nw_size;
            uint16_t type__value;
            { /* u */
                uint32_t u__nelements;
                pos = start2 + 0;
                if (SPICE_UNLIKELY(pos + 2 > message_end)) {
                    goto error;
                }
                type__value = read_uint16(pos);
                if (type__value == SPICE_TUNNEL_IP_TYPE_IPv4) {
                    u__nelements = 4;

                    u__nw_size = u__nelements;
                } else {
                    u__nw_size = 0;
                }

            }

            u__nw_size = 2 + u__nw_size;
        } else {
            u__nw_size = 0;
        }

    }

    nw_size = 22 + u__nw_size;
    mem_size = sizeof(SpiceMsgcTunnelAddGenericService) + name__extra_size + description__extra_size;

    /* Check if message fits in reported side */
    if (start + nw_size > message_end) {
        return NULL;
    }

    /* Validated extents and calculated size */
    data = (uint8_t *)malloc(mem_size);
    if (SPICE_UNLIKELY(data == NULL)) {
        goto error;
    }
    end = data + sizeof(SpiceMsgcTunnelAddGenericService);
    in = start;

    out = (SpiceMsgcTunnelAddGenericService *)data;

    out->type = consume_uint16(&in);
    out->id = consume_uint32(&in);
    out->group = consume_uint32(&in);
    out->port = consume_uint32(&in);
    /* Reuse data from network message */
    out->name = (size_t)(message_start + consume_uint32(&in));
    /* Reuse data from network message */
    out->description = (size_t)(message_start + consume_uint32(&in));
    if (out->type == SPICE_TUNNEL_SERVICE_TYPE_IPP) {
        out->u.ip.type = consume_uint16(&in);
        if (out->u.ip.type == SPICE_TUNNEL_IP_TYPE_IPv4) {
            uint32_t ipv4__nelements;
            ipv4__nelements = 4;
            memcpy(out->u.ip.u.ipv4, in, ipv4__nelements);
            in += ipv4__nelements;
        }
    }

    assert(in <= message_end);

    for (i = 0; i < n_ptr; i++) {
        if (ptr_info[i].offset == 0) {
            *ptr_info[i].dest = NULL;
        } else {
            /* Align to 32 bit */
            end = (uint8_t *)SPICE_ALIGN((size_t)end, 4);
            *ptr_info[i].dest = (void *)end;
            end = ptr_info[i].parse(message_start, message_end, end, &ptr_info[i], minor);
            if (SPICE_UNLIKELY(end == NULL)) {
                goto error;
            }
        }
    }

    assert(end <= data + mem_size);

    *size = end - data;
    *free_message = (message_destructor_t) free;
    return data;

   error:
    if (data != NULL) {
        free(data);
    }
    return NULL;
}