1
#define _WIN32_WINNT 0x0400
2
#include <windows.h>
3
#include <winioctl.h>
4
//ReadFileLink
5
ULONGLONG *GetFileClusters(
6
PCHAR lpFileName,
7
ULONG *ClusterSize,
8
ULONG *ClCount,
9
ULONG *FileSize
10
)
11

{
12
HANDLE hFile;
13
ULONG OutSize;
14
ULONG Bytes, Cls, CnCount, r;
15
ULONGLONG *Clusters = NULL;
16
BOOLEAN Result = FALSE;
17
LARGE_INTEGER PrevVCN, Lcn;
18
STARTING_VCN_INPUT_BUFFER InBuf;
19
PRETRIEVAL_POINTERS_BUFFER OutBuf;
20
CHAR Name[7];
21
22
Name[0] = lpSrcName[0];
23
Name[1] = ':';
24
Name[2] = 0;
25
26
GetDiskFreeSpace(Name, &SecPerCl, &BtPerSec, NULL, NULL);
27
28
ClusterSize = SecPerCl * BtPerSec;
29
30
hFile = CreateFile(lpFileName, FILE_READ_ATTRIBUTES,
31
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
32
NULL, OPEN_EXISTING, 0, 0);
33
34
if (hFile != INVALID_HANDLE_VALUE)
35
{
36
*FileSize = GetFileSize(hFile, NULL);
37
38
OutSize = sizeof(RETRIEVAL_POINTERS_BUFFER) + (*FileSize / ClusterSize) * sizeof(OutBuf->Extents);
39
40
OutBuf = malloc(OutSize);
41
42
InBuf.StartingVcn.QuadPart = 0;
43
44
if (DeviceIoControl(hFile, FSCTL_GET_RETRIEVAL_POINTERS, &InBuf,
45
sizeof(InBuf), OutBuf, OutSize, &Bytes, NULL))
46
{
47
*ClCount = (*FileSize + ClusterSize - 1) / ClusterSize;
48
49
Clusters = malloc(*ClCount * sizeof(ULONGLONG));
50
51
PrevVCN = OutBuf->StartingVcn;
52
53
for (r = 0, Cls = 0; r < OutBuf->ExtentCount; r++)
54
{
55
Lcn = OutBuf->Extents[r].Lcn;
56
57
for (CnCount = (ULONG)(OutBuf->Extents[r].NextVcn.QuadPart - PrevVCN.QuadPart);
58
CnCount; CnCount--, Cls++, Lcn.QuadPart++) Clusters[Cls] = Lcn.QuadPart;
59
60
PrevVCN = OutBuf->Extents[r].NextVcn;
61
}
62
}
63
64
free(OutBuf);
65
66
CloseHandle(hFile);
67
}
68
return Clusters;
69
}
70
71
//how do we use the clusters
72
void Read(
73
PCHAR lpSrcName
74
)
75

{
76
ULONG ClusterSize, BlockSize;
77
ULONGLONG *Clusters;
78
ULONG ClCount, FileSize, Bytes;
79
HANDLE hDrive, hFile;
80
ULONG SecPerCl, BtPerSec, r;
81
PVOID Buff;
82
LARGE_INTEGER Offset;
83
CHAR Name[7];
84
85
Clusters = GetFileClusters(lpSrcName, &ClusterSize, &ClCount, &FileSize);
86
87
if (Clusters)
88
{
89
Name[0] = '\\';
90
Name[1] = '\\';
91
Name[2] = '.';
92
Name[3] = '\\';
93
Name[4] = lpSrcName[0];
94
Name[5] = ':';
95
Name[6] = 0;
96
97
hDrive = CreateFile(Name, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0);
98
99
if (hDrive != INVALID_HANDLE_VALUE)
100
{
101
102
Buff = malloc(ClusterSize);
103
104
for (r = 0; r < ClCount; r++, FileSize -= BlockSize)
105
{
106
Offset.QuadPart = ClusterSize * Clusters[r];
107
108
SetFilePointer(hDrive, Offset.LowPart, &Offset.HighPart, FILE_BEGIN);
109
110
ReadFile(hDrive, Buff, ClusterSize, &Bytes, NULL);
111
112
BlockSize = FileSize < ClusterSize ? FileSize : ClusterSize;
113
114
}
115
116
free(Buff);
117
118
CloseHandle(hDrive);
119
}
120
free(Clusters);
121
}
122
}
123

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
