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 |