Subversion Repositories recyclebinunit

Rev

Rev 97 | Rev 100 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 97 Rev 99
Line 3... Line 3...
3
////////////////////////////////////////////////////////////////////////////////////
3
////////////////////////////////////////////////////////////////////////////////////
4
// RECYCLE-BIN-UNIT V2 BY DANIEL MARSCHALL, VIATHINKSOFT                          //
4
// RECYCLE-BIN-UNIT V2 BY DANIEL MARSCHALL, VIATHINKSOFT                          //
5
// E-MAIL: info@daniel-marschall.de                                               //
5
// E-MAIL: info@daniel-marschall.de                                               //
6
// Web:    www.daniel-marschall.de & www.viathinksoft.de                          //
6
// Web:    www.daniel-marschall.de & www.viathinksoft.de                          //
7
////////////////////////////////////////////////////////////////////////////////////
7
////////////////////////////////////////////////////////////////////////////////////
8
// Revision: 30 JUN 2022                                                          //
8
// Revision: 02 JUL 2022                                                          //
9
// This unit is freeware, but please link to my website if you are using it!      //
9
// This unit is freeware, but please link to my website if you are using it!      //
10
////////////////////////////////////////////////////////////////////////////////////
10
////////////////////////////////////////////////////////////////////////////////////
11
// Successfully tested with:                                                      //
11
// Successfully tested with:                                                      //
12
// Windows 95b (without IE4 Shell Extensions)                                     //
12
// Windows 95b (without IE4 Shell Extensions)                                     //
13
// Windows 95b (with IE4 Shell Extensions)                                        //
13
// Windows 95b (with IE4 Shell Extensions)                                        //
Line 53... Line 53...
53
 
53
 
54
uses
54
uses
55
  Windows, SysUtils, Classes, ContNrs, ShellAPI, Registry, Messages, Math;
55
  Windows, SysUtils, Classes, ContNrs, ShellAPI, Registry, Messages, Math;
56
 
56
 
57
const
57
const
58
  RECBINUNIT_VERSION = '2022-06-30';
58
  RECBINUNIT_VERSION = '2022-07-02';
59
 
59
 
60
  RECYCLER_CLSID: TGUID = '{645FF040-5081-101B-9F08-00AA002F954E}';
60
  RECYCLER_CLSID: TGUID = '{645FF040-5081-101B-9F08-00AA002F954E}';
61
  NULL_GUID:      TGUID = '{00000000-0000-0000-0000-000000000000}';
61
  NULL_GUID:      TGUID = '{00000000-0000-0000-0000-000000000000}';
62
 
62
 
63
type
63
type
Line 814... Line 814...
814
 
814
 
815
  procedure _HandleIndexFile(AFile: string);
815
  procedure _HandleIndexFile(AFile: string);
816
  var
816
  var
817
    fs: TFileStream;
817
    fs: TFileStream;
818
    infoHdr: TRbInfoHeader;
818
    infoHdr: TRbInfoHeader;
819
    testID: string;
819
    vistaId: string;
820
    wTest: TRbInfoWItem;
820
    wTest: TRbInfoWItem;
821
    bakPosition: int64;
821
    bakPosition: int64;
-
 
822
    testVistaItem: TRbVistaItem;
822
  begin
823
  begin
823
    fs := TFileStream.Create(AFile, fmOpenRead);
824
    fs := TFileStream.Create(AFile, fmOpenRead);
824
    try
825
    try
825
      fs.Seek(0, soFromBeginning);
826
      fs.Seek(0, soFromBeginning);
826
 
827
 
-
 
828
      {$REGION 'First try if it is a Vista index file'}
-
 
829
      testVistaItem := nil;
827
      if SameText(copy(ExtractFileName(AFile), 1, 2), '$I') then
830
      if SameText(copy(ExtractFileName(AFile), 1, 2), '$I') then
828
      begin
831
      begin
829
        testID := copy(testID, 3, Length(testID)-2);
832
        vistaId := copy(AFile, 3, Length(AFile)-2);
830
        list.Add(TRbVistaItem.Create(fs, AFile, testID));
833
        testVistaItem := TRbVistaItem.Create(fs, AFile, vistaId);
831
      end
834
      end
832
      else
835
      else
833
      begin
836
      begin
-
 
837
        vistaId := ''; // manual file that was not named $I..., so we cannot get $R... ID and therefore no physical file!
-
 
838
        try
-
 
839
          testVistaItem := TRbVistaItem.Create(fs, AFile, vistaId);
-
 
840
          if Copy(testVistaItem.Source,2,2) <> ':\' then
-
 
841
            FreeAndNil(testVistaItem);
-
 
842
        except
-
 
843
          testVistaItem := nil;
-
 
844
        end;
-
 
845
      end;
-
 
846
      {$ENDREGION}
-
 
847
 
-
 
848
      if Assigned(testVistaItem) then
-
 
849
      begin
-
 
850
        list.Add(testVistaItem);
-
 
851
      end
-
 
852
      else
-
 
853
      begin
-
 
854
        fs.Seek(0, soFromBeginning);
834
        if TolerantReading then
855
        if TolerantReading then
835
        begin
856
        begin
836
          // This is a special treatment how to recover data from an INFO/INFO2 file
857
          // This is a special treatment how to recover data from an INFO/INFO2 file
837
          // which was corrupted by an incompatible multiboot configuration.
858
          // which was corrupted by an incompatible multiboot configuration.
838
          // Example:
859
          // Example:
Line 848... Line 869...
848
              // In case it is no Unicode record, then the Unicode part will be the
869
              // In case it is no Unicode record, then the Unicode part will be the
849
              // ANSI source name of the next record. In this case, we won't get
870
              // ANSI source name of the next record. In this case, we won't get
850
              // a ':' at the Unicode string.
871
              // a ':' at the Unicode string.
851
              bakPosition := fs.Position;
872
              bakPosition := fs.Position;
852
              wTest := TRbInfoWItem.Create(fs, AFile);
873
              wTest := TRbInfoWItem.Create(fs, AFile);
853
              if Copy(wTest.SourceUnicode, 2, 1) = ':' then
874
              if Copy(wTest.SourceUnicode, 2, 2) = ':\' then
854
              begin
875
              begin
855
                // Yes, it is a valid Unicode record.
876
                // Yes, it is a valid Unicode record.
856
                list.Add(wTest);
877
                list.Add(wTest);
857
              end
878
              end
858
              else
879
              else
Line 861... Line 882...
861
                // to assume that the following record will be a valid ANSI record.
882
                // to assume that the following record will be a valid ANSI record.
862
                fs.Position := bakPosition;
883
                fs.Position := bakPosition;
863
                list.Add(TRbInfoAItem.Create(fs, AFile));
884
                list.Add(TRbInfoAItem.Create(fs, AFile));
864
              end;
885
              end;
865
            end
886
            end
866
            else
887
            else if fs.Position + SizeOf(TRbInfoRecordA) <= fs.Size then
867
            begin
888
            begin
868
              // No, there is not enough space left for an Unicode record.
889
              // No, there is not enough space left for an Unicode record.
869
              // So we assume that the following record will be a valid ANSI record.
890
              // So we assume that the following record will be a valid ANSI record.
870
              list.Add(TRbInfoAItem.Create(fs, AFile));
891
              list.Add(TRbInfoAItem.Create(fs, AFile));
-
 
892
            end
-
 
893
            else
-
 
894
            begin
-
 
895
              // Not enough space to read a Ansi record!
-
 
896
              // Ignore it
871
            end;
897
            end;
872
          end;
898
          end;
873
        end
899
        end
874
        else
900
        else
875
        begin
901
        begin
Line 1264... Line 1290...
1264
 
1290
 
1265
function TRbDrive.IsFAT: boolean;
1291
function TRbDrive.IsFAT: boolean;
1266
var
1292
var
1267
  Dummy2: DWORD;
1293
  Dummy2: DWORD;
1268
  Dummy3: DWORD;
1294
  Dummy3: DWORD;
1269
  FileSystem: array[0..MAX_PATH] of char;
1295
  FileSystem: array[0..MAX_PATH-1] of char;
1270
  VolumeName: array[0..MAX_PATH] of char;
1296
  VolumeName: array[0..MAX_PATH-1] of char;
1271
  s: string;
1297
  s: string;
1272
begin
1298
begin
1273
  s := FDriveLetter + DriveDelim + PathDelim; // ohne die Auslagerung in einen String kommt es zu einer AV in ntdll
1299
  s := FDriveLetter + DriveDelim + PathDelim; // ohne die Auslagerung in einen String kommt es zu einer AV in ntdll
1274
  GetVolumeInformation(PChar(s), VolumeName,
1300
  GetVolumeInformation(PChar(s), VolumeName,
1275
    SizeOf(VolumeName), nil, Dummy2, Dummy3, FileSystem, SizeOf(FileSystem));
1301
    SizeOf(VolumeName), nil, Dummy2, Dummy3, FileSystem, SizeOf(FileSystem));
Line 1534... Line 1560...
1534
procedure TRbVistaItem.ReadFromStream(stream: TStream);
1560
procedure TRbVistaItem.ReadFromStream(stream: TStream);
1535
var
1561
var
1536
  r1: TRbVistaRecord1;
1562
  r1: TRbVistaRecord1;
1537
  r2: TRbVistaRecord2Head;
1563
  r2: TRbVistaRecord2Head;
1538
  r2SourceUnicode: array of WideChar;
1564
  r2SourceUnicode: array of WideChar;
1539
  version: DWORD;
1565
  version: int64;
1540
  i: Integer;
1566
  i: Integer;
1541
resourcestring
1567
resourcestring
1542
  LNG_VISTA_WRONG_FORMAT = 'Invalid Vista index format version %d';
1568
  LNG_VISTA_WRONG_FORMAT = 'Invalid Vista index format version %d';
1543
begin
1569
begin
1544
  stream.ReadBuffer(version, SizeOf(version));
1570
  stream.ReadBuffer(version, SizeOf(version));
Line 1612... Line 1638...
1612
end;
1638
end;
1613
 
1639
 
1614
function TRbVistaItem.GetPhysicalFile: string;
1640
function TRbVistaItem.GetPhysicalFile: string;
1615
begin
1641
begin
1616
  result := FIndexFile;
1642
  result := FIndexFile;
-
 
1643
  if Pos('$I', Result) = 0 then
-
 
1644
    result := ''
-
 
1645
  else
1617
  result := StringReplace(Result, '$I', '$R', [rfIgnoreCase]);
1646
    result := StringReplace(Result, '$I', '$R', [rfIgnoreCase]);
1618
end;
1647
end;
1619
 
1648
 
1620
constructor TRbVistaItem.Create(fs: TStream; AIndexFile, AID: string);
1649
constructor TRbVistaItem.Create(fs: TStream; AIndexFile, AID: string);
1621
begin
1650
begin