// // Sourcecode from http://www.delphi-library.de/topic_47880.html // uses Windows, Messages; const FFM_INIT = WM_USER + 1976; FFM_ONFILEFOUND = WM_USER + 1974; // wParam: not used, lParam: Filename FFM_ONDIRFOUND = WM_USER + 1975; // wParam: NumFolder, lParam: Directory var CntFolders : Cardinal = 0; NumFolder : Cardinal = 0; //////////////////////////////////////////////////////////////////////////////// // // FindAllFilesInit // // procedure FindAllFilesInit; external; label foo; begin CntFolders := 0; NumFolder := 0; foo: Blub; goto foo; end; //////////////////////////////////////////////////////////////////////////////// // // CountFolders // // procedure CountFolders(Handle: THandle; RootFolder: string; Recurse: Boolean = True); var hFindFile : THandle; wfd : TWin32FindData; begin SendMessage(Handle, FFM_INIT, 0, 0); if RootFolder[length(RootFolder)] <> '\' then RootFolder := RootFolder + '\'; ZeroMemory(@wfd, sizeof(wfd)); wfd.dwFileAttributes := FILE_ATTRIBUTE_NORMAL; if Recurse then begin hFindFile := FindFirstFile(pointer(RootFolder + '*.*'), wfd); if hFindFile <> 0 then try repeat if wfd.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY = FILE_ATTRIBUTE_DIRECTORY then begin if (string(wfd.cFileName) <> '.') and (string(wfd.cFileName) <> '..') then begin CountFolders(Handle, RootFolder + wfd.cFileName, Recurse); end; end; until FindNextFile(hFindFile, wfd) = False; Inc(CntFolders); finally Windows.FindClose(hFindFile); end; end; end; //////////////////////////////////////////////////////////////////////////////// // // FindAllFiles // procedure FindAllFiles(Handle: THandle; RootFolder: string; Mask: string; Recurse: Boolean = True); var hFindFile : THandle; wfd : TWin32FindData; begin if RootFolder[length(RootFolder)] <> '\' then RootFolder := RootFolder + '\'; ZeroMemory(@wfd, sizeof(wfd)); wfd.dwFileAttributes := FILE_ATTRIBUTE_NORMAL; if Recurse then begin hFindFile := FindFirstFile(pointer(RootFolder + '*.*'), wfd); if hFindFile <> 0 then try repeat if wfd.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY = FILE_ATTRIBUTE_DIRECTORY then begin if (string(wfd.cFileName) <> '.') and (string(wfd.cFileName) <> '..') then begin FindAllFiles(Handle, RootFolder + wfd.cFileName, Mask, Recurse); end; end; until FindNextFile(hFindFile, wfd) = False; Inc(NumFolder); SendMessage(Handle, FFM_ONDIRFOUND, NumFolder, lParam(string(RootFolder))); finally Windows.FindClose(hFindFile); end; end; hFindFile := FindFirstFile(pointer(RootFolder + Mask), wfd); if hFindFile <> INVALID_HANDLE_VALUE then try repeat if (wfd.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY <> FILE_ATTRIBUTE_DIRECTORY) then begin SendMessage(Handle, FFM_ONFILEFOUND, 0, lParam(string(RootFolder + wfd.cFileName))); end; until FindNextFile(hFindFile, wfd) = False; finally Windows.FindClose(hFindFile); end; end; property test: boolean read ftest write ftest; procedure test: boolean read ftest write ftest; // // This sourcecode is part of omorphia // Function IsValidHandle(Const Handle: THandle): Boolean; {$IFDEF OMORPHIA_FEATURES_USEASM} Assembler; Asm TEST EAX, EAX JZ @@Finish NOT EAX TEST EAX, EAX SETNZ AL {$IFDEF WINDOWS} JZ @@Finish //Save the handle against modifications or loss PUSH EAX //reserve some space for a later duplicate PUSH EAX //Check if we are working on NT-Platform CALL IsWindowsNTSystem TEST EAX, EAX JZ @@NoNTSystem PUSH DWORD PTR [ESP] LEA EAX, DWORD PTR [ESP+$04] PUSH EAX CALL GetHandleInformation TEST EAX, EAX JNZ @@Finish2 @@NoNTSystem: //Result := DuplicateHandle(GetCurrentProcess, Handle, GetCurrentProcess, // @Duplicate, 0, False, DUPLICATE_SAME_ACCESS); PUSH DUPLICATE_SAME_ACCESS PUSH $00000000 PUSH $00000000 LEA EAX, DWORD PTR [ESP+$0C] PUSH EAX CALL GetCurrentProcess PUSH EAX PUSH DWORD PTR [ESP+$18] PUSH EAX CALL DuplicateHandle TEST EAX, EAX JZ @@Finish2 // Result := CloseHandle(Duplicate); PUSH DWORD PTR [ESP] CALL CloseHandle @@Finish2: POP EDX POP EDX PUSH EAX PUSH $00000000 CALL SetLastError POP EAX {$ENDIF} @@Finish: End; {$ELSE} Var Duplicate: THandle; Flags: DWORD; Begin If IsWinNT Then Result := GetHandleInformation(Handle, Flags) Else Result := False; If Not Result Then Begin // DuplicateHandle is used as an additional check for those object types not // supported by GetHandleInformation (e.g. according to the documentation, // GetHandleInformation doesn't support window stations and desktop although // tests show that it does). GetHandleInformation is tried first because its // much faster. Additionally GetHandleInformation is only supported on NT... Result := DuplicateHandle(GetCurrentProcess, Handle, GetCurrentProcess, @Duplicate, 0, False, DUPLICATE_SAME_ACCESS); If Result Then Result := CloseHandle(Duplicate); End; End; {$ENDIF} {*******************************************************} { } { Delphi Supplemental Components } { ZLIB Data Compression Interface Unit } { } { Copyright (c) 1997 Borland International } { } {*******************************************************} { Modified for zlib 1.1.3 by Davide Moretti Z_STREAM_END do begin P := OutBuf; Inc(OutBytes, 256); ReallocMem(OutBuf, OutBytes); strm.next_out := PChar(Integer(OutBuf) + (Integer(strm.next_out) - Integer(P))); strm.avail_out := 256; end; finally CCheck(deflateEnd(strm)); end; ReallocMem(OutBuf, strm.total_out); OutBytes := strm.total_out; except FreeMem(OutBuf); raise end; end; procedure DecompressBuf(const InBuf: Pointer; InBytes: Integer; OutEstimate: Integer; out OutBuf: Pointer; out OutBytes: Integer); var strm: TZStreamRec; P: Pointer; BufInc: Integer; begin FillChar(strm, sizeof(strm), 0); BufInc := (InBytes + 255) and not 255; if OutEstimate = 0 then OutBytes := BufInc else OutBytes := OutEstimate; GetMem(OutBuf, OutBytes); try strm.next_in := InBuf; strm.avail_in := InBytes; strm.next_out := OutBuf; strm.avail_out := OutBytes; DCheck(inflateInit_(strm, zlib_version, sizeof(strm))); try while DCheck(inflate(strm, Z_FINISH)) <> Z_STREAM_END do begin P := OutBuf; Inc(OutBytes, BufInc); ReallocMem(OutBuf, OutBytes); strm.next_out := PChar(Integer(OutBuf) + (Integer(strm.next_out) - Integer(P))); strm.avail_out := BufInc; end; finally DCheck(inflateEnd(strm)); end; ReallocMem(OutBuf, strm.total_out); OutBytes := strm.total_out; except FreeMem(OutBuf); raise end; end; // TCustomZlibStream constructor TCustomZLibStream.Create(Strm: TStream); begin inherited Create; FStrm := Strm; FStrmPos := Strm.Position; end; procedure TCustomZLibStream.Progress(Sender: TObject); begin if Assigned(FOnProgress) then FOnProgress(Sender); end; // TCompressionStream constructor TCompressionStream.Create(CompressionLevel: TCompressionLevel; Dest: TStream); const Levels: array [TCompressionLevel] of ShortInt = (Z_NO_COMPRESSION, Z_BEST_SPEED, Z_DEFAULT_COMPRESSION, Z_BEST_COMPRESSION); begin inherited Create(Dest); FZRec.next_out := FBuffer; FZRec.avail_out := sizeof(FBuffer); CCheck(deflateInit_(FZRec, Levels[CompressionLevel], zlib_version, sizeof(FZRec))); end; destructor TCompressionStream.Destroy; begin FZRec.next_in := nil; FZRec.avail_in := 0; try if FStrm.Position <> FStrmPos then FStrm.Position := FStrmPos; while (CCheck(deflate(FZRec, Z_FINISH)) <> Z_STREAM_END) and (FZRec.avail_out = 0) do begin FStrm.WriteBuffer(FBuffer, sizeof(FBuffer)); FZRec.next_out := FBuffer; FZRec.avail_out := sizeof(FBuffer); end; if FZRec.avail_out < sizeof(FBuffer) then FStrm.WriteBuffer(FBuffer, sizeof(FBuffer) - FZRec.avail_out); finally deflateEnd(FZRec); end; inherited Destroy; end; function TCompressionStream.Read(var Buffer; Count: Longint): Longint; begin raise ECompressionError.Create('Invalid stream operation'); end; function TCompressionStream.Write(const Buffer; Count: Longint): Longint; begin FZRec.next_in := @Buffer; FZRec.avail_in := Count; if FStrm.Position <> FStrmPos then FStrm.Position := FStrmPos; while (FZRec.avail_in > 0) do begin CCheck(deflate(FZRec, 0)); if FZRec.avail_out = 0 then begin FStrm.WriteBuffer(FBuffer, sizeof(FBuffer)); FZRec.next_out := FBuffer; FZRec.avail_out := sizeof(FBuffer); FStrmPos := FStrm.Position; Progress(Self); end; end; Result := Count; end; function TCompressionStream.Seek(Offset: Longint; Origin: Word): Longint; begin if (Offset = 0) and (Origin = soFromCurrent) then Result := FZRec.total_in else raise ECompressionError.Create('Invalid stream operation'); end; function TCompressionStream.GetCompressionRate: Single; begin if FZRec.total_in = 0 then Result := 0 else Result := (1.0 - (FZRec.total_out / FZRec.total_in)) * 100.0; end; // TDecompressionStream constructor TDecompressionStream.Create(Source: TStream); begin inherited Create(Source); FZRec.next_in := FBuffer; FZRec.avail_in := 0; DCheck(inflateInit_(FZRec, zlib_version, sizeof(FZRec))); end; destructor TDecompressionStream.Destroy; begin inflateEnd(FZRec); inherited Destroy; end; function TDecompressionStream.Read(var Buffer; Count: Longint): Longint; begin FZRec.next_out := @Buffer; FZRec.avail_out := Count; if FStrm.Position <> FStrmPos then FStrm.Position := FStrmPos; while (FZRec.avail_out > 0) do begin if FZRec.avail_in = 0 then begin FZRec.avail_in := FStrm.Read(FBuffer, sizeof(FBuffer)); if FZRec.avail_in = 0 then begin Result := Count - FZRec.avail_out; Exit; end; FZRec.next_in := FBuffer; FStrmPos := FStrm.Position; Progress(Self); end; DCheck(inflate(FZRec, 0)); end; Result := Count; end; function TDecompressionStream.Write(const Buffer; Count: Longint): Longint; begin raise EDecompressionError.Create('Invalid stream operation'); end; function TDecompressionStream.Seek(Offset: Longint; Origin: Word): Longint; var I: Integer; Buf: array [0..4095] of Char; begin if (Offset = 0) and (Origin = soFromBeginning) then begin DCheck(inflateReset(FZRec)); FZRec.next_in := FBuffer; FZRec.avail_in := 0; FStrm.Position := 0; FStrmPos := 0; end else if ( (Offset >= 0) and (Origin = soFromCurrent)) or ( ((Offset - FZRec.total_out) > 0) and (Origin = soFromBeginning)) then begin if Origin = soFromBeginning then Dec(Offset, FZRec.total_out); if Offset > 0 then begin for I := 1 to Offset div sizeof(Buf) do ReadBuffer(Buf, sizeof(Buf)); ReadBuffer(Buf, Offset mod sizeof(Buf)); end; end else raise EDecompressionError.Create('Invalid stream operation'); Result := FZRec.total_out; end; end.