So I went way farther down this rabbit hole than I had intended - I hope my boss doesn't find out.
Since I use Macrium, I thought this would be a fun "little" project to spend a little time on. Macrium saves its metadata in XML byte format (one byte per character rather than 2) within the MRIMG file. The comments are between <comment></comment> tags. I figured I could just use a file object to read the file in chunks and search for the text. Wrong. AHK's string functions (RegExMatch as well) do not work when there are embedded zeros (nulls) within the haystack.
After a search, I found some archived AHK functions
here that seemed to fit the bill perfectly. The poster had put inline machine code in them to search regardless of nulls. After much trial and error, however, I could never get them to work for me.
More searching brought me to some other posts where scripts had been created to copy the file buffer they were using, byte by byte, to a secondary buffer, replacing the nulls with other codes along the way and then searching the secondary buffer. After all, we don't care about anything but the XML text anyway.
I don't typically fill in the comment fields on my images, so I created a small one of a leftover 16MB partition on my drive and wrote the code below. After getting all the offsets correct, it finally worked. I then created another image of my recovery partition of about 500 MB. I ran the script and thought my machine had hung. It took about 5 minutes to finally come up with the comments. The metadata was located near the end of the file and AHK had a LOT of nulls to replace. And I have a very fast machine.
Examining another file (I installed the free XhD hex editor) showed the XML data to be much nearer to the top of the file. There seems to be no rhyme nor reason for the placement of the metadata and there MUST be a pointer of some kind near the beginning of the file pointing to its location which is how the properties tab can display it so quickly. I couldn't figure out where that pointer was, however.
Feel free to use the code below to play with, but start with very SMALL images. It's not pretty because there was a lot of hacking and trial and error required to come up with it. I'm sure it could be written more efficiently, but it is what it is. Perhaps someone else can use it as a springboard to come up with something faster, but I've spent WAY too much time playing with it. Have to actually get some work done now.
Code: Select all
#Requires AutoHotkey v1.1.33+
ImgFile := A_Desktop . "\MR-Test.mrimg"
Buffer := ""
BegTag := "<comment>"
BegTagLen := StrLen(BegTag)
EndTag := "</comment>"
oFile := FileOpen(ImgFile, "r")
While(!oFile.AtEOF) {
VarSetCapacity(Buffer, 0)
oFile.RawRead(Buffer, 4096)
BuffLen := StrLen(Buffer) * 2
NewBuff := ""
Loop %BuffLen% {
Char := NumGet(Buffer, A_Index, "UChar")
If (Char = 0) {
NewBuff .= " "
} Else {
NewBuff .= Chr(Char)
}
}
BegOffset := InStr(NewBuff, BegTag)
BegOffset += BegOffset = 0 ? 0 : oFile.Pos - 4096
EndOffset := Instr(NewBuff, EndTag)
EndOffset += EndOffset = 0 ? 0 : oFile.Pos - 4096
If ((BegOffset > 0) && (EndOffset > 0))
Break
}
oFile.Seek(BegOffset + BegTagLen, 0)
CommentText := oFile.Read(EndOffset - (BegOffset + BegTagLen))
oFile.Close()
MsgBox % "Comment: " . CommentText
ExitApp
Russ