Since less information One possibility would be to use alternative streams on NTFS, which can be added to files and folders. You can simply try this by typing "notepad C: \ temp: hidden1.txt" into comandline, a new filestream will be created if you use yes. After saving, you can open it in the same way. This can also be done from delphi (load / save). Will only work when using NTFS. I do not know if this method is used in the described case, you can find ADS using the following code:
unit u_ListADS; // 20120928 by Thomas Wassermann // www.devworx.de interface uses Windows, Messages, SysUtils, Variants, Classes, StrUtils; Procedure GetADS(List: TStrings; const Path, WildCard: String; Recursiv: Boolean = false); function NtQueryInformationFile(FileHandle: Cardinal; IoStatusBlock: Pointer; FileInformation: Pointer; FileInformationLength: Cardinal; FileInformationClass: Cardinal): Cardinal; stdcall; external 'ntdll.dll'; implementation type _FILE_STREAM_INFORMATION = record NextEntryOffset: Cardinal; StreamNameLength: Cardinal; StreamSize: int64; StreamAllocationSize: int64; StreamName: array [0 .. MAX_PATH] of WideChar; end; PFILE_STREAM_INFORMATION = ^_FILE_STREAM_INFORMATION; function GetStreams(aFilename: String): TStringList; var FileHandle: Integer; FileName: array [0 .. MAX_PATH] of WideChar; StreamName: String; InfoBlock: _FILE_STREAM_INFORMATION; StatusBlock: record Status: Cardinal; Information: PDWORD; end; Procedure Analyze; begin CopyMemory(@FileName, @InfoBlock.StreamName, InfoBlock.StreamNameLength); StreamName := Copy(Filename, 1, PosEx(':', Filename, 2) - 1); if StreamName <> ':' then Result.Add(StreamName); end; begin Result := TStringList.Create; FileHandle := FileOpen(aFilename, GENERIC_READ); NtQueryInformationFile(FileHandle, @StatusBlock, @InfoBlock, SizeOf(InfoBlock), 22); FileClose(FileHandle); if InfoBlock.StreamNameLength <> 0 then Repeat if (InfoBlock.NextEntryOffset <> 0) then begin InfoBlock := PFILE_STREAM_INFORMATION(PByte(@InfoBlock) + InfoBlock.NextEntryOffset)^; Analyze; end; until InfoBlock.NextEntryOffset = 0 end; Procedure GetADS(List: TStrings; const Path, WildCard: String; Recursiv: Boolean = false); Var SR: SysUtils.TSearchRec; RES: Integer; SP: String; StreamList: TStringList; i: Integer; begin if length(Path) = 0 then exit; if length(WildCard) = 0 then exit; SP := IncludeTrailingBackSlash(Path) + WildCard; RES := FindFirst(IncludeTrailingBackSlash(Path) + '*.*', faDirectory, SR); While RES = 0 Do Begin If (SR.attr And faDirectory) <> 0 Then If SR.Name[1] <> '.' Then if Recursiv then GetADS(List, IncludeTrailingBackSlash(Path) + SR.Name, WildCard, Recursiv); RES := FindNext(SR); End; SysUtils.FindClose(SR); RES := FindFirst(SP, $27, SR); While RES = 0 Do Begin StreamList := GetStreams(IncludeTrailingBackSlash(Path) + SR.Name); for i := 0 to StreamList.Count - 1 do List.Add(IncludeTrailingBackSlash(Path) + SR.Name + StreamList[i]); StreamList.Free; RES := FindNext(SR); End; SysUtils.FindClose(SR); end; end.
The call may be, for example,
GetADS(Listbox1.Items,Directory.Text, WildCards.Text,rekursiv.checked);
source share