diff --git a/PasZip.pas b/PasZip.pas index d80fc9a6a..29a272a9f 100644 --- a/PasZip.pas +++ b/PasZip.pas @@ -36,6 +36,10 @@ - .zip reading from file, resource or direct memory - Windows only - .zip write into a file (new .zip creation, not update) - Windows only + This unit is a cut-down stand-alone zip reader/writer, to be used e.g. + in installers or size-critical projects. Consider mormot.core.zip.pas from + mORMot 2 for more features, and better performance (thanks to libdeflate). + } {$WARNINGS OFF} @@ -334,6 +338,7 @@ implementation {$ifndef FPC} type PtrUInt = {$ifdef CPU64}NativeUInt{$else}cardinal{$endif}; + PtrInt = {$ifdef CPU64}NativeInt {$else}integer {$endif}; {$endif FPC} // special tuned Move() routine, including data overlap bug correction @@ -3810,9 +3815,13 @@ procedure CreateVoidZip(const aFileName: TFileName); FileClose(H); end; - {$ifdef MSWINDOWS} +function ValidHandle(Handle: THandle): boolean; {$ifdef HASINLINE}inline;{$endif} +begin + result := PtrInt(Handle) > 0; +end; + type splitInt64 = packed record loCard, hiCard: cardinal @@ -3831,10 +3840,10 @@ function CompressFile(const srcFile, dstFile: TFileName; failIfGrow: boolean): b try sf := CreateFile(pointer(srcFile), GENERIC_READ, FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0); - if sf <> INVALID_HANDLE_VALUE then begin + if ValidHandle(sf) then begin df := CreateFile(pointer(dstFile), GENERIC_READ or GENERIC_WRITE, 0, nil, CREATE_ALWAYS, 0, 0); - if df <> INVALID_HANDLE_VALUE then begin + if ValidHandle(df) then begin sm := CreateFileMapping(sf, nil, PAGE_READONLY, 0, 0, nil); if sm <> 0 then begin splitInt64(sl).loCard := GetFileSize(sf, @splitInt64(sl).hiCard); @@ -3907,10 +3916,10 @@ function UncompressFile(const srcFile, dstFile: TFileName; lastWriteTime: int64; sf := CreateFile(pointer(srcFile), GENERIC_READ, FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL or FILE_FLAG_SEQUENTIAL_SCAN, 0); - if sf <> INVALID_HANDLE_VALUE then begin + if ValidHandle(sf) then begin df := CreateFile(pointer(dstFile), GENERIC_READ or GENERIC_WRITE, 0, nil, CREATE_ALWAYS, attr or FILE_FLAG_SEQUENTIAL_SCAN, 0); - if df <> INVALID_HANDLE_VALUE then begin + if ValidHandle(df) then begin sm := CreateFileMapping(sf, nil, PAGE_READONLY, 0, 0, nil); if sm <> 0 then begin sb := MapViewOfFile(sm, FILE_MAP_READ, 0, 0, 0); @@ -3991,7 +4000,7 @@ function GetCompressedFileInfo(const comprFile: TFileName; var size: int64; crc32 := 0; file_ := CreateFile(pointer(comprFile), GENERIC_READ, FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0); - if file_ <> INVALID_HANDLE_VALUE then begin + if ValidHandle(file_) then begin result := ReadFile(file_, size, 8, c1, nil) and (c1 = 8) and ReadFile(file_, crc32, 4, c1, nil) and (c1 = 4); CloseHandle(file_); @@ -4007,7 +4016,7 @@ function GetUncompressedFileInfo(const uncomprFile: TFileName; var size: int64; result := false; file_ := CreateFile(pointer(uncomprFile), GENERIC_READ, FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0); - if file_ <> INVALID_HANDLE_VALUE then begin + if ValidHandle(file_) then begin splitInt64(size).loCard := GetFileSize(file_, @splitInt64(size).hiCard); map := CreateFileMapping(file_, nil, PAGE_READONLY, 0, 0, nil); if map <> 0 then begin @@ -4069,14 +4078,11 @@ function Zip(const zip: TFileName; const files, zipAs: array of TFileName; NoSubDirectories: boolean = false): boolean; var i1, i2, i3: integer; - dstFh: THandle; - srcFh: THandle; + dstFh, srcFh: THandle; ft: TFileTime; - c1: dword; + c1, size: dword; lfhr: TLocalFileHeader; - srcBuf: pointer; - dstBuf: pointer; - size: dword; + srcBuf, dstBuf: pointer; zipRec: array of record name: TZipName; fhr: TFileHeader; @@ -4084,7 +4090,7 @@ function Zip(const zip: TFileName; const files, zipAs: array of TFileName; lhr: TLastHeader; begin dstFh := CreateFile(pointer(zip), GENERIC_WRITE, 0, nil, CREATE_ALWAYS, 0, 0); - result := dstFh <> INVALID_HANDLE_VALUE; + result := ValidHandle(dstFh); if result then begin SetLength(zipRec, Length(files)); i2 := 0; @@ -4103,7 +4109,7 @@ function Zip(const zip: TFileName; const files, zipAs: array of TFileName; name := TZipName(zipAs[i1]); srcFh := CreateFile(pointer(files[i1]), GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, 0, 0); - if srcFh <> INVALID_HANDLE_VALUE then begin + if ValidHandle(srcFh) then begin size := GetFileSize(srcFh, nil); srcBuf := pointer(LocalAlloc(LPTR, size)); if srcBuf <> nil then begin @@ -4230,6 +4236,7 @@ procedure InitCrc32Tab; end; {$endif} + {$ifdef MSWINDOWS} { TZipRead } @@ -4314,7 +4321,7 @@ constructor TZipRead.Create(const aFileName: TFileName; ZipStartOffset, Size: fShowMessageBoxOnError := ShowMessageBoxOnError; file_ := CreateFile(pointer(aFileName), GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, 0, 0); - if file_ = INVALID_HANDLE_VALUE then + if not ValidHandle(file_) then exit; // file doesn't exist -> leave no Entry[] (Count=0) if Size = 0 then Size := GetFileSize(file_, nil); @@ -4345,13 +4352,13 @@ constructor TZipRead.Create(const aFileName: TFileName; ZipStartOffset, Size: procedure TZipRead.UnMap; begin Count := 0; - if file_ <> INVALID_HANDLE_VALUE then begin + if ValidHandle(file_) then begin if map <> 0 then begin UnmapViewOfFile(Buf); CloseHandle(map); end; CloseHandle(file_); - file_ := INVALID_HANDLE_VALUE; + file_ := 0; end; Buf := nil; end; @@ -4453,7 +4460,7 @@ function TZipRead.CheckFile(aIndex: integer; DestPath: TFileName): boolean; DestPath := DestPath + '\'; F := CreateFile(pointer(DestPath + Entry[aIndex].Name), GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, 0, 0); - if F <> INVALID_HANDLE_VALUE then + if ValidHandle(F) then with Entry[aIndex] do try Size := GetFileSize(F, nil); @@ -4508,7 +4515,7 @@ function TZipRead.UnZipFile(aIndex: integer; DestPath: TFileName; {$endif} f := DestPath + n; H := FileOpen(f, fmOpenRead); - if H <> INVALID_HANDLE_VALUE then begin + if ValidHandle(H) then begin GetFileTime(H, nil, nil, @fFileTime); FileTimeToLocalFileTime(fFileTime, fFileTime); fFileSize := GetFileSize(H, nil); @@ -4524,7 +4531,7 @@ function TZipRead.UnZipFile(aIndex: integer; DestPath: TFileName; end; ForceDirectories(ExtractFileDir(f)); H := FileCreate(f); - if H <> INVALID_HANDLE_VALUE then + if ValidHandle(H) then try if info^.zZipMethod = 0 then begin // stored method if info^.zcrc32 <> not UpdateCrc32(dword(-1), data, info^.zfullSize) then @@ -4612,26 +4619,31 @@ procedure TZipWrite.AddDeflated(const aFileName: TFileName; RemovePath: boolean; FileTime: LongRec; begin H := FileOpen(aFileName, fmOpenRead or fmShareDenyNone); - if H = INVALID_HANDLE_VALUE then - exit; - if RemovePath then - ZipName := TZipName(ExtractFileName(aFileName)) - else - ZipName := TZipName(aFileName); - GetFileTime(H, nil, nil, @Time); - FileTimeToLocalFileTime(Time, Time); - FileTimeToDosDateTime(Time, FileTime.Hi, FileTime.Lo); - Size := GetFileSize(H, nil); - getmem(buf, Size); - FileRead(H, buf^, Size); - AddDeflated(ZipName, buf, size, CompressLevel, integer(FileTime)); - freemem(buf); - FileClose(H); + if ValidHandle(H) then + try + if RemovePath then + ZipName := TZipName(ExtractFileName(aFileName)) + else + ZipName := TZipName(aFileName); + GetFileTime(H, nil, nil, @Time); + FileTimeToLocalFileTime(Time, Time); + FileTimeToDosDateTime(Time, FileTime.Hi, FileTime.Lo); + Size := GetFileSize(H, nil); + getmem(buf, Size); + try + FileRead(H, buf^, Size); + AddDeflated(ZipName, buf, size, CompressLevel, integer(FileTime)); + finally + freemem(buf); + end; + finally + FileClose(H); + end; end; procedure TZipWrite.AddFromZip(const ZipEntry: TZipEntry); begin - if (self = nil) or (Handle = 0) or (Handle = integer(INVALID_HANDLE_VALUE)) then + if (self = nil) or not ValidHandle(Handle) then exit; if Count >= length(Entry) then SetLength(Entry, length(Entry) + 20); @@ -4656,7 +4668,7 @@ procedure TZipWrite.AddFromZip(const ZipEntry: TZipEntry); procedure TZipWrite.AddStored(const aZipName: TZipName; Buf: pointer; Size, FileAge: integer); begin - if (self = nil) or (Handle = 0) or (Handle = integer(INVALID_HANDLE_VALUE)) then + if (self = nil) or not ValidHandle(Handle) then exit; if Count >= length(Entry) then SetLength(Entry, length(Entry) + 20); @@ -4684,7 +4696,7 @@ procedure TZipWrite.AddStored(const aZipName: TZipName; Buf: pointer; Size, procedure TZipWrite.Append(const Content: RawByteZip); begin - if (self = nil) or (Handle = 0) or (Handle = integer(INVALID_HANDLE_VALUE)) or + if (self = nil) or not ValidHandle(Handle) or (fAppendOffset <> 0) then exit; fAppendOffset := length(Content); diff --git a/SynopseCommit.inc b/SynopseCommit.inc index ec9055f7d..eeadcb539 100644 --- a/SynopseCommit.inc +++ b/SynopseCommit.inc @@ -1 +1 @@ -'1.18.7657' +'1.18.7658'