示例#1
0
 /**
  * Reads a single mapi prop.
  *
  * @param string        &$buffer
  * @param int           $size
  * @param mixed         &$read
  * @param array         &$mapiprops
  *
  * @access private
  * @return int
  */
 private function readSingleMapiProp(&$buffer, &$size, &$read, &$mapiprops)
 {
     $propTag = 0;
     $len = 0;
     $origSize = $size;
     $isNamedId = 0;
     $namedProp = 0;
     $count = 0;
     $mvProp = 0;
     $guid = 0;
     if ($size < 8) {
         return MAPI_E_NOT_FOUND;
     }
     $hresult = $this->readFromTnefStream($buffer, self::DWORD, $propTag);
     if ($hresult !== NOERROR) {
         ZLog::Write(LOGLEVEL_WARN, "TNEF: There was an error reading a mapi property tag from the stream.");
         return $hresult;
     }
     $size -= 4;
     ZLog::Write(LOGLEVEL_DEBUG, "TNEF: mapi prop type:" . dechex(mapi_prop_type($propTag)));
     ZLog::Write(LOGLEVEL_DEBUG, "TNEF: mapi prop tag: 0x" . sprintf("%04x", mapi_prop_id($propTag)));
     if (mapi_prop_id($propTag) >= 0x8000) {
         // Named property, first read GUID, then name/id
         if ($size < 24) {
             ZLog::Write(LOGLEVEL_WARN, "TNEF: Corrupt guid size for named property:" . dechex($propTag));
             return MAPI_E_CORRUPT_DATA;
         }
         //strip GUID & name/id
         $hresult = $this->readBuffer($buffer, 16, $guid);
         if ($hresult !== NOERROR) {
             ZLog::Write(LOGLEVEL_WARN, "TNEF: There was an error reading stream property buffer");
             return $hresult;
         }
         $size -= 16;
         //it is not used and is here only for eventual debugging
         $readableGuid = unpack("VV/v2v/n4n", $guid);
         $readableGuid = sprintf("{%08x-%04x-%04x-%04x-%04x%04x%04x}", $readableGuid['V'], $readableGuid['v1'], $readableGuid['v2'], $readableGuid['n1'], $readableGuid['n2'], $readableGuid['n3'], $readableGuid['n4']);
         ZLog::Write(LOGLEVEL_DEBUG, "TNEF: guid:{$readableGuid}");
         $hresult = $this->readFromTnefStream($buffer, self::DWORD, $isNamedId);
         if ($hresult !== NOERROR) {
             ZLog::Write(LOGLEVEL_WARN, "TNEF: There was an error reading stream property checksum.");
             return $hresult;
         }
         $size -= 4;
         if ($isNamedId != 0) {
             // A string name follows
             //read length of the property
             $hresult = $this->readFromTnefStream($buffer, self::DWORD, $len);
             if ($hresult !== NOERROR) {
                 ZLog::Write(LOGLEVEL_WARN, "TNEF: There was an error reading mapi property's length");
                 return $hresult;
             }
             $size -= 4;
             if ($size < $len) {
                 return MAPI_E_CORRUPT_DATA;
             }
             //read the name of the property, eg Keywords
             $hresult = $this->readBuffer($buffer, $len, $namedProp);
             if ($hresult !== NOERROR) {
                 ZLog::Write(LOGLEVEL_WARN, "TNEF: There was an error reading stream property buffer");
                 return $hresult;
             }
             $size -= $len;
             //Re-align
             $buffer = substr($buffer, $len & 3 ? 4 - ($len & 3) : 0);
             $size -= $len & 3 ? 4 - ($len & 3) : 0;
         } else {
             $hresult = $this->readFromTnefStream($buffer, self::DWORD, $namedProp);
             if ($hresult !== NOERROR) {
                 ZLog::Write(LOGLEVEL_WARN, "TNEF: There was an error reading mapi property's length");
                 return $hresult;
             }
             ZLog::Write(LOGLEVEL_DEBUG, "TNEF: named: 0x" . sprintf("%04x", $namedProp));
             $size -= 4;
         }
         if ($this->store !== false) {
             $named = mapi_getidsfromnames($this->store, array($namedProp), array(makeguid($readableGuid)));
             $propTag = mapi_prop_tag(mapi_prop_type($propTag), mapi_prop_id($named[0]));
         } else {
             ZLog::Write(LOGLEVEL_WARN, "TNEF: Store not available. It is impossible to get named properties");
         }
     }
     ZLog::Write(LOGLEVEL_DEBUG, "TNEF: mapi prop tag: 0x" . sprintf("%04x", mapi_prop_id($propTag)) . " " . sprintf("%04x", mapi_prop_type($propTag)));
     if ($propTag & MV_FLAG) {
         if ($size < 4) {
             return MAPI_E_CORRUPT_DATA;
         }
         //read the number of properties
         $hresult = $this->readFromTnefStream($buffer, self::DWORD, $count);
         if ($hresult !== NOERROR) {
             ZLog::Write(LOGLEVEL_WARN, "TNEF: There was an error reading number of properties for:" . dechex($propTag));
             return $hresult;
         }
         $size -= 4;
     } else {
         $count = 1;
     }
     for ($mvProp = 0; $mvProp < $count; $mvProp++) {
         switch (mapi_prop_type($propTag) & ~MV_FLAG) {
             case PT_I2:
             case PT_LONG:
                 $hresult = $this->readBuffer($buffer, 4, $value);
                 if ($hresult !== NOERROR) {
                     ZLog::Write(LOGLEVEL_WARN, "TNEF: There was an error reading stream property buffer");
                     return $hresult;
                 }
                 $value = unpack("V", $value);
                 $value = intval($value[1], 16);
                 if ($propTag & MV_FLAG) {
                     $mapiprops[$propTag][] = $value;
                 } else {
                     $mapiprops[$propTag] = $value;
                 }
                 $size -= 4;
                 ZLog::Write(LOGLEVEL_DEBUG, "TNEF: int or long propvalue:" . $value);
                 break;
             case PT_R4:
                 if ($propTag & MV_FLAG) {
                     $hresult = $this->readBuffer($buffer, 4, $mapiprops[$propTag][]);
                     if ($hresult !== NOERROR) {
                         ZLog::Write(LOGLEVEL_WARN, "TNEF: There was an error reading stream property buffer");
                         return $hresult;
                     }
                 } else {
                     $hresult = $this->readBuffer($buffer, 4, $mapiprops[$propTag]);
                     if ($hresult !== NOERROR) {
                         ZLog::Write(LOGLEVEL_WARN, "TNEF: There was an error reading stream property buffer");
                         return $hresult;
                     }
                 }
                 $size -= 4;
                 ZLog::Write(LOGLEVEL_DEBUG, "TNEF: propvalue:" . $mapiprops[$propTag]);
                 break;
             case PT_BOOLEAN:
                 $hresult = $this->readBuffer($buffer, 4, $mapiprops[$propTag]);
                 if ($hresult !== NOERROR) {
                     ZLog::Write(LOGLEVEL_WARN, "TNEF: There was an error reading stream property buffer");
                     return $hresult;
                 }
                 $size -= 4;
                 //reported by dw2412
                 //cast to integer as it evaluates to 1 or 0 because
                 //a non empty string evaluates to true :(
                 $mapiprops[$propTag] = (int) bin2hex($mapiprops[$propTag][0]);
                 ZLog::Write(LOGLEVEL_DEBUG, "TNEF: propvalue:" . $mapiprops[$propTag]);
                 break;
             case PT_SYSTIME:
                 if ($size < 8) {
                     return MAPI_E_CORRUPT_DATA;
                 }
                 if ($propTag & MV_FLAG) {
                     $hresult = $this->readBuffer($buffer, 8, $mapiprops[$propTag][]);
                     if ($hresult !== NOERROR) {
                         ZLog::Write(LOGLEVEL_WARN, "TNEF: There was an error reading stream property buffer");
                         return $hresult;
                     }
                 } else {
                     $hresult = $this->readBuffer($buffer, 8, $mapiprops[$propTag]);
                     if ($hresult !== NOERROR) {
                         ZLog::Write(LOGLEVEL_WARN, "TNEF: There was an error reading stream property buffer");
                         return $hresult;
                     }
                 }
                 //we have to convert the filetime to an unixtime timestamp
                 $filetime = unpack("V2v", $mapiprops[$propTag]);
                 //php on 64-bit systems converts unsigned values differently than on 32 bit systems
                 //we need this "fix" in order to get the same values on both types of systems
                 $filetime['v2'] = substr(sprintf("%08x", $filetime['v2']), -8);
                 $filetime['v1'] = substr(sprintf("%08x", $filetime['v1']), -8);
                 $filetime = hexdec($filetime['v2'] . $filetime['v1']);
                 $filetime = ($filetime - 116444736000000000) / 10000000;
                 $mapiprops[$propTag] = $filetime;
                 // we have to set the start and end times separately because the standard PR_START_DATE and PR_END_DATE aren't enough
                 if ($propTag == PR_START_DATE) {
                     $mapiprops[$this->props["starttime"]] = $mapiprops[$this->props["commonstart"]] = $filetime;
                 }
                 if ($propTag == PR_END_DATE) {
                     $mapiprops[$this->props["endtime"]] = $mapiprops[$this->props["commonend"]] = $filetime;
                 }
                 $size -= 8;
                 ZLog::Write(LOGLEVEL_DEBUG, "TNEF: propvalue:" . $mapiprops[$propTag]);
                 break;
             case PT_DOUBLE:
             case PT_CURRENCY:
             case PT_I8:
             case PT_APPTIME:
                 if ($size < 8) {
                     return MAPI_E_CORRUPT_DATA;
                 }
                 if ($propTag & MV_FLAG) {
                     $hresult = $this->readBuffer($buffer, 8, $mapiprops[$propTag][]);
                     if ($hresult !== NOERROR) {
                         ZLog::Write(LOGLEVEL_WARN, "TNEF: There was an error reading stream property buffer");
                         return $hresult;
                     }
                 } else {
                     $hresult = $this->readBuffer($buffer, 8, $mapiprops[$propTag]);
                     if ($hresult !== NOERROR) {
                         ZLog::Write(LOGLEVEL_WARN, "TNEF: There was an error reading stream property buffer");
                         return $hresult;
                     }
                 }
                 $size -= 8;
                 ZLog::Write(LOGLEVEL_DEBUG, "TNEF: propvalue:" . $mapiprops[$propTag]);
                 break;
             case PT_STRING8:
                 if ($size < 8) {
                     return MAPI_E_CORRUPT_DATA;
                 }
                 // Skip next 4 bytes, it's always '1' (ULONG)
                 $buffer = substr($buffer, 4);
                 $size -= 4;
                 //read length of the property
                 $hresult = $this->readFromTnefStream($buffer, self::DWORD, $len);
                 if ($hresult !== NOERROR) {
                     ZLog::Write(LOGLEVEL_WARN, "TNEF: There was an error reading mapi property's length");
                     return $hresult;
                 }
                 $size -= 4;
                 if ($size < $len) {
                     return MAPI_E_CORRUPT_DATA;
                 }
                 if ($propTag & MV_FLAG) {
                     $hresult = $this->readBuffer($buffer, $len, $mapiprops[$propTag][]);
                     if ($hresult !== NOERROR) {
                         ZLog::Write(LOGLEVEL_WARN, "TNEF: There was an error reading stream property buffer");
                         return $hresult;
                     }
                 } else {
                     $hresult = $this->readBuffer($buffer, $len, $mapiprops[$propTag]);
                     if ($hresult !== NOERROR) {
                         ZLog::Write(LOGLEVEL_WARN, "TNEF: There was an error reading stream property buffer");
                         return $hresult;
                     }
                 }
                 //location fix. it looks like tnef uses this value for location
                 if (mapi_prop_id($propTag) == 0x8342) {
                     $mapiprops[$this->props["location"]] = $mapiprops[$propTag];
                     unset($mapiprops[$propTag]);
                 }
                 $size -= $len;
                 //Re-align
                 $buffer = substr($buffer, $len & 3 ? 4 - ($len & 3) : 0);
                 $size -= $len & 3 ? 4 - ($len & 3) : 0;
                 ZLog::Write(LOGLEVEL_DEBUG, "TNEF: propvalue:" . $mapiprops[$propTag]);
                 break;
             case PT_UNICODE:
                 if ($size < 8) {
                     return MAPI_E_CORRUPT_DATA;
                 }
                 // Skip next 4 bytes, it's always '1' (ULONG)
                 $buffer = substr($buffer, 4);
                 $size -= 4;
                 //read length of the property
                 $hresult = $this->readFromTnefStream($buffer, self::DWORD, $len);
                 if ($hresult !== NOERROR) {
                     ZLog::Write(LOGLEVEL_WARN, "TNEF: There was an error reading mapi property's length");
                     return $hresult;
                 }
                 $size -= 4;
                 if ($size < $len) {
                     return MAPI_E_CORRUPT_DATA;
                 }
                 //currently unicode strings are not supported bz mapi_setprops, so we'll use PT_STRING8
                 $propTag = mapi_prop_tag(PT_STRING8, mapi_prop_id($propTag));
                 if ($propTag & MV_FLAG) {
                     $hresult = $this->readBuffer($buffer, $len, $mapiprops[$propTag][]);
                     if ($hresult !== NOERROR) {
                         ZLog::Write(LOGLEVEL_WARN, "TNEF: There was an error reading stream property buffer");
                         return $hresult;
                     }
                 } else {
                     $hresult = $this->readBuffer($buffer, $len, $mapiprops[$propTag]);
                     if ($hresult !== NOERROR) {
                         ZLog::Write(LOGLEVEL_WARN, "TNEF: There was an error reading stream property buffer");
                         return $hresult;
                     }
                 }
                 //location fix. it looks like tnef uses this value for location
                 if (mapi_prop_id($propTag) == 0x8342) {
                     $mapiprops[$this->props["location"]] = iconv("UCS-2", "windows-1252", $mapiprops[$propTag]);
                     unset($mapiprops[$propTag]);
                 }
                 //convert from unicode to windows encoding
                 if (isset($mapiprops[$propTag])) {
                     $mapiprops[$propTag] = iconv("UCS-2", "windows-1252", $mapiprops[$propTag]);
                 }
                 $size -= $len;
                 //Re-align
                 $buffer = substr($buffer, $len & 3 ? 4 - ($len & 3) : 0);
                 $size -= $len & 3 ? 4 - ($len & 3) : 0;
                 if (isset($mapiprops[$propTag])) {
                     ZLog::Write(LOGLEVEL_DEBUG, "TNEF: propvalue:" . $mapiprops[$propTag]);
                 }
                 break;
             case PT_OBJECT:
                 // PST sends PT_OBJECT data. Treat as PT_BINARY
             // PST sends PT_OBJECT data. Treat as PT_BINARY
             case PT_BINARY:
                 if ($size < self::BYTE) {
                     return MAPI_E_CORRUPT_DATA;
                 }
                 // Skip next 4 bytes, it's always '1' (ULONG)
                 $buffer = substr($buffer, 4);
                 $size -= 4;
                 //read length of the property
                 $hresult = $this->readFromTnefStream($buffer, self::DWORD, $len);
                 if ($hresult !== NOERROR) {
                     ZLog::Write(LOGLEVEL_WARN, "TNEF: There was an error reading mapi property's length");
                     return $hresult;
                 }
                 $size -= 4;
                 if (mapi_prop_type($propTag) == PT_OBJECT) {
                     // IMessage guid [ 0x00020307 C000 0000 0000 0000 00 00 00 46 ]
                     $buffer = substr($buffer, 16);
                     $size -= 16;
                     $len -= 16;
                 }
                 if ($size < $len) {
                     return MAPI_E_CORRUPT_DATA;
                 }
                 if ($propTag & MV_FLAG) {
                     $hresult = $this->readBuffer($buffer, $len, $mapiprops[$propTag][]);
                     if ($hresult !== NOERROR) {
                         ZLog::Write(LOGLEVEL_WARN, "TNEF: There was an error reading stream property buffer");
                         return $hresult;
                     }
                 } else {
                     $hresult = $this->readBuffer($buffer, $len, $mapiprops[$propTag]);
                     if ($hresult !== NOERROR) {
                         ZLog::Write(LOGLEVEL_WARN, "TNEF: There was an error reading stream property buffer");
                         return $hresult;
                     }
                 }
                 $size -= $len;
                 //Re-align
                 $buffer = substr($buffer, $len & 3 ? 4 - ($len & 3) : 0);
                 $size -= $len & 3 ? 4 - ($len & 3) : 0;
                 ZLog::Write(LOGLEVEL_DEBUG, "TNEF: propvalue:" . bin2hex($mapiprops[$propTag]));
                 break;
             default:
                 return MAPI_E_INVALID_PARAMETER;
                 break;
         }
     }
     return NOERROR;
 }
 /**
  * Gets the properties from a MAPI object and sets them in the Sync object according to mapping
  *
  * @param SyncObject        &$message
  * @param mixed             $mapimessage
  * @param array             $mapping
  *
  * @access private
  * @return
  */
 private function getPropsFromMAPI(&$message, $mapimessage, $mapping)
 {
     $messageprops = $this->getProps($mapimessage, $mapping);
     foreach ($mapping as $asprop => $mapiprop) {
         // Get long strings via openproperty
         if (isset($messageprops[mapi_prop_tag(PT_ERROR, mapi_prop_id($mapiprop))])) {
             if ($messageprops[mapi_prop_tag(PT_ERROR, mapi_prop_id($mapiprop))] == MAPI_E_NOT_ENOUGH_MEMORY_32BIT || $messageprops[mapi_prop_tag(PT_ERROR, mapi_prop_id($mapiprop))] == MAPI_E_NOT_ENOUGH_MEMORY_64BIT) {
                 $messageprops[$mapiprop] = MAPIUtils::readPropStream($mapimessage, $mapiprop);
             }
         }
         if (isset($messageprops[$mapiprop])) {
             if (mapi_prop_type($mapiprop) == PT_BOOLEAN) {
                 // Force to actual '0' or '1'
                 if ($messageprops[$mapiprop]) {
                     $message->{$asprop} = 1;
                 } else {
                     $message->{$asprop} = 0;
                 }
             } else {
                 // Special handling for PR_MESSAGE_FLAGS
                 if ($mapiprop == PR_MESSAGE_FLAGS) {
                     $message->{$asprop} = $messageprops[$mapiprop] & 1;
                 } else {
                     if ($mapiprop == PR_RTF_COMPRESSED) {
                         //do not send rtf to the mobile
                         continue;
                     } else {
                         if (is_array($messageprops[$mapiprop])) {
                             $message->{$asprop} = array_map("w2u", $messageprops[$mapiprop]);
                         } else {
                             if (mapi_prop_type($mapiprop) != PT_BINARY && mapi_prop_type($mapiprop) != PT_MV_BINARY) {
                                 $message->{$asprop} = w2u($messageprops[$mapiprop]);
                             } else {
                                 $message->{$asprop} = $messageprops[$mapiprop];
                             }
                         }
                     }
                 }
             }
         }
     }
 }
示例#3
0
 /**
  * Function which saves the exception data in an attachment.
  * @param array $exception_props the exception data (like any other MAPI appointment)
  * @param array $exception_recips list of recipients
  * @param mapi_message $copy_attach_from mapi message from which attachments should be copied
  * @return array properties of the exception
  */
 function createExceptionAttachment($exception_props, $exception_recips = array(), $copy_attach_from = false)
 {
     // Create new attachment.
     $attachment = mapi_message_createattach($this->message);
     $props = array();
     $props[PR_ATTACHMENT_FLAGS] = 2;
     $props[PR_ATTACHMENT_HIDDEN] = true;
     $props[PR_ATTACHMENT_LINKID] = 0;
     $props[PR_ATTACH_FLAGS] = 0;
     $props[PR_ATTACH_METHOD] = 5;
     $props[PR_DISPLAY_NAME] = "Exception";
     $props[PR_EXCEPTION_STARTTIME] = $this->fromGMT($this->tz, $exception_props[$this->proptags["startdate"]]);
     $props[PR_EXCEPTION_ENDTIME] = $this->fromGMT($this->tz, $exception_props[$this->proptags["duedate"]]);
     mapi_message_setprops($attachment, $props);
     $imessage = mapi_attach_openobj($attachment, MAPI_CREATE | MAPI_MODIFY);
     if ($copy_attach_from) {
         $attachmentTable = mapi_message_getattachmenttable($copy_attach_from);
         if ($attachmentTable) {
             $attachments = mapi_table_queryallrows($attachmentTable, array(PR_ATTACH_NUM, PR_ATTACH_SIZE, PR_ATTACH_LONG_FILENAME, PR_ATTACHMENT_HIDDEN, PR_DISPLAY_NAME, PR_ATTACH_METHOD));
             foreach ($attachments as $attach_props) {
                 $attach_old = mapi_message_openattach($copy_attach_from, (int) $attach_props[PR_ATTACH_NUM]);
                 $attach_newResourceMsg = mapi_message_createattach($imessage);
                 mapi_copyto($attach_old, array(), array(), $attach_newResourceMsg, 0);
                 mapi_savechanges($attach_newResourceMsg);
             }
         }
     }
     $props = $props + $exception_props;
     // FIXME: the following piece of code is written to fix the creation
     // of an exception. This is only a quickfix as it is not yet possible
     // to change an existing exception.
     // remove mv properties when needed
     foreach ($props as $propTag => $propVal) {
         if ((mapi_prop_type($propTag) & MV_FLAG) == MV_FLAG && is_null($propVal)) {
             unset($props[$propTag]);
         }
     }
     mapi_message_setprops($imessage, $props);
     $this->setExceptionRecipients($imessage, $exception_recips, true);
     mapi_message_savechanges($imessage);
     mapi_message_savechanges($attachment);
 }
示例#4
0
文件: ics.php 项目: nnaannoo/paskot
 function _getPropsFromMAPI(&$message, $mapimessage, $mapping)
 {
     foreach ($mapping as $asprop => $mapipropstring) {
         // Get the MAPI property we need to be reading
         $mapiprop = $this->_getPropIDFromString($mapipropstring);
         $prop = mapi_getprops($mapimessage, array($mapiprop));
         // Get long strings via openproperty
         if (isset($prop[mapi_prop_tag(PT_ERROR, mapi_prop_id($mapiprop))])) {
             if ($prop[mapi_prop_tag(PT_ERROR, mapi_prop_id($mapiprop))] == -2147024882 || $prop[mapi_prop_tag(PT_ERROR, mapi_prop_id($mapiprop))] == 2147942414.0) {
                 // 64 bit
                 $prop = array($mapiprop => readPropStream($mapimessage, $mapiprop));
             }
         }
         if (isset($prop[$mapiprop])) {
             if (mapi_prop_type($mapiprop) == PT_BOOLEAN) {
                 // Force to actual '0' or '1'
                 if ($prop[$mapiprop]) {
                     $message->{$asprop} = 1;
                 } else {
                     $message->{$asprop} = 0;
                 }
             } else {
                 // Special handling for PR_MESSAGE_FLAGS
                 if ($mapiprop == PR_MESSAGE_FLAGS) {
                     $message->{$asprop} = $prop[$mapiprop] & 1;
                 } else {
                     if ($mapiprop == PR_RTF_COMPRESSED) {
                         //do not send rtf to the mobile
                         continue;
                     } else {
                         if (is_array($prop[$mapiprop])) {
                             $message->{$asprop} = array_map("w2u", $prop[$mapiprop]);
                         } else {
                             if (mapi_prop_type($mapiprop) != PT_BINARY && mapi_prop_type($mapiprop) != PT_MV_BINARY) {
                                 $message->{$asprop} = w2u($prop[$mapiprop]);
                             } else {
                                 $message->{$asprop} = $prop[$mapiprop];
                             }
                         }
                     }
                 }
             }
         }
     }
 }
示例#5
0
文件: z_tnef.php 项目: jkreska/test1
 function _readSingleMapiProp(&$buffer, &$size, &$read, &$mapiprops)
 {
     $propTag = 0;
     $len = 0;
     $origSize = $size;
     $isNamedId = 0;
     $namedProp = 0;
     $count = 0;
     $mvProp = 0;
     $guid = 0;
     if ($size < 8) {
         return MAPI_E_NOT_FOUND;
     }
     $hresult = $this->_readFromTnefStream($buffer, ZP_DWORD, $propTag);
     if ($hresult !== NOERROR) {
         debugLog("There was an error reading a mapi property tag from the stream.");
         return $hresult;
     }
     $size -= 4;
     //debugLog("mapi prop type:".dechex(mapi_prop_type($propTag)));
     //debugLog("mapi prop tag: 0x".sprintf("%04x", mapi_prop_id($propTag)));
     if (mapi_prop_id($propTag) >= 0x8000) {
         // Named property, first read GUID, then name/id
         if ($size < 24) {
             debugLog("Corrupt guid size for named property:" . dechex($propTag));
             return MAPI_E_CORRUPT_DATA;
         }
         //strip GUID & name/id
         $hresult = $this->_readBuffer($buffer, 16, $guid);
         if ($hresult !== NOERROR) {
             debugLog("There was an error reading stream property buffer");
             return $hresult;
         }
         $size -= 16;
         //it is not used and is here only for eventual debugging
         $readableGuid = unpack("VV/v2v/n4n", $guid);
         $readableGuid = sprintf("{%08x-%04x-%04x-%04x-%04x%04x%04x}", $readableGuid['V'], $readableGuid['v1'], $readableGuid['v2'], $readableGuid['n1'], $readableGuid['n2'], $readableGuid['n3'], $readableGuid['n4']);
         //debugLog("guid:$readableGuid");
         $hresult = $this->_readFromTnefStream($buffer, ZP_DWORD, $isNamedId);
         if ($hresult !== NOERROR) {
             debugLog("There was an error reading stream property checksum.");
             return $hresult;
         }
         $size -= 4;
         if ($isNamedId != 0) {
             // A string name follows
             //read length of the property
             $hresult = $this->_readFromTnefStream($buffer, ZP_DWORD, $len);
             if ($hresult !== NOERROR) {
                 debugLog("There was an error reading mapi property's length");
                 return $hresult;
             }
             $size -= 4;
             if ($size < $len) {
                 return MAPI_E_CORRUPT_DATA;
             }
             //read the name of the property, eg Keywords
             $hresult = $this->_readBuffer($buffer, $len, $namedProp);
             if ($hresult !== NOERROR) {
                 debugLog("There was an error reading stream property buffer");
                 return $hresult;
             }
             $size -= $len;
             //Re-align
             $buffer = substr($buffer, $len & 3 ? 4 - ($len & 3) : 0);
             $size -= $len & 3 ? 4 - ($len & 3) : 0;
         } else {
             $hresult = $this->_readFromTnefStream($buffer, ZP_DWORD, $namedProp);
             if ($hresult !== NOERROR) {
                 debugLog("There was an error reading mapi property's length");
                 return $hresult;
             }
             //debugLog("named: 0x".sprintf("%04x", $namedProp));
             $size -= 4;
         }
         if ($this->_store !== false) {
             $named = mapi_getidsfromnames($this->_store, array($namedProp), array(makeguid($readableGuid)));
             $propTag = mapi_prop_tag(mapi_prop_type($propTag), mapi_prop_id($named[0]));
         } else {
             debugLog("Store not available. It is impossible to get named properties");
         }
     }
     //debugLog("mapi prop tag: 0x".sprintf("%04x", mapi_prop_id($propTag))." ".sprintf("%04x", mapi_prop_type($propTag)));
     if ($propTag & MV_FLAG) {
         if ($size < 4) {
             return MAPI_E_CORRUPT_DATA;
         }
         //read the number of properties
         $hresult = $this->_readFromTnefStream($buffer, ZP_DWORD, $count);
         if ($hresult !== NOERROR) {
             debugLog("There was an error reading number of properties for:" . dechex($propTag));
             return $hresult;
         }
         $size -= 4;
     } else {
         $count = 1;
     }
     for ($mvProp = 0; $mvProp < $count; $mvProp++) {
         switch (mapi_prop_type($propTag) & ~MV_FLAG) {
             case PT_I2:
             case PT_LONG:
                 $hresult = $this->_readBuffer($buffer, 4, $value);
                 if ($hresult !== NOERROR) {
                     debugLog("There was an error reading stream property buffer");
                     return $hresult;
                 }
                 $value = unpack("V", $value);
                 $value = intval($value[1], 16);
                 if ($propTag & MV_FLAG) {
                     $mapiprops[$propTag][] = $value;
                 } else {
                     $mapiprops[$propTag] = $value;
                 }
                 $size -= 4;
                 //debugLog("int or long propvalue:".$value);
                 break;
             case PT_R4:
                 if ($propTag & MV_FLAG) {
                     $hresult = $this->_readBuffer($buffer, 4, $mapiprops[$propTag][]);
                     if ($hresult !== NOERROR) {
                         debugLog("There was an error reading stream property buffer");
                         return $hresult;
                     }
                 } else {
                     $hresult = $this->_readBuffer($buffer, 4, $mapiprops[$propTag]);
                     if ($hresult !== NOERROR) {
                         debugLog("There was an error reading stream property buffer");
                         return $hresult;
                     }
                 }
                 $size -= 4;
                 //debugLog("propvalue:".$mapiprops[$propTag]);
                 break;
             case PT_BOOLEAN:
                 $hresult = $this->_readBuffer($buffer, 4, $mapiprops[$propTag]);
                 if ($hresult !== NOERROR) {
                     debugLog("There was an error reading stream property buffer");
                     return $hresult;
                 }
                 $size -= 4;
                 //debugLog("propvalue:".$mapiprops[$propTag]);
                 break;
             case PT_SYSTIME:
                 if ($size < 8) {
                     return MAPI_E_CORRUPT_DATA;
                 }
                 if ($propTag & MV_FLAG) {
                     $hresult = $this->_readBuffer($buffer, 8, $mapiprops[$propTag][]);
                     if ($hresult !== NOERROR) {
                         debugLog("There was an error reading stream property buffer");
                         return $hresult;
                     }
                 } else {
                     $hresult = $this->_readBuffer($buffer, 8, $mapiprops[$propTag]);
                     if ($hresult !== NOERROR) {
                         debugLog("There was an error reading stream property buffer");
                         return $hresult;
                     }
                 }
                 //we have to convert the filetime to an unixtime timestamp
                 $filetime = unpack("V2v", $mapiprops[$propTag]);
                 $filetime = hexdec(sprintf("%08x%08x", $filetime['v2'], $filetime['v1']));
                 $filetime = ($filetime - 116444736000000000) / 10000000;
                 $mapiprops[$propTag] = $filetime;
                 // we have to set the start and end times separately because the standard PR_START_DATE and PR_END_DATE aren't enough
                 if ($propTag == PR_START_DATE) {
                     $namedStartTime = GetPropIDFromString($this->_store, "PT_SYSTIME:{00062002-0000-0000-C000-000000000046}:0x820d");
                     $mapiprops[$namedStartTime] = $filetime;
                     $namedCommonStart = GetPropIDFromString($this->_store, "PT_SYSTIME:{00062008-0000-0000-C000-000000000046}:0x8516");
                     $mapiprops[$namedCommonStart] = $filetime;
                 }
                 if ($propTag == PR_END_DATE) {
                     $namedEndTime = GetPropIDFromString($this->_store, "PT_SYSTIME:{00062002-0000-0000-C000-000000000046}:0x820e");
                     $mapiprops[$namedEndTime] = $filetime;
                     $namedCommonEnd = GetPropIDFromString($this->_store, "PT_SYSTIME:{00062008-0000-0000-C000-000000000046}:0x8517");
                     $mapiprops[$namedCommonEnd] = $filetime;
                 }
                 $size -= 8;
                 //debugLog("propvalue:".$mapiprops[$propTag]);
                 break;
             case PT_DOUBLE:
             case PT_CURRENCY:
             case PT_I8:
             case PT_APPTIME:
                 if ($size < 8) {
                     return MAPI_E_CORRUPT_DATA;
                 }
                 if ($propTag & MV_FLAG) {
                     $hresult = $this->_readBuffer($buffer, 8, $mapiprops[$propTag][]);
                     if ($hresult !== NOERROR) {
                         debugLog("There was an error reading stream property buffer");
                         return $hresult;
                     }
                 } else {
                     $hresult = $this->_readBuffer($buffer, 8, $mapiprops[$propTag]);
                     if ($hresult !== NOERROR) {
                         debugLog("There was an error reading stream property buffer");
                         return $hresult;
                     }
                 }
                 $size -= 8;
                 //debugLog("propvalue:".$mapiprops[$propTag]);
                 break;
             case PT_STRING8:
                 if ($size < 8) {
                     return MAPI_E_CORRUPT_DATA;
                 }
                 // Skip next 4 bytes, it's always '1' (ULONG)
                 $buffer = substr($buffer, 4);
                 $size -= 4;
                 //read length of the property
                 $hresult = $this->_readFromTnefStream($buffer, ZP_DWORD, $len);
                 if ($hresult !== NOERROR) {
                     debugLog("There was an error reading mapi property's length");
                     return $hresult;
                 }
                 $size -= 4;
                 if ($size < $len) {
                     return MAPI_E_CORRUPT_DATA;
                 }
                 if ($propTag & MV_FLAG) {
                     $hresult = $this->_readBuffer($buffer, $len, $mapiprops[$propTag][]);
                     if ($hresult !== NOERROR) {
                         debugLog("There was an error reading stream property buffer");
                         return $hresult;
                     }
                 } else {
                     $hresult = $this->_readBuffer($buffer, $len, $mapiprops[$propTag]);
                     if ($hresult !== NOERROR) {
                         debugLog("There was an error reading stream property buffer");
                         return $hresult;
                     }
                 }
                 //location fix. it looks like tnef uses this value for location
                 if (mapi_prop_id($propTag) == 0x8342) {
                     $namedLocation = GetPropIDFromString($this->_store, "PT_STRING8:{00062002-0000-0000-C000-000000000046}:0x8208");
                     $mapiprops[$namedLocation] = $mapiprops[$propTag];
                     unset($mapiprops[$propTag]);
                 }
                 $size -= $len;
                 //Re-align
                 $buffer = substr($buffer, $len & 3 ? 4 - ($len & 3) : 0);
                 $size -= $len & 3 ? 4 - ($len & 3) : 0;
                 //debugLog("propvalue:".$mapiprops[$propTag]);
                 break;
             case PT_UNICODE:
                 if ($size < 8) {
                     return MAPI_E_CORRUPT_DATA;
                 }
                 // Skip next 4 bytes, it's always '1' (ULONG)
                 $buffer = substr($buffer, 4);
                 $size -= 4;
                 //read length of the property
                 $hresult = $this->_readFromTnefStream($buffer, ZP_DWORD, $len);
                 if ($hresult !== NOERROR) {
                     debugLog("There was an error reading mapi property's length");
                     return $hresult;
                 }
                 $size -= 4;
                 if ($size < $len) {
                     return MAPI_E_CORRUPT_DATA;
                 }
                 //currently unicode strings are not supported bz mapi_setprops, so we'll use PT_STRING8
                 $propTag = mapi_prop_tag(PT_STRING8, mapi_prop_id($propTag));
                 if ($propTag & MV_FLAG) {
                     $hresult = $this->_readBuffer($buffer, $len, $mapiprops[$propTag][]);
                     if ($hresult !== NOERROR) {
                         debugLog("There was an error reading stream property buffer");
                         return $hresult;
                     }
                 } else {
                     $hresult = $this->_readBuffer($buffer, $len, $mapiprops[$propTag]);
                     if ($hresult !== NOERROR) {
                         debugLog("There was an error reading stream property buffer");
                         return $hresult;
                     }
                 }
                 //location fix. it looks like tnef uses this value for location
                 if (mapi_prop_id($propTag) == 0x8342) {
                     $namedLocation = GetPropIDFromString($this->_store, "PT_STRING8:{00062002-0000-0000-C000-000000000046}:0x8208");
                     $mapiprops[$namedLocation] = $mapiprops[$propTag];
                     unset($mapiprops[$propTag]);
                     $mapiprops[$namedLocation] = iconv("UCS-2", "windows-1252", $mapiprops[$namedLocation]);
                 }
                 //convert from unicode to windows encoding
                 if (isset($mapiprops[$propTag])) {
                     $mapiprops[$propTag] = iconv("UCS-2", "windows-1252", $mapiprops[$propTag]);
                 }
                 $size -= $len;
                 //Re-align
                 $buffer = substr($buffer, $len & 3 ? 4 - ($len & 3) : 0);
                 $size -= $len & 3 ? 4 - ($len & 3) : 0;
                 //debugLog("propvalue:".$mapiprops[$propTag]);
                 break;
             case PT_OBJECT:
                 // PST sends PT_OBJECT data. Treat as PT_BINARY
             // PST sends PT_OBJECT data. Treat as PT_BINARY
             case PT_BINARY:
                 if ($size < ZP_BYTE) {
                     return MAPI_E_CORRUPT_DATA;
                 }
                 // Skip next 4 bytes, it's always '1' (ULONG)
                 $buffer = substr($buffer, 4);
                 $size -= 4;
                 //read length of the property
                 $hresult = $this->_readFromTnefStream($buffer, ZP_DWORD, $len);
                 if ($hresult !== NOERROR) {
                     debugLog("There was an error reading mapi property's length");
                     return $hresult;
                 }
                 $size -= 4;
                 if (mapi_prop_type($propTag) == PT_OBJECT) {
                     // TODO: IMessage guid [ 0x00020307 C000 0000 0000 0000 00 00 00 46 ]
                     $buffer = substr($buffer, 16);
                     $size -= 16;
                     $len -= 16;
                 }
                 if ($size < $len) {
                     return MAPI_E_CORRUPT_DATA;
                 }
                 if ($propTag & MV_FLAG) {
                     $hresult = $this->_readBuffer($buffer, $len, $mapiprops[$propTag][]);
                     if ($hresult !== NOERROR) {
                         debugLog("There was an error reading stream property buffer");
                         return $hresult;
                     }
                 } else {
                     $hresult = $this->_readBuffer($buffer, $len, $mapiprops[$propTag]);
                     if ($hresult !== NOERROR) {
                         debugLog("There was an error reading stream property buffer");
                         return $hresult;
                     }
                 }
                 $size -= $len;
                 //Re-align
                 $buffer = substr($buffer, $len & 3 ? 4 - ($len & 3) : 0);
                 $size -= $len & 3 ? 4 - ($len & 3) : 0;
                 //debugLog("propvalue:".bin2hex($mapiprops[$propTag]));
                 break;
             default:
                 return MAPI_E_INVALID_PARAMETER;
                 break;
         }
     }
     return NOERROR;
 }
示例#6
0
 function _getPropsFromMAPI(&$message, $mapimessage, $mapping)
 {
     foreach ($mapping as $asprop => $mapipropstring) {
         // Get the MAPI property we need to be reading
         $mapiprop = $this->_getPropIDFromString($mapipropstring);
         if ($mapiprop == PR_BODY) {
             // special handling for PR_BODY
             $message->{$asprop} = str_replace("\n", "\r\n", w2u(str_replace("\r", "", mapi_openproperty($mapimessage, PR_BODY))));
             if (strlen($message->{$asprop}) > 0) {
                 $message->bodytruncated = 0;
                 $message->bodysize = strlen($message->body);
             }
         } else {
             // Normal property
             $prop = mapi_getprops($mapimessage, array($mapiprop));
             if (isset($prop[$mapiprop])) {
                 if (mapi_prop_type($mapiprop) == PT_BOOLEAN) {
                     // Force to actual '0' or '1'
                     if ($prop[$mapiprop]) {
                         $message->{$asprop} = 1;
                     } else {
                         $message->{$asprop} = 0;
                     }
                 } else {
                     // Special handling for PR_MESSAGE_FLAGS
                     if ($mapiprop == PR_MESSAGE_FLAGS) {
                         $message->{$asprop} = $prop[$mapiprop] & 1;
                     } else {
                         if (is_array($prop[$mapiprop])) {
                             $message->{$asprop} = array_map("w2u", $prop[$mapiprop]);
                         } else {
                             if (mapi_prop_type($mapiprop) != PT_BINARY && mapi_prop_type($mapiprop) != PT_MV_BINARY) {
                                 $message->{$asprop} = w2u($prop[$mapiprop]);
                             } else {
                                 $message->{$asprop} = $prop[$mapiprop];
                             }
                         }
                     }
                 }
             }
         }
     }
 }
function setProperty($property, $value, &$props, $properties)
{
    if (isset($value) && isset($properties[$property])) {
        //multi values have to be saved as an array
        if ($properties[$property] & MV_FLAG) {
            $value = explode(';', $value);
        }
        if (mapi_prop_type($properties[$property]) == PT_SYSTIME && !DATES_AS_TIMESTAMPS) {
            $value = strtotime($value);
        }
        if (mapi_prop_type($properties[$property]) != PT_BINARY && mapi_prop_type($properties[$property]) != PT_MV_BINARY) {
            if (is_array($value)) {
                $props[$properties[$property]] = array_map("to_windows1252", $value);
            } else {
                $props[$properties[$property]] = to_windows1252($value);
            }
        } else {
            $props[$properties[$property]] = to_windows1252($value);
        }
    }
}