Hi all, When I was doing some tests on the issue of OEM char sets I noticed some problems in TZipBuilder as wel, I tried to fix them when spotted, so here you have the remarks + possible fixes. ------------------------ 1- function ConvertOem2Iso has a loop that is not needed we can let the WinAPI do the work for us: void __fastcall TZipBuilder::ConvertOem2Iso( char *Source, CodePageDirection Direction ) file://changed R. Aelbrecht avoid redundant loop if(Direction == cpdOEM2ISO) OemToCharBuff(Source, Source, strlen(Source)); else CharToOemBuff(Source,Source,strlen(Source)); ---------------------------- 2- in function SetZipSwitches did not always pass correct codepage to the dll : void __fastcall TZipBuilder::SetZipSwitches( String &NameOfZipFile, int zpVersion ) file://changed R. Aelbrecht to allow OEM2ISo conversion in Delete function // if ( FCodePage == cpOEM ) // ZipParms2->fWantedCodePage = 2; ZipParms2->fWantedCodePage = FCodePage; ------------------------ 3- Function rename does not work when full paths are used in the ZipRenameRec we try to match these names with the names in the archive but the archive names have no drive name In function int __fastcall TZipBuilder::Rename( TList &RenameList, unsigned long DateTime ) After statement : RenRec->Dest = ReplaceForwardSlash( RenRec->Dest.c_str() ); file://added R.Aelbrecht to allow drive name in RenameList Source and destination RemoveDriveSpec(RenRec->Source); RemoveDriveSpec(RenRec->Dest); file://end add ------------------------ 4- function rename does not work when filenames in the archive are with OEM char set In function int __fastcall TZipBuilder::Rename( TList &RenameList, unsigned long DateTime ) After statement: StrLCopy( MDZD[ i ]->FileName, Buffer, CEH.FileNameLen ); file://Added R.Aelbrecht to convert OEM char set in original file else we // don't find the file FHostNum = CEH.VersionMadeBy1; FHostVer = CEH.VersionMadeBy0; ConvertOem2Iso(MDZD[i]->FileName, cpdOEM2ISO); file://DiskStart is not used in this function and we need FHostNum later MDZD[i]->DiskStart = (FHostNum << 8) + FHostVer; file://end add and after statement : MDZD[ i ]->FileName = new char[ LOH.FileNameLen + 1 ]; StrPLCopy( MDZD[ i ]->FileName, OrigFileName, LOH.FileNameLen + 1 ); file://added R.Aelbrecht to allow OEM char sets in Rename file://we replaced the filename look if we need to reconvert it FHostNum = (MDZD[i]->DiskStart & 0xFF00) >> 8; FHostVer = (MDZD[i]->DiskStart & 0xFF); ConvertOem2Iso(MDZD[i]->FileName, cpdISO2OEM); file://end add ------------------------ 5- Function copyzippedfiles does not work when full paths are used in the FSpecArgs we try to match these names with the names in the archive but the archive names have no drive name In function int __fastcall TZipBuilder::CopyZippedFiles( TZipBuilder *DestZipBuilder, bool DeleteFromSource, OvrOpts OverwriteDest ) After statement : for( int s = 0; s < FSpecArgs->Count; s++ ) { file://added R.Aelbrecht to allow drive name in FSpecArg AnsiString FSpec = FSpecArgs->Strings[s]; RemoveDriveSpec(FSpec); file://end add + change: file://changed R.Aelbrecht for drive in FSpecArg if ( !AnsiStrIComp( FSpec.c_str(), zde->FileName.c_str() ) ) ------------------------ 6- In CopyZippedFiles if in the source archive the filenames were with OEM char set, then we need to copy them the same way to have the local and central headers match In function int __fastcall TZipBuilder::CopyZippedFiles( TZipBuilder *DestZipBuilder, bool DeleteFromSource, OvrOpts OverwriteDest ) After statement : // Write this changed central header to disk WriteJoin( &CEH, sizeof( CEH ), DS_CEHBadWrite ); file://added by R. Aelbrecht file://if filename was converted OEM2ISO then we have to reconvert before copying FHostNum = CEH.VersionMadeBy1; FHostVer = CEH.VersionMadeBy0; ConvertOem2Iso(MDZD[d]->FileName, cpdISO2OEM); file://end add ------------------------ 7- For the above changes a small function was added to TZipBuilder file://Added by R. Aelbrecht to remove the Drive from a full path specification void __fastcall TZipBuilder::RemoveDriveSpec(AnsiString& FullPathName) { if(ExtractFileDrive(FullPathName) != "") { int position = FullPathName.Pos("\\"); FullPathName = FullPathName.SubString(position + 1, FullPathName.Length() - position); } } ------------------------ 8- The example given in the on-line help for CopyZippedFiles is not correct and is somewhat misleading I propose to change it to ZipBuilder1->ZipFileName = "SourceZip.zip"; ZipBuilder1->FSpecArgs->Clear( ); ZipBuilder1->FSpecArgs->Add( "C:\\AutoExec.bat" ); ZipBuilder1->FSpecArgs->Add( "C:\\Config.sys" ); ZipBuilder2->ZipFileName = "DestinationZip.zip"; ZipBuilder2->FSpecArgs->Clear( ); ZipBuilder2->HowToDelete = htdAllowUndo; Result = ZipBuilder1->CopyZippedFiles( ZipBuilder2, true, OvrConfirm ); When the Result is 0 (Ok) then the two files are removed from SourceZip.zip and were copied into DestinationZip.zip. The Original destination archive (DestinationZip.zip) is placed into the recycle bin. File(s) that are not copied because you answered NO on the overwrite question, or in case OvrNever was specified, can be found in the FSpecArgs list from the source afterwards. Since we have no access to the .rtf files we cannot change the help files. I did not try to translate the cpp statements into Pascal, my experience with Pascal is from Turbopascal and I have no means of testing anything Regards -- Roger Aelbrecht http://web.wanadoo.be/driehoeksw