Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ; REQUIRES NEWER sqlite3.dll THAN IS PROVIDED IN DBA
- #Include <DBA>
- RunAsAdmin()
- class ProgressReporter {
- static available := [5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]
- __new() {
- this.num := this.available.remove()
- }
- __set(k, v) {
- if (k = "progress")
- ToolTip Progress: %v%, , , % this.num
- return v
- }
- __delete() {
- tooltip, , , % this.num
- this.available.insert(this.num)
- }
- }
- class ObjectFileList {
- dirdict := {}
- filedict := {}
- addDir(ref, name, parent) {
- this.dirdict[ref] := { name: name, parent: parent }
- }
- addFile(ref, name, parent) {
- this.filedict[ref] := { name: name, parent: parent }
- }
- allocate(length) {
- this.filedict.SetCapacity(length)
- this.dirdict.SetCapacity(length)
- }
- Query(string) {
- ret := []
- for k,v in this.filedict
- if InStr(v.name, string)
- ret.Insert(v.name)
- return ret
- }
- }
- class DatabaseFileList {
- __new() {
- this.db := DBA.DatabaseFactory.OpenDatabase("SqLite", ":memory:")
- this.db.Query("CREATE TABLE files (id INTEGER PRIMARY KEY, parent_id INTEGER, isdir INTEGER, name TEXT)")
- this.db.BeginTransaction()
- }
- addDir(ref, name, parent) {
- this.db.Insert({ id: ref, parent_id: parent, isdir: 1, name: name }, "files")
- }
- addFile(ref, name, parent) {
- this.db.Insert({ id: ref, parent_id: parent, isdir: 0, name: name }, "files")
- }
- allocate(length) {
- }
- Query(string) {
- this.db.EndTransaction()
- ret := []
- q := "SELECT * FROM files LIMIT 20"
- rows := this.db.Query(q).Rows
- msgbox % "rows: " rows "`n" (IsObject(rows) ? rows.__class "`n" LSON(rows) : "not an object")
- for i, row in rows
- ret.Insert(row.name)
- return ret
- }
- Count() {
- return this.db.Query("SELECT COUNT(*) FROM files").Rows[1][1]
- }
- }
- x := BuildFileDatabase(new ProgressReporter(), "C:", new DatabaseFileList())
- msgbox % "x: " x "`n" (IsObject(x) ? x.__class : "not an object") "`nRow Count: " x.Count()
- q := x.Query(".ahk")
- msgbox % "q: " q "`n" (IsObject(q) ? q.__class "`n" LSON(q) : "not an object")
- x.db.Query("ATTACH 'filelist.sqlite' AS diskdb")
- x.db.Query("CREATE TABLE diskdb.files AS SELECT * FROM files")
- BuildFileDatabase(WorkerThread, Drive, FileList = "") {
- ;=== get root folder ("\") refnumber
- SHARE_RW := 3 ;FILE_SHARE_READ | FILE_SHARE_WRITE
- 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)
- return -1
- ;BY_HANDLE_FILE_INFORMATION
- ; 0 DWORD dwFileAttributes;
- ; 4 FILETIME ftCreationTime;
- ; 12 FILETIME ftLastAccessTime;
- ; 20 FILETIME ftLastWriteTime;
- ; 28 DWORD dwVolumeSerialNumber;
- ; 32 DWORD nFileSizeHigh;
- ; 36 DWORD nFileSizeLow;
- ; 40 DWORD nNumberOfLinks;
- ; 44 DWORD nFileIndexHigh;
- ; 48 DWORD nFileIndexLow;
- VarSetCapacity(fi, 52, 0)
- result := DllCall("GetFileInformationByHandle", PTR, hRoot, PTR, &fi, "UINT")
- DllCall("CloseHandle", PTR, hRoot, "UINT")
- if(!result)
- return -2
- if !IsObject(FileList)
- FileList := new ObjectFileList()
- FileList.addDir(((NumGet(fi, 44) << 32) + NumGet(fi, 48)), drive, 0)
- ;=== open USN journal
- GENERIC_RW := 0xC0000000 ;GENERIC_READ | GENERIC_WRITE
- if((hJRoot := DllCall("CreateFileW", wstr, "\\.\" drive, uint, GENERIC_RW, uint, SHARE_RW, PTR, 0, uint, OPEN_EXISTING := 3, uint, 0, uint, 0, PTR)) = -1)
- return -3
- cb := 0
- VarSetCapacity(cujd, 16) ;CREATE_USN_JOURNAL_DATA
- NumPut(0x800000, cujd, 0, "uint64")
- NumPut(0x100000, cujd, 8, "uint64")
- 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)
- {
- DllCall("CloseHandle", PTR, hJRoot, "UINT")
- return -4
- }
- ;=== prepare data to query USN journal
- ;USN_JOURNAL_DATA
- ; 0 DWORDLONG UsnJournalID;
- ; 8 USN FirstUsn;
- ; 16 USN NextUsn;
- ; 24 USN LowestValidUsn;
- ; 32 USN MaxUsn;
- ; 40 DWORDLONG MaximumSize;
- ; 48 DWORDLONG AllocationDelta;
- VarSetCapacity(ujd, 56, 0)
- 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)
- {
- DllCall("CloseHandle", PTR, hJRoot, "UINT")
- return -5
- }
- JournalMaxSize := NumGet(ujd, 40, "uint64")
- ;=== enumerate USN journal
- cb := 0
- FileList.allocate(JournalMaxSize // (128 * 10))
- JournalChunkSize := 0x100000
- VarSetCapacity(pData, 8 + JournalChunkSize, 0)
- ;MFT_ENUM_DATA
- ; 0 DWORDLONG StartFileReferenceNumber;
- ; 8 USN LowUsn;
- ; 16 USN HighUsn;
- VarSetCapacity(med, 24, 0)
- NumPut(NumGet(ujd, 16, "uint64"), med, 16, "uint64") ;med.HighUsn=ujd.NextUsn
- num := 0
- WorkerThread.Progress := 0
- while(DllCall("DeviceIoControl", PTR, hJRoot, uint, FSCTL_ENUM_USN_DATA := 0x000900b3, PTR, &med, uint, 24, PTR, &pData, uint, 8 + JournalChunkSize, uintp, cb, PTR, "UINT"))
- {
- pUSN := &pData + 8
- ;USN_RECORD
- ; 0 DWORD RecordLength;
- ; 4 WORD MajorVersion;
- ; 6 WORD MinorVersion;
- ; 8 DWORDLONG FileReferenceNumber;
- ; 16 DWORDLONG ParentFileReferenceNumber;
- ; 24 USN Usn;
- ; 32 LARGE_INTEGER TimeStamp;
- ; 40 DWORD Reason;
- ; 44 DWORD SourceInfo;
- ; 48 DWORD SecurityId;
- ; 52 DWORD FileAttributes;
- ; 56 WORD FileNameLength;
- ; 58 WORD FileNameOffset;
- ; 60 WCHAR FileName[1];
- while(cb > 60)
- {
- ref := "" NumGet(pUSN + 8, "uint64") ;USN.FileReferenceNumber
- refparent := "" NumGet(pUSN + 16, "uint64") ;USN.ParentFileReferenceNumber
- fn := StrGet(pUSN + 60, NumGet(pUSN + 56, "ushort") // 2, "UTF-16") ;USN.FileName
- if(IsDir := NumGet(pUSN + 52) & 0x10) ;USN.FileAttributes & FILE_ATTRIBUTE_DIRECTORY
- FileList.addDir(ref, fn, refparent)
- else
- {
- FileList.addFile(ref, fn, refparent)
- num++
- }
- i := NumGet(pUSN + 0) ;USN.RecordLength
- pUSN += i
- cb -= i
- }
- NumPut(NumGet(pData, "uint64"), med, "uint64")
- WorkerThread.Progress := Round(A_index * JournalChunkSize / JournalMaxSize * 90)
- }
- DllCall("CloseHandle", PTR, hJRoot, "UINT")
- ;=== connect files to parent folders
- ;Tree := {}
- ; for k, v in filedict
- ; {
- ;WorkerThread.Progress := 90 + (A_index / num * 10)
- ; v2 := v
- ; fn := v.name
- ; SubFolderDict := [v.name]
- ; while(v2.parent)
- ; {
- ; p := dirdict[v2.parent]
- ; dirdict[v2.parent].num++
- ; SubFolderDict.Insert(v2.name)
- ; v2 := p
- ; }
- ;continue
- ;;Create tree structure
- ;node := Tree
- ;Loop % len := SubFolderDict.MaxIndex()
- ;{
- ; if(!node.HasKey(SubFolderDict[len - A_index + 1]))
- ; node[SubFolderDict[len - A_index + 1]] := {}
- ; node := node[SubFolderDict[len - A_index + 1]]
- ;}
- ; }
- ; filedict := ""
- ; dirdict.SetCapacity(dirdict.getCapacity())
- ; msgbox % filedict.getCapacity() ", " dirdict.getCapacity()
- ; return Tree
- return FileList
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement