[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/wimlib/wimlib-0.2/ -> wim.c (source)

   1  /*
   2  
   3  wimlib - Library for working with WIM files 
   4  Copyright (C) 2010 Carl Thijssen
   5  
   6  This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version.
   7  
   8  This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
   9  
  10  You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 
  11  
  12  */
  13  
  14  #include <stdio.h>
  15  #include <stdlib.h>
  16  #include <string.h>
  17  #include <sys/stat.h>
  18  #include "lzx.h"
  19  #include "wim.h"
  20  
  21  /* Thanks to the chntpw project! */
  22  static char *w2a(void *string, int len)
  23  {
  24     int i, k;
  25      char *cstring;
  26  
  27      int out_len = 0;
  28      for(i = 0; i < len; i += 2)
  29      {
  30          // unsigned v = ((unsigned char *)string)[i] + ((unsigned char *)string)[i+1] * 256u;
  31          unsigned v = ((unsigned char *)string)[i] + ((unsigned char *)string)[i+1] * 512u;
  32          if (v < 256)
  33              out_len += 1;
  34          else if(v < 0x800)
  35              out_len += 2;
  36          else
  37              out_len += 3;
  38      }
  39      cstring = (char *) malloc(out_len+1);
  40      if (!cstring) {
  41          printf("FATAL! ex_next: malloc() failed! Out of memory?\n");
  42          abort();
  43      }
  44  
  45      for(i = 0, k = 0; i < len; i += 2)
  46      {
  47          unsigned v = ((unsigned char *)string)[i] + ((unsigned char *)string)[i+1] * 512u;
  48          if (v < 256)
  49              cstring[k++] = v;
  50          else if(v < 0x800) {
  51              cstring[k++] = 0xc0 | (v >> 6);
  52              cstring[k++] = 0x80 | (v & 0x3f);
  53          } else {
  54              cstring[k++] = 0xe0 | (v >> 12);
  55              cstring[k++] = 0x80 | ((v >> 6) & 0x3f);
  56              cstring[k++] = 0x80 | (v & 0x3f);
  57          }
  58      }
  59      cstring[out_len] = '\0';
  60      return cstring;
  61  }
  62  
  63  static char *a2w(void *string, int len, int *out_len)
  64  {
  65      unsigned char *regw = (unsigned char*) malloc(len*2+2);
  66      unsigned char *out = regw;
  67      unsigned char *in = (unsigned char*) string;
  68  
  69      for (;len>0; ++in, --len) {
  70          if (!(in[0] & 0x80)) {
  71              *out++ = *in;
  72              *out++ = 0;
  73          } else if ((in[0] & 0xe0) == 0xc0 && len >= 2) {
  74              *out++ = (in[0] & 0x1f) << 6 | (in[1] & 0x3f);
  75              *out++ = (in[0] & 0x1f) >> 2;
  76              ++in, --len;
  77          } else if (len >= 3) {
  78              /* assume 3 byte*/
  79              *out++ = (in[1] & 0xf) << 6 | (in[2] & 0x3f);
  80              *out++ = (in[0] & 0xf) << 4 | ((in[1] & 0x3f) >> 2);
  81              in += 2;
  82              len -= 2;
  83          }
  84      }
  85      *out_len = out - regw;
  86      out[0] = out[1] = 0;
  87      return (char *) regw;
  88  }
  89  
  90  DWORD GetDWord(FILE *fp)
  91  {
  92       register DWORD dw;
  93        dw =  (DWORD) (fgetc(fp) & 0xFF);
  94        dw |= ((DWORD) (fgetc(fp) & 0xFF) << 0x08);
  95        dw |= ((DWORD) (fgetc(fp) & 0xFF) << 0x10);
  96        dw |= ((DWORD) (fgetc(fp) & 0xFF) << 0x18);
  97        return(dw);
  98  }
  99  
 100  USHORT GetUshort(FILE *fp)
 101  {
 102        register USHORT w;
 103        w =  (USHORT) (fgetc(fp) & 0xFF);
 104        w |= ((USHORT) (fgetc(fp) & 0xFF) << 0x08);
 105        return(w);
 106  }
 107  
 108  LARGE_INTEGER GetULargeInteger(FILE *fp)
 109  {
 110        register ULARGE_INTEGER li;
 111        li = (ULARGE_INTEGER) (fgetc(fp) & 0xFF);
 112        li |= ((ULARGE_INTEGER) (fgetc(fp) & 0xFF) << 0x08) ;
 113        li |= ((ULARGE_INTEGER) (fgetc(fp) & 0xFF) << 0x10) ;
 114        li |= ((ULARGE_INTEGER) (fgetc(fp) & 0xFF) << 0x18) ;
 115        li |= ((ULARGE_INTEGER) (fgetc(fp) & 0xFF) << 0x20) ;
 116        li |= ((ULARGE_INTEGER) (fgetc(fp) & 0xFF) << 0x28) ;
 117        li |= ((ULARGE_INTEGER) (fgetc(fp) & 0xFF) << 0x30) ;
 118        li |= ((ULARGE_INTEGER) (fgetc(fp) & 0xFF) << 0x38) ;
 119        return(li);
 120  }
 121  
 122  LARGE_INTEGER GetLargeInteger(FILE *fp)
 123  {
 124        register LARGE_INTEGER li;
 125        li = (LARGE_INTEGER) (fgetc(fp) & 0xFF);
 126        li |= ((LARGE_INTEGER) (fgetc(fp) & 0xFF) << 0x08) ;
 127        li |= ((LARGE_INTEGER) (fgetc(fp) & 0xFF) << 0x10) ;
 128        li |= ((LARGE_INTEGER) (fgetc(fp) & 0xFF) << 0x18) ;
 129        li |= ((LARGE_INTEGER) (fgetc(fp) & 0xFF) << 0x20) ;
 130        li |= ((LARGE_INTEGER) (fgetc(fp) & 0xFF) << 0x28) ;
 131        li |= ((LARGE_INTEGER) (fgetc(fp) & 0xFF) << 0x30) ;
 132        li |= ((LARGE_INTEGER) (fgetc(fp) & 0xFF) << 0x38) ;
 133        return(li);
 134  }
 135  
 136  LARGE_INTEGER GetLargeInteger7(FILE *fp)
 137  {
 138        register LARGE_INTEGER li;
 139        li = (LARGE_INTEGER) (fgetc(fp) & 0xFF);
 140        li |= ((LARGE_INTEGER) (fgetc(fp) & 0xFF) << 0x08) ;
 141        li |= ((LARGE_INTEGER) (fgetc(fp) & 0xFF) << 0x10) ;
 142        li |= ((LARGE_INTEGER) (fgetc(fp) & 0xFF) << 0x18) ;
 143        li |= ((LARGE_INTEGER) (fgetc(fp) & 0xFF) << 0x20) ;
 144        li |= ((LARGE_INTEGER) (fgetc(fp) & 0xFF) << 0x28) ;
 145        li |= ((LARGE_INTEGER) (fgetc(fp) & 0xFF) << 0x30) ;
 146        // li |= ((LARGE_INTEGER) (fgetc(fp) & 0xFF) << 0x38) ;
 147        return(li);
 148  }
 149  
 150  BYTE GetFlags1(FILE *fp)
 151  {
 152     register BYTE b;
 153     b = (BYTE) (fgetc(fp) & 0xFF);
 154     return b;
 155  }
 156  
 157  int ReadUnCompressedFile(FILE *fp,LARGE_INTEGER offset, LARGE_INTEGER size, LARGE_INTEGER unpacksize, char *filename)
 158  {
 159    fseek(fp,offset,SEEK_SET);
 160    FILE *outfile=fopen(filename,"wb");
 161    LARGE_INTEGER i=0;
 162    for(i=0;i<size;i++)
 163    {
 164      char curchar=fgetc(fp);
 165      fputc(curchar,outfile);
 166    }
 167    fclose(outfile);
 168    return 0;
 169  }
 170  
 171  int ReadFileResource(FILE *fp,LARGE_INTEGER offset, LARGE_INTEGER size, LARGE_INTEGER unpacksize, char *filename)
 172  {
 173    fseek(fp,offset,SEEK_SET);
 174    unsigned long baseoffset=ftell(fp);
 175    // printf("Base Offset = %u filename =%s\n", baseoffset,filename);
 176    LARGE_INTEGER ChunckSize = 32768;
 177    LARGE_INTEGER NumberOfChuncks = ( unpacksize + ChunckSize - 1 ) >> 15 ;
 178    // printf("Number of chuncks = %u\n",NumberOfChuncks);
 179    int EntrySize = 4 ;
 180    if (unpacksize > (LARGE_INTEGER) 1 << 32)
 181    {
 182      EntrySize = 8 ;
 183    }
 184    //printf ("Entry Size = %d\n",EntrySize);
 185    LARGE_INTEGER ChunckOffsets[NumberOfChuncks];
 186    LARGE_INTEGER j=0;
 187    for (j=0;j<NumberOfChuncks ;j++)
 188    {
 189      LARGE_INTEGER ChunckOffset;
 190      if (j==0)
 191      {
 192        ChunckOffset=0;
 193      } else {
 194        if (EntrySize == 4)
 195        {
 196          ChunckOffset=(LARGE_INTEGER) GetDWord(fp);
 197        } else {
 198          ChunckOffset=GetLargeInteger(fp);
 199        }
 200      }
 201      //printf(" Chunckoffset %d is ",j);
 202      //printf("%u\n",ChunckOffset);
 203      ChunckOffsets[j]=ChunckOffset;
 204    }
 205  
 206    FILE *outfile=fopen(filename,"wb");
 207    if (!outfile)
 208    {
 209      printf("Could not open outfile %s\n",filename);
 210    }
 211    LARGE_INTEGER totalchunks=0;
 212    struct LZXstate *state;
 213    unsigned char ibuf[32768];
 214    unsigned char obuf[32768];
 215  
 216    for (j=0;j<NumberOfChuncks-1;j++)
 217    {
 218      totalchunks=totalchunks+ChunckOffsets[j+1]-ChunckOffsets[j];
 219      LARGE_INTEGER curoffset=ftell(fp);
 220      // printf("Writing Chunck %d at offset %u ", j, curoffset);
 221      // printf("insize %u ", ChunckOffsets[j+1]-ChunckOffsets[j]);
 222      // printf("outsize = %u\n",ChunckSize);
 223      state=LZXinit(15);
 224      LARGE_INTEGER ilen=fread(ibuf,1,ChunckOffsets[j+1]-ChunckOffsets[j],fp);
 225      //printf("ibuf read %u bytes\n",ilen);
 226  
 227      if ( ChunckOffsets[j+1]-ChunckOffsets[j] == ChunckSize )
 228      {
 229          fwrite(ibuf, 1, ChunckSize, outfile);
 230      } else {
 231        int status=LZXdecompress(state,ibuf,obuf,ilen,ChunckSize);
 232        switch(status)
 233        {
 234           case DECR_OK: 
 235                // printf("OK\n");
 236                fwrite(obuf, 1, ChunckSize, outfile);
 237                break;
 238           default:
 239              printf("Written Chunck %d at offset %u ", j, curoffset);
 240              printf("insize %u ", ChunckOffsets[j+1]-ChunckOffsets[j]);
 241              printf("outsize = %u\n",ChunckSize);
 242              printf("ERROR\n");
 243              break;
 244        }
 245      }
 246    }
 247    totalchunks=totalchunks+size-ChunckOffsets[NumberOfChuncks-1];
 248    state=LZXinit(15);
 249    LARGE_INTEGER ilen=fread(ibuf,1,size-ChunckOffsets[NumberOfChuncks-1],fp);
 250    
 251    if (size-ChunckOffsets[NumberOfChuncks-1] >= unpacksize % ChunckSize)
 252    {
 253       printf("Copying %u input bytes to output file of total ",unpacksize % ChunckSize);
 254       printf("%u\n",size-ChunckOffsets[NumberOfChuncks-1]);
 255       fwrite(ibuf, 1,size-ChunckOffsets[NumberOfChuncks-1], outfile);
 256    } else {
 257      int status=LZXdecompress(state,ibuf,obuf,ilen,unpacksize % ChunckSize);
 258      switch(status)
 259      {
 260           case DECR_OK:
 261                fwrite(obuf, 1,unpacksize % ChunckSize, outfile);
 262                break;
 263           default:
 264                printf("isize = %u ",size-ChunckOffsets[NumberOfChuncks-1]);
 265                printf("osize = %u ",unpacksize % ChunckSize);
 266                printf("ERROR\n");
 267                break;
 268      }
 269    }
 270  
 271    LZXreset(state);
 272    fclose(outfile);
 273    return 0;
 274  }
 275  
 276  
 277  FILE_RESOURCE_HEADER *ReadLookupTable(FILE *fp,LARGE_INTEGER offset,LARGE_INTEGER size,LARGE_INTEGER *numoffsets)
 278  {
 279    fseek(fp,offset,SEEK_SET);
 280    unsigned long curoffset=ftell(fp);
 281    //printf("Current Offset = %u size %u \n", curoffset,size);
 282    //printf("numoffsets = %u\n", size/50);
 283  
 284    FILE_RESOURCE_HEADER *FileResourceHeaderList=malloc(sizeof(FILE_RESOURCE_HEADER)*size/50);
 285    // printf("Now here before reading the offsets\n");
 286    
 287    // FILE_RESOURCE_HEADER FileResourceHeader;
 288    LARGE_INTEGER OffsetCount=0;
 289    while(ftell(fp) < offset + size)
 290    {
 291  
 292      FileResourceHeaderList[OffsetCount].ResourceHeaderIndex=OffsetCount;
 293      FileResourceHeaderList[OffsetCount].ResourceHeader.Size=GetLargeInteger7(fp);
 294      FileResourceHeaderList[OffsetCount].ResourceHeader.Flags=GetFlags1(fp);
 295      FileResourceHeaderList[OffsetCount].ResourceHeader.Offset=GetLargeInteger(fp);
 296      FileResourceHeaderList[OffsetCount].ResourceHeader.OriginalSize=GetLargeInteger(fp);
 297      FileResourceHeaderList[OffsetCount].PartNumber=GetUshort(fp);
 298      FileResourceHeaderList[OffsetCount].ReferenceCount=GetDWord(fp);
 299      int result=fread(FileResourceHeaderList[OffsetCount].Hash,sizeof(BYTE),20,fp);
 300  
 301       if (FileResourceHeaderList[OffsetCount].ResourceHeader.Flags & RESHDR_FLAG_METADATA )
 302       {
 303         // This is the resource that points to a metadata file resource
 304         //printf("Resource #%u ",OffsetCount);
 305         //printf("size=%u ",FileResourceHeaderList[OffsetCount].ResourceHeader.Size);
 306         //printf("osize = %u ",FileResourceHeaderList[OffsetCount].ResourceHeader.OriginalSize);
 307         //printf("flags = %u ",FileResourceHeaderList[OffsetCount].ResourceHeader.Flags);
 308         //printf("offset = %u ",FileResourceHeaderList[OffsetCount].ResourceHeader.Offset);
 309         //printf("\n");
 310       }
 311  
 312       //  printf("ResourceHeaderPartNumber = %u\n",FileResourceHeader.PartNumber);
 313       //  printf("ResourceHeaderReferenceCount = %u\n",FileResourceHeader.ReferenceCount);
 314       //  printf("ResourceHeaderHash = |%s|\n",FileResourceHeader.Hash);
 315      
 316      OffsetCount++;
 317    }
 318  
 319    //printf("numoffsets = %u\n", OffsetCount);
 320  
 321    *numoffsets=OffsetCount;
 322    return FileResourceHeaderList;
 323  
 324  }
 325  
 326  int ExtractFile(DIRENTRY *extractfile,FILE_RESOURCE_HEADER *frh, LARGE_INTEGER numoffsets, FILE *fp, CHAR *filename)
 327  {
 328    FILE_RESOURCE_HEADER hashkey;
 329    memcpy(hashkey.Hash,extractfile->Hash,sizeof(BYTE)*20);
 330    FILE_RESOURCE_HEADER *foundhash=bsearch(&hashkey,frh,numoffsets,sizeof(FILE_RESOURCE_HEADER),comparehashes);
 331    if (foundhash != NULL)
 332    {
 333      printf("FOUND %s\n",extractfile->fullpath);
 334      WriteFile(fp,foundhash,filename);
 335    } else {
 336      printf("NOT FOUND %s\n",extractfile->fullpath);
 337      return 1;
 338    }
 339    return 0;
 340  }
 341  
 342  
 343  int WriteFile(FILE *fp,FILE_RESOURCE_HEADER *FileResourceHeader, char *filename)
 344  { 
 345      printf("Now writing file %s\n",filename);;
 346      LARGE_INTEGER rememberoffset=ftell(fp);
 347      if (FileResourceHeader->ResourceHeader.Flags == 0)
 348      {
 349         FILE *outfile=fopen(filename,"wb");
 350         /// KLOPT DIT WEL???
 351         fseek(fp,FileResourceHeader->ResourceHeader.Offset,SEEK_SET);
 352         fwrite(fp, 1, FileResourceHeader->ResourceHeader.Size, outfile);
 353         fclose(outfile);
 354      } else {
 355        if (FileResourceHeader->ResourceHeader.Flags == 4 || FileResourceHeader->ResourceHeader.Flags == 6 )
 356        {
 357          printf("Going to read the file resource at offset %u ",FileResourceHeader->ResourceHeader.Offset);
 358          printf(" Size %u ",FileResourceHeader->ResourceHeader.Size);
 359          printf(" OSize %u\n",FileResourceHeader->ResourceHeader.OriginalSize);
 360          ReadFileResource(fp,FileResourceHeader->ResourceHeader.Offset, FileResourceHeader->ResourceHeader.Size, FileResourceHeader->ResourceHeader.OriginalSize, filename);
 361        } else {
 362          printf("Flags = %d\n",FileResourceHeader->ResourceHeader.Flags);
 363        }
 364      }
 365      fseek(fp,rememberoffset,SEEK_SET);
 366      return 0;
 367  }
 368  
 369  int PrintXML(BYTE *xml,LARGE_INTEGER size)
 370  {
 371    if (size <= 2)
 372    {
 373      printf("ERROR: Wrong XML size: %u\n",size);
 374      return 1;
 375    }
 376  
 377    BYTE *xmlnoheader=(BYTE *)malloc(sizeof(BYTE) * (size -2));
 378  
 379    memcpy(xmlnoheader,&(xml[2]),size-2);
 380  
 381    char *xmlstring=strdup(w2a(xmlnoheader,size-2));
 382    printf("%s",xmlstring);
 383    return 0;
 384  }
 385  
 386  BYTE *ReadXML(FILE *fp,LARGE_INTEGER offset,LARGE_INTEGER size)
 387  {
 388      BYTE *buf=malloc(sizeof(BYTE)*size);
 389      LARGE_INTEGER ilen=fread(buf,size,sizeof(BYTE),fp);
 390      return buf;
 391  }
 392  
 393  
 394  RESHDR_DISK_SHORT WriteXML(FILE *fp,BYTE *buf,LARGE_INTEGER size)
 395  {
 396    RESHDR_DISK_SHORT result;
 397    result.Offset=ftell(fp);
 398    fwrite(buf,size,sizeof(BYTE),fp);
 399  
 400    result.Size=size;
 401    result.OriginalSize=size;
 402    result.Flags=0;
 403  
 404    return result;
 405  }
 406  
 407  int PrintSecurityData(SECURITY_DATA sd)
 408  {
 409      printf("SecurityData\n");
 410      printf("------------\n");
 411      printf("Total length = %u\n",sd.TotalLength);
 412      printf("NumEntries = %u\n",sd.NumEntries);
 413      int k=0;
 414      for (k=0;k<sd.NumEntries;k++)
 415      {
 416        printf("Entry %u",k);
 417        printf(" has size %u",sd.Sizes[k]);
 418        int l=0;
 419        printf("and Descriptor |",k);
 420        for (l=0;l<sd.Sizes[k];l++)
 421        {
 422          printf("%x",sd.Descriptors[k][l]);
 423        }
 424        printf("|\n");
 425      }
 426  }
 427  
 428  SECURITY_DATA ReadSecurityData(FILE *fp,LARGE_INTEGER offset)
 429  {
 430    // printf("Reading Security block at offset %u\n",offset);
 431  
 432    fseek(fp,offset,SEEK_SET);
 433  
 434    SECURITY_DATA SecurityData;
 435    SecurityData.TotalLength=GetDWord(fp);
 436    SecurityData.NumEntries=GetDWord(fp);
 437  
 438    // printf("SecurityData Total Length= %u\n",SecurityData.TotalLength);
 439    // printf("SecurityData NumEntries = %u\n",SecurityData.NumEntries);
 440  
 441    LARGE_INTEGER pos=ftell(fp);
 442    //printf("Current Position = %u\n",pos);
 443    //while((pos & 7) != 0)
 444    //{
 445    //  pos++;
 446    //}
 447    // printf("Current Position = %u\n",pos);
 448    fseek(fp,pos,SEEK_SET);
 449  
 450    SecurityData.Sizes=(LARGE_INTEGER *)malloc(SecurityData.NumEntries*sizeof(LARGE_INTEGER));
 451    SecurityData.Descriptors=(BYTE **)malloc(SecurityData.NumEntries*sizeof(BYTE*));
 452    LARGE_INTEGER TotalSecuritySize=0;
 453    DWORD k=0;
 454    for (k=0;k<SecurityData.NumEntries;k++)
 455    {
 456      LARGE_INTEGER position=ftell(fp);
 457      LARGE_INTEGER mysize=GetLargeInteger(fp);
 458      // printf("SecurityDescriptor %u has size %u ",k,mysize);
 459      //printf("at offset %u\n",position);
 460      SecurityData.Sizes[k]=mysize;
 461      TotalSecuritySize+=mysize;
 462    }
 463    // printf("Total securityDescriptor size = %u\n",TotalSecuritySize);
 464    for (k=0;k<SecurityData.NumEntries;k++)
 465    {
 466      BYTE *curpoint=(BYTE *)malloc(sizeof(BYTE)*SecurityData.Sizes[k]);
 467      int result=fread(curpoint,sizeof(BYTE),SecurityData.Sizes[k],fp);
 468      SecurityData.Descriptors[k]=curpoint;
 469    }
 470    
 471    fseek(fp,offset+SecurityData.TotalLength,SEEK_SET);
 472    LARGE_INTEGER curpos=ftell(fp);
 473    // printf("After Security data has been read the Position = %u\n",curpos);
 474    return SecurityData;
 475  }
 476  
 477  int comparehashes (const void* x, const void *y)
 478  {
 479    FILE_RESOURCE_HEADER *headerx=(FILE_RESOURCE_HEADER *) x;
 480    FILE_RESOURCE_HEADER *headery=(FILE_RESOURCE_HEADER *) y;
 481    return memcmp((BYTE *) headerx->Hash, (BYTE *)headery->Hash, 20);
 482  }
 483  
 484  int compareoffsets (const void* a, const void *b)
 485  {
 486    FILE_RESOURCE_HEADER *headerx=(FILE_RESOURCE_HEADER *) a;
 487    FILE_RESOURCE_HEADER *headery=(FILE_RESOURCE_HEADER *) b;
 488    
 489    printf("Comparing %u ",headerx->ResourceHeader.Offset);
 490    printf("to %u ",headery->ResourceHeader.Offset);
 491    
 492    if (headerx->ResourceHeader.Offset == headery->ResourceHeader.Offset)
 493    {
 494      return 0;
 495    } else {
 496      if (headerx->ResourceHeader.Offset > headery->ResourceHeader.Offset)
 497      {
 498        return 1;
 499      } else {
 500        return -1;
 501      }
 502    }
 503    //return (headerx->ResourceHeader.Offset - headery->ResourceHeader.Offset);
 504  }
 505  
 506  DIRENTRY *ReadDirEntry(FILE *fp)
 507  {
 508    DIRENTRY *Direntry=malloc(sizeof(DIRENTRY));
 509    LARGE_INTEGER curpos=ftell(fp);
 510    // printf("Reading entry at offset %u : length",curpos);
 511    Direntry->Length=GetLargeInteger(fp);    
 512    // printf(" Length = %u\n",Direntry->Length);
 513    Direntry->SubdirOffset=0;
 514    Direntry->FileNameAscii=strdup("");
 515    Direntry->next=NULL;
 516    Direntry->DirContentSize=0;
 517  
 518    if (Direntry->Length >=104)
 519    {
 520          Direntry->Attributes=GetDWord(fp);
 521          Direntry->SecurityId=GetDWord(fp);
 522          Direntry->SubdirOffset=GetLargeInteger(fp);
 523          Direntry->Unused1=GetLargeInteger(fp);
 524          Direntry->Unused2=GetLargeInteger(fp);
 525          Direntry->CreationTime=GetLargeInteger(fp);
 526          Direntry->LastAccessTime=GetLargeInteger(fp);
 527          Direntry->LastWriteTime=GetLargeInteger(fp);
 528  
 529          Direntry->Hash=malloc(sizeof(BYTE) * 20);
 530          int result=fread(Direntry->Hash,sizeof(BYTE),20,fp);
 531  
 532          Direntry->ReparseTag=GetDWord(fp);
 533          // Direntry->ReparseReserved=GetDWord(fp);
 534          // Direntry->ReparseReserved=GetDWord(fp);
 535          Direntry->HardLink=GetLargeInteger(fp);
 536          Direntry->Streams=GetUshort(fp);
 537          Direntry->ShortNameLength=GetUshort(fp);
 538          Direntry->FileNameLength=GetUshort(fp);
 539  
 540  
 541          Direntry->FileName=(char *)malloc(sizeof(char) * Direntry->FileNameLength);
 542          result=fread(Direntry->FileName,sizeof(CHAR)*Direntry->FileNameLength,1,fp);
 543          Direntry->FileNameAscii=strdup(w2a(Direntry->FileName,Direntry->FileNameLength));
 544  
 545          Direntry->FileNamePad=GetUshort(fp);
 546  
 547          Direntry->ShortFileName=(char *)malloc(sizeof(char) * Direntry->ShortNameLength);
 548          result=fread(Direntry->ShortFileName,sizeof(CHAR)*Direntry->ShortNameLength,1,fp);
 549          Direntry->ShortFileNameAscii=strdup(w2a(Direntry->ShortFileName,Direntry->ShortNameLength));
 550          
 551         
 552         if(Direntry->Streams >0)
 553         {
 554           Direntry->StreamEntries=(STREAM_ENTRY *)malloc(Direntry->Streams*sizeof(STREAM_ENTRY));
 555           USHORT i;
 556           for(i=0;i<Direntry->Streams;i++)
 557           {
 558               printf("Getting Streamentry %d\n",i);
 559               Direntry->StreamEntries[i].Length=GetLargeInteger(fp);
 560               Direntry->StreamEntries[i].Unused1=GetLargeInteger(fp);
 561               int result=fread(&(Direntry->StreamEntries[i].Hash),sizeof(BYTE),20,fp);
 562               Direntry->StreamEntries[i].StreamNameLength=GetUshort(fp);
 563               Direntry->StreamEntries[i].StreamName=(CHAR *)malloc(sizeof(CHAR)*Direntry->StreamEntries[i].StreamNameLength);
 564               result=fread(&(Direntry->StreamEntries[i].StreamName),sizeof(Direntry->StreamEntries[i].StreamName),1,fp);
 565           }
 566         }
 567      LARGE_INTEGER bytes_read = ftell(fp)-curpos;
 568      if (bytes_read != Direntry->Length)
 569      {
 570        Direntry->rest=(BYTE *)malloc(sizeof(BYTE)*(Direntry->Length-bytes_read));
 571        Direntry->restsize=Direntry->Length-bytes_read;
 572        //printf("WARNING Adding %u rest bytes for %s\n",Direntry->restsize,Direntry->fullpath);
 573        int result=fread(Direntry->rest,sizeof(Direntry->rest),1,fp);
 574  
 575        /*
 576        if (Direntry->FileNamePad != 0)
 577        {
 578          printf("        NONZERO PAD %u ",Direntry->FileNamePad);
 579        }
 580        printf("Length : %u ",Direntry->ShortNameLength);
 581        printf("Length : %u ",Direntry->Length);
 582        printf("mod 8 : %u ",Direntry->Length % 8);
 583        printf("Bytes_read : %u ",bytes_read);
 584        printf("Storing extrabytes from direntry: %u |",Direntry->Length-bytes_read);
 585        int j=0;
 586        for (j=0;j<Direntry->Length-bytes_read;j++)
 587        { 
 588          printf("%x",Direntry->rest[j]) ;
 589        }
 590        printf("| |%s| ",Direntry->FileNameAscii);
 591        printf("|%s",Direntry->ShortFileNameAscii);
 592        printf("|\n");
 593        */
 594        
 595  
 596      } else {
 597        // printf("We have a good entry here without extra bytes...\n");
 598        Direntry->restsize=0;
 599      }
 600    } else {
 601      if (Direntry->Length > 0)
 602      {
 603        printf("                           Entry too small: %u\n",Direntry->Length);
 604      }
 605    }
 606    return Direntry;
 607  }
 608  
 609  
 610  int PrintDirEntry(DIRENTRY *Direntry)
 611  {
 612      printf("Direntry.Length = %u\n",Direntry->Length);
 613      printf("Direntry.Attributes = %u\n",Direntry->Attributes);
 614      printf("Direntry.SubdirOffset = %u\n",Direntry->SubdirOffset);
 615      printf("Direntry.Unused1 = %u\n",Direntry->Unused1);
 616      printf("Direntry.Unused2 = %u\n",Direntry->Unused2);
 617      printf("Direntry.CreationTime = %u\n",Direntry->CreationTime);
 618      printf("Direntry.LastAccessTime = %u\n",Direntry->LastAccessTime);
 619      printf("Direntry.LastWriteTime = %u\n",Direntry->LastWriteTime);
 620      printf("Direntry.Hash = |");
 621      int i=0;
 622      for (;i<20;i++)
 623      {
 624         printf("%2x",(Direntry->Hash)[i]);
 625      }
 626      printf ("|\n");
 627      printf("Direntry.Hash = %s\n",Direntry->Hash);
 628      printf("Direntry.ReparseTag = %u\n",Direntry->ReparseTag);
 629      printf("Direntry.HardLink = %u\n",Direntry->HardLink);
 630      printf("Direntry.Streams = %u\n",Direntry->Streams);
 631      printf("Direntry.ShortNameLength = %u\n",Direntry->ShortNameLength);
 632      printf("Direntry.FileNameLength = %u\n",Direntry->FileNameLength);
 633      printf("Direntry.FileName = %s\n",Direntry->FileName);
 634      printf("Direntry.FileNameAscii = %s\n",Direntry->FileNameAscii);
 635      printf("Direntry.fullpath = |%s|\n",Direntry->fullpath);
 636    return 0;
 637  }
 638  
 639  RESHDR_DISK_SHORT WriteIntegrity(FILE *fp)
 640  {
 641    RESHDR_DISK_SHORT result;
 642    result.Offset=0;
 643    result.Size=0;
 644    result.OriginalSize=0;
 645    result.Flags=0;
 646    return result;
 647  }
 648  
 649  RESHDR_DISK_SHORT WriteBootMetaData(FILE *fp,BOOT_META_DATA bmd)
 650  {
 651    RESHDR_DISK_SHORT result;
 652    result.Offset=ftell(fp);
 653  
 654    LARGE_INTEGER curoffset=bmd.SecurityData.TotalLength;
 655  
 656    WriteSecurityData(fp,bmd.SecurityData);
 657    WriteDirentries2(fp,bmd.DirEntry,curoffset);
 658  
 659    result.Size=ftell(fp)-result.Offset;
 660    result.OriginalSize=result.Size;
 661    result.Flags=0;
 662    return result;
 663  }
 664  
 665  
 666  int PrintDirentries(DIRENTRY *Direntry,LARGE_INTEGER myoffset)
 667  {
 668     DIRENTRY *keepentry=Direntry;
 669     LARGE_INTEGER keepoffset=myoffset;
 670     if(Direntry->kids !=NULL)
 671     {
 672       myoffset+=Direntry->CurDirSize;
 673     }
 674     while(Direntry != NULL)
 675     {
 676       printf("OFFSET = %u ",myoffset);
 677       if(Direntry->kids !=NULL)
 678       {
 679         printf("Directory = %s",Direntry->fullpath);
 680         printf(" LENGTH = %u",Direntry->Length);
 681         printf(" CTIME = %llu",Direntry->CreationTime);
 682         printf(" CURDIRSIZE %u",Direntry->CurDirSize);
 683         printf(" DIRSIZE %u",Direntry->DirContentSize);
 684         printf(" SUBDIROFFSET = %u\n",myoffset);
 685         myoffset+=Direntry->DirContentSize;
 686       } else {
 687         printf("File = %s",Direntry->fullpath);
 688         printf(" LENGTH= %u\n",Direntry->Length);
 689       }
 690       printf(" RESTSIZE= %u\n",Direntry->restsize);
 691       Direntry=Direntry->nextbrother;
 692     }
 693  
 694     Direntry=keepentry;
 695     myoffset=keepoffset;
 696  
 697     while(Direntry != NULL)
 698     {
 699       PrintDirentries(Direntry->kids,myoffset);
 700       myoffset+=Direntry->DirContentSize;
 701       Direntry=Direntry->nextbrother;
 702     }
 703  }
 704  
 705  int AddDirHere(DIRENTRY *tree,DIRENTRY *newfile)
 706  {
 707    DIRENTRY *curentry=tree;
 708    newfile->SecurityId=tree->SecurityId;
 709    newfile->CreationTime=tree->CreationTime;
 710    newfile->LastAccessTime=tree->LastAccessTime;
 711    newfile->LastWriteTime=tree->LastWriteTime;
 712    DIRENTRY *thekids=tree->kids;
 713    if (thekids->Length == 0)
 714    {
 715      newfile->nextbrother=thekids;
 716      tree->kids=newfile;
 717      return 0;
 718    }
 719    DIRENTRY *previousentry=thekids;
 720    curentry=thekids->nextbrother;
 721    while(curentry->Length != 0)
 722    {
 723      // printf("Current entry = %s\n",curentry->fullpath);
 724      previousentry=curentry;
 725      curentry=curentry->nextbrother;
 726    }
 727    newfile->nextbrother=curentry;
 728    previousentry->nextbrother=newfile;
 729    // tree->CurDirSize+=newfile->Length;
 730    return 0;
 731  }
 732  
 733  
 734  int AddDir(DIRENTRY *tree, DIRENTRY *newfile, CHAR *path)
 735  {
 736    DIRENTRY *Direntry=tree;
 737    // printf("NOW ENTERING addition of file %s to %s\n",newfile->FileNameAscii,path);
 738     while(Direntry != NULL)
 739     {
 740       if(Direntry->kids !=NULL)
 741       {
 742         // printf("Directory = %s",Direntry->fullpath);
 743         if (!strcasecmp(Direntry->fullpath,path))
 744         {
 745           // printf("Found the directory to add the file to: %s\n",path);
 746           Direntry->DirContentSize+=newfile->Length+8;
 747           AddDirHere(Direntry,newfile);
 748           return 0;
 749         } else {
 750           //traverse further into the tree
 751           int result = AddDir(Direntry->kids,newfile,path);
 752           if (result==0)
 753           {
 754             // Added the entry underneath this path
 755             // printf("Added %u",newfile->DirContentSize);
 756             // printf("To directory %s",Direntry->fullpath);
 757             Direntry->DirContentSize+=newfile->DirContentSize;
 758             return 0;
 759           }
 760        }
 761       }
 762       Direntry=Direntry->nextbrother;
 763     }
 764    // Not Found in this tree, returning 1
 765    return 1;
 766  }
 767  
 768  int AddFile2(DIRENTRY *tree, DIRENTRY *newfile, CHAR *path)
 769  {
 770    DIRENTRY *Direntry=tree;
 771    // printf("NOW ENTERING addition of file %s to %s\n",newfile->FileNameAscii,path);
 772     while(Direntry != NULL)
 773     {
 774       if(Direntry->kids !=NULL)
 775       {
 776         // printf("Directory = %s",Direntry->fullpath);
 777         if (!strcasecmp(Direntry->fullpath,path))
 778         {
 779           // printf("Found the diredtory to add the file to: %s\n",path);
 780           Direntry->DirContentSize+=newfile->Length;
 781           newfile->nextbrother=Direntry->kids;
 782  
 783           newfile->SecurityId=Direntry->SecurityId;
 784           newfile->CreationTime=Direntry->CreationTime;
 785           newfile->LastAccessTime=Direntry->LastAccessTime;
 786           newfile->LastWriteTime=Direntry->LastWriteTime;
 787  
 788           Direntry->kids=newfile;
 789           // new file added, stop traversing and return success
 790           return 0;
 791         } else {
 792           //traverse further into the tree
 793           int result = AddFile2(Direntry->kids,newfile,path);
 794           if (result==0)
 795           {
 796             // Added the entry underneath this path
 797             Direntry->DirContentSize+=newfile->Length;
 798             return 0;
 799           }
 800        }
 801       }
 802       Direntry=Direntry->nextbrother;
 803     }
 804    // Not Found in this tree, returning 1
 805    return 1;
 806  }  
 807  
 808  
 809  DIRENTRY *FindFile2(DIRENTRY *tree, CHAR *path, CHAR *filename)
 810  {
 811    DIRENTRY *Direntry=tree;
 812    // printf("NOW ENTERING RENAME of file %s to %s\n",path,newfilename);
 813     while(Direntry != NULL)
 814     {
 815       if(Direntry->kids !=NULL)
 816       {
 817         //printf("Directory = %s\n",Direntry->fullpath);
 818         DIRENTRY *result=FindFile2(Direntry->kids,path,filename);
 819         if(result != NULL)
 820         {
 821           return result;
 822         }
 823       } else {
 824         if (!strcasecmp(Direntry->FileNameAscii,filename))
 825         {
 826            // printf("Found file %s in path %s, now checking path\n",filename,tree->fullpath);
 827            CHAR *checkfullpath=malloc(strlen(path) + strlen(filename) + 2);
 828            strcpy(checkfullpath,path);
 829            strcat(checkfullpath,"/");
 830            strcat(checkfullpath,filename);
 831            if (!strcasecmp("",path) || !strcasecmp(checkfullpath,Direntry->fullpath))
 832            {
 833              printf("FOUND File = %s as %s\n",Direntry->FileNameAscii,Direntry->fullpath);
 834              return Direntry;
 835            }
 836         }
 837       }
 838       Direntry=Direntry->nextbrother;
 839     }
 840    // not found
 841    return NULL;
 842  }
 843  
 844  int RenameFile2(DIRENTRY *tree, CHAR *path,CHAR *newfilename)
 845  {
 846    DIRENTRY *Direntry=tree;
 847    // printf("NOW ENTERING RENAME of file %s to %s\n",path,newfilename);
 848    int newsize=0;
 849    CHAR *wnewname=(CHAR *)a2w(newfilename,strlen(newfilename),&newsize);
 850     while(Direntry != NULL)
 851     {
 852       if(Direntry->kids !=NULL)
 853       {
 854         // printf("Directory = %s",Direntry->fullpath);
 855         RenameFile2(Direntry->kids,path,newfilename);
 856       } else {
 857         // printf("File = %s",Direntry->fullpath);
 858         if (!strcasecmp(Direntry->fullpath,path))
 859         {
 860            // printf("FOUND File = %s\n",Direntry->fullpath);
 861            if (newsize != Direntry->FileNameLength)
 862            {
 863              printf("ERROR: different file name size: %u",newsize);
 864              printf(" current size: %u\n",Direntry->FileNameLength);
 865            } else {
 866              Direntry->FileName = wnewname ;
 867            }
 868         }
 869       }
 870       Direntry=Direntry->nextbrother;
 871     }
 872  
 873    return 0;
 874  }
 875  
 876  int WriteDirentries2(FILE *fp,DIRENTRY *Direntry,LARGE_INTEGER myoffset)
 877  {
 878     DIRENTRY *current=Direntry;
 879     LARGE_INTEGER curdiroffset=myoffset;
 880     LARGE_INTEGER initialoffset=myoffset;
 881  
 882     // Determine currents directory size
 883     LARGE_INTEGER CurDirSize=8;
 884     while(current != NULL)
 885     {
 886       CurDirSize+=current->Length; 
 887       current=current->nextbrother;
 888     }
 889     current=Direntry;
 890  
 891     // printf("Current dir size = %u\n",CurDirSize);
 892  
 893     LARGE_INTEGER keepoffset=myoffset;
 894  
 895     // Print current directory contents
 896     while(current != NULL)
 897     {
 898       //printf("OFFSET = %u ",curdiroffset);
 899       curdiroffset+=current->Length;
 900       if(current->kids ==NULL)
 901       {
 902         //printf("File = %s",current->fullpath);
 903         //printf(" LENGTH= %u\n",current->Length);
 904         WriteDirEntry(fp,current);
 905       } else {
 906         //printf("Directory = %s",current->fullpath);
 907         //printf(" LENGTH= %u",current->Length);
 908         //printf(" MYOFFSET= %u", myoffset );
 909         //printf(" CURDIRSIZE= %u", CurDirSize );
 910         //printf(" DIRCONTENTSIZE= %u", current->DirContentSize );
 911         //printf(" SUBDIROFFSET= %u\n",myoffset +CurDirSize);
 912         current->SubdirOffset=myoffset+CurDirSize;
 913         WriteDirEntry(fp,current);
 914         myoffset+=current->DirContentSize;
 915       }
 916      current=current->nextbrother;
 917     }
 918  
 919     // Print Subdirs Directories
 920     current=Direntry; // go back to the start...
 921     myoffset=keepoffset;
 922     while(current != NULL)
 923     {
 924       if(current->kids !=NULL)
 925       {
 926         //printf("Directory = %s",current->fullpath);
 927         //printf(" LENGTH = %u",current->Length);
 928         //printf(" DIRSIZE %u",current->DirContentSize);
 929         //printf(" MYOFFSET %u",myoffset);
 930         //printf(" CURDIRSIZE %u",CurDirSize);
 931         //printf(" SUBDIROFFSET = %u\n",myoffset + CurDirSize);
 932         WriteDirentries2(fp,current->kids,myoffset+CurDirSize);
 933         myoffset+=current->DirContentSize;
 934       } 
 935       current=current->nextbrother;
 936     }
 937     return 0;
 938  }
 939  
 940  
 941  int PrintDirentries2(DIRENTRY *Direntry,LARGE_INTEGER myoffset)
 942  {
 943     DIRENTRY *current=Direntry;
 944     LARGE_INTEGER curdiroffset=myoffset;
 945     LARGE_INTEGER initialoffset=myoffset;
 946  
 947     // Determine currents directory size
 948     LARGE_INTEGER CurDirSize=8;
 949     while(current != NULL)
 950     {
 951       CurDirSize+=current->Length; 
 952       current=current->nextbrother;
 953     }
 954     current=Direntry;
 955  
 956     // printf("Current dir size = %u\n",CurDirSize);
 957  
 958     LARGE_INTEGER keepoffset=myoffset;
 959  
 960     // Print current directory contents
 961     while(current != NULL)
 962     {
 963       printf("OFFSET = %u ",curdiroffset);
 964       curdiroffset+=current->Length;
 965       if(current->kids ==NULL)
 966       {
 967         printf("File = %s",current->fullpath);
 968         printf(" LENGTH= %u",current->Length);
 969       } else {
 970         printf("Directory = %s",current->fullpath);
 971         printf(" LENGTH= %u",current->Length);
 972         printf(" MYOFFSET= %u", myoffset );
 973         printf(" CURDIRSIZE= %u", CurDirSize );
 974         printf(" CTIME= %llu", current->CreationTime );
 975         printf(" DIRCONTENTSIZE= %u", current->DirContentSize );
 976         printf(" SUBDIROFFSET= %u",myoffset +CurDirSize);
 977         myoffset+=current->DirContentSize;
 978       }
 979      printf(" RESTSIZE= %u\n",current->restsize);
 980      current=current->nextbrother;
 981     }
 982  
 983     // Print Subdirs Directories
 984     current=Direntry; // go back to the start...
 985     myoffset=keepoffset;
 986     while(current != NULL)
 987     {
 988       if(current->kids !=NULL)
 989       {
 990         //printf("Directory = %s",current->fullpath);
 991         //printf(" LENGTH = %u",current->Length);
 992         //printf(" DIRSIZE %u",current->DirContentSize);
 993         //printf(" MYOFFSET %u",myoffset);
 994         //printf(" CURDIRSIZE %u",CurDirSize);
 995         //printf(" SUBDIROFFSET = %u\n",myoffset + CurDirSize);
 996         PrintDirentries2(current->kids,myoffset+CurDirSize);
 997         myoffset+=current->DirContentSize;
 998       } 
 999       current=current->nextbrother;
1000     }
1001     return 0;
1002  }
1003  
1004  LARGE_INTEGER CalculateDirContents(DIRENTRY *Direntry)
1005  {
1006     Direntry->DirContentSize=8; // Starting off with 8 bytes corresponding to the End-Of-Dir marker
1007  
1008     DIRENTRY *current=Direntry->kids;
1009     while(current != NULL)
1010     {
1011       printf("File = %s\n",current->fullpath);
1012       Direntry->DirContentSize+=current->Length;
1013  
1014       if(current->kids !=NULL)
1015       {
1016         Direntry->DirContentSize+=CalculateDirContents(current->kids);
1017       }
1018       current=current->nextbrother;
1019     }
1020     printf("Contents of %s ",Direntry->fullpath);
1021     printf(" Has Size %u\n",Direntry->DirContentSize);
1022     return Direntry->DirContentSize;
1023  }
1024  
1025  int DeleteFile(char *filepath,DIRENTRY *Direntry)
1026  {
1027     int result=1;
1028     while(Direntry != NULL && Direntry->next != NULL)
1029     {
1030       DIRENTRY *NextEntry=Direntry->next;
1031       if(!strcasecmp(filepath,NextEntry->fullpath))
1032       {
1033          printf("FOUND %s\n",filepath);
1034          Direntry->next = NextEntry->next;
1035          result=0;
1036          break;
1037          // free(tmpde);
1038       }
1039       Direntry=Direntry->next;
1040     }
1041    return result;
1042  }
1043  
1044  DIRENTRY *CreateDirectory(char *filename, char *destpath, BYTE *filehash)
1045  {
1046  
1047        DIRENTRY *newfile=malloc(sizeof(DIRENTRY));
1048  
1049        newfile->Attributes=FILE_ATTRIBUTE_DIRECTORY;
1050        newfile->SecurityId=0;
1051        newfile->SubdirOffset=100; // will be adjusted later on
1052        newfile->Unused1=0;
1053        newfile->Unused2=0;
1054  
1055        // Just copy the file-time from the parent directory
1056        newfile->CreationTime=0;
1057        newfile->LastAccessTime=0;
1058        newfile->LastWriteTime=0;
1059  
1060        // we recieved the hash in the parameters
1061        newfile->Hash=filehash;
1062        memcpy(newfile->Hash,filehash,20);
1063  
1064        newfile->ReparseTag=0;
1065        newfile->ReparseReserved=0;
1066        newfile->HardLink=0;
1067        newfile->Streams=0;
1068  
1069        newfile->FileNameAscii=strdup(filename);
1070        newfile->FileName=a2w(filename,strlen(filename),(int *) &(newfile->FileNameLength));
1071        newfile->ShortNameLength=0;
1072        newfile->FileNamePad=0;
1073  
1074        newfile->Length=104+newfile->FileNameLength;
1075  
1076        newfile->rest=NULL;
1077        newfile->restsize= 8 - (newfile->Length % 8);
1078  
1079        if ( newfile->restsize != 0  && newfile->restsize != 8)
1080        {
1081           // printf("Length=%u ",newfile->Length);
1082           // printf("Restsize = %u\n",newfile->restsize);
1083           newfile->rest=(BYTE *)malloc(newfile->restsize);
1084           int i=0;
1085           for(i=0;i<newfile->restsize;i++)
1086           {
1087             newfile->rest[i]=0;
1088           }
1089           newfile->Length+=newfile->restsize;
1090        } else {
1091          newfile->restsize=0;
1092        }
1093  
1094        newfile->DirContentSize=8;
1095  
1096        newfile->fullpath=malloc(strlen(destpath) + strlen(filename) + 2);
1097        strcpy(newfile->fullpath,destpath);
1098        strcat(newfile->fullpath,"/");
1099        strcat(newfile->fullpath,filename);
1100  
1101        DIRENTRY *eod=malloc(sizeof(DIRENTRY));
1102        eod->Length=0;
1103        eod->kids=NULL;
1104        eod->nextbrother=NULL;
1105        eod->fullpath=malloc(strlen(newfile->fullpath) + 3);
1106        strcpy(eod->fullpath,newfile->fullpath);
1107        strcat(eod->fullpath,"/");
1108  
1109        newfile->kids=eod;
1110  
1111        return newfile;
1112  }
1113  
1114  DIRENTRY *CreateFile(char *filename, char *destpath, BYTE *filehash)
1115  {
1116  
1117        DIRENTRY *newfile=malloc(sizeof(DIRENTRY));
1118  
1119        newfile->Attributes=FILE_ATTRIBUTE_NORMAL;
1120        newfile->SecurityId=0;
1121        newfile->SubdirOffset=0;
1122        newfile->Unused1=0;
1123        newfile->Unused2=0;
1124  
1125        // Just copy the file-time from the parent directory
1126        newfile->CreationTime=0;
1127        newfile->LastAccessTime=0;
1128        newfile->LastWriteTime=0;
1129  
1130        // we recieved the hash in the parameters
1131        newfile->Hash=malloc(sizeof(BYTE)*20);
1132        memcpy(newfile->Hash,filehash,20);
1133  
1134        newfile->ReparseTag=0;
1135        newfile->ReparseReserved=0;
1136        newfile->HardLink=0;
1137        newfile->Streams=0;
1138  
1139        newfile->FileNameAscii=strdup(filename);
1140        newfile->FileName=a2w(filename,strlen(filename),(int *) &(newfile->FileNameLength));
1141        newfile->ShortNameLength=0;
1142        newfile->FileNamePad=0;
1143  
1144        newfile->Length=104+newfile->FileNameLength;
1145  
1146        newfile->rest=NULL;
1147        newfile->restsize= 8 - (newfile->Length % 8);
1148  
1149        if ( newfile->restsize != 0  && newfile->restsize != 8)
1150        {
1151           // printf("Length=%u ",newfile->Length);
1152           // printf("Restsize = %u\n",newfile->restsize);
1153           newfile->rest=(BYTE *)malloc(newfile->restsize);
1154           int i=0;
1155           for(i=0;i<newfile->restsize;i++)
1156           {
1157             newfile->rest[i]=0;
1158           }
1159           newfile->Length+=newfile->restsize;
1160        } else {
1161          newfile->restsize=0;
1162        }
1163  
1164        newfile->fullpath=malloc(strlen(destpath) + strlen(filename) + 2);
1165        strcpy(newfile->fullpath,destpath);
1166        strcat(newfile->fullpath,"/");
1167        strcat(newfile->fullpath,filename);
1168  
1169        return newfile;
1170  }
1171  
1172  
1173  DIRENTRY *ReadDir2(FILE *fp,LARGE_INTEGER offset,char *path,DIRENTRY *me,LARGE_INTEGER *content)
1174  { 
1175    DIRENTRY *mydad=me;
1176    mydad->CurDirSize=0;
1177    LARGE_INTEGER CurSize=0;
1178    for(;;)
1179    {
1180      fseek(fp,offset,SEEK_SET);
1181      LARGE_INTEGER curpos=ftell(fp);
1182      // printf("Reading at offset %u for path %s\n",curpos, path);
1183      DIRENTRY *curentry=ReadDirEntry(fp);
1184      // printf("DirEntry read for %s\n",curentry->FileNameAscii);
1185      *content+=curentry->Length;
1186      mydad->CurDirSize+=curentry->Length;
1187      curentry->fullpath=(CHAR *)malloc(sizeof(CHAR)*(strlen(path)+strlen(curentry->FileNameAscii) + 3));
1188      strcpy(curentry->fullpath,path);
1189      strcat(curentry->fullpath,"/");
1190      strcat(curentry->fullpath,curentry->FileNameAscii);
1191      me->nextbrother=curentry;
1192      me=me->nextbrother;
1193      
1194      if (curentry->Length == 0)
1195      {
1196         if (me->DirContentSize == 0)
1197         {
1198            *content+=8;
1199         }
1200         return(mydad->nextbrother);
1201      } else {
1202        if(curentry->SubdirOffset!=0)
1203        {
1204          char *newpath=(char *)malloc(strlen(curentry->FileNameAscii)+strlen(path)+3);
1205          strcpy(newpath,path);
1206          newpath=strcat(newpath,"/");
1207          newpath=strcat(newpath,curentry->FileNameAscii);
1208          me->DirContentSize=0;
1209          me->kids=ReadDir2(fp,curentry->SubdirOffset,newpath,me,&(me->DirContentSize));
1210          *content+=me->DirContentSize;
1211        } 
1212      }
1213      offset=curpos+curentry->Length;
1214    }
1215  }
1216  
1217  DIRENTRY *ReadDir(FILE *fp,LARGE_INTEGER *offset,char *path,DIRENTRY *last)
1218  {
1219      fseek(fp,*offset,SEEK_SET);
1220      LARGE_INTEGER curpos=ftell(fp);
1221      last->next=ReadDirEntry(fp);
1222      last=last->next;
1223      LARGE_INTEGER nextoffset=curpos+last->Length;
1224      CHAR *fullpath=(CHAR *)malloc(sizeof(CHAR)*(strlen(path)+strlen(last->FileNameAscii) + 3));
1225      strcpy(fullpath,path);
1226      strcat(fullpath,"/");
1227      strcat(fullpath,last->FileNameAscii);
1228      last->fullpath=fullpath;
1229  
1230      //printf("  Filename =|%s|",fullpath);
1231      //printf("DEBUG %u ",*offset);
1232      //printf("%s\n",fullpath);
1233      //printf("  nextoffset =|%u|",nextoffset);
1234      //printf("  subdiroffset =|%u|\n",last->SubdirOffset);
1235  
1236      if (last->Length == 0)
1237      {
1238          printf ("End of current directory %s\n",path);
1239          return last; 
1240      } else {
1241        if(last->SubdirOffset!=0)
1242        {
1243          char *newpath=(char *)malloc(strlen(last->FileNameAscii)+strlen(path)+3);
1244          strcpy(newpath,path);
1245          newpath=strcat(newpath,"/");
1246          newpath=strcat(newpath,last->FileNameAscii);
1247          *offset=last->SubdirOffset;
1248          // PrintDirEntry(last);
1249          last=ReadDir(fp,offset,newpath,last);
1250        } 
1251      }
1252      *offset=nextoffset;
1253      // PrintDirEntry(last);
1254      last=ReadDir(fp,offset,path,last);
1255      return last;
1256  }
1257  
1258  BOOT_META_DATA ReadBootMetaDataTable(FILE *fp,RESHDR_DISK_SHORT BootMetaData)
1259  {
1260  
1261    BOOT_META_DATA bmd;
1262    LARGE_INTEGER totalsize=0;
1263  
1264    if (BootMetaData.Size != BootMetaData.OriginalSize)
1265    {
1266      // printf("Compressed metadata table\n");
1267      int result=ReadFileResource(fp,BootMetaData.Offset,BootMetaData.Size,BootMetaData.OriginalSize,"__boot_metadata__");
1268      FILE *bm=fopen("__boot_metadata__","r");
1269      bmd.SecurityData = ReadSecurityData(bm,0);
1270      // printf("Succesfully read security data\n");
1271      // PrintSecurityData(bmd.SecurityData);
1272      bmd.DirEntry=(DIRENTRY *)malloc(sizeof(DIRENTRY));
1273      LARGE_INTEGER bmdoffset=bmd.SecurityData.TotalLength;
1274      ReadDir2(bm,bmdoffset,"",bmd.DirEntry,&totalsize);
1275      // printf("Succesfully read dirinfo\n");
1276      fclose(bm);
1277      // remove("__boot_metadata__");
1278    } else {
1279      // printf("Uncompressed metadata table\n");
1280      int result=ReadUnCompressedFile(fp,BootMetaData.Offset,BootMetaData.Size,BootMetaData.OriginalSize,"__boot_metadata__");
1281      FILE *bm=fopen("__boot_metadata__","r");
1282      bmd.SecurityData = ReadSecurityData(bm,0);
1283      // printf("Succesfully read security data\n");
1284      // PrintSecurityData(bmd.SecurityData);
1285      bmd.DirEntry=(DIRENTRY *)malloc(sizeof(DIRENTRY));
1286      LARGE_INTEGER bmdoffset=bmd.SecurityData.TotalLength;
1287      ReadDir2(bm,bmdoffset,"",bmd.DirEntry,&totalsize);
1288      fclose(bm);
1289      // remove("__boot_metadata__");
1290    }
1291    if (bmd.DirEntry->nextbrother != NULL)
1292    {
1293      bmd.DirEntry=bmd.DirEntry->nextbrother;
1294    } 
1295    
1296    // PrintBootMetaData(bmd);
1297  
1298    return bmd;
1299  }
1300  
1301  int CopyPart(FILE *fp,LARGE_INTEGER Offset, LARGE_INTEGER Size,char *filename)
1302  {
1303    
1304    fseek(fp,Offset,SEEK_SET);
1305    FILE *outfile=fopen(filename,"ab");
1306    char curchar;
1307    while(Size-->0)
1308    {
1309       curchar=fgetc(fp);
1310       fputc(curchar,outfile);
1311    }
1312    fclose(outfile);
1313  
1314    return 0;
1315  }
1316  
1317  
1318  int WriteDWord(FILE *fp,DWORD value)
1319  {
1320    unsigned char *src = (unsigned char *)&value;
1321    fputc(src[0],fp);
1322    fputc(src[1],fp);
1323    fputc(src[2],fp);
1324    fputc(src[3],fp);
1325    return 0;
1326  }
1327  
1328  int WriteUshort(FILE *fp,USHORT value)
1329  {
1330    unsigned char *src = (unsigned char *)&value;
1331    fputc(src[0],fp);
1332    fputc(src[1],fp);
1333    return 0;
1334  }
1335  
1336  int WriteLargeInteger7(FILE *fp,LARGE_INTEGER value)
1337  {
1338    unsigned char *src = (unsigned char *)&value;
1339    fputc(src[0],fp);
1340    fputc(src[1],fp);
1341    fputc(src[2],fp);
1342    fputc(src[3],fp);
1343    fputc(src[4],fp);
1344    fputc(src[5],fp);
1345    fputc(src[6],fp);
1346     return 0;
1347  }
1348  
1349  int WriteLargeInteger(FILE *fp,LARGE_INTEGER value)
1350  {
1351    unsigned char *src = (unsigned char *)&value;
1352    fputc(src[0],fp);
1353    fputc(src[1],fp);
1354    fputc(src[2],fp);
1355    fputc(src[3],fp);
1356    fputc(src[4],fp);
1357    fputc(src[5],fp);
1358    fputc(src[6],fp);
1359    fputc(src[7],fp);
1360     return 0;
1361  }
1362  
1363  int WriteFlags1(FILE *fp,LARGE_INTEGER value)
1364  {
1365    fputc(value,fp);
1366    return 0;
1367  }
1368  
1369  
1370  RESHDR_DISK_SHORT WriteLookupTable(FILE *fp,FILE_RESOURCE_HEADER *frh,LARGE_INTEGER items)
1371  {
1372  
1373    RESHDR_DISK_SHORT result;
1374    result.Offset=ftell(fp);
1375    int OffsetCount=0;
1376    for (;OffsetCount<items;OffsetCount++)
1377    {
1378      // FileResourceHeaderList[OffsetCount].ResourceHeaderIndex;
1379      WriteLargeInteger7(fp,frh[OffsetCount].ResourceHeader.Size);
1380      WriteFlags1(fp,frh[OffsetCount].ResourceHeader.Flags);
1381      WriteLargeInteger(fp,frh[OffsetCount].ResourceHeader.Offset);
1382      WriteLargeInteger(fp,frh[OffsetCount].ResourceHeader.OriginalSize);
1383      WriteUshort(fp,frh[OffsetCount].PartNumber);
1384      WriteDWord(fp,frh[OffsetCount].ReferenceCount);
1385      fwrite(frh[OffsetCount].Hash,sizeof(BYTE),20,fp);
1386    }
1387    result.Size=ftell(fp)-result.Offset;
1388    result.OriginalSize=result.Size;
1389    result.Flags=0;
1390    return result;
1391  }
1392  
1393  int WriteWimHeader(FILE *fp,WIM_HEADER *Header)
1394  {
1395  
1396    fseek(fp,0,SEEK_SET);
1397  
1398    fwrite(Header->ImageTag,1,sizeof(Header->ImageTag),fp);
1399  
1400    WriteDWord(fp,Header->Size);
1401    WriteDWord(fp,Header->Version);
1402    WriteDWord(fp,Header->Flags);
1403    WriteDWord(fp,Header->ChunckSize);
1404  
1405    fwrite(Header->Guid,1,sizeof(CHAR)*16,fp);
1406  
1407    WriteUshort(fp,Header->PartNumber);
1408    WriteUshort(fp,Header->TotalParts);
1409    WriteDWord(fp,Header->ImageCount);
1410   
1411    WriteLargeInteger7(fp,Header->OffsetTable.Size);
1412    WriteFlags1(fp,Header->OffsetTable.Flags);
1413    WriteLargeInteger(fp,Header->OffsetTable.Offset);
1414    WriteLargeInteger(fp,Header->OffsetTable.OriginalSize);
1415  
1416    WriteLargeInteger7(fp,Header->XmlData.Size);
1417    WriteFlags1(fp,Header->XmlData.Flags);
1418    WriteLargeInteger(fp,Header->XmlData.Offset);
1419    WriteLargeInteger(fp,Header->XmlData.OriginalSize);
1420  
1421    WriteLargeInteger7(fp,Header->BootMetaData.Size);
1422    WriteFlags1(fp,Header->BootMetaData.Flags);
1423    WriteLargeInteger(fp,Header->BootMetaData.Offset);
1424    WriteLargeInteger(fp,Header->BootMetaData.OriginalSize);
1425  
1426    WriteDWord(fp,Header->BootIndex);
1427  
1428    WriteLargeInteger7(fp,Header->Integrity.Size);
1429    WriteFlags1(fp,Header->Integrity.Flags);
1430    WriteLargeInteger(fp,Header->Integrity.Offset);
1431    WriteLargeInteger(fp,Header->Integrity.OriginalSize);
1432  
1433    fwrite(Header->Unused,1,sizeof(Header->Unused),fp);
1434  
1435    return 0;
1436  }
1437  
1438  int ReadXMLInfo(FILE *fp)
1439  {
1440  
1441    int result;
1442    WIM_HEADER *Header=malloc(sizeof(WIM_HEADER));
1443  
1444    fseek(fp,0,SEEK_SET);
1445    
1446    result=fread(&(Header->ImageTag),sizeof(Header->ImageTag),1,fp);
1447  
1448    Header->Size=GetDWord(fp);
1449    Header->Version=GetDWord(fp);
1450    Header->Flags=GetDWord(fp);
1451    Header->ChunckSize=GetDWord(fp);
1452  
1453    result=fread(&(Header->Guid),sizeof(CHAR)*16,1,fp);
1454  
1455    Header->PartNumber=GetUshort(fp);
1456    Header->TotalParts=GetUshort(fp);
1457    Header->ImageCount=GetDWord(fp);
1458  
1459    Header->OffsetTable.Size=GetLargeInteger7(fp);
1460    Header->OffsetTable.Flags=GetFlags1(fp);
1461    Header->OffsetTable.Offset=GetLargeInteger(fp);
1462    Header->OffsetTable.OriginalSize=GetLargeInteger(fp);
1463    
1464    LARGE_INTEGER mysize=GetLargeInteger7(fp);
1465    Header->XmlData.Flags=GetFlags1(fp);
1466    LARGE_INTEGER lioffset=GetLargeInteger(fp);
1467    fseek(fp,lioffset,SEEK_SET);
1468    BYTE *buf=malloc(sizeof(BYTE) * mysize);
1469    LARGE_INTEGER ilen=fread(buf,mysize,sizeof(BYTE),fp);
1470    BYTE *xmlnoheader=(BYTE *)malloc(sizeof(BYTE) * (mysize -2));
1471    memcpy(xmlnoheader,&(buf[2]),mysize-2);
1472    char *xmlstring=strdup(w2a(xmlnoheader,mysize-2));
1473    printf("%s",xmlstring);
1474    return 0;
1475  }
1476  
1477  int ReadWimHeader(FILE *fp,WIM_HEADER *Header)
1478  {
1479  
1480    int result;
1481  
1482    fseek(fp,0,SEEK_SET);
1483    
1484    result=fread(&(Header->ImageTag),sizeof(Header->ImageTag),1,fp);
1485  
1486    Header->Size=GetDWord(fp);
1487    Header->Version=GetDWord(fp);
1488    Header->Flags=GetDWord(fp);
1489    Header->ChunckSize=GetDWord(fp);
1490  
1491    result=fread(&(Header->Guid),sizeof(CHAR)*16,1,fp);
1492  
1493    Header->PartNumber=GetUshort(fp);
1494    Header->TotalParts=GetUshort(fp);
1495    Header->ImageCount=GetDWord(fp);
1496  
1497    Header->OffsetTable.Size=GetLargeInteger7(fp);
1498    Header->OffsetTable.Flags=GetFlags1(fp);
1499    Header->OffsetTable.Offset=GetLargeInteger(fp);
1500    Header->OffsetTable.OriginalSize=GetLargeInteger(fp);
1501  
1502    Header->XmlData.Size=GetLargeInteger7(fp);
1503    Header->XmlData.Flags=GetFlags1(fp);
1504    Header->XmlData.Offset=GetLargeInteger(fp);
1505    Header->XmlData.OriginalSize=GetLargeInteger(fp);
1506  
1507    Header->BootMetaData.Size=GetLargeInteger7(fp);
1508    Header->BootMetaData.Flags=GetFlags1(fp);
1509    Header->BootMetaData.Offset=GetLargeInteger(fp);
1510    Header->BootMetaData.OriginalSize=GetLargeInteger(fp);
1511  
1512    Header->BootIndex=GetDWord(fp);
1513  
1514    Header->Integrity.Size=GetLargeInteger7(fp);
1515    Header->Integrity.Flags=GetFlags1(fp);
1516    Header->Integrity.Offset=GetLargeInteger(fp);
1517    Header->Integrity.OriginalSize=GetLargeInteger(fp);
1518  
1519    result=fread(&(Header->Unused),sizeof(Header->Unused),1,fp);
1520  
1521    return 0;
1522  
1523  }
1524  
1525  
1526  
1527  
1528  
1529  int PrintHeader (WIM_HEADER Header)
1530  {
1531  
1532    printf("Imagetag = %s\n",Header.ImageTag);
1533    printf("Headersize = %X\n",Header.Size);
1534    printf("Version = %X\n",Header.Version);
1535    printf("Flags = %X\n",Header.Flags);
1536  
1537    if (Header.Flags & FLAG_HEADER_COMPRESS_XPRESS)
1538    {
1539      printf("    COMPRESS XPRESS FLAG is set\n");
1540    }
1541    if (Header.Flags & FLAG_HEADER_COMPRESS_LZX)
1542    {
1543      printf("    COMPRESS LZX FLAG is set\n");
1544    }
1545    printf("ChunckSize = %u\n",Header.ChunckSize);
1546    printf("Guid = %X\n",Header.Guid);
1547    printf("PartNumber = %u\n",Header.PartNumber);
1548    printf("TotalParts = %u\n",Header.TotalParts);
1549    printf("ImageCount = %u\n",Header.ImageCount);
1550  
1551    printf("OffsetTable Size = %X\n",Header.OffsetTable.Size);
1552    printf("OffsetTable Flags = %x\n",Header.OffsetTable.Flags);
1553    printf("OffsetTable Offset = %X\n",Header.OffsetTable.Offset);
1554    printf("OffsetTable OriginalSize = %X\n",Header.OffsetTable.OriginalSize);
1555  
1556    printf("XmlData Size = %X\n",Header.XmlData.Size);
1557    printf("XmlData Flags  = %x\n",Header.XmlData.Flags);
1558    printf("XmlData Offset = %X\n",Header.XmlData.Offset);
1559    printf("XmlData OriginalSize = %X\n",Header.XmlData.OriginalSize);
1560  
1561    printf("BootMetaData Size = %X\n",Header.BootMetaData.Size);
1562    printf("BootMetaData Flags = %x\n",Header.BootMetaData.Flags);
1563    printf("BootMetaData Offset = %X\n",Header.BootMetaData.Offset);
1564    printf("BootMetaData OriginalSize = %X\n",Header.BootMetaData.OriginalSize);
1565  
1566    printf("Header.BootIndex = %u\n",Header.BootIndex);
1567  
1568    printf("Integrity Flags = %hX\n",Header.Integrity.Flags);
1569    printf("Integrity Size = %u\n",Header.Integrity.Size);
1570    printf("Integrity Offset = %u\n",Header.Integrity.Offset);
1571    printf("Integrity OriginalSize = %u\n",Header.Integrity.OriginalSize);
1572  
1573    return 0;
1574  
1575  }
1576  
1577  int CopyFileResource(FILE *infile, FILE_RESOURCE_HEADER *frh, FILE *of)
1578  {
1579  
1580    fseek(infile,frh->ResourceHeader.Offset,SEEK_SET);
1581    frh->ResourceHeader.Offset=ftell(of);
1582    LARGE_INTEGER byteswritten=0;
1583    while(byteswritten<frh->ResourceHeader.Size)
1584    {
1585       BYTE curchar=fgetc(infile);
1586       fputc(curchar,of);
1587       byteswritten++;
1588    }
1589    return 0;
1590  }
1591  
1592  FILE_RESOURCE_HEADER *AddFileResource(CHAR *path,FILE *of)
1593  {
1594    FILE_RESOURCE_HEADER *frh=malloc(sizeof(FILE_RESOURCE_HEADER));
1595  
1596    frh->ResourceHeader.Offset=ftell(of);
1597    FILE *infile=fopen(path,"r");
1598    if (infile == NULL)
1599    {
1600      printf("ERROR: Could not open file %s\n",path);
1601      exit(0);
1602    }
1603    CHAR curchar;
1604    while(!feof(infile))
1605    {
1606      curchar=fgetc(infile);
1607      fputc(curchar,of);
1608    }
1609    frh->ResourceHeader.Size=ftell(infile);
1610    frh->ResourceHeader.OriginalSize=frh->ResourceHeader.Size;
1611    frh->PartNumber=1;
1612    frh->ReferenceCount=1;
1613    fclose(infile);
1614    return frh;
1615  } 
1616  
1617  int CopyFileResources(FILE *infile,FILE *of,FILE_RESOURCE_HEADER *frh,LARGE_INTEGER numitems)
1618  {
1619    LARGE_INTEGER frhindex=0;
1620    for(frhindex=0;frhindex<numitems;frhindex++)
1621    {
1622      if(frh[frhindex].ResourceHeader.Flags & RESHDR_FLAG_METADATA)
1623      {
1624        // printf("Metadata file resource found\n");
1625      } else {
1626         CopyFileResource(infile,&(frh[frhindex]),of);
1627      }
1628    }
1629    return 0;
1630  }
1631  
1632  int WriteSecurityData(FILE *fp,SECURITY_DATA sd)
1633  {
1634      LARGE_INTEGER pos=ftell(fp);
1635      //while(pos & 7 != 0)
1636      //{
1637        // fputc(0,fp);
1638        // pos++;
1639      //}
1640      WriteDWord(fp,sd.TotalLength);
1641      WriteDWord(fp,sd.NumEntries);
1642      int k;
1643      for (k=0;k<sd.NumEntries;k++)
1644      {
1645        // printf("Writing size value %u\n",sd.Sizes[k]);
1646        WriteLargeInteger(fp,sd.Sizes[k]);
1647      }
1648      for (k=0;k<sd.NumEntries;k++)
1649      {
1650        fwrite(sd.Descriptors[k],sizeof(BYTE),sd.Sizes[k],fp);
1651      }
1652      LARGE_INTEGER writesize=ftell(fp)-pos;
1653      if(writesize != sd.TotalLength)
1654      {
1655        
1656         int c=0;
1657         for (c=0;c<sd.TotalLength-writesize;c++)
1658         {
1659           fputc(0,fp);
1660         }
1661      }
1662      LARGE_INTEGER writesize2=ftell(fp)-pos;
1663      if(writesize2 != sd.TotalLength)
1664      {
1665         printf("ERRRRRRRRRRRRRRRRRRRRRROOOOOOOOOORRRRRRRRRRRRRR security data not written with expected size: %u\n",sd.TotalLength);
1666      }
1667      return 0;
1668  }
1669  
1670  int WriteDirEntry(FILE *fp,DIRENTRY *direntry)
1671  {
1672    LARGE_INTEGER curpos=ftell(fp);
1673    WriteLargeInteger(fp,direntry->Length);
1674    if(direntry->Length == 0)
1675    {
1676      return 0;
1677    }
1678  
1679    WriteDWord(fp,direntry->Attributes);
1680    WriteDWord(fp,direntry->SecurityId);
1681    WriteLargeInteger(fp,direntry->SubdirOffset);
1682  
1683    WriteLargeInteger(fp,direntry->Unused1);
1684    WriteLargeInteger(fp,direntry->Unused2);
1685    WriteLargeInteger(fp,direntry->CreationTime);
1686    WriteLargeInteger(fp,direntry->LastAccessTime);
1687    WriteLargeInteger(fp,direntry->LastWriteTime);
1688  
1689    fwrite(direntry->Hash,sizeof(BYTE),20,fp);
1690  
1691    WriteDWord(fp,direntry->ReparseTag);
1692    // WriteDWord(fp,direntry->ReparseReserved);
1693    WriteLargeInteger(fp,direntry->HardLink);
1694    WriteUshort(fp,direntry->Streams);
1695  
1696    WriteUshort(fp,direntry->ShortNameLength);
1697    WriteUshort(fp,direntry->FileNameLength);
1698  
1699    fwrite(direntry->FileName,direntry->FileNameLength,1,fp);
1700    WriteUshort(fp,direntry->FileNamePad);
1701    fwrite(direntry->ShortFileName,direntry->ShortNameLength,1,fp);
1702  
1703    USHORT streamindex=0;
1704    for (streamindex=0;streamindex<direntry->Streams;streamindex++)
1705    {
1706      WriteLargeInteger(fp,direntry->StreamEntries[streamindex].Length);
1707      WriteLargeInteger(fp,direntry->StreamEntries[streamindex].Unused1);
1708      fwrite(direntry->StreamEntries[streamindex].Hash,20,1,fp);
1709      WriteUshort(fp,direntry->StreamEntries[streamindex].StreamNameLength);
1710      fwrite(direntry->StreamEntries[streamindex].StreamName,direntry->StreamEntries[streamindex].StreamNameLength,1,fp);
1711    }
1712  
1713    fwrite(direntry->rest,direntry->restsize,1,fp);
1714    LARGE_INTEGER newpos=ftell(fp);
1715    if (newpos-curpos != direntry->Length)
1716    {
1717      printf("ERROR writing Direntry= %s ",direntry->fullpath);
1718      printf("Written Size = %u",newpos-curpos);
1719      printf("I thought it was  = %u\n",direntry->Length);
1720    }
1721  
1722    return 0;
1723  }
1724  
1725  FILE_RESOURCE_HEADER *WriteUnCompressedFileResource(FILE *of,char *srcfilename)
1726  {
1727    FILE_RESOURCE_HEADER *lte=malloc(sizeof(FILE_RESOURCE_HEADER));
1728  
1729    FILE *infile=fopen(srcfilename,"rb");
1730    lte->ResourceHeader.Offset=ftell(of);
1731    int cheap_hash_counter=0;
1732    while(!feof(infile))
1733    {
1734       BYTE curchar=fgetc(infile);
1735       fputc(curchar,of);
1736       // cheap hash, the first 20 bytes from file itself
1737       // we have to check anyway if there are doubles
1738       if(cheap_hash_counter++<20)
1739       {
1740         lte->Hash[cheap_hash_counter]=curchar;
1741       }
1742    }
1743    fclose(infile);
1744    lte->ResourceHeader.Size=ftell(infile);
1745    lte->ResourceHeader.OriginalSize=lte->ResourceHeader.Size;
1746    lte->ResourceHeader.Flags=0;
1747    lte->PartNumber=1;
1748    lte->ReferenceCount=1;
1749    return lte;
1750  }
1751  
1752  int PrintLookupTable(FILE_RESOURCE_HEADER *frh, LARGE_INTEGER numoffsets)
1753  {
1754    LARGE_INTEGER i=0;
1755    for(i=0;i<numoffsets;i++)
1756    {
1757      printf("Offset number %u\n",i);
1758      printf("------------------\n",i);
1759      printf("Offset = %u\n",frh[i].ResourceHeader.Offset);
1760      printf("Size = %u\n",frh[i].ResourceHeader.Size);
1761      printf("OriginalSize = %u\n",frh[i].ResourceHeader.OriginalSize);
1762    }
1763    return 0;
1764  }
1765  
1766  int PrintBootMetaData(BOOT_META_DATA bmd)
1767  {
1768      PrintSecurityData(bmd.SecurityData);
1769      //CalculateDirContents(bmd.DirEntry->nextbrother);
1770      LARGE_INTEGER StartOffset=bmd.SecurityData.TotalLength;
1771      bmd.DirEntry->DirContentSize=0;
1772      PrintDirentries2(bmd.DirEntry,StartOffset);
1773  }
1774  
1775  


Generated: Tue Mar 17 22:47:18 2015 Cross-referenced by PHPXref 0.7.1