Advertisement
infogulch

Untitled

May 30th, 2012
78
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.25 KB | None | 0 0
  1. ; REQUIRES NEWER sqlite3.dll THAN IS PROVIDED IN DBA
  2. #Include <DBA>
  3.  
  4. RunAsAdmin()
  5.  
  6. class ProgressReporter {
  7. static available := [5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]
  8.  
  9. __new() {
  10. this.num := this.available.remove()
  11. }
  12.  
  13. __set(k, v) {
  14. if (k = "progress")
  15. ToolTip Progress: %v%, , , % this.num
  16. return v
  17. }
  18.  
  19. __delete() {
  20. tooltip, , , % this.num
  21. this.available.insert(this.num)
  22. }
  23. }
  24.  
  25. class ObjectFileList {
  26. dirdict := {}
  27. filedict := {}
  28.  
  29. addDir(ref, name, parent) {
  30. this.dirdict[ref] := { name: name, parent: parent }
  31. }
  32.  
  33. addFile(ref, name, parent) {
  34. this.filedict[ref] := { name: name, parent: parent }
  35. }
  36.  
  37. allocate(length) {
  38. this.filedict.SetCapacity(length)
  39. this.dirdict.SetCapacity(length)
  40. }
  41.  
  42. Query(string) {
  43. ret := []
  44. for k,v in this.filedict
  45. if InStr(v.name, string)
  46. ret.Insert(v.name)
  47. return ret
  48. }
  49. }
  50.  
  51. class DatabaseFileList {
  52. __new() {
  53. this.db := DBA.DatabaseFactory.OpenDatabase("SqLite", ":memory:")
  54. this.db.Query("CREATE TABLE files (id INTEGER PRIMARY KEY, parent_id INTEGER, isdir INTEGER, name TEXT)")
  55. this.db.BeginTransaction()
  56. }
  57.  
  58. addDir(ref, name, parent) {
  59. this.db.Insert({ id: ref, parent_id: parent, isdir: 1, name: name }, "files")
  60. }
  61.  
  62. addFile(ref, name, parent) {
  63. this.db.Insert({ id: ref, parent_id: parent, isdir: 0, name: name }, "files")
  64. }
  65.  
  66. allocate(length) {
  67. }
  68.  
  69. Query(string) {
  70. this.db.EndTransaction()
  71. ret := []
  72.  
  73. q := "SELECT * FROM files LIMIT 20"
  74.  
  75. rows := this.db.Query(q).Rows
  76. msgbox % "rows: " rows "`n" (IsObject(rows) ? rows.__class "`n" LSON(rows) : "not an object")
  77.  
  78. for i, row in rows
  79. ret.Insert(row.name)
  80. return ret
  81. }
  82.  
  83. Count() {
  84. return this.db.Query("SELECT COUNT(*) FROM files").Rows[1][1]
  85. }
  86. }
  87.  
  88. x := BuildFileDatabase(new ProgressReporter(), "C:", new DatabaseFileList())
  89.  
  90. msgbox % "x: " x "`n" (IsObject(x) ? x.__class : "not an object") "`nRow Count: " x.Count()
  91.  
  92. q := x.Query(".ahk")
  93.  
  94. msgbox % "q: " q "`n" (IsObject(q) ? q.__class "`n" LSON(q) : "not an object")
  95.  
  96. x.db.Query("ATTACH 'filelist.sqlite' AS diskdb")
  97.  
  98. x.db.Query("CREATE TABLE diskdb.files AS SELECT * FROM files")
  99.  
  100. BuildFileDatabase(WorkerThread, Drive, FileList = "") {
  101. ;=== get root folder ("\") refnumber
  102. SHARE_RW := 3 ;FILE_SHARE_READ | FILE_SHARE_WRITE
  103. if((hRoot := DllCall("CreateFileW", wstr, "\\.\" drive "\", uint, 0, uint, SHARE_RW, PTR, 0, uint, OPEN_EXISTING := 3, uint, FILE_FLAG_BACKUP_SEMANTICS := 0x2000000, PTR, 0, PTR)) = -1)
  104. return -1
  105. ;BY_HANDLE_FILE_INFORMATION
  106. ; 0 DWORD dwFileAttributes;
  107. ; 4 FILETIME ftCreationTime;
  108. ; 12 FILETIME ftLastAccessTime;
  109. ; 20 FILETIME ftLastWriteTime;
  110. ; 28 DWORD dwVolumeSerialNumber;
  111. ; 32 DWORD nFileSizeHigh;
  112. ; 36 DWORD nFileSizeLow;
  113. ; 40 DWORD nNumberOfLinks;
  114. ; 44 DWORD nFileIndexHigh;
  115. ; 48 DWORD nFileIndexLow;
  116. VarSetCapacity(fi, 52, 0)
  117. result := DllCall("GetFileInformationByHandle", PTR, hRoot, PTR, &fi, "UINT")
  118. DllCall("CloseHandle", PTR, hRoot, "UINT")
  119. if(!result)
  120. return -2
  121.  
  122. if !IsObject(FileList)
  123. FileList := new ObjectFileList()
  124. FileList.addDir(((NumGet(fi, 44) << 32) + NumGet(fi, 48)), drive, 0)
  125.  
  126. ;=== open USN journal
  127. GENERIC_RW := 0xC0000000 ;GENERIC_READ | GENERIC_WRITE
  128. if((hJRoot := DllCall("CreateFileW", wstr, "\\.\" drive, uint, GENERIC_RW, uint, SHARE_RW, PTR, 0, uint, OPEN_EXISTING := 3, uint, 0, uint, 0, PTR)) = -1)
  129. return -3
  130. cb := 0
  131. VarSetCapacity(cujd, 16) ;CREATE_USN_JOURNAL_DATA
  132. NumPut(0x800000, cujd, 0, "uint64")
  133. NumPut(0x100000, cujd, 8, "uint64")
  134. if(DllCall("DeviceIoControl", PTR, hJRoot, uint, FSCTL_CREATE_USN_JOURNAL := 0x000900e7, PTR, &cujd, uint, 16, PTR, 0, uint, 0, UINTP, cb, PTR, 0, "UINT") = 0)
  135. {
  136. DllCall("CloseHandle", PTR, hJRoot, "UINT")
  137. return -4
  138. }
  139. ;=== prepare data to query USN journal
  140. ;USN_JOURNAL_DATA
  141. ; 0 DWORDLONG UsnJournalID;
  142. ; 8 USN FirstUsn;
  143. ; 16 USN NextUsn;
  144. ; 24 USN LowestValidUsn;
  145. ; 32 USN MaxUsn;
  146. ; 40 DWORDLONG MaximumSize;
  147. ; 48 DWORDLONG AllocationDelta;
  148. VarSetCapacity(ujd, 56, 0)
  149. if(DllCall("DeviceIoControl", PTR, hJRoot, uint, FSCTL_QUERY_USN_JOURNAL := 0x000900f4, PTR, 0, uint, 0, PTR, &ujd, uint, 56, UINTP, cb, PTR, 0, "UINT") = 0)
  150. {
  151. DllCall("CloseHandle", PTR, hJRoot, "UINT")
  152. return -5
  153. }
  154. JournalMaxSize := NumGet(ujd, 40, "uint64")
  155.  
  156. ;=== enumerate USN journal
  157. cb := 0
  158. FileList.allocate(JournalMaxSize // (128 * 10))
  159. JournalChunkSize := 0x100000
  160. VarSetCapacity(pData, 8 + JournalChunkSize, 0)
  161. ;MFT_ENUM_DATA
  162. ; 0 DWORDLONG StartFileReferenceNumber;
  163. ; 8 USN LowUsn;
  164. ; 16 USN HighUsn;
  165. VarSetCapacity(med, 24, 0)
  166. NumPut(NumGet(ujd, 16, "uint64"), med, 16, "uint64") ;med.HighUsn=ujd.NextUsn
  167. num := 0
  168. WorkerThread.Progress := 0
  169. while(DllCall("DeviceIoControl", PTR, hJRoot, uint, FSCTL_ENUM_USN_DATA := 0x000900b3, PTR, &med, uint, 24, PTR, &pData, uint, 8 + JournalChunkSize, uintp, cb, PTR, "UINT"))
  170. {
  171. pUSN := &pData + 8
  172. ;USN_RECORD
  173. ; 0 DWORD RecordLength;
  174. ; 4 WORD MajorVersion;
  175. ; 6 WORD MinorVersion;
  176. ; 8 DWORDLONG FileReferenceNumber;
  177. ; 16 DWORDLONG ParentFileReferenceNumber;
  178. ; 24 USN Usn;
  179. ; 32 LARGE_INTEGER TimeStamp;
  180. ; 40 DWORD Reason;
  181. ; 44 DWORD SourceInfo;
  182. ; 48 DWORD SecurityId;
  183. ; 52 DWORD FileAttributes;
  184. ; 56 WORD FileNameLength;
  185. ; 58 WORD FileNameOffset;
  186. ; 60 WCHAR FileName[1];
  187. while(cb > 60)
  188. {
  189. ref := "" NumGet(pUSN + 8, "uint64") ;USN.FileReferenceNumber
  190. refparent := "" NumGet(pUSN + 16, "uint64") ;USN.ParentFileReferenceNumber
  191. fn := StrGet(pUSN + 60, NumGet(pUSN + 56, "ushort") // 2, "UTF-16") ;USN.FileName
  192. if(IsDir := NumGet(pUSN + 52) & 0x10) ;USN.FileAttributes & FILE_ATTRIBUTE_DIRECTORY
  193. FileList.addDir(ref, fn, refparent)
  194. else
  195. {
  196. FileList.addFile(ref, fn, refparent)
  197. num++
  198. }
  199. i := NumGet(pUSN + 0) ;USN.RecordLength
  200. pUSN += i
  201. cb -= i
  202. }
  203. NumPut(NumGet(pData, "uint64"), med, "uint64")
  204. WorkerThread.Progress := Round(A_index * JournalChunkSize / JournalMaxSize * 90)
  205. }
  206. DllCall("CloseHandle", PTR, hJRoot, "UINT")
  207. ;=== connect files to parent folders
  208. ;Tree := {}
  209. ; for k, v in filedict
  210. ; {
  211. ;WorkerThread.Progress := 90 + (A_index / num * 10)
  212. ; v2 := v
  213. ; fn := v.name
  214. ; SubFolderDict := [v.name]
  215. ; while(v2.parent)
  216. ; {
  217. ; p := dirdict[v2.parent]
  218. ; dirdict[v2.parent].num++
  219. ; SubFolderDict.Insert(v2.name)
  220. ; v2 := p
  221. ; }
  222. ;continue
  223. ;;Create tree structure
  224. ;node := Tree
  225. ;Loop % len := SubFolderDict.MaxIndex()
  226. ;{
  227. ; if(!node.HasKey(SubFolderDict[len - A_index + 1]))
  228. ; node[SubFolderDict[len - A_index + 1]] := {}
  229. ; node := node[SubFolderDict[len - A_index + 1]]
  230. ;}
  231. ; }
  232. ; filedict := ""
  233. ; dirdict.SetCapacity(dirdict.getCapacity())
  234. ; msgbox % filedict.getCapacity() ", " dirdict.getCapacity()
  235. ; return Tree
  236. return FileList
  237. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement