HashMap<Integer, PSTDescriptorItem> getPSTDescriptorItems(PSTNodeInputStream in) throws PSTException, IOException { // make sure the signature is correct in.seek(0); int sig = in.read(); if (sig != 0x2) { throw new PSTException("Unable to process descriptor node, bad signature: " + sig); } HashMap<Integer, PSTDescriptorItem> output = new HashMap<Integer, PSTDescriptorItem>(); int numberOfItems = (int) in.seekAndReadLong(2, 2); int offset; if (this.getPSTFileType() == PSTFile.PST_TYPE_ANSI) { offset = 4; } else { offset = 8; } byte[] data = new byte[(int) in.length()]; in.seek(0); in.read(data); for (int x = 0; x < numberOfItems; x++) { PSTDescriptorItem item = new PSTDescriptorItem(data, offset, this); output.put(item.descriptorIdentifier, item); if (this.getPSTFileType() == PSTFile.PST_TYPE_ANSI) { offset += 12; } else { offset += 24; } } return output; }
/** * read the name-to-id map from the file and load it in * * @param in * @throws IOException * @throws PSTException */ private void processNameToIdMap(RandomAccessFile in) throws IOException, PSTException { // Create our guid map for (int i = 0; i < guidStrings.length; ++i) { UUID uuid = UUID.fromString(guidStrings[i]); guidMap.put(uuid, i); /* System.out.printf("guidMap[{%s}] = %d\n", uuid.toString(), i); /**/ } // process the name to id map DescriptorIndexNode nameToIdMapDescriptorNode = (getDescriptorIndexNode(97)); // nameToIdMapDescriptorNode.readData(this); // get the descriptors if we have them HashMap<Integer, PSTDescriptorItem> localDescriptorItems = null; if (nameToIdMapDescriptorNode.localDescriptorsOffsetIndexIdentifier != 0) { // PSTDescriptor descriptor = new PSTDescriptor(this, // nameToIdMapDescriptorNode.localDescriptorsOffsetIndexIdentifier); // localDescriptorItems = descriptor.getChildren(); localDescriptorItems = this.getPSTDescriptorItems( nameToIdMapDescriptorNode.localDescriptorsOffsetIndexIdentifier); } // process the map // PSTTableBC bcTable = new PSTTableBC(nameToIdMapDescriptorNode.dataBlock.data, // nameToIdMapDescriptorNode.dataBlock.blockOffsets); OffsetIndexItem off = this.getOffsetIndexNode(nameToIdMapDescriptorNode.dataOffsetIndexIdentifier); PSTNodeInputStream nodein = new PSTNodeInputStream(this, off); byte[] tmp = new byte[1024]; nodein.read(tmp); PSTTableBC bcTable = new PSTTableBC(nodein); HashMap<Integer, PSTTableBCItem> tableItems = (bcTable.getItems()); // Get the guids PSTTableBCItem guidEntry = tableItems.get(2); // PidTagNameidStreamGuid guids = getData(guidEntry, localDescriptorItems); int nGuids = guids.length / 16; UUID[] uuidArray = new UUID[nGuids]; int[] uuidIndexes = new int[nGuids]; int offset = 0; for (int i = 0; i < nGuids; ++i) { long mostSigBits = (PSTObject.convertLittleEndianBytesToLong(guids, offset, offset + 4) << 32) | (PSTObject.convertLittleEndianBytesToLong(guids, offset + 4, offset + 6) << 16) | PSTObject.convertLittleEndianBytesToLong(guids, offset + 6, offset + 8); long leastSigBits = PSTObject.convertBigEndianBytesToLong(guids, offset + 8, offset + 16); uuidArray[i] = new UUID(mostSigBits, leastSigBits); if (guidMap.containsKey(uuidArray[i])) { uuidIndexes[i] = guidMap.get(uuidArray[i]); } else { uuidIndexes[i] = -1; // We don't know this guid } /* System.out.printf("uuidArray[%d] = {%s},%d\n", i, uuidArray[i].toString(), uuidIndexes[i]); /**/ offset += 16; } // if we have a reference to an internal descriptor PSTTableBCItem mapEntries = tableItems.get(3); // byte[] nameToIdByte = getData(mapEntries, localDescriptorItems); // process the entries for (int x = 0; x + 8 < nameToIdByte.length; x += 8) { int dwPropertyId = (int) PSTObject.convertLittleEndianBytesToLong(nameToIdByte, x, x + 4); int wGuid = (int) PSTObject.convertLittleEndianBytesToLong(nameToIdByte, x + 4, x + 6); int wPropIdx = ((int) PSTObject.convertLittleEndianBytesToLong(nameToIdByte, x + 6, x + 8)); if ((wGuid & 0x0001) == 0) { wPropIdx += 0x8000; wGuid >>= 1; int guidIndex; if (wGuid == 1) { guidIndex = PS_MAPI; } else if (wGuid == 2) { guidIndex = PS_PUBLIC_STRINGS; } else { guidIndex = uuidIndexes[wGuid - 3]; } nameToId.put((long) dwPropertyId | ((long) guidIndex << 32), wPropIdx); idToName.put(wPropIdx, (long) dwPropertyId); /* System.out.printf("0x%08X:%04X, 0x%08X\n", dwPropertyId, guidIndex, wPropIdx); /**/ } // else the identifier is a string } }