-
Notifications
You must be signed in to change notification settings - Fork 1
/
FileMapping.pas
171 lines (155 loc) · 7.22 KB
/
FileMapping.pas
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
unit FileMapping;
interface
uses
Windows, SysUtils;
type
TFileMappingAsByteArray = class
private
FFileHandle,
FFileMapping: THandle;
FByteArray: PByteArray;
FArraySize: Cardinal;
FCRC32: Cardinal;
FCRC32Ready: Boolean;
function FGetCRC32: Cardinal;
public
property ArraySize: Cardinal read FArraySize;
property ByteArray: PByteArray read FByteArray;
property CRC32: Cardinal read FGetCRC32;
constructor Create(const AFileName: TFileName);
constructor CreateNew(const AFileName: TFileName; const AArraySize: Cardinal);
destructor Destroy; override;
end {TFileMappingAsByteArray};
implementation
{TFileMappingAsByteArray}
constructor TFileMappingAsByteArray.Create(const AFileName: TFileName);
begin
inherited Create;
FFileHandle := CreateFile(PAnsiChar(AFileName),
Windows.GENERIC_READ,
Windows.FILE_SHARE_READ,
Nil,
Windows.OPEN_EXISTING,
Windows.FILE_ATTRIBUTE_NORMAL or Windows.File_Flag_Sequential_Scan,
0);
SysUtils.Win32Check(FFileHandle <> Windows.INVALID_HANDLE_VALUE);
FArraySize := GetFileSize(FFileHandle, Nil);
SysUtils.Win32Check(Windows.GetLastError = 0);
if FArraySize = 0 then begin
FFileMapping := 0;
FByteArray := Nil;
FCRC32Ready := True;
FCRC32 := 0;
end else begin
FFileMapping := CreateFileMapping(FFileHandle,
Nil,
Windows.PAGE_READONLY or Windows.SEC_COMMIT,
0,
0,
Nil);
SysUtils.Win32Check(FFileMapping <> 0);
FByteArray := MapViewOfFile(FFileMapping,
Windows.FILE_MAP_READ,
0,
0,
0);
SysUtils.Win32Check(Assigned(FByteArray));
FCRC32Ready := False;
end {if};
end {TFileMappingAsByteArray.Create};
constructor TFileMappingAsByteArray.CreateNew(const AFileName: TFileName; const AArraySize: Cardinal);
begin
inherited Create;
FFileHandle := CreateFile(PAnsiChar(AFileName),
Windows.GENERIC_READ or Windows.GENERIC_WRITE,
Windows.FILE_SHARE_READ,
Nil,
Windows.CREATE_ALWAYS,
Windows.FILE_ATTRIBUTE_NORMAL or Windows.FILE_FLAG_SEQUENTIAL_SCAN,
0);
SysUtils.Win32Check(FFileHandle <> Windows.INVALID_HANDLE_VALUE);
FArraySize := AArraySize;
if FArraySize = 0 then begin
FFileMapping := 0;
FByteArray := Nil;
FCRC32Ready := True;
FCRC32 := 0;
end else begin
FFileMapping := CreateFileMapping( FFileHandle,
Nil,
Windows.PAGE_READWRITE or Windows.SEC_COMMIT,
0,
FArraySize,
Nil);
SysUtils.Win32Check(FFileMapping <> 0);
FByteArray:=MapViewOfFile(FFileMapping,
Windows.FILE_MAP_WRITE,
0,
0,
0);
SysUtils.Win32Check(Assigned(FByteArray));
FCRC32Ready := False;
end {if};
end {TFileMappingAsByteArray.CreateNew};
destructor TFileMappingAsByteArray.Destroy;
begin
if Assigned(FByteArray) then UnmapViewOfFile(FByteArray);
if FFileMapping<>0 then CloseHandle(FFileMapping);
if (FFileHandle <> Windows.INVALID_HANDLE_VALUE) and (FFileHandle <> 0) then CloseHandle(FFileHandle);
inherited Destroy;
end {TFileMappingAsByteArray.Destroy};
function TFileMappingAsByteArray.FGetCRC32: Cardinal;
const
Table: array [Byte] of Cardinal =
($00000000, $77073096, $EE0E612C, $990951BA, $076DC419, $706AF48F, $E963A535, $9E6495A3,
$0EDB8832, $79DCB8A4, $E0D5E91E, $97D2D988, $09B64C2B, $7EB17CBD, $E7B82D07, $90BF1D91,
$1DB71064, $6AB020F2, $F3B97148, $84BE41DE, $1ADAD47D, $6DDDE4EB, $F4D4B551, $83D385C7,
$136C9856, $646BA8C0, $FD62F97A, $8A65C9EC, $14015C4F, $63066CD9, $FA0F3D63, $8D080DF5,
$3B6E20C8, $4C69105E, $D56041E4, $A2677172, $3C03E4D1, $4B04D447, $D20D85FD, $A50AB56B,
$35B5A8FA, $42B2986C, $DBBBC9D6, $ACBCF940, $32D86CE3, $45DF5C75, $DCD60DCF, $ABD13D59,
$26D930AC, $51DE003A, $C8D75180, $BFD06116, $21B4F4B5, $56B3C423, $CFBA9599, $B8BDA50F,
$2802B89E, $5F058808, $C60CD9B2, $B10BE924, $2F6F7C87, $58684C11, $C1611DAB, $B6662D3D,
$76DC4190, $01DB7106, $98D220BC, $EFD5102A, $71B18589, $06B6B51F, $9FBFE4A5, $E8B8D433,
$7807C9A2, $0F00F934, $9609A88E, $E10E9818, $7F6A0DBB, $086D3D2D, $91646C97, $E6635C01,
$6B6B51F4, $1C6C6162, $856530D8, $F262004E, $6C0695ED, $1B01A57B, $8208F4C1, $F50FC457,
$65B0D9C6, $12B7E950, $8BBEB8EA, $FCB9887C, $62DD1DDF, $15DA2D49, $8CD37CF3, $FBD44C65,
$4DB26158, $3AB551CE, $A3BC0074, $D4BB30E2, $4ADFA541, $3DD895D7, $A4D1C46D, $D3D6F4FB,
$4369E96A, $346ED9FC, $AD678846, $DA60B8D0, $44042D73, $33031DE5, $AA0A4C5F, $DD0D7CC9,
$5005713C, $270241AA, $BE0B1010, $C90C2086, $5768B525, $206F85B3, $B966D409, $CE61E49F,
$5EDEF90E, $29D9C998, $B0D09822, $C7D7A8B4, $59B33D17, $2EB40D81, $B7BD5C3B, $C0BA6CAD,
$EDB88320, $9ABFB3B6, $03B6E20C, $74B1D29A, $EAD54739, $9DD277AF, $04DB2615, $73DC1683,
$E3630B12, $94643B84, $0D6D6A3E, $7A6A5AA8, $E40ECF0B, $9309FF9D, $0A00AE27, $7D079EB1,
$F00F9344, $8708A3D2, $1E01F268, $6906C2FE, $F762575D, $806567CB, $196C3671, $6E6B06E7,
$FED41B76, $89D32BE0, $10DA7A5A, $67DD4ACC, $F9B9DF6F, $8EBEEFF9, $17B7BE43, $60B08ED5,
$D6D6A3E8, $A1D1937E, $38D8C2C4, $4FDFF252, $D1BB67F1, $A6BC5767, $3FB506DD, $48B2364B,
$D80D2BDA, $AF0A1B4C, $36034AF6, $41047A60, $DF60EFC3, $A867DF55, $316E8EEF, $4669BE79,
$CB61B38C, $BC66831A, $256FD2A0, $5268E236, $CC0C7795, $BB0B4703, $220216B9, $5505262F,
$C5BA3BBE, $B2BD0B28, $2BB45A92, $5CB36A04, $C2D7FFA7, $B5D0CF31, $2CD99E8B, $5BDEAE1D,
$9B64C2B0, $EC63F226, $756AA39C, $026D930A, $9C0906A9, $EB0E363F, $72076785, $05005713,
$95BF4A82, $E2B87A14, $7BB12BAE, $0CB61B38, $92D28E9B, $E5D5BE0D, $7CDCEFB7, $0BDBDF21,
$86D3D2D4, $F1D4E242, $68DDB3F8, $1FDA836E, $81BE16CD, $F6B9265B, $6FB077E1, $18B74777,
$88085AE6, $FF0F6A70, $66063BCA, $11010B5C, $8F659EFF, $F862AE69, $616BFFD3, $166CCF45,
$A00AE278, $D70DD2EE, $4E048354, $3903B3C2, $A7672661, $D06016F7, $4969474D, $3E6E77DB,
$AED16A4A, $D9D65ADC, $40DF0B66, $37D83BF0, $A9BCAE53, $DEBB9EC5, $47B2CF7F, $30B5FFE9,
$BDBDF21C, $CABAC28A, $53B39330, $24B4A3A6, $BAD03605, $CDD70693, $54DE5729, $23D967BF,
$B3667A2E, $C4614AB8, $5D681B02, $2A6F2B94, $B40BBE37, $C30C8EA1, $5A05DF1B, $2D02EF8D);
var
Index: Cardinal;
AByte: Byte;
begin
if FCRC32Ready then begin
Result := FCRC32;
end else begin
Result := $FFFFFFFF;
if FArraySize > 0 then begin
for Index := 0 to FArraySize - 1 do begin
AByte := {$R-}FByteArray^[Index]{$R+};
Result := (Result shr 8) xor Table[AByte xor (Result and $000000FF)];
end {for};
end {if};
Result := not Result;
FCRC32 := Result;
FCRC32Ready := True;
end {if};
end {TFileMappingAsByteArray.FGetCRC32};
end.