Exemple #1
0
static char *loadstring(FILE *f)
{
  ULONG l;
  char buf[4], *p=buf;
  if(1!=fread(buf, 4, 1, f) || (l=getu32(&p))>SANITYMAXLEN || !(p=malloc(l)))
    return NULL;
  fread(p, 1, l, f);
  return p;
}
Exemple #2
0
static struct Image *loadimage(FILE *f)
{
  char buf[20], *p=buf;
  WORD le, te, w, h, d;
  int imgsz;
  struct Image *im;
  if(1!=fread(buf, 20, 1, f))
    return NULL;
  le=get16(&p); te=get16(&p); w=get16(&p); h=get16(&p); d=get16(&p);
  if(w<=0 || w>MAXICONSIZE || h<=0 || h>MAXICONSIZE || d<1 || d>8)
    return NULL;
  imgsz=2*((w+15)>>4)*h*d;
  if(!(im=malloc(imgsz+sizeof(struct Image))))
    return NULL;
  im->LeftEdge=le; im->TopEdge=te; im->Width=w; im->Height=h;
  im->Depth=d; im->ImageData=(UWORD*)getu32(&p);
  im->PlanePick=*p++; im->PlaneOnOff=*p++;
  im->NextImage=(struct Image *)getu32(&p);
  if(im->ImageData) {
    im->ImageData=(UWORD *)(im+1);
    fread(im->ImageData, 1, imgsz, f);
  }
  return im;
}
Exemple #3
0
static void decode_glowicon(struct DiskObject *diskobj, char *glow, LONG len)
{
  int imgno=0, gotface=0;
  struct { char width, height; UWORD dunno1, dunno2; } face;
  while(len>=8) {
    ULONG id = getu32(&glow);
    LONG clen = get32(&glow);
    char *chunk = glow;
    len -= 8;
    if(clen<0)
      clen = len;
    if(clen>len)
      break;
    switch(id) {
     case 0x46414345: /* FACE */
       if(clen>=6) {
	 face.width = 1+*chunk++;
	 face.height = 1+*chunk++;
	 face.dunno1 = getu16(&chunk);
	 face.dunno2 = getu16(&chunk);
	 gotface = 1;
	 diskobj->do_Gadget.Width = face.width;
	 diskobj->do_Gadget.Height = face.height;
       break;
       }
       break;
     case 0x494d4147: /* IMAG */
       if(!gotface || imgno>1)
	 break;
       decode_IMAG((unsigned char *)chunk, clen, face.width, face.height,
		   (imgno++? &diskobj->do_Gadget.SelectRender :
		    &diskobj->do_Gadget.GadgetRender));
       break;
    }
    if(clen&1)
      clen++;
    len -= clen;
    glow += clen;
  }
}
Exemple #4
0
static struct DiskObject *int_load_do(char *filename)
{
  FILE *f;
  struct DiskObject *diskobj;
  char buf[78], *p=buf;
  int error=0;
  if((f=fopen(filename, "r"))) {
    if(1==fread(buf, 78, 1, f) &&
       (diskobj=calloc(1, sizeof(struct DiskObject)))) {
      diskobj->do_Magic=getu16(&p); diskobj->do_Version=getu16(&p);
      if(diskobj->do_Magic!=WB_DISKMAGIC) {
	free(diskobj);
	return NULL;
      }
      diskobj->do_Gadget.NextGadget=(struct Gadget *)getu32(&p);
      diskobj->do_Gadget.LeftEdge=get16(&p);
      diskobj->do_Gadget.TopEdge=get16(&p);
      diskobj->do_Gadget.Width=get16(&p); diskobj->do_Gadget.Height=get16(&p);
      diskobj->do_Gadget.Flags=getu16(&p);
      diskobj->do_Gadget.Activation=getu16(&p);
      diskobj->do_Gadget.GadgetType=getu16(&p);
      diskobj->do_Gadget.GadgetRender=(APTR)getu32(&p);
      diskobj->do_Gadget.SelectRender=(APTR)getu32(&p);
      diskobj->do_Gadget.GadgetText=(struct IntuiText *)getu32(&p);
      diskobj->do_Gadget.MutualExclude=get32(&p);
      diskobj->do_Gadget.SpecialInfo=(APTR)getu32(&p);
      diskobj->do_Gadget.GadgetID=getu16(&p);
      diskobj->do_Gadget.UserData=(APTR)getu32(&p);
      diskobj->do_Type=*p; p+=2;
      diskobj->do_DefaultTool=(char *)getu32(&p);
      diskobj->do_ToolTypes=(char **)getu32(&p);
      diskobj->do_CurrentX=get32(&p);
      diskobj->do_CurrentY=get32(&p);
      diskobj->do_DrawerData=(struct DrawerData *)getu32(&p);
      diskobj->do_ToolWindow=(char *)getu32(&p);
      diskobj->do_StackSize=get32(&p);
      
      if(diskobj->do_DrawerData) {
	struct DrawerData *dd;
	if(1==fread(buf, 56, 1, f) &&
	   (diskobj->do_DrawerData=dd=calloc(1, sizeof(struct DrawerData)))) {
	  p=buf;
	  dd->dd_NewWindow.LeftEdge=get16(&p);
	  dd->dd_NewWindow.TopEdge=get16(&p);
	  dd->dd_NewWindow.Width=get16(&p);
	  dd->dd_NewWindow.Height=get16(&p);
	  dd->dd_NewWindow.DetailPen=*p++;
	  dd->dd_NewWindow.BlockPen=*p++;
	  dd->dd_NewWindow.IDCMPFlags=getu32(&p);
	  dd->dd_NewWindow.Flags=getu32(&p);
	  dd->dd_NewWindow.FirstGadget=(struct Gadget *)getu32(&p);
	  dd->dd_NewWindow.CheckMark=(struct Image *)getu32(&p);
	  dd->dd_NewWindow.Title=(UBYTE *)getu32(&p);
	  dd->dd_NewWindow.Screen=(struct Screen *)getu32(&p);
	  dd->dd_NewWindow.BitMap=(struct BitMap *)getu32(&p);
	  dd->dd_NewWindow.MinWidth=get16(&p);
	  dd->dd_NewWindow.MinHeight=get16(&p);
	  dd->dd_NewWindow.MaxWidth=getu16(&p);
	  dd->dd_NewWindow.MaxHeight=getu16(&p);
	  dd->dd_NewWindow.Type=getu16(&p);
	  dd->dd_CurrentX=get32(&p);
	  dd->dd_CurrentY=get32(&p);
	} else error++;
      }

      if(!(diskobj->do_Gadget.GadgetRender=loadimage(f)))
	error++;
	
      if(diskobj->do_Gadget.Flags&2)
	if(!(diskobj->do_Gadget.SelectRender=loadimage(f)))
	  error++;
	else ;
      else if(diskobj->do_Gadget.Flags&1)
	if(!(diskobj->do_Gadget.SelectRender=
	     backfillimage((struct Image *)diskobj->do_Gadget.GadgetRender)))
	  error++;
	else ;
      else diskobj->do_Gadget.SelectRender=NULL;
      
      if(diskobj->do_DefaultTool)
	if(!(diskobj->do_DefaultTool=loadstring(f)))
	  error++;

      if(diskobj->do_ToolTypes)
	if(!(diskobj->do_ToolTypes=loadtooltypes(f)))
	  error++;

      if(diskobj->do_ToolWindow)
	if(!(diskobj->do_ToolWindow=loadstring(f)))
	  error++;

      if(diskobj->do_DrawerData && diskobj->do_Version) {
	char buf[6], *p=buf;
	if(1==fread(buf, 6, 1, f)) {
	  diskobj->do_DrawerData->dd_Flags=getu32(&p);
	  diskobj->do_DrawerData->dd_ViewModes=getu16(&p);
	}
      }

      if(diskobj->do_Version) {
	/* Check for GlowIcon */
	char buf[8], *p = buf, *glowicon;
	LONG len;
	if(1==fread(buf, 4, 1, f) && !strncmp(buf, "FORM", 4) &&
	   1==fread(buf, 8, 1, f) && !strncmp(buf+4, "ICON", 4) &&
	   (len = get32(&p))>4 && (glowicon = malloc(len))!=NULL) {
	  if(1==fread(glowicon, len-4, 1, f))
	    decode_glowicon(diskobj, glowicon, len-4);
	  free(glowicon);
	}
      }

      if(!error) {
	fclose(f);
	return diskobj;
      }

      FreeDiskObject(diskobj);
    }
    fclose(f);
    }
  return NULL;
}
Exemple #5
0
uint pzip_Encode(   u08* input_buf,   uint input_len,   u08* encode_buf   ) {

    /* This is the top-level compression function.                             */
    /*   input_buf:  Contents of file to be compressed.                        */
    /*   encode_buf: Where to leave the result.                                */
    /*   return val: Compressed length -- count of valid bytes in encode_buf.  */

    int num_chose_loe[      PZIP_ORDER +1 ];
    int num_tried_by_order[ PZIP_ORDER +1 ];
    int num_coded_by_order[ PZIP_ORDER +1 ];
    int num_coded_det = 0;

    clock_t began_at = clock();

    Pzip*  pzip  = pzip_create();
    Arith* arith = pzip->arith;

    u08* input_ptr      =  input_buf;
    u08* input_buf_end  =  input_buf + input_len;

    assert( PZIP_SEED_BYTES > 0 );

    /* Seed a preamble: */
    memcpy( encode_buf, input_ptr, PZIP_SEED_BYTES );
    memset( input_ptr - PZIP_MAX_CONTEXT_LEN, PZIP_SEED_BYTE, PZIP_MAX_CONTEXT_LEN );
    input_ptr  += PZIP_SEED_BYTES;

    arith_Start_Encoding( arith, encode_buf + PZIP_SEED_BYTES );

    memset( num_chose_loe,      0, (PZIP_ORDER +1) * sizeof(int) );
    memset( num_tried_by_order, 0, (PZIP_ORDER +1) * sizeof(int) );
    memset( num_coded_by_order, 0, (PZIP_ORDER +1) * sizeof(int) );

    while (input_ptr < input_buf_end) {

        int symbol = *input_ptr;                      /* Current symbol to encode.             */
        u32 key  = getu32( input_ptr -4 );        /* Last four chars seen on input stream. */

        trie_Fill_Active_Contexts( input_ptr ); /* Must come before det_Enc(), cuz that uses the top Context node */

        excluded_symbols_Clear( pzip->excluded_symbols );

        if (deterministic_Encode(   pzip->det,   arith,   input_ptr,   input_buf,   symbol,   pzip->excluded_symbols,   active_contexts.c[ PZIP_ORDER ]   )) {

            ++ num_coded_det;

        } else {

            /* Try selected contexts until one encodes 'symbol': */
            int order = PZIP_ORDER+1;
            for(order = choose_context( active_contexts.c, order, key, pzip->excluded_symbols, pzip->see ),   ++ num_chose_loe[ order ];   ;
                order = choose_context( active_contexts.c, order, key, pzip->excluded_symbols, pzip->see )
            ){

                ++ num_tried_by_order[ order ];

                /* Try to code symbol using selected order model: */
                if (context_Encode( active_contexts.c[order], arith, pzip->excluded_symbols, pzip->see, key, symbol )) {
                    ++ num_coded_by_order[ order ];
                    break;
                }
                        
                if (order == 0) {
                    /* Encode raw with order -1: */
                    order_minus_one_Encode( symbol, 256, arith, pzip->excluded_symbols );
                    break;
                }
            }

            /* Did encode, now update the stats: */
            {   int coded_order = max( order, 0 );
                for (order = 0;   order <= PZIP_ORDER;   order++) {
                    context_Update( active_contexts.c[order], symbol, key, pzip->see, coded_order );
                }
            }
        }

        deterministic_Update( pzip->det, input_ptr, symbol, active_contexts.c[ PZIP_ORDER ] );

        ++ input_ptr;

        /* Maybe assure user we haven't crashed: */
        if (verbose   &&   (input_ptr - input_buf) % PZIP_PRINTF_INTERVAL == 0) {
            fprintf(stderr, "%d/%d\r", (input_ptr - input_buf), input_len );
            fflush( stderr );
        }
    }
    if (verbose) {
        clock_t clocks  = clock() - began_at;                        /* Do NOT combine   */
        double  secs    = (double)clocks / (double)CLOCKS_PER_SEC;   /* these two lines! */
        fprintf(stderr, "%d/%d\n", input_len, input_len );
        fprintf(stderr,"%s : %f secs = %2.1f %ss/sec\n", "encode", secs, (double)input_len / secs, "byte" );
    }



    {   uint encode_len = (arith_Finish_Encoding( arith ) - (encode_buf + PZIP_SEED_BYTES)) + PZIP_SEED_BYTES;

#ifdef OLD
        pzip_destroy( pzip );
#endif

        /* The arithc has stuffed 1 byte; put it back: */ 
        encode_buf[ PZIP_SEED_BYTES-1 ] = input_buf[ PZIP_SEED_BYTES-1 ];

        if (verbose) {
            printf( "o : %7s : %7s : %7s\n", "loe", "tried", "coded" );
            printf("d : %7d : %7d : %7d\n", input_len, input_len, num_coded_det );
            {   int  i;
                for (i = PZIP_ORDER+1;   i --> 0;   ) {
                    printf(
                        "%d : %7d : %7d : %7d\n",
                        i, num_chose_loe[i], num_tried_by_order[i], num_coded_by_order[i]
                    );
                }
            }
        }

        return encode_len;
    }
}
Exemple #6
0
void pzip_Decode(   u08* output_buf,   uint output_len,   u08* encode_buf   ) {

    clock_t began_at = clock();
    Pzip*  pzip      = pzip_create();
    Arith* arith     = pzip->arith;

    u08* output_ptr     = output_buf;
    u08* output_buf_end = output_buf + output_len;

    memcpy( output_ptr, encode_buf, PZIP_SEED_BYTES );
    memset( output_ptr - PZIP_MAX_CONTEXT_LEN, PZIP_SEED_BYTE, PZIP_MAX_CONTEXT_LEN );

    output_ptr += PZIP_SEED_BYTES;
    encode_buf += PZIP_SEED_BYTES;

    arith_Start_Decoding( arith, encode_buf );

    while (output_ptr < output_buf_end) {

        int      symbol;
        u32    key      = getu32( output_ptr - 4 );;

        trie_Fill_Active_Contexts( output_ptr );

        excluded_symbols_Clear( pzip->excluded_symbols );

        if (!deterministic_Decode( pzip->det, arith, output_ptr, output_buf, &symbol, pzip->excluded_symbols, active_contexts.c[PZIP_ORDER] )) {

            /* Go down the orders: */
            int order = PZIP_ORDER+1;
            for(order = choose_context( active_contexts.c, order, key, pzip->excluded_symbols, pzip->see );   ;
                order = choose_context( active_contexts.c, order, key, pzip->excluded_symbols, pzip->see )
            ){

                /* Try to coder from order: */
                if (context_Decode( active_contexts.c[order], arith, pzip->excluded_symbols, pzip->see, key, &symbol )) {
                    break;
                }
                        
                if (order == 0) {
                    /* Decode raw with order -1: */
                    symbol = order_minus_one_Decode( 256, arith, pzip->excluded_symbols );
                    break;
                }
            }

            /* Did decode, now update the stats: */
            {   int coded_order = max( order, 0 );
                for (order = 0;   order <= PZIP_ORDER;   ++order) {
                    context_Update( active_contexts.c[order], symbol, key, pzip->see, coded_order );
                }
            }
        }

        deterministic_Update( pzip->det, output_ptr, symbol, active_contexts.c[ PZIP_ORDER ] );

        *output_ptr++ = symbol;
                
        /* Maybe assure user we haven't crashed: */
        if (verbose   &&   (output_ptr - output_buf) % PZIP_PRINTF_INTERVAL == 0) {
            fprintf(stderr, "%d/%d\r", (output_ptr - output_buf), output_len );
            fflush( stderr );
        }
    }

    if (verbose) {
        clock_t clocks  = clock() - began_at;                        /* Do NOT combine   */
        double  secs    = (double)clocks / (double)CLOCKS_PER_SEC;   /* these two lines! */
        fprintf(stderr, "%d/%d\n", output_len, output_len );
        fprintf(stderr,"%s : %f secs = %2.1f %ss/sec\n", "decode", secs, (double)output_len / secs, "byte" );
    }

    pzip_destroy( pzip );
}
Exemple #7
0
/* return 1 on error and 0 on success */
static uint8_t
ext2fs_dent_copy(EXT2FS_INFO * ext2fs, EXT2FS_DINFO * dinfo,
    char *ext2_dent, FS_DENT * fs_dent)
{
    FS_INFO *fs = &(ext2fs->fs_info);

    if (ext2fs->deentry_type == EXT2_DE_V1) {
	ext2fs_dentry1 *dir = (ext2fs_dentry1 *) ext2_dent;

	fs_dent->inode = getu32(fs, dir->inode);

	/* ext2 does not null terminate */
	if (getu16(fs, dir->name_len) >= fs_dent->name_max) {
	    tsk_errno = TSK_ERR_FS_ARG;
	    snprintf(tsk_errstr, TSK_ERRSTR_L,
		"ext2fs_dent_copy: Name Space too Small %d %lu",
		getu16(fs, dir->name_len), fs_dent->name_max);
	    tsk_errstr2[0] = '\0';
	    return 1;
	}

	/* Copy and Null Terminate */
	strncpy(fs_dent->name, dir->name, getu16(fs, dir->name_len));
	fs_dent->name[getu16(fs, dir->name_len)] = '\0';

	fs_dent->ent_type = FS_DENT_UNDEF;
    }
    else {
	ext2fs_dentry2 *dir = (ext2fs_dentry2 *) ext2_dent;

	fs_dent->inode = getu32(fs, dir->inode);

	/* ext2 does not null terminate */
	if (dir->name_len >= fs_dent->name_max) {
	    tsk_errno = TSK_ERR_FS_ARG;
	    snprintf(tsk_errstr, TSK_ERRSTR_L,
		"ext2_dent_copy: Name Space too Small %d %lu",
		dir->name_len, fs_dent->name_max);
	    tsk_errstr2[0] = '\0';
	    return 1;
	}

	/* Copy and Null Terminate */
	strncpy(fs_dent->name, dir->name, dir->name_len);
	fs_dent->name[dir->name_len] = '\0';

	switch (dir->type) {
	case EXT2_DE_REG_FILE:
	    fs_dent->ent_type = FS_DENT_REG;
	    break;
	case EXT2_DE_DIR:
	    fs_dent->ent_type = FS_DENT_DIR;
	    break;
	case EXT2_DE_CHRDEV:
	    fs_dent->ent_type = FS_DENT_CHR;
	    break;
	case EXT2_DE_BLKDEV:
	    fs_dent->ent_type = FS_DENT_BLK;
	    break;
	case EXT2_DE_FIFO:
	    fs_dent->ent_type = FS_DENT_FIFO;
	    break;
	case EXT2_DE_SOCK:
	    fs_dent->ent_type = FS_DENT_SOCK;
	    break;
	case EXT2_DE_SYMLINK:
	    fs_dent->ent_type = FS_DENT_LNK;
	    break;
	case EXT2_DE_UNKNOWN:
	default:
	    fs_dent->ent_type = FS_DENT_UNDEF;
	    break;
	}
    }

    fs_dent->path = dinfo->dirs;
    fs_dent->pathdepth = dinfo->depth;

    if ((fs != NULL) && (fs_dent->inode)
	&& (fs_dent->inode <= fs->last_inum)) {
	/* Get inode */
	if (fs_dent->fsi)
	    fs_inode_free(fs_dent->fsi);

	if ((fs_dent->fsi = fs->inode_lookup(fs, fs_dent->inode)) == NULL) {
	    strncat(tsk_errstr2, " - ext2fs_dent_copy",
		TSK_ERRSTR_L - strlen(tsk_errstr2));
	    return 1;
	}
    }
    else {
	if (fs_dent->fsi)
	    fs_inode_free(fs_dent->fsi);
	fs_dent->fsi = NULL;
    }
    return 0;
}
Exemple #8
0
/* 
**
** Read contents of directory block
**
** if entry is active call action with myflags set to FS_FLAG_NAME_ALLOC, if 
** it is deleted then call action with FS_FLAG_NAME_UNALLOC.
** len is the size of buf
**
** return 1 to stop, 0 on success, and -1 on error
*/
static int
ext2fs_dent_parse_block(EXT2FS_INFO * ext2fs, EXT2FS_DINFO * dinfo,
    char *buf, int len, int flags, FS_DENT_WALK_FN action, void *ptr)
{
    FS_INFO *fs = &(ext2fs->fs_info);

    int dellen = 0;
    int idx;
    uint16_t reclen;
    uint32_t inode;
    char *dirPtr;
    FS_DENT *fs_dent;
    int minreclen = 4;

    if ((fs_dent = fs_dent_alloc(EXT2FS_MAXNAMLEN + 1, 0)) == NULL)
	return -1;

    /* update each time by the actual length instead of the
     ** recorded length so we can view the deleted entries 
     */
    for (idx = 0; idx <= len - EXT2FS_DIRSIZ_lcl(1); idx += minreclen) {

	unsigned int namelen;
	int myflags = 0;
	dirPtr = &buf[idx];

	if (ext2fs->deentry_type == EXT2_DE_V1) {
	    ext2fs_dentry1 *dir = (ext2fs_dentry1 *) dirPtr;
	    inode = getu32(fs, dir->inode);
	    namelen = getu16(fs, dir->name_len);
	    reclen = getu16(fs, dir->rec_len);
	}
	else {
	    ext2fs_dentry2 *dir = (ext2fs_dentry2 *) dirPtr;
	    inode = getu32(fs, dir->inode);
	    namelen = dir->name_len;
	    reclen = getu16(fs, dir->rec_len);
	}

	minreclen = EXT2FS_DIRSIZ_lcl(namelen);

	/* 
	 ** Check if we may have a valid directory entry.  If we don't,
	 ** then increment to the next word and try again.  
	 */
	if ((inode > fs->last_inum) ||
	    (inode < 0) ||
	    (namelen > EXT2FS_MAXNAMLEN) ||
	    (namelen <= 0) ||
	    (reclen < minreclen) || (reclen % 4) || (idx + reclen > len)) {

	    minreclen = 4;
	    if (dellen > 0)
		dellen -= 4;
	    continue;
	}

	/* Before we process an entry in unallocated space, make
	 * sure that it also ends in the unalloc space */
	if ((dellen) && (dellen < minreclen)) {
	    minreclen = 4;
	    if (dellen > 0)
		dellen -= 4;
	    continue;
	}

	if (ext2fs_dent_copy(ext2fs, dinfo, dirPtr, fs_dent)) {
	    fs_dent_free(fs_dent);
	    return -1;
	}

	myflags = 0;
	/* Do we have a deleted entry? */
	if ((dellen > 0) || (inode == 0)) {
	    myflags |= FS_FLAG_NAME_UNALLOC;
	    if (dellen > 0)
		dellen -= minreclen;

	    if (flags & FS_FLAG_NAME_UNALLOC) {
		int retval;
		retval = action(fs, fs_dent, myflags, ptr);
		if (retval == WALK_STOP) {
		    fs_dent_free(fs_dent);
		    return 1;
		}
		else if (retval == WALK_ERROR) {
		    fs_dent_free(fs_dent);
		    return -1;
		}
	    }
	}
	/* We have a non-deleted entry */
	else {
	    myflags |= FS_FLAG_NAME_ALLOC;
	    if (flags & FS_FLAG_NAME_ALLOC) {
		int retval;

		retval = action(fs, fs_dent, myflags, ptr);
		if (retval == WALK_STOP) {
		    fs_dent_free(fs_dent);
		    return 1;
		}
		else if (retval == WALK_ERROR) {
		    fs_dent_free(fs_dent);
		    return -1;
		}
	    }
	}

	/* If the actual length is shorter then the 
	 ** recorded length, then the next entry(ies) have been 
	 ** deleted.  Set dellen to the length of data that 
	 ** has been deleted
	 **
	 ** Because we aren't guaranteed with Ext2FS that the next
	 ** entry begins right after this one, we will check to
	 ** see if the difference is less than a possible entry
	 ** before we waste time searching it
	 */
	if ((reclen - minreclen >= EXT2FS_DIRSIZ_lcl(1))
	    && (dellen <= 0))
	    dellen = reclen - minreclen;


	/* we will be recursing directories */
	if ((myflags & FS_FLAG_NAME_ALLOC) &&
	    (flags & FS_FLAG_NAME_RECURSE) &&
	    (!ISDOT(fs_dent->name)) &&
	    ((fs_dent->fsi->mode & FS_INODE_FMT) == FS_INODE_DIR)) {

	    if (dinfo->depth < MAX_DEPTH) {
		dinfo->didx[dinfo->depth] =
		    &dinfo->dirs[strlen(dinfo->dirs)];
		strncpy(dinfo->didx[dinfo->depth], fs_dent->name,
		    DIR_STRSZ - strlen(dinfo->dirs));
		strncat(dinfo->dirs, "/", DIR_STRSZ);
	    }
	    dinfo->depth++;
	    if (ext2fs_dent_walk_lcl(&(ext2fs->fs_info), dinfo,
		    fs_dent->inode, flags, action, ptr)) {
		/* If this fails because the directory could not be 
		 * loaded, then we still continue */
		if (verbose) {
		    fprintf(stderr,
			"ffs_dent_parse_block: error reading directory: %"
			PRIuINUM "\n", fs_dent->inode);
		    tsk_error_print(stderr);
		}

		tsk_errno = 0;
		tsk_errstr[0] = '\0';
		tsk_errstr2[0] = '\0';
	    }


	    dinfo->depth--;
	    if (dinfo->depth < MAX_DEPTH)
		*dinfo->didx[dinfo->depth] = '\0';
	}
    }

    fs_dent_free(fs_dent);
    return 0;
}				/* end ext2fs_dent_parse_block() */
Exemple #9
0
/* 
 * Load the primary partition table (MBR) into the internal
 * data structures in MM_INFO
 *
 * This will automatically call load_ext_table for extended
 * partitions
 *
 * sect_cur is the addres of the table to load
 *
 * 0 is returned if the load is successful and 1 if error
 */
static uint8_t
dos_load_prim_table(MM_INFO * mm, uint8_t test)
{
    dos_sect sect;
    int i;
    char *table_str;
    SSIZE_T cnt;
    DADDR_T taddr = mm->offset / mm->block_size + DOS_PART_SOFFSET;
    DADDR_T max_addr = (mm->img_info->size - mm->offset) / mm->block_size;	// max sector

    if (verbose)
	fprintf(stderr,
	    "dos_load_prim: Table Sector: %" PRIuDADDR "\n", taddr);

    /* Read the table */
    cnt = mm_read_block_nobuf
	(mm, (char *) &sect, sizeof(sect), DOS_PART_SOFFSET);

    if (cnt != sizeof(sect)) {
	snprintf(tsk_errstr2, TSK_ERRSTR_L,
	    "Primary DOS table sector %" PRIuDADDR, taddr);
	if (cnt != -1) {
	    tsk_errno = TSK_ERR_MM_READ;
	    tsk_errstr[0] = '\0';
	}
	return 1;
    }


    /* Sanity Check */
    if (mm_guessu16(mm, sect.magic, DOS_MAGIC)) {
	tsk_errno = TSK_ERR_MM_MAGIC;
	snprintf(tsk_errstr, TSK_ERRSTR_L,
	    "File is not a DOS partition (invalid primary magic) (Sector: %"
	    PRIuDADDR ")", taddr);
	tsk_errstr2[0] = '\0';
	return 1;
    }

    /* Because FAT and NTFS use the same magic - check for a
     * standard MS OEM name and sizes.  Not a great check, but we can't 
     * really test the table entries.  
     */
    if (test) {

	if (verbose)
	    fprintf(stderr,
		"dos_load_prim_table: Testing FAT/NTFS conditions\n");

	if (strncmp("MSDOS", sect.oemname, 5) == 0) {
	    tsk_errno = TSK_ERR_MM_MAGIC;
	    snprintf(tsk_errstr, TSK_ERRSTR_L,
		"dos_load_prim_table: MSDOS OEM name exists");
	    tsk_errstr2[0] = '\0';
	    return 1;
	}
	else if (strncmp("MSWIN", sect.oemname, 5) == 0) {
	    tsk_errno = TSK_ERR_MM_MAGIC;
	    snprintf(tsk_errstr, TSK_ERRSTR_L,
		"dos_load_prim_table: MSWIN OEM name exists");
	    tsk_errstr2[0] = '\0';
	    return 1;
	}
	else if (strncmp("NTFS", sect.oemname, 4) == 0) {
	    tsk_errno = TSK_ERR_MM_MAGIC;
	    snprintf(tsk_errstr, TSK_ERRSTR_L,
		"dos_load_prim_table: NTFS OEM name exists");
	    tsk_errstr2[0] = '\0';
	    return 1;
	}
    }

    /* Add an entry of 1 sector for the table  to the internal structure */
    if ((table_str = mymalloc(32)) == NULL)
	return 1;

    snprintf(table_str, 32, "Primary Table (#0)");
    if (NULL == mm_part_add(mm, DOS_PART_SOFFSET, (DADDR_T) 1,
	    MM_TYPE_DESC, table_str, -1, -1))
	return 1;

    /* Cycle through the partition table */
    for (i = 0; i < 4; i++) {
	dos_part *part = &sect.ptable[i];

	/* We currently ignore CHS */
	uint32_t part_start = getu32(mm, part->start_sec);
	uint32_t part_size = getu32(mm, part->size_sec);

	if (verbose)
	    fprintf(stderr,
		"load_pri:0:%d    Start: %" PRIu32 "   Size: %" PRIu32
		"  Type: %d\n", i, part_start, part_size, part->ptype);

	if (part_size == 0)
	    continue;

	if (part_start > max_addr) {
	    tsk_errno = TSK_ERR_MM_BLK_NUM;
	    snprintf(tsk_errstr, TSK_ERRSTR_L,
		"dos_load_prim_table: Starting sector too large for image");
	    tsk_errstr2[0] = '\0';
	    return 1;
	}
#if 0
// I'm not sure if this is too strict ...
	else if ((part_start + part_size) > max_addr) {
	    tsk_errno = TSK_ERR_MM_BLK_NUM
		snprintf(tsk_errstr, TSK_ERRSTR_L,
		"dos_load_prim_table: Partition ends after image");
	    tsk_errstr2[0] = '\0';
	    return 1;
	}
#endif

	/* Add the partition to the internal structure 
	 * If it is an extended partition, process it now */
	if (dos_is_ext(part->ptype)) {
	    if (NULL == mm_part_add(mm, (DADDR_T) part_start,
		    (DADDR_T) part_size, MM_TYPE_DESC,
		    dos_get_desc(part->ptype), 0, i))
		return 1;

	    if (dos_load_ext_table(mm, part_start, part_start, 1))
		return 1;
	}
	else {
	    if (NULL == mm_part_add(mm, (DADDR_T) part_start,
		    (DADDR_T) part_size, MM_TYPE_VOL,
		    dos_get_desc(part->ptype), 0, i))
		return 1;
	}
    }
    return 0;
}
Exemple #10
0
/* 
 * Load an extended partition table into the structure in MM_INFO.
 *
 * sect_cur: The sector where the extended table is located
 * sect_ext_base: The sector of the primary extended table (this does
 *   not change for recursive calls)
 * table: a counter that identifies the table depth 
 *   (increases by 1 for each recursive call)
 * 
 * For the primary extended table, sect_cur == sect_ext_base 
 *
 * Return 1 on error and 0 on success
 *
 */
static uint8_t
dos_load_ext_table(MM_INFO * mm, DADDR_T sect_cur, DADDR_T sect_ext_base,
    int table)
{
    dos_sect sect;
    int i;
    char *table_str;
    SSIZE_T cnt;
    DADDR_T max_addr = (mm->img_info->size - mm->offset) / mm->block_size;	// max sector

    if (verbose)
	fprintf(stderr,
	    "dos_load_ext: Table Sector: %" PRIuDADDR
	    ", Primary Base Sector: %" PRIuDADDR "\n", sect_cur,
	    sect_ext_base);

    /* Read the partition table sector */
    cnt = mm_read_block_nobuf
	(mm, (char *) &sect, sizeof(sect), (DADDR_T) sect_cur);
    if (cnt != sizeof(sect)) {
	snprintf(tsk_errstr2, TSK_ERRSTR_L,
	    "Extended DOS table sector %" PRIuDADDR, sect_cur);
	if (cnt != -1) {
	    tsk_errno = TSK_ERR_MM_READ;
	    tsk_errstr[0] = '\0';
	}
	return 1;
    }

    /* Sanity Check */
    if (getu16(mm, sect.magic) != DOS_MAGIC) {
	tsk_errno = TSK_ERR_MM_MAGIC;
	snprintf(tsk_errstr, TSK_ERRSTR_L,
	    "Extended DOS partition table in sector %"
	    PRIuDADDR, sect_cur);
	tsk_errstr2[0] = '\0';
	return 1;
    }

    /* Add an entry of 1 length for the table  to the internal structure */
    if ((table_str = mymalloc(32)) == NULL)
	return 1;

    snprintf(table_str, 32, "Extended Table (#%d)", table);
    if (NULL == mm_part_add(mm, (DADDR_T) sect_cur, (DADDR_T) 1,
	    MM_TYPE_DESC, table_str, table, -1)) {
	return 1;
    }

    /* Cycle through the four partitions in the table 
     *
     * When another extended partition is found, it is processed
     * inside of the loop
     */
    for (i = 0; i < 4; i++) {
	dos_part *part = &sect.ptable[i];

	/* Get the starting sector and size, we currently
	 * ignore CHS */
	uint32_t part_start = getu32(mm, part->start_sec);
	uint32_t part_size = getu32(mm, part->size_sec);

	if (verbose)
	    fprintf(stderr,
		"load_ext: %d:%d    Start: %" PRIu32 "   Size: %"
		PRIu32 "  Type: %d\n", table, i, part_start, part_size,
		part->ptype);

	if (part_size == 0)
	    continue;

	/* partitions are addressed differently 
	 * in extended partitions */
	if (dos_is_ext(part->ptype)) {

	    /* part start is added to the start of the
	     * first extended partition (the primary
	     * extended partition) */

	    if (sect_ext_base + part_start > max_addr) {
		tsk_errno = TSK_ERR_MM_BLK_NUM;
		snprintf(tsk_errstr, TSK_ERRSTR_L,
		    "dos_load_ext_table: Starting sector too large for image");
		tsk_errstr2[0] = '\0';
		return 1;
	    }

	    if (NULL == mm_part_add(mm,
		    (DADDR_T) (sect_ext_base + part_start),
		    (DADDR_T) part_size, MM_TYPE_DESC,
		    dos_get_desc(part->ptype), table, i))
		return 1;


	    /* Process the extended partition */
	    if (dos_load_ext_table(mm, sect_ext_base + part_start,
		    sect_ext_base, table + 1))
		return 1;
	}

	else {
	    /* part_start is added to the start of the 
	     * current partition for the actual
	     * starting location */

	    if (sect_cur + part_start > max_addr) {
		tsk_errno = TSK_ERR_MM_BLK_NUM;
		snprintf(tsk_errstr, TSK_ERRSTR_L,
		    "dos_load_ext_table: Starting sector too large for image");
		tsk_errstr2[0] = '\0';
		return 1;
	    }
	    if (NULL == mm_part_add(mm, (DADDR_T) (sect_cur + part_start),
		    (DADDR_T) part_size, MM_TYPE_VOL,
		    dos_get_desc(part->ptype), table, i))
		return 1;
	}
    }

    return 0;
}
main()
{
	char path[20];
	int fd;
	//super block read
	fatfs_sb *s1;
	struct Image_info i1;
	uint16_t ssize;
	uint8_t numfat;
	uint8_t numroot;
	uint64_t sectors;
	uint64_t lastCount;
	uint32_t secperfat;
	//cluster size
	uint8_t csize;
	uint64_t firstFactSector;
	uint64_t firstDataSector;
 	uint64_t firstClusterSec;
	uint64_t clusterCnt;
	uint64_t lastCluster;
	uint32_t mask;
	uint64_t sectorRoot; 
 	uint16_t ssize_sh=9;//must be changed for different sector size
	uint32_t dentry_cnt_se;
	uint32_t dentry_cnt_cl;
	uint64_t inumCnt;
	uint64_t firstInum;
	uint64_t lastInum;
	uint64_t rootInum;
	uint64_t block_count;        
	uint64_t first_block;        
	uint64_t last_block; 
	uint64_t last_block_act;     
	char *dinodes;//inodes data structure
	int cnt;
	int flag_for_end;
	printf("Please provide the path \n");
	scanf("%s",path);
	if((fd=open(path,O_RDONLY|O_BINARY))<0)
	{
		printf("Issue with the file open");
	}
//going for calculating the image lenght
	i1.len=lseek(fd,0,SEEK_END);
	lseek(fd,0,SEEK_SET);
	printf("%"PRId64"\n",i1.len);
	cnt=read(fd,(char *)s1,sizeof(* s1));
	//code to get endian format
	check_endian_format(&flag_for_end,s1->magic,FATFS_FS_MAGIC);
	if(flag_for_end==0)
	{
		printf("Big endian \n");
	}
	else
	{
		printf("Little endian \n ");
	}
	ssize=getu16(flag_for_end,s1->ssize);
	printf("Size of sector is %" PRIu16 "\n",ssize);
	
	csize=s1->csize;
	numfat=s1->numfat;
	numroot=getu16(flag_for_end,s1->numroot);
	
	//sectors=getu16(0,s1->sectors16);
	//if(sectors==0)
	//{
	
		sectors=getu32(flag_for_end,s1->sectors32);

		lastCount=sectors-1;
		printf("sectors are %" PRIu64 "\n",sectors);
	
	//}

	//secperfat=getu16(flag_for_end,s1->sectors16);
	//printf("sectors per fat are %" PRIu32 "\n",secperfat);
	if(secperfat==0)
	{
	
		secperfat=getu32(flag_for_end,s1->a.f32.sectperfat32);
		printf("sectors per fat are %" PRIu32 "\n",secperfat);
	
	}

	firstFactSector=getu16(flag_for_end,s1->reserved);
	

	firstDataSector=firstFactSector+secperfat*numfat;
	
	firstClusterSec=firstDataSector+(((numroot) * 32 + ssize - 1) / ssize);	
	printf("first cluster sector %" PRIu64 "\n",firstClusterSec);
	clusterCnt=(sectors-firstClusterSec)/csize;
	lastCluster=clusterCnt+1;
	if(clusterCnt > 65525)	
	{	
		printf("\n Setting mask for FAT 32 system");
		mask=FATFS_32_MASK;
	}
	sectorRoot=getu32(flag_for_end,s1->rootclust);
	dinodes=(char *)malloc(sizeof(csize<<ssize_sh));
	//calculating number of d entries
	dentry_cnt_se=ssize/sizeof(fatfs_dentry);
	dentry_cnt_cl=csize*dentry_cnt_se;
	
	//working with block
	first_block = 0;
    	block_count = sectors;
    	last_block = last_block_act = block_count - 1;
    	block_size = ssize;
	last_block_act =i1.len/block_size - 1;

	//calculation of inode number 
	
    	root_inum = FATFS_ROOTINO;
   	first_inum = FATFS_FIRSTINO;
    	last_inum =(FATFS_SECT_2_INODE(firstDataSector,last_block_act + 1) - 1) + FATFS_NUM_SPECFILE;
    	inum_count = last_inum - first_inum + 1;
	

	
}