Bug 1226556 - part 1: allow reading GUID columns in ESEDBReader.jsm, r=MattN draft
authorGijs Kruitbosch <gijskruitbosch@gmail.com>
Sat, 30 Jan 2016 11:21:40 +0000
changeset 328538 0d78a5256fb4432b256a5f94460db7f144db8a25
parent 328537 517bc7ebc8b1b748b3b3c85766b94a230d827f7a
child 328539 bcc6624f825d2ac952c925f3a7ccfb78f80ff97d
push id10368
push usergijskruitbosch@gmail.com
push dateWed, 03 Feb 2016 14:49:00 +0000
reviewersMattN
bugs1226556
milestone47.0a1
Bug 1226556 - part 1: allow reading GUID columns in ESEDBReader.jsm, r=MattN
browser/components/migration/ESEDBReader.jsm
--- 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;