1 /*****************************************************************************
2 
3   DriveVolume
4 
5   Class for opening a volume and getting information on it and defragging it
6   and stuff.
7 
8 *****************************************************************************/
9 
10 
11 #ifndef DRIVEVOLUME_H
12 #define DRIVEVOLUME_H
13 
14 
15 #include "Unfrag.h"
16 #include <vector>
17 #include <string>
18 
19 
20 using namespace std;
21 
22 #pragma pack (push, 1)
23 typedef struct
24 {
25     unsigned int Archive    : 1;
26     unsigned int Compressed : 1;
27     unsigned int Directory  : 1;
28     unsigned int Encrypted  : 1;
29     unsigned int Hidden     : 1;
30     unsigned int Normal     : 1;
31     unsigned int Offline    : 1;
32     unsigned int ReadOnly   : 1;
33     unsigned int Reparse    : 1;
34     unsigned int Sparse     : 1;
35     unsigned int System     : 1;
36     unsigned int Temporary  : 1;
37 
38     // For defragmenting purposes and other information
39     unsigned int Unmovable    : 1;  // can we even touch it?
40     unsigned int Process      : 1;  // should we process it?
41     unsigned int AccessDenied : 1;  // could we not open it?
42 } FileAttr;
43 
44 
45 typedef struct
46 {
47     uint64 StartLCN;
48     uint64 Length;
49 } Extent;
50 
51 
52 typedef struct
53 {
54     wstring   Name;
55     uint32   DirIndice;   // indice into directory list
56     uint64   Size;
57     uint64   Clusters;
58     FileAttr Attributes;
59     vector<Extent> Fragments;
60 } FileInfo;
61 
62 
63 typedef vector<FileInfo> FileList;
64 
65 
66 typedef struct
67 {
68     wstring Name;
69     wstring Serial;
70     DWORD  MaxNameLen;
71     wstring FileSystem;
72     uint64 ClusterCount;
73     uint32 ClusterSize;
74     uint64 TotalBytes;
75     uint64 FreeBytes;
76 } VolumeInfo;
77 #pragma pack (pop)
78 
79 
80 // Callback function for Scan()
81 // NOTE: Do *NOT* close the HANDLE given to you. It is provided for convenience,
82 // and is closed automatically by the function that calls you!
83 typedef bool (*ScanCallback) (FileInfo &Info, HANDLE &FileHandle, void *UserData);
84 
85 
86 extern bool BuildDBCallback (FileInfo &Info, HANDLE &FileHandle, void *UserData);
87 
88 
89 class DriveVolume
90 {
91 public:
92     DriveVolume ();
93     ~DriveVolume ();
94 
95     bool Open            (wstring Name);  // opens the volume
96     void Close           (void);
97     bool ObtainInfo      (void);         // retrieves drive geometry
98     bool GetBitmap       (void);         // gets drive bitmap
99 
100     // builds list of files on drive
101     // if QuitMonitor ever becomes true (ie from a separate thread) it will clean up and return
102     bool BuildFileList   (bool &QuitMonitor, double &Progress);
103 
104     // Functions for accessing the volume bitmap
105     bool IsClusterUsed   (uint64 Cluster);
106     void SetClusterUsed  (uint64 Cluster, bool Used);
107 
108     DISK_GEOMETRY GetGeometry (void) { return (Geometry); }
109     VolumeInfo GetVolumeInfo (void) { return (VolInfo); }
110 
111     wstring GetRootPath (void) { return (RootPath); }
112 
113     // Scans drive starting from the root dir and calls a user defined function
114     // for each file/directory encountered. void* UserData is passed to this
115     // function so you can give it some good ol' fashioned context.
116     bool Scan (ScanCallback Callback, void *UserData);
117 
118     // Retrieve a directory string from the file database
119     wstring   &GetDBDir       (uint32 Indice);
120     uint32    GetDBDirCount  (void);
121     // Retrieve file strings/info from the file database
122     FileInfo &GetDBFile      (uint32 Indice);
123     uint32    GetDBFileCount (void);
124     // Kill it!
125     uint32    RemoveDBFile   (uint32 Indice);
126 
127     // This is for actual defragmenting! It will automatically update the drive bitmap.
128     // Will not move any other files out of the way.
129     // Failure (return value of false) means that something is in the way.
130     bool MoveFileDumb (uint32 FileIndice, uint64 NewLCN);
131 
132     // Look for a range of sequential free clusters
133     // Returns true if one could be found, false if not
134     bool FindFreeRange (uint64 StartLCN, uint64 ReqLength, uint64 &LCNResult);
135 
136 private:
137     friend bool BuildDBCallback (FileInfo &Info, HANDLE &FileHandle, void *UserData);
138 
139     // DirPrefix should be in the form "drive:\\path\\" ie, C:\CRAP\     .
140     bool ScanDirectory (wstring DirPrefix, ScanCallback Callback, void *UserData);
141 
142     // given a file's attributes, should it be processed or not?
143     bool ShouldProcess (FileAttr Attr);
144 
145     bool GetClusterInfo (FileInfo &Info, HANDLE &HandleResult);
146 
147     VolumeInfo               VolInfo;
148     FileList                 Files;
149     vector<wstring>           Directories; // Directories[Files[x].DirIndice]
150     wstring                   RootPath;    // ie, C:\    .
151     HANDLE                   Handle;
152     DISK_GEOMETRY            Geometry;
153     uint32                  *BitmapDetail;
154 };
155 
156 
157 #endif // DRIVEVOLUME_H
158