Type TDelFlags =
Set of (cdfOverride1, cdfOverride3, cdfOverride7, cdfOverride15, cdfOverride31,
cdfSplit, cdfSplitLarge, cdfFileTable);
// cdfFileTable do not use on Win NT file system.
Const cdfDefault = [cdfOverride7
{, cdfFileTable}];
cdfDefaultLarge = [cdfOverride1, cdfSplitLarge
{, cdfFileTable}];
Function ClearAndDeleteFile(FileName: WideString; Flags: TDelFlags = cdfDefault): ByteBool;
Var Handle: THandle;
Len, LF: TLargeIntRec;
DecSize, BufSize, i, i2: LongInt;
Buffer: PLongWordArray;
Begin
Result := False;
FileName := _ExpandFileName(FileName);
Handle := CreateFileW(Pointer(FileName), amGenericWrite
or amGenericRead,
amFileShareRead
or amFileShareWrite
or amFileShareDelete,
nil, cdOpenExisting, 0, 0);
If Handle = InvalidHandle
Then Exit;
Buffer :=
nil;
Try
Len.Lo := GetFileSize(
Handle, @Len.Hi);
If Len.Org = InvalidFileSizeLI
Then Exit;
If (Len.Hi = 0)
and (Len.Lo <= $00A00000)
Then BufSize := Len.Lo
shr 2
Else BufSize := $00280000;
Buffer := Memory.Get((BufSize + 1)
shl 2);
Memory.Fill1(Buffer, BufSize
shl 2, LongWord(_Random(-1)));
If cdfOverride31
in Flags
Then i := 31
Else If cdfOverride15
in Flags
Then i := 15
Else If cdfOverride7
in Flags
Then i := 7
Else If cdfOverride1
in Flags
Then i := 1
Else i := 3;
For i := i
downto 0
do Begin
For i2 := BufSize - 1
downto 0
do Buffer^[i2] := Buffer^[i2]
xor LongWord(_Random(-1));
i2 := BufSize
shl 2 - _Random(BufSize);
LF.Org := Len.Org;
SetFilePointer(
Handle, 0,
nil, mmFileBegin);
While LF.Org >= i2
do Begin
WriteDataNE(
Handle, Buffer, i2,
nil,
nil);
Dec(LF.Org, i2);
End;
WriteDataNE(
Handle, Buffer, LongInt(LF.Lo),
nil,
nil);
FlushFileBuffers(
Handle);
End;
If (cdfSplit
in Flags)
or (cdfSplitLarge
in Flags)
Then Begin
DecSize := GetClusterSize(_ExtractFileDrive(FileName), 512);
LF.Org := Len.Org;
SetFilePointer(
Handle, LF.Lo, @LF.Hi, mmFileBegin);
If cdfSplitLarge
in Flags
Then Begin
i := DecSize;
While LF.Org > i
do Begin
Dec(LF.Org, i);
SetFilePointer(
Handle, -i,
nil, mmFileCurrent);
SetEndOfFile(
Handle);
FlushFileBuffers(
Handle);
i := DecSize + LF.Org
shr 10;
End
End Else While LF.Org > DecSize
do Begin
Dec(LF.Org, DecSize);
SetFilePointer(
Handle, -DecSize,
nil, mmFileCurrent);
SetEndOfFile(
Handle);
FlushFileBuffers(
Handle);
End;
End;
SetFilePointer(
Handle, 0,
nil, mmFileBegin);
SetEndOfFile(
Handle);
Finally
Memory.Free(Pointer(Buffer));
CloseHandle(
Handle);
End;
DeleteFileW(Pointer(FileName));
If cdfFileTable
in Flags
Then Begin
For i := 0
to 99
do Begin
FileName := WideString('
CF') + WideChar(i
div 10
or $30) + WideChar(i
mod 10
or $30) + WideString('
.FNSClearDir');
Handle := CreateFileW(Pointer(FileName), amGenericWrite,
amFileShareRead
or amFileShareWrite
or amFileShareDelete,
nil, cdCreateAlways, 0, 0);
If Handle <> InvalidHandle
Then CloseHandle(
Handle);
End;
For i := 99
downto 0
do Begin
FileName := WideString('
CF') + WideChar(i
div 10
or $30) + WideChar(i
mod 10
or $30) + WideString('
.FNSClearDir');
DeleteFileW(Pointer(FileName));
End;
End;
Result := True;
End;