Bug 1226556 - part 1: allow reading GUID columns in ESEDBReader.jsm, r=MattN
--- a/browser/components/migration/ESEDBReader.jsm
+++ b/browser/components/migration/ESEDBReader.jsm
@@ -56,16 +56,17 @@ var COLUMN_TYPES = {
JET_coltypDateTime: 8, /* Integral date, fractional time */
JET_coltypBinary: 9, /* Binary data, < 255 bytes */
JET_coltypText: 10, /* ANSI text, case insensitive, < 255 bytes */
JET_coltypLongBinary: 11, /* Binary data, long value */
JET_coltypLongText: 12, /* ANSI text, long value */
JET_coltypUnsignedLong: 14, /* 4-byte unsigned integer */
JET_coltypLongLong: 15, /* 8-byte signed integer */
+ JET_coltypGUID: 16, /* 16-byte globally unique identifier */
};
// Not very efficient, but only used for error messages
function getColTypeName(numericValue) {
return Object.keys(COLUMN_TYPES).find(t => COLUMN_TYPES[t] == numericValue) || "unknown";
}
// All type constants and method wrappers go on this object:
@@ -381,16 +382,19 @@ ESEDB.prototype = {
let wchar_tArray = ctypes.ArrayType(ctypes.char16_t);
// size on the column is in bytes, 2 bytes to a wchar, so:
let charCount = column.dbSize >> 1;
buffer = new wchar_tArray(charCount);
} else if (column.type == "boolean") {
buffer = new ctypes.uint8_t();
} else if (column.type == "date") {
buffer = new KERNEL.FILETIME();
+ } else if (column.type == "guid") {
+ let byteArray = ctypes.ArrayType(ctypes.uint8_t);
+ buffer = new byteArray(column.dbSize);
} else {
throw "Unknown type " + column.type;
}
return [buffer, buffer.constructor.size];
},
_convertResult(column, buffer, err) {
if (err != 0) {
@@ -403,16 +407,32 @@ ESEDB.prototype = {
}
}
if (column.type == "string") {
return buffer ? buffer.readString() : "";
}
if (column.type == "boolean") {
return buffer ? (255 == buffer.value) : false;
}
+ if (column.type == "guid") {
+ if (buffer.length != 16) {
+ Cu.reportError("Buffer size for guid field " + column.id + " should have been 16!");
+ return "";
+ }
+ let rv = "{";
+ for (let i = 0; i < 16; i++) {
+ if (i == 4 || i == 6 || i == 8 || i == 10) {
+ rv += "-";
+ }
+ let byteValue = buffer.addressOfElement(i).contents;
+ // Ensure there's a leading 0
+ rv += ("0" + byteValue.toString(16)).substr(-2);
+ }
+ return rv + "}";
+ }
if (column.type == "date") {
if (!buffer) {
return null;
}
let systemTime = new KERNEL.SYSTEMTIME();
let result = KERNEL.FileTimeToSystemTime(buffer.address(), systemTime.address());
if (result == 0) {
throw new Error(ctypes.winLastError);
@@ -452,16 +472,21 @@ ESEDB.prototype = {
throw new Error("Invalid column type for column " + column.name +
"; expected bit type, got type " + getColTypeName(dbType));
}
} else if (column.type == "date") {
if (dbType != COLUMN_TYPES.JET_coltypLongLong) {
throw new Error("Invalid column type for column " + column.name +
"; expected long long type, got type " + getColTypeName(dbType));
}
+ } else if (column.type == "guid") {
+ if (dbType != COLUMN_TYPES.JET_coltypGUID) {
+ throw new Error("Invalid column type for column " + column.name +
+ "; expected guid type, got type " + getColTypeName(dbType));
+ }
} else if (column.type) {
throw new Error("Unknown column type " + column.type + " requested for column " +
column.name + ", don't know what to do.");
}
rv.push({name: column.name, id: columnInfoFromDB.columnid, type: column.type, dbSize, dbType});
}
return rv;