/* wimlib - Library for working with WIM files Copyright (C) 2010 Carl Thijssen 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. 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. 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 */ #include #include #include #include #include "lzx.h" #include "wim.h" /* Thanks to the chntpw project! */ static char *w2a(void *string, int len) { int i, k; char *cstring; int out_len = 0; for(i = 0; i < len; i += 2) { // unsigned v = ((unsigned char *)string)[i] + ((unsigned char *)string)[i+1] * 256u; unsigned v = ((unsigned char *)string)[i] + ((unsigned char *)string)[i+1] * 512u; if (v < 256) out_len += 1; else if(v < 0x800) out_len += 2; else out_len += 3; } cstring = (char *) malloc(out_len+1); if (!cstring) { printf("FATAL! ex_next: malloc() failed! Out of memory?\n"); abort(); } for(i = 0, k = 0; i < len; i += 2) { unsigned v = ((unsigned char *)string)[i] + ((unsigned char *)string)[i+1] * 512u; if (v < 256) cstring[k++] = v; else if(v < 0x800) { cstring[k++] = 0xc0 | (v >> 6); cstring[k++] = 0x80 | (v & 0x3f); } else { cstring[k++] = 0xe0 | (v >> 12); cstring[k++] = 0x80 | ((v >> 6) & 0x3f); cstring[k++] = 0x80 | (v & 0x3f); } } cstring[out_len] = '\0'; return cstring; } static char *a2w(void *string, int len, int *out_len) { unsigned char *regw = (unsigned char*) malloc(len*2+2); unsigned char *out = regw; unsigned char *in = (unsigned char*) string; for (;len>0; ++in, --len) { if (!(in[0] & 0x80)) { *out++ = *in; *out++ = 0; } else if ((in[0] & 0xe0) == 0xc0 && len >= 2) { *out++ = (in[0] & 0x1f) << 6 | (in[1] & 0x3f); *out++ = (in[0] & 0x1f) >> 2; ++in, --len; } else if (len >= 3) { /* assume 3 byte*/ *out++ = (in[1] & 0xf) << 6 | (in[2] & 0x3f); *out++ = (in[0] & 0xf) << 4 | ((in[1] & 0x3f) >> 2); in += 2; len -= 2; } } *out_len = out - regw; out[0] = out[1] = 0; return (char *) regw; } DWORD GetDWord(FILE *fp) { register DWORD dw; dw = (DWORD) (fgetc(fp) & 0xFF); dw |= ((DWORD) (fgetc(fp) & 0xFF) << 0x08); dw |= ((DWORD) (fgetc(fp) & 0xFF) << 0x10); dw |= ((DWORD) (fgetc(fp) & 0xFF) << 0x18); return(dw); } USHORT GetUshort(FILE *fp) { register USHORT w; w = (USHORT) (fgetc(fp) & 0xFF); w |= ((USHORT) (fgetc(fp) & 0xFF) << 0x08); return(w); } LARGE_INTEGER GetULargeInteger(FILE *fp) { register ULARGE_INTEGER li; li = (ULARGE_INTEGER) (fgetc(fp) & 0xFF); li |= ((ULARGE_INTEGER) (fgetc(fp) & 0xFF) << 0x08) ; li |= ((ULARGE_INTEGER) (fgetc(fp) & 0xFF) << 0x10) ; li |= ((ULARGE_INTEGER) (fgetc(fp) & 0xFF) << 0x18) ; li |= ((ULARGE_INTEGER) (fgetc(fp) & 0xFF) << 0x20) ; li |= ((ULARGE_INTEGER) (fgetc(fp) & 0xFF) << 0x28) ; li |= ((ULARGE_INTEGER) (fgetc(fp) & 0xFF) << 0x30) ; li |= ((ULARGE_INTEGER) (fgetc(fp) & 0xFF) << 0x38) ; return(li); } LARGE_INTEGER GetLargeInteger(FILE *fp) { register LARGE_INTEGER li; li = (LARGE_INTEGER) (fgetc(fp) & 0xFF); li |= ((LARGE_INTEGER) (fgetc(fp) & 0xFF) << 0x08) ; li |= ((LARGE_INTEGER) (fgetc(fp) & 0xFF) << 0x10) ; li |= ((LARGE_INTEGER) (fgetc(fp) & 0xFF) << 0x18) ; li |= ((LARGE_INTEGER) (fgetc(fp) & 0xFF) << 0x20) ; li |= ((LARGE_INTEGER) (fgetc(fp) & 0xFF) << 0x28) ; li |= ((LARGE_INTEGER) (fgetc(fp) & 0xFF) << 0x30) ; li |= ((LARGE_INTEGER) (fgetc(fp) & 0xFF) << 0x38) ; return(li); } LARGE_INTEGER GetLargeInteger7(FILE *fp) { register LARGE_INTEGER li; li = (LARGE_INTEGER) (fgetc(fp) & 0xFF); li |= ((LARGE_INTEGER) (fgetc(fp) & 0xFF) << 0x08) ; li |= ((LARGE_INTEGER) (fgetc(fp) & 0xFF) << 0x10) ; li |= ((LARGE_INTEGER) (fgetc(fp) & 0xFF) << 0x18) ; li |= ((LARGE_INTEGER) (fgetc(fp) & 0xFF) << 0x20) ; li |= ((LARGE_INTEGER) (fgetc(fp) & 0xFF) << 0x28) ; li |= ((LARGE_INTEGER) (fgetc(fp) & 0xFF) << 0x30) ; // li |= ((LARGE_INTEGER) (fgetc(fp) & 0xFF) << 0x38) ; return(li); } BYTE GetFlags1(FILE *fp) { register BYTE b; b = (BYTE) (fgetc(fp) & 0xFF); return b; } int ReadUnCompressedFile(FILE *fp,LARGE_INTEGER offset, LARGE_INTEGER size, LARGE_INTEGER unpacksize, char *filename) { fseek(fp,offset,SEEK_SET); FILE *outfile=fopen(filename,"wb"); LARGE_INTEGER i=0; for(i=0;i> 15 ; // printf("Number of chuncks = %u\n",NumberOfChuncks); int EntrySize = 4 ; if (unpacksize > (LARGE_INTEGER) 1 << 32) { EntrySize = 8 ; } //printf ("Entry Size = %d\n",EntrySize); LARGE_INTEGER ChunckOffsets[NumberOfChuncks]; LARGE_INTEGER j=0; for (j=0;j= unpacksize % ChunckSize) { printf("Copying %u input bytes to output file of total ",unpacksize % ChunckSize); printf("%u\n",size-ChunckOffsets[NumberOfChuncks-1]); fwrite(ibuf, 1,size-ChunckOffsets[NumberOfChuncks-1], outfile); } else { int status=LZXdecompress(state,ibuf,obuf,ilen,unpacksize % ChunckSize); switch(status) { case DECR_OK: fwrite(obuf, 1,unpacksize % ChunckSize, outfile); break; default: printf("isize = %u ",size-ChunckOffsets[NumberOfChuncks-1]); printf("osize = %u ",unpacksize % ChunckSize); printf("ERROR\n"); break; } } LZXreset(state); fclose(outfile); return 0; } FILE_RESOURCE_HEADER *ReadLookupTable(FILE *fp,LARGE_INTEGER offset,LARGE_INTEGER size,LARGE_INTEGER *numoffsets) { fseek(fp,offset,SEEK_SET); unsigned long curoffset=ftell(fp); //printf("Current Offset = %u size %u \n", curoffset,size); //printf("numoffsets = %u\n", size/50); FILE_RESOURCE_HEADER *FileResourceHeaderList=malloc(sizeof(FILE_RESOURCE_HEADER)*size/50); // printf("Now here before reading the offsets\n"); // FILE_RESOURCE_HEADER FileResourceHeader; LARGE_INTEGER OffsetCount=0; while(ftell(fp) < offset + size) { FileResourceHeaderList[OffsetCount].ResourceHeaderIndex=OffsetCount; FileResourceHeaderList[OffsetCount].ResourceHeader.Size=GetLargeInteger7(fp); FileResourceHeaderList[OffsetCount].ResourceHeader.Flags=GetFlags1(fp); FileResourceHeaderList[OffsetCount].ResourceHeader.Offset=GetLargeInteger(fp); FileResourceHeaderList[OffsetCount].ResourceHeader.OriginalSize=GetLargeInteger(fp); FileResourceHeaderList[OffsetCount].PartNumber=GetUshort(fp); FileResourceHeaderList[OffsetCount].ReferenceCount=GetDWord(fp); int result=fread(FileResourceHeaderList[OffsetCount].Hash,sizeof(BYTE),20,fp); if (FileResourceHeaderList[OffsetCount].ResourceHeader.Flags & RESHDR_FLAG_METADATA ) { // This is the resource that points to a metadata file resource //printf("Resource #%u ",OffsetCount); //printf("size=%u ",FileResourceHeaderList[OffsetCount].ResourceHeader.Size); //printf("osize = %u ",FileResourceHeaderList[OffsetCount].ResourceHeader.OriginalSize); //printf("flags = %u ",FileResourceHeaderList[OffsetCount].ResourceHeader.Flags); //printf("offset = %u ",FileResourceHeaderList[OffsetCount].ResourceHeader.Offset); //printf("\n"); } // printf("ResourceHeaderPartNumber = %u\n",FileResourceHeader.PartNumber); // printf("ResourceHeaderReferenceCount = %u\n",FileResourceHeader.ReferenceCount); // printf("ResourceHeaderHash = |%s|\n",FileResourceHeader.Hash); OffsetCount++; } //printf("numoffsets = %u\n", OffsetCount); *numoffsets=OffsetCount; return FileResourceHeaderList; } int ExtractFile(DIRENTRY *extractfile,FILE_RESOURCE_HEADER *frh, LARGE_INTEGER numoffsets, FILE *fp, CHAR *filename) { FILE_RESOURCE_HEADER hashkey; memcpy(hashkey.Hash,extractfile->Hash,sizeof(BYTE)*20); FILE_RESOURCE_HEADER *foundhash=bsearch(&hashkey,frh,numoffsets,sizeof(FILE_RESOURCE_HEADER),comparehashes); if (foundhash != NULL) { printf("FOUND %s\n",extractfile->fullpath); WriteFile(fp,foundhash,filename); } else { printf("NOT FOUND %s\n",extractfile->fullpath); return 1; } return 0; } int WriteFile(FILE *fp,FILE_RESOURCE_HEADER *FileResourceHeader, char *filename) { printf("Now writing file %s\n",filename);; LARGE_INTEGER rememberoffset=ftell(fp); if (FileResourceHeader->ResourceHeader.Flags == 0) { FILE *outfile=fopen(filename,"wb"); /// KLOPT DIT WEL??? fseek(fp,FileResourceHeader->ResourceHeader.Offset,SEEK_SET); fwrite(fp, 1, FileResourceHeader->ResourceHeader.Size, outfile); fclose(outfile); } else { if (FileResourceHeader->ResourceHeader.Flags == 4 || FileResourceHeader->ResourceHeader.Flags == 6 ) { printf("Going to read the file resource at offset %u ",FileResourceHeader->ResourceHeader.Offset); printf(" Size %u ",FileResourceHeader->ResourceHeader.Size); printf(" OSize %u\n",FileResourceHeader->ResourceHeader.OriginalSize); ReadFileResource(fp,FileResourceHeader->ResourceHeader.Offset, FileResourceHeader->ResourceHeader.Size, FileResourceHeader->ResourceHeader.OriginalSize, filename); } else { printf("Flags = %d\n",FileResourceHeader->ResourceHeader.Flags); } } fseek(fp,rememberoffset,SEEK_SET); return 0; } int PrintXML(BYTE *xml,LARGE_INTEGER size) { if (size <= 2) { printf("ERROR: Wrong XML size: %u\n",size); return 1; } BYTE *xmlnoheader=(BYTE *)malloc(sizeof(BYTE) * (size -2)); memcpy(xmlnoheader,&(xml[2]),size-2); char *xmlstring=strdup(w2a(xmlnoheader,size-2)); printf("%s",xmlstring); return 0; } BYTE *ReadXML(FILE *fp,LARGE_INTEGER offset,LARGE_INTEGER size) { BYTE *buf=malloc(sizeof(BYTE)*size); LARGE_INTEGER ilen=fread(buf,size,sizeof(BYTE),fp); return buf; } RESHDR_DISK_SHORT WriteXML(FILE *fp,BYTE *buf,LARGE_INTEGER size) { RESHDR_DISK_SHORT result; result.Offset=ftell(fp); fwrite(buf,size,sizeof(BYTE),fp); result.Size=size; result.OriginalSize=size; result.Flags=0; return result; } int PrintSecurityData(SECURITY_DATA sd) { printf("SecurityData\n"); printf("------------\n"); printf("Total length = %u\n",sd.TotalLength); printf("NumEntries = %u\n",sd.NumEntries); int k=0; for (k=0;kHash, (BYTE *)headery->Hash, 20); } int compareoffsets (const void* a, const void *b) { FILE_RESOURCE_HEADER *headerx=(FILE_RESOURCE_HEADER *) a; FILE_RESOURCE_HEADER *headery=(FILE_RESOURCE_HEADER *) b; printf("Comparing %u ",headerx->ResourceHeader.Offset); printf("to %u ",headery->ResourceHeader.Offset); if (headerx->ResourceHeader.Offset == headery->ResourceHeader.Offset) { return 0; } else { if (headerx->ResourceHeader.Offset > headery->ResourceHeader.Offset) { return 1; } else { return -1; } } //return (headerx->ResourceHeader.Offset - headery->ResourceHeader.Offset); } DIRENTRY *ReadDirEntry(FILE *fp) { DIRENTRY *Direntry=malloc(sizeof(DIRENTRY)); LARGE_INTEGER curpos=ftell(fp); // printf("Reading entry at offset %u : length",curpos); Direntry->Length=GetLargeInteger(fp); // printf(" Length = %u\n",Direntry->Length); Direntry->SubdirOffset=0; Direntry->FileNameAscii=strdup(""); Direntry->next=NULL; Direntry->DirContentSize=0; if (Direntry->Length >=104) { Direntry->Attributes=GetDWord(fp); Direntry->SecurityId=GetDWord(fp); Direntry->SubdirOffset=GetLargeInteger(fp); Direntry->Unused1=GetLargeInteger(fp); Direntry->Unused2=GetLargeInteger(fp); Direntry->CreationTime=GetLargeInteger(fp); Direntry->LastAccessTime=GetLargeInteger(fp); Direntry->LastWriteTime=GetLargeInteger(fp); Direntry->Hash=malloc(sizeof(BYTE) * 20); int result=fread(Direntry->Hash,sizeof(BYTE),20,fp); Direntry->ReparseTag=GetDWord(fp); // Direntry->ReparseReserved=GetDWord(fp); // Direntry->ReparseReserved=GetDWord(fp); Direntry->HardLink=GetLargeInteger(fp); Direntry->Streams=GetUshort(fp); Direntry->ShortNameLength=GetUshort(fp); Direntry->FileNameLength=GetUshort(fp); Direntry->FileName=(char *)malloc(sizeof(char) * Direntry->FileNameLength); result=fread(Direntry->FileName,sizeof(CHAR)*Direntry->FileNameLength,1,fp); Direntry->FileNameAscii=strdup(w2a(Direntry->FileName,Direntry->FileNameLength)); Direntry->FileNamePad=GetUshort(fp); Direntry->ShortFileName=(char *)malloc(sizeof(char) * Direntry->ShortNameLength); result=fread(Direntry->ShortFileName,sizeof(CHAR)*Direntry->ShortNameLength,1,fp); Direntry->ShortFileNameAscii=strdup(w2a(Direntry->ShortFileName,Direntry->ShortNameLength)); if(Direntry->Streams >0) { Direntry->StreamEntries=(STREAM_ENTRY *)malloc(Direntry->Streams*sizeof(STREAM_ENTRY)); USHORT i; for(i=0;iStreams;i++) { printf("Getting Streamentry %d\n",i); Direntry->StreamEntries[i].Length=GetLargeInteger(fp); Direntry->StreamEntries[i].Unused1=GetLargeInteger(fp); int result=fread(&(Direntry->StreamEntries[i].Hash),sizeof(BYTE),20,fp); Direntry->StreamEntries[i].StreamNameLength=GetUshort(fp); Direntry->StreamEntries[i].StreamName=(CHAR *)malloc(sizeof(CHAR)*Direntry->StreamEntries[i].StreamNameLength); result=fread(&(Direntry->StreamEntries[i].StreamName),sizeof(Direntry->StreamEntries[i].StreamName),1,fp); } } LARGE_INTEGER bytes_read = ftell(fp)-curpos; if (bytes_read != Direntry->Length) { Direntry->rest=(BYTE *)malloc(sizeof(BYTE)*(Direntry->Length-bytes_read)); Direntry->restsize=Direntry->Length-bytes_read; //printf("WARNING Adding %u rest bytes for %s\n",Direntry->restsize,Direntry->fullpath); int result=fread(Direntry->rest,sizeof(Direntry->rest),1,fp); /* if (Direntry->FileNamePad != 0) { printf(" NONZERO PAD %u ",Direntry->FileNamePad); } printf("Length : %u ",Direntry->ShortNameLength); printf("Length : %u ",Direntry->Length); printf("mod 8 : %u ",Direntry->Length % 8); printf("Bytes_read : %u ",bytes_read); printf("Storing extrabytes from direntry: %u |",Direntry->Length-bytes_read); int j=0; for (j=0;jLength-bytes_read;j++) { printf("%x",Direntry->rest[j]) ; } printf("| |%s| ",Direntry->FileNameAscii); printf("|%s",Direntry->ShortFileNameAscii); printf("|\n"); */ } else { // printf("We have a good entry here without extra bytes...\n"); Direntry->restsize=0; } } else { if (Direntry->Length > 0) { printf(" Entry too small: %u\n",Direntry->Length); } } return Direntry; } int PrintDirEntry(DIRENTRY *Direntry) { printf("Direntry.Length = %u\n",Direntry->Length); printf("Direntry.Attributes = %u\n",Direntry->Attributes); printf("Direntry.SubdirOffset = %u\n",Direntry->SubdirOffset); printf("Direntry.Unused1 = %u\n",Direntry->Unused1); printf("Direntry.Unused2 = %u\n",Direntry->Unused2); printf("Direntry.CreationTime = %u\n",Direntry->CreationTime); printf("Direntry.LastAccessTime = %u\n",Direntry->LastAccessTime); printf("Direntry.LastWriteTime = %u\n",Direntry->LastWriteTime); printf("Direntry.Hash = |"); int i=0; for (;i<20;i++) { printf("%2x",(Direntry->Hash)[i]); } printf ("|\n"); printf("Direntry.Hash = %s\n",Direntry->Hash); printf("Direntry.ReparseTag = %u\n",Direntry->ReparseTag); printf("Direntry.HardLink = %u\n",Direntry->HardLink); printf("Direntry.Streams = %u\n",Direntry->Streams); printf("Direntry.ShortNameLength = %u\n",Direntry->ShortNameLength); printf("Direntry.FileNameLength = %u\n",Direntry->FileNameLength); printf("Direntry.FileName = %s\n",Direntry->FileName); printf("Direntry.FileNameAscii = %s\n",Direntry->FileNameAscii); printf("Direntry.fullpath = |%s|\n",Direntry->fullpath); return 0; } RESHDR_DISK_SHORT WriteIntegrity(FILE *fp) { RESHDR_DISK_SHORT result; result.Offset=0; result.Size=0; result.OriginalSize=0; result.Flags=0; return result; } RESHDR_DISK_SHORT WriteBootMetaData(FILE *fp,BOOT_META_DATA bmd) { RESHDR_DISK_SHORT result; result.Offset=ftell(fp); LARGE_INTEGER curoffset=bmd.SecurityData.TotalLength; WriteSecurityData(fp,bmd.SecurityData); WriteDirentries2(fp,bmd.DirEntry,curoffset); result.Size=ftell(fp)-result.Offset; result.OriginalSize=result.Size; result.Flags=0; return result; } int PrintDirentries(DIRENTRY *Direntry,LARGE_INTEGER myoffset) { DIRENTRY *keepentry=Direntry; LARGE_INTEGER keepoffset=myoffset; if(Direntry->kids !=NULL) { myoffset+=Direntry->CurDirSize; } while(Direntry != NULL) { printf("OFFSET = %u ",myoffset); if(Direntry->kids !=NULL) { printf("Directory = %s",Direntry->fullpath); printf(" LENGTH = %u",Direntry->Length); printf(" CTIME = %llu",Direntry->CreationTime); printf(" CURDIRSIZE %u",Direntry->CurDirSize); printf(" DIRSIZE %u",Direntry->DirContentSize); printf(" SUBDIROFFSET = %u\n",myoffset); myoffset+=Direntry->DirContentSize; } else { printf("File = %s",Direntry->fullpath); printf(" LENGTH= %u\n",Direntry->Length); } printf(" RESTSIZE= %u\n",Direntry->restsize); Direntry=Direntry->nextbrother; } Direntry=keepentry; myoffset=keepoffset; while(Direntry != NULL) { PrintDirentries(Direntry->kids,myoffset); myoffset+=Direntry->DirContentSize; Direntry=Direntry->nextbrother; } } int AddDirHere(DIRENTRY *tree,DIRENTRY *newfile) { DIRENTRY *curentry=tree; newfile->SecurityId=tree->SecurityId; newfile->CreationTime=tree->CreationTime; newfile->LastAccessTime=tree->LastAccessTime; newfile->LastWriteTime=tree->LastWriteTime; DIRENTRY *thekids=tree->kids; if (thekids->Length == 0) { newfile->nextbrother=thekids; tree->kids=newfile; return 0; } DIRENTRY *previousentry=thekids; curentry=thekids->nextbrother; while(curentry->Length != 0) { // printf("Current entry = %s\n",curentry->fullpath); previousentry=curentry; curentry=curentry->nextbrother; } newfile->nextbrother=curentry; previousentry->nextbrother=newfile; // tree->CurDirSize+=newfile->Length; return 0; } int AddDir(DIRENTRY *tree, DIRENTRY *newfile, CHAR *path) { DIRENTRY *Direntry=tree; // printf("NOW ENTERING addition of file %s to %s\n",newfile->FileNameAscii,path); while(Direntry != NULL) { if(Direntry->kids !=NULL) { // printf("Directory = %s",Direntry->fullpath); if (!strcasecmp(Direntry->fullpath,path)) { // printf("Found the directory to add the file to: %s\n",path); Direntry->DirContentSize+=newfile->Length+8; AddDirHere(Direntry,newfile); return 0; } else { //traverse further into the tree int result = AddDir(Direntry->kids,newfile,path); if (result==0) { // Added the entry underneath this path // printf("Added %u",newfile->DirContentSize); // printf("To directory %s",Direntry->fullpath); Direntry->DirContentSize+=newfile->DirContentSize; return 0; } } } Direntry=Direntry->nextbrother; } // Not Found in this tree, returning 1 return 1; } int AddFile2(DIRENTRY *tree, DIRENTRY *newfile, CHAR *path) { DIRENTRY *Direntry=tree; // printf("NOW ENTERING addition of file %s to %s\n",newfile->FileNameAscii,path); while(Direntry != NULL) { if(Direntry->kids !=NULL) { // printf("Directory = %s",Direntry->fullpath); if (!strcasecmp(Direntry->fullpath,path)) { // printf("Found the diredtory to add the file to: %s\n",path); Direntry->DirContentSize+=newfile->Length; newfile->nextbrother=Direntry->kids; newfile->SecurityId=Direntry->SecurityId; newfile->CreationTime=Direntry->CreationTime; newfile->LastAccessTime=Direntry->LastAccessTime; newfile->LastWriteTime=Direntry->LastWriteTime; Direntry->kids=newfile; // new file added, stop traversing and return success return 0; } else { //traverse further into the tree int result = AddFile2(Direntry->kids,newfile,path); if (result==0) { // Added the entry underneath this path Direntry->DirContentSize+=newfile->Length; return 0; } } } Direntry=Direntry->nextbrother; } // Not Found in this tree, returning 1 return 1; } DIRENTRY *FindFile2(DIRENTRY *tree, CHAR *path, CHAR *filename) { DIRENTRY *Direntry=tree; // printf("NOW ENTERING RENAME of file %s to %s\n",path,newfilename); while(Direntry != NULL) { if(Direntry->kids !=NULL) { //printf("Directory = %s\n",Direntry->fullpath); DIRENTRY *result=FindFile2(Direntry->kids,path,filename); if(result != NULL) { return result; } } else { if (!strcasecmp(Direntry->FileNameAscii,filename)) { // printf("Found file %s in path %s, now checking path\n",filename,tree->fullpath); CHAR *checkfullpath=malloc(strlen(path) + strlen(filename) + 2); strcpy(checkfullpath,path); strcat(checkfullpath,"/"); strcat(checkfullpath,filename); if (!strcasecmp("",path) || !strcasecmp(checkfullpath,Direntry->fullpath)) { printf("FOUND File = %s as %s\n",Direntry->FileNameAscii,Direntry->fullpath); return Direntry; } } } Direntry=Direntry->nextbrother; } // not found return NULL; } int RenameFile2(DIRENTRY *tree, CHAR *path,CHAR *newfilename) { DIRENTRY *Direntry=tree; // printf("NOW ENTERING RENAME of file %s to %s\n",path,newfilename); int newsize=0; CHAR *wnewname=(CHAR *)a2w(newfilename,strlen(newfilename),&newsize); while(Direntry != NULL) { if(Direntry->kids !=NULL) { // printf("Directory = %s",Direntry->fullpath); RenameFile2(Direntry->kids,path,newfilename); } else { // printf("File = %s",Direntry->fullpath); if (!strcasecmp(Direntry->fullpath,path)) { // printf("FOUND File = %s\n",Direntry->fullpath); if (newsize != Direntry->FileNameLength) { printf("ERROR: different file name size: %u",newsize); printf(" current size: %u\n",Direntry->FileNameLength); } else { Direntry->FileName = wnewname ; } } } Direntry=Direntry->nextbrother; } return 0; } int WriteDirentries2(FILE *fp,DIRENTRY *Direntry,LARGE_INTEGER myoffset) { DIRENTRY *current=Direntry; LARGE_INTEGER curdiroffset=myoffset; LARGE_INTEGER initialoffset=myoffset; // Determine currents directory size LARGE_INTEGER CurDirSize=8; while(current != NULL) { CurDirSize+=current->Length; current=current->nextbrother; } current=Direntry; // printf("Current dir size = %u\n",CurDirSize); LARGE_INTEGER keepoffset=myoffset; // Print current directory contents while(current != NULL) { //printf("OFFSET = %u ",curdiroffset); curdiroffset+=current->Length; if(current->kids ==NULL) { //printf("File = %s",current->fullpath); //printf(" LENGTH= %u\n",current->Length); WriteDirEntry(fp,current); } else { //printf("Directory = %s",current->fullpath); //printf(" LENGTH= %u",current->Length); //printf(" MYOFFSET= %u", myoffset ); //printf(" CURDIRSIZE= %u", CurDirSize ); //printf(" DIRCONTENTSIZE= %u", current->DirContentSize ); //printf(" SUBDIROFFSET= %u\n",myoffset +CurDirSize); current->SubdirOffset=myoffset+CurDirSize; WriteDirEntry(fp,current); myoffset+=current->DirContentSize; } current=current->nextbrother; } // Print Subdirs Directories current=Direntry; // go back to the start... myoffset=keepoffset; while(current != NULL) { if(current->kids !=NULL) { //printf("Directory = %s",current->fullpath); //printf(" LENGTH = %u",current->Length); //printf(" DIRSIZE %u",current->DirContentSize); //printf(" MYOFFSET %u",myoffset); //printf(" CURDIRSIZE %u",CurDirSize); //printf(" SUBDIROFFSET = %u\n",myoffset + CurDirSize); WriteDirentries2(fp,current->kids,myoffset+CurDirSize); myoffset+=current->DirContentSize; } current=current->nextbrother; } return 0; } int PrintDirentries2(DIRENTRY *Direntry,LARGE_INTEGER myoffset) { DIRENTRY *current=Direntry; LARGE_INTEGER curdiroffset=myoffset; LARGE_INTEGER initialoffset=myoffset; // Determine currents directory size LARGE_INTEGER CurDirSize=8; while(current != NULL) { CurDirSize+=current->Length; current=current->nextbrother; } current=Direntry; // printf("Current dir size = %u\n",CurDirSize); LARGE_INTEGER keepoffset=myoffset; // Print current directory contents while(current != NULL) { printf("OFFSET = %u ",curdiroffset); curdiroffset+=current->Length; if(current->kids ==NULL) { printf("File = %s",current->fullpath); printf(" LENGTH= %u",current->Length); } else { printf("Directory = %s",current->fullpath); printf(" LENGTH= %u",current->Length); printf(" MYOFFSET= %u", myoffset ); printf(" CURDIRSIZE= %u", CurDirSize ); printf(" CTIME= %llu", current->CreationTime ); printf(" DIRCONTENTSIZE= %u", current->DirContentSize ); printf(" SUBDIROFFSET= %u",myoffset +CurDirSize); myoffset+=current->DirContentSize; } printf(" RESTSIZE= %u\n",current->restsize); current=current->nextbrother; } // Print Subdirs Directories current=Direntry; // go back to the start... myoffset=keepoffset; while(current != NULL) { if(current->kids !=NULL) { //printf("Directory = %s",current->fullpath); //printf(" LENGTH = %u",current->Length); //printf(" DIRSIZE %u",current->DirContentSize); //printf(" MYOFFSET %u",myoffset); //printf(" CURDIRSIZE %u",CurDirSize); //printf(" SUBDIROFFSET = %u\n",myoffset + CurDirSize); PrintDirentries2(current->kids,myoffset+CurDirSize); myoffset+=current->DirContentSize; } current=current->nextbrother; } return 0; } LARGE_INTEGER CalculateDirContents(DIRENTRY *Direntry) { Direntry->DirContentSize=8; // Starting off with 8 bytes corresponding to the End-Of-Dir marker DIRENTRY *current=Direntry->kids; while(current != NULL) { printf("File = %s\n",current->fullpath); Direntry->DirContentSize+=current->Length; if(current->kids !=NULL) { Direntry->DirContentSize+=CalculateDirContents(current->kids); } current=current->nextbrother; } printf("Contents of %s ",Direntry->fullpath); printf(" Has Size %u\n",Direntry->DirContentSize); return Direntry->DirContentSize; } int DeleteFile(char *filepath,DIRENTRY *Direntry) { int result=1; while(Direntry != NULL && Direntry->next != NULL) { DIRENTRY *NextEntry=Direntry->next; if(!strcasecmp(filepath,NextEntry->fullpath)) { printf("FOUND %s\n",filepath); Direntry->next = NextEntry->next; result=0; break; // free(tmpde); } Direntry=Direntry->next; } return result; } DIRENTRY *CreateDirectory(char *filename, char *destpath, BYTE *filehash) { DIRENTRY *newfile=malloc(sizeof(DIRENTRY)); newfile->Attributes=FILE_ATTRIBUTE_DIRECTORY; newfile->SecurityId=0; newfile->SubdirOffset=100; // will be adjusted later on newfile->Unused1=0; newfile->Unused2=0; // Just copy the file-time from the parent directory newfile->CreationTime=0; newfile->LastAccessTime=0; newfile->LastWriteTime=0; // we recieved the hash in the parameters newfile->Hash=filehash; memcpy(newfile->Hash,filehash,20); newfile->ReparseTag=0; newfile->ReparseReserved=0; newfile->HardLink=0; newfile->Streams=0; newfile->FileNameAscii=strdup(filename); newfile->FileName=a2w(filename,strlen(filename),(int *) &(newfile->FileNameLength)); newfile->ShortNameLength=0; newfile->FileNamePad=0; newfile->Length=104+newfile->FileNameLength; newfile->rest=NULL; newfile->restsize= 8 - (newfile->Length % 8); if ( newfile->restsize != 0 && newfile->restsize != 8) { // printf("Length=%u ",newfile->Length); // printf("Restsize = %u\n",newfile->restsize); newfile->rest=(BYTE *)malloc(newfile->restsize); int i=0; for(i=0;irestsize;i++) { newfile->rest[i]=0; } newfile->Length+=newfile->restsize; } else { newfile->restsize=0; } newfile->DirContentSize=8; newfile->fullpath=malloc(strlen(destpath) + strlen(filename) + 2); strcpy(newfile->fullpath,destpath); strcat(newfile->fullpath,"/"); strcat(newfile->fullpath,filename); DIRENTRY *eod=malloc(sizeof(DIRENTRY)); eod->Length=0; eod->kids=NULL; eod->nextbrother=NULL; eod->fullpath=malloc(strlen(newfile->fullpath) + 3); strcpy(eod->fullpath,newfile->fullpath); strcat(eod->fullpath,"/"); newfile->kids=eod; return newfile; } DIRENTRY *CreateFile(char *filename, char *destpath, BYTE *filehash) { DIRENTRY *newfile=malloc(sizeof(DIRENTRY)); newfile->Attributes=FILE_ATTRIBUTE_NORMAL; newfile->SecurityId=0; newfile->SubdirOffset=0; newfile->Unused1=0; newfile->Unused2=0; // Just copy the file-time from the parent directory newfile->CreationTime=0; newfile->LastAccessTime=0; newfile->LastWriteTime=0; // we recieved the hash in the parameters newfile->Hash=malloc(sizeof(BYTE)*20); memcpy(newfile->Hash,filehash,20); newfile->ReparseTag=0; newfile->ReparseReserved=0; newfile->HardLink=0; newfile->Streams=0; newfile->FileNameAscii=strdup(filename); newfile->FileName=a2w(filename,strlen(filename),(int *) &(newfile->FileNameLength)); newfile->ShortNameLength=0; newfile->FileNamePad=0; newfile->Length=104+newfile->FileNameLength; newfile->rest=NULL; newfile->restsize= 8 - (newfile->Length % 8); if ( newfile->restsize != 0 && newfile->restsize != 8) { // printf("Length=%u ",newfile->Length); // printf("Restsize = %u\n",newfile->restsize); newfile->rest=(BYTE *)malloc(newfile->restsize); int i=0; for(i=0;irestsize;i++) { newfile->rest[i]=0; } newfile->Length+=newfile->restsize; } else { newfile->restsize=0; } newfile->fullpath=malloc(strlen(destpath) + strlen(filename) + 2); strcpy(newfile->fullpath,destpath); strcat(newfile->fullpath,"/"); strcat(newfile->fullpath,filename); return newfile; } DIRENTRY *ReadDir2(FILE *fp,LARGE_INTEGER offset,char *path,DIRENTRY *me,LARGE_INTEGER *content) { DIRENTRY *mydad=me; mydad->CurDirSize=0; LARGE_INTEGER CurSize=0; for(;;) { fseek(fp,offset,SEEK_SET); LARGE_INTEGER curpos=ftell(fp); // printf("Reading at offset %u for path %s\n",curpos, path); DIRENTRY *curentry=ReadDirEntry(fp); // printf("DirEntry read for %s\n",curentry->FileNameAscii); *content+=curentry->Length; mydad->CurDirSize+=curentry->Length; curentry->fullpath=(CHAR *)malloc(sizeof(CHAR)*(strlen(path)+strlen(curentry->FileNameAscii) + 3)); strcpy(curentry->fullpath,path); strcat(curentry->fullpath,"/"); strcat(curentry->fullpath,curentry->FileNameAscii); me->nextbrother=curentry; me=me->nextbrother; if (curentry->Length == 0) { if (me->DirContentSize == 0) { *content+=8; } return(mydad->nextbrother); } else { if(curentry->SubdirOffset!=0) { char *newpath=(char *)malloc(strlen(curentry->FileNameAscii)+strlen(path)+3); strcpy(newpath,path); newpath=strcat(newpath,"/"); newpath=strcat(newpath,curentry->FileNameAscii); me->DirContentSize=0; me->kids=ReadDir2(fp,curentry->SubdirOffset,newpath,me,&(me->DirContentSize)); *content+=me->DirContentSize; } } offset=curpos+curentry->Length; } } DIRENTRY *ReadDir(FILE *fp,LARGE_INTEGER *offset,char *path,DIRENTRY *last) { fseek(fp,*offset,SEEK_SET); LARGE_INTEGER curpos=ftell(fp); last->next=ReadDirEntry(fp); last=last->next; LARGE_INTEGER nextoffset=curpos+last->Length; CHAR *fullpath=(CHAR *)malloc(sizeof(CHAR)*(strlen(path)+strlen(last->FileNameAscii) + 3)); strcpy(fullpath,path); strcat(fullpath,"/"); strcat(fullpath,last->FileNameAscii); last->fullpath=fullpath; //printf(" Filename =|%s|",fullpath); //printf("DEBUG %u ",*offset); //printf("%s\n",fullpath); //printf(" nextoffset =|%u|",nextoffset); //printf(" subdiroffset =|%u|\n",last->SubdirOffset); if (last->Length == 0) { printf ("End of current directory %s\n",path); return last; } else { if(last->SubdirOffset!=0) { char *newpath=(char *)malloc(strlen(last->FileNameAscii)+strlen(path)+3); strcpy(newpath,path); newpath=strcat(newpath,"/"); newpath=strcat(newpath,last->FileNameAscii); *offset=last->SubdirOffset; // PrintDirEntry(last); last=ReadDir(fp,offset,newpath,last); } } *offset=nextoffset; // PrintDirEntry(last); last=ReadDir(fp,offset,path,last); return last; } BOOT_META_DATA ReadBootMetaDataTable(FILE *fp,RESHDR_DISK_SHORT BootMetaData) { BOOT_META_DATA bmd; LARGE_INTEGER totalsize=0; if (BootMetaData.Size != BootMetaData.OriginalSize) { // printf("Compressed metadata table\n"); int result=ReadFileResource(fp,BootMetaData.Offset,BootMetaData.Size,BootMetaData.OriginalSize,"__boot_metadata__"); FILE *bm=fopen("__boot_metadata__","r"); bmd.SecurityData = ReadSecurityData(bm,0); // printf("Succesfully read security data\n"); // PrintSecurityData(bmd.SecurityData); bmd.DirEntry=(DIRENTRY *)malloc(sizeof(DIRENTRY)); LARGE_INTEGER bmdoffset=bmd.SecurityData.TotalLength; ReadDir2(bm,bmdoffset,"",bmd.DirEntry,&totalsize); // printf("Succesfully read dirinfo\n"); fclose(bm); // remove("__boot_metadata__"); } else { // printf("Uncompressed metadata table\n"); int result=ReadUnCompressedFile(fp,BootMetaData.Offset,BootMetaData.Size,BootMetaData.OriginalSize,"__boot_metadata__"); FILE *bm=fopen("__boot_metadata__","r"); bmd.SecurityData = ReadSecurityData(bm,0); // printf("Succesfully read security data\n"); // PrintSecurityData(bmd.SecurityData); bmd.DirEntry=(DIRENTRY *)malloc(sizeof(DIRENTRY)); LARGE_INTEGER bmdoffset=bmd.SecurityData.TotalLength; ReadDir2(bm,bmdoffset,"",bmd.DirEntry,&totalsize); fclose(bm); // remove("__boot_metadata__"); } if (bmd.DirEntry->nextbrother != NULL) { bmd.DirEntry=bmd.DirEntry->nextbrother; } // PrintBootMetaData(bmd); return bmd; } int CopyPart(FILE *fp,LARGE_INTEGER Offset, LARGE_INTEGER Size,char *filename) { fseek(fp,Offset,SEEK_SET); FILE *outfile=fopen(filename,"ab"); char curchar; while(Size-->0) { curchar=fgetc(fp); fputc(curchar,outfile); } fclose(outfile); return 0; } int WriteDWord(FILE *fp,DWORD value) { unsigned char *src = (unsigned char *)&value; fputc(src[0],fp); fputc(src[1],fp); fputc(src[2],fp); fputc(src[3],fp); return 0; } int WriteUshort(FILE *fp,USHORT value) { unsigned char *src = (unsigned char *)&value; fputc(src[0],fp); fputc(src[1],fp); return 0; } int WriteLargeInteger7(FILE *fp,LARGE_INTEGER value) { unsigned char *src = (unsigned char *)&value; fputc(src[0],fp); fputc(src[1],fp); fputc(src[2],fp); fputc(src[3],fp); fputc(src[4],fp); fputc(src[5],fp); fputc(src[6],fp); return 0; } int WriteLargeInteger(FILE *fp,LARGE_INTEGER value) { unsigned char *src = (unsigned char *)&value; fputc(src[0],fp); fputc(src[1],fp); fputc(src[2],fp); fputc(src[3],fp); fputc(src[4],fp); fputc(src[5],fp); fputc(src[6],fp); fputc(src[7],fp); return 0; } int WriteFlags1(FILE *fp,LARGE_INTEGER value) { fputc(value,fp); return 0; } RESHDR_DISK_SHORT WriteLookupTable(FILE *fp,FILE_RESOURCE_HEADER *frh,LARGE_INTEGER items) { RESHDR_DISK_SHORT result; result.Offset=ftell(fp); int OffsetCount=0; for (;OffsetCountImageTag,1,sizeof(Header->ImageTag),fp); WriteDWord(fp,Header->Size); WriteDWord(fp,Header->Version); WriteDWord(fp,Header->Flags); WriteDWord(fp,Header->ChunckSize); fwrite(Header->Guid,1,sizeof(CHAR)*16,fp); WriteUshort(fp,Header->PartNumber); WriteUshort(fp,Header->TotalParts); WriteDWord(fp,Header->ImageCount); WriteLargeInteger7(fp,Header->OffsetTable.Size); WriteFlags1(fp,Header->OffsetTable.Flags); WriteLargeInteger(fp,Header->OffsetTable.Offset); WriteLargeInteger(fp,Header->OffsetTable.OriginalSize); WriteLargeInteger7(fp,Header->XmlData.Size); WriteFlags1(fp,Header->XmlData.Flags); WriteLargeInteger(fp,Header->XmlData.Offset); WriteLargeInteger(fp,Header->XmlData.OriginalSize); WriteLargeInteger7(fp,Header->BootMetaData.Size); WriteFlags1(fp,Header->BootMetaData.Flags); WriteLargeInteger(fp,Header->BootMetaData.Offset); WriteLargeInteger(fp,Header->BootMetaData.OriginalSize); WriteDWord(fp,Header->BootIndex); WriteLargeInteger7(fp,Header->Integrity.Size); WriteFlags1(fp,Header->Integrity.Flags); WriteLargeInteger(fp,Header->Integrity.Offset); WriteLargeInteger(fp,Header->Integrity.OriginalSize); fwrite(Header->Unused,1,sizeof(Header->Unused),fp); return 0; } int ReadXMLInfo(FILE *fp) { int result; WIM_HEADER *Header=malloc(sizeof(WIM_HEADER)); fseek(fp,0,SEEK_SET); result=fread(&(Header->ImageTag),sizeof(Header->ImageTag),1,fp); Header->Size=GetDWord(fp); Header->Version=GetDWord(fp); Header->Flags=GetDWord(fp); Header->ChunckSize=GetDWord(fp); result=fread(&(Header->Guid),sizeof(CHAR)*16,1,fp); Header->PartNumber=GetUshort(fp); Header->TotalParts=GetUshort(fp); Header->ImageCount=GetDWord(fp); Header->OffsetTable.Size=GetLargeInteger7(fp); Header->OffsetTable.Flags=GetFlags1(fp); Header->OffsetTable.Offset=GetLargeInteger(fp); Header->OffsetTable.OriginalSize=GetLargeInteger(fp); LARGE_INTEGER mysize=GetLargeInteger7(fp); Header->XmlData.Flags=GetFlags1(fp); LARGE_INTEGER lioffset=GetLargeInteger(fp); fseek(fp,lioffset,SEEK_SET); BYTE *buf=malloc(sizeof(BYTE) * mysize); LARGE_INTEGER ilen=fread(buf,mysize,sizeof(BYTE),fp); BYTE *xmlnoheader=(BYTE *)malloc(sizeof(BYTE) * (mysize -2)); memcpy(xmlnoheader,&(buf[2]),mysize-2); char *xmlstring=strdup(w2a(xmlnoheader,mysize-2)); printf("%s",xmlstring); return 0; } int ReadWimHeader(FILE *fp,WIM_HEADER *Header) { int result; fseek(fp,0,SEEK_SET); result=fread(&(Header->ImageTag),sizeof(Header->ImageTag),1,fp); Header->Size=GetDWord(fp); Header->Version=GetDWord(fp); Header->Flags=GetDWord(fp); Header->ChunckSize=GetDWord(fp); result=fread(&(Header->Guid),sizeof(CHAR)*16,1,fp); Header->PartNumber=GetUshort(fp); Header->TotalParts=GetUshort(fp); Header->ImageCount=GetDWord(fp); Header->OffsetTable.Size=GetLargeInteger7(fp); Header->OffsetTable.Flags=GetFlags1(fp); Header->OffsetTable.Offset=GetLargeInteger(fp); Header->OffsetTable.OriginalSize=GetLargeInteger(fp); Header->XmlData.Size=GetLargeInteger7(fp); Header->XmlData.Flags=GetFlags1(fp); Header->XmlData.Offset=GetLargeInteger(fp); Header->XmlData.OriginalSize=GetLargeInteger(fp); Header->BootMetaData.Size=GetLargeInteger7(fp); Header->BootMetaData.Flags=GetFlags1(fp); Header->BootMetaData.Offset=GetLargeInteger(fp); Header->BootMetaData.OriginalSize=GetLargeInteger(fp); Header->BootIndex=GetDWord(fp); Header->Integrity.Size=GetLargeInteger7(fp); Header->Integrity.Flags=GetFlags1(fp); Header->Integrity.Offset=GetLargeInteger(fp); Header->Integrity.OriginalSize=GetLargeInteger(fp); result=fread(&(Header->Unused),sizeof(Header->Unused),1,fp); return 0; } int PrintHeader (WIM_HEADER Header) { printf("Imagetag = %s\n",Header.ImageTag); printf("Headersize = %X\n",Header.Size); printf("Version = %X\n",Header.Version); printf("Flags = %X\n",Header.Flags); if (Header.Flags & FLAG_HEADER_COMPRESS_XPRESS) { printf(" COMPRESS XPRESS FLAG is set\n"); } if (Header.Flags & FLAG_HEADER_COMPRESS_LZX) { printf(" COMPRESS LZX FLAG is set\n"); } printf("ChunckSize = %u\n",Header.ChunckSize); printf("Guid = %X\n",Header.Guid); printf("PartNumber = %u\n",Header.PartNumber); printf("TotalParts = %u\n",Header.TotalParts); printf("ImageCount = %u\n",Header.ImageCount); printf("OffsetTable Size = %X\n",Header.OffsetTable.Size); printf("OffsetTable Flags = %x\n",Header.OffsetTable.Flags); printf("OffsetTable Offset = %X\n",Header.OffsetTable.Offset); printf("OffsetTable OriginalSize = %X\n",Header.OffsetTable.OriginalSize); printf("XmlData Size = %X\n",Header.XmlData.Size); printf("XmlData Flags = %x\n",Header.XmlData.Flags); printf("XmlData Offset = %X\n",Header.XmlData.Offset); printf("XmlData OriginalSize = %X\n",Header.XmlData.OriginalSize); printf("BootMetaData Size = %X\n",Header.BootMetaData.Size); printf("BootMetaData Flags = %x\n",Header.BootMetaData.Flags); printf("BootMetaData Offset = %X\n",Header.BootMetaData.Offset); printf("BootMetaData OriginalSize = %X\n",Header.BootMetaData.OriginalSize); printf("Header.BootIndex = %u\n",Header.BootIndex); printf("Integrity Flags = %hX\n",Header.Integrity.Flags); printf("Integrity Size = %u\n",Header.Integrity.Size); printf("Integrity Offset = %u\n",Header.Integrity.Offset); printf("Integrity OriginalSize = %u\n",Header.Integrity.OriginalSize); return 0; } int CopyFileResource(FILE *infile, FILE_RESOURCE_HEADER *frh, FILE *of) { fseek(infile,frh->ResourceHeader.Offset,SEEK_SET); frh->ResourceHeader.Offset=ftell(of); LARGE_INTEGER byteswritten=0; while(byteswrittenResourceHeader.Size) { BYTE curchar=fgetc(infile); fputc(curchar,of); byteswritten++; } return 0; } FILE_RESOURCE_HEADER *AddFileResource(CHAR *path,FILE *of) { FILE_RESOURCE_HEADER *frh=malloc(sizeof(FILE_RESOURCE_HEADER)); frh->ResourceHeader.Offset=ftell(of); FILE *infile=fopen(path,"r"); if (infile == NULL) { printf("ERROR: Could not open file %s\n",path); exit(0); } CHAR curchar; while(!feof(infile)) { curchar=fgetc(infile); fputc(curchar,of); } frh->ResourceHeader.Size=ftell(infile); frh->ResourceHeader.OriginalSize=frh->ResourceHeader.Size; frh->PartNumber=1; frh->ReferenceCount=1; fclose(infile); return frh; } int CopyFileResources(FILE *infile,FILE *of,FILE_RESOURCE_HEADER *frh,LARGE_INTEGER numitems) { LARGE_INTEGER frhindex=0; for(frhindex=0;frhindexLength); if(direntry->Length == 0) { return 0; } WriteDWord(fp,direntry->Attributes); WriteDWord(fp,direntry->SecurityId); WriteLargeInteger(fp,direntry->SubdirOffset); WriteLargeInteger(fp,direntry->Unused1); WriteLargeInteger(fp,direntry->Unused2); WriteLargeInteger(fp,direntry->CreationTime); WriteLargeInteger(fp,direntry->LastAccessTime); WriteLargeInteger(fp,direntry->LastWriteTime); fwrite(direntry->Hash,sizeof(BYTE),20,fp); WriteDWord(fp,direntry->ReparseTag); // WriteDWord(fp,direntry->ReparseReserved); WriteLargeInteger(fp,direntry->HardLink); WriteUshort(fp,direntry->Streams); WriteUshort(fp,direntry->ShortNameLength); WriteUshort(fp,direntry->FileNameLength); fwrite(direntry->FileName,direntry->FileNameLength,1,fp); WriteUshort(fp,direntry->FileNamePad); fwrite(direntry->ShortFileName,direntry->ShortNameLength,1,fp); USHORT streamindex=0; for (streamindex=0;streamindexStreams;streamindex++) { WriteLargeInteger(fp,direntry->StreamEntries[streamindex].Length); WriteLargeInteger(fp,direntry->StreamEntries[streamindex].Unused1); fwrite(direntry->StreamEntries[streamindex].Hash,20,1,fp); WriteUshort(fp,direntry->StreamEntries[streamindex].StreamNameLength); fwrite(direntry->StreamEntries[streamindex].StreamName,direntry->StreamEntries[streamindex].StreamNameLength,1,fp); } fwrite(direntry->rest,direntry->restsize,1,fp); LARGE_INTEGER newpos=ftell(fp); if (newpos-curpos != direntry->Length) { printf("ERROR writing Direntry= %s ",direntry->fullpath); printf("Written Size = %u",newpos-curpos); printf("I thought it was = %u\n",direntry->Length); } return 0; } FILE_RESOURCE_HEADER *WriteUnCompressedFileResource(FILE *of,char *srcfilename) { FILE_RESOURCE_HEADER *lte=malloc(sizeof(FILE_RESOURCE_HEADER)); FILE *infile=fopen(srcfilename,"rb"); lte->ResourceHeader.Offset=ftell(of); int cheap_hash_counter=0; while(!feof(infile)) { BYTE curchar=fgetc(infile); fputc(curchar,of); // cheap hash, the first 20 bytes from file itself // we have to check anyway if there are doubles if(cheap_hash_counter++<20) { lte->Hash[cheap_hash_counter]=curchar; } } fclose(infile); lte->ResourceHeader.Size=ftell(infile); lte->ResourceHeader.OriginalSize=lte->ResourceHeader.Size; lte->ResourceHeader.Flags=0; lte->PartNumber=1; lte->ReferenceCount=1; return lte; } int PrintLookupTable(FILE_RESOURCE_HEADER *frh, LARGE_INTEGER numoffsets) { LARGE_INTEGER i=0; for(i=0;inextbrother); LARGE_INTEGER StartOffset=bmd.SecurityData.TotalLength; bmd.DirEntry->DirContentSize=0; PrintDirentries2(bmd.DirEntry,StartOffset); }