function getFullRecurrenceBlob() { $message = mapi_msgstore_openentry($this->store, $this->messageprops[PR_ENTRYID]); $recurrBlob = ''; $stream = mapi_openproperty($message, $this->proptags["recurring_data"], IID_IStream, 0, 0); $stat = mapi_stream_stat($stream); for ($i = 0; $i < $stat['cb']; $i += 1024) { $recurrBlob .= mapi_stream_read($stream, 1024); } if (!empty($recurrBlob)) { $this->messageprops[$this->proptags["recurring_data"]] = $recurrBlob; } }
/** * A wrapper for mapi_inetmapi_imtoinet function * * @param MAPIMessage $mapimessage * @param SyncObject $message * * @access private * @return boolean */ private function imtoinet($mapimessage, &$message) { if (function_exists("mapi_inetmapi_imtoinet")) { $addrbook = $this->getAddressbook(); $mstream = mapi_inetmapi_imtoinet($this->session, $addrbook, $mapimessage, array()); $mstreamstat = mapi_stream_stat($mstream); if ($mstreamstat['cb'] < MAX_EMBEDDED_SIZE) { if (Request::GetProtocolVersion() >= 12.0) { if (!isset($message->asbody)) { $message->asbody = new SyncBaseBody(); } //TODO data should be wrapped in a MapiStreamWrapper $message->asbody->data = mapi_stream_read($mstream, MAX_EMBEDDED_SIZE); $message->asbody->estimatedDataSize = $mstreamstat["cb"]; $message->asbody->truncated = 0; } else { $message->mimetruncated = 0; //TODO mimedata should be a wrapped in a MapiStreamWrapper $message->mimedata = mapi_stream_read($mstream, MAX_EMBEDDED_SIZE); $message->mimesize = $mstreamstat["cb"]; } unset($message->body, $message->bodytruncated); return true; } ZLog::Write(LOGLEVEL_WARN, sprintf("Your request (%d bytes) exceeds the value for inline attachments (%d bytes). You can change the value of MAX_EMBEDDED_SIZE in config.php", $mstreamstat['cb'], MAX_EMBEDDED_SIZE)); } return false; }
/** * A wrapper for mapi_inetmapi_imtoinet function * * @param MAPIMessage $mapimessage * @param SyncObject $message * * @access private * @return boolean */ private function imtoinet($mapimessage, &$message) { // if it is a signed message get a full attachment generated by ZCP $props = mapi_getprops($mapimessage, array(PR_MESSAGE_CLASS)); if (isset($props[PR_MESSAGE_CLASS]) && $props[PR_MESSAGE_CLASS] && strpos(strtolower($props[PR_MESSAGE_CLASS]), 'multipartsigned')) { // find the required attachment $attachtable = mapi_message_getattachmenttable($mapimessage); mapi_table_restrict($attachtable, MAPIUtils::GetSignedAttachmentRestriction()); if (mapi_table_getrowcount($attachtable) == 1) { $rows = mapi_table_queryrows($attachtable, array(PR_ATTACH_NUM, PR_ATTACH_SIZE), 0, 1); if (isset($rows[0][PR_ATTACH_NUM])) { $mapiattach = mapi_message_openattach($mapimessage, $rows[0][PR_ATTACH_NUM]); $stream = mapi_openpropertytostream($mapiattach, PR_ATTACH_DATA_BIN); $streamsize = $rows[0][PR_ATTACH_SIZE]; } } } elseif (function_exists("mapi_inetmapi_imtoinet")) { $addrbook = $this->getAddressbook(); $stream = mapi_inetmapi_imtoinet($this->session, $addrbook, $mapimessage, array('use_tnef' => -1)); $mstreamstat = mapi_stream_stat($stream); $streamsize = $mstreamstat["cb"]; } if (isset($stream) && isset($streamsize)) { if (Request::GetProtocolVersion() >= 12.0) { if (!isset($message->asbody)) { $message->asbody = new SyncBaseBody(); } //TODO data should be wrapped in a MapiStreamWrapper $message->asbody->data = mapi_stream_read($stream, $streamsize); $message->asbody->estimatedDataSize = $streamsize; $message->asbody->truncated = 0; } else { $message->mimetruncated = 0; //TODO mimedata should be a wrapped in a MapiStreamWrapper $message->mimedata = mapi_stream_read($stream, $streamsize); $message->mimesize = $streamsize; } unset($message->body, $message->bodytruncated); return true; } else { ZLog::Write(LOGLEVEL_ERROR, sprintf("Error opening attachment for imtoinet")); } return false; }
/** * Reads data of large properties from a stream * * @param MAPIMessage $message * @param long $prop * * @access public * @return string */ public static function readPropStream($message, $prop) { $stream = mapi_openproperty($message, $prop, IID_IStream, 0, 0); $ret = mapi_last_hresult(); if ($ret == MAPI_E_NOT_FOUND) { ZLog::Write(LOGLEVEL_DEBUG, sprintf("MAPIUtils->readPropStream: property 0x%s not found. It is either empty or not set. It will be ignored.", str_pad(dechex($prop), 8, 0, STR_PAD_LEFT))); return ""; } elseif ($ret) { ZLog::Write(LOGLEVEL_ERROR, "MAPIUtils->readPropStream error opening stream: 0X%X", $ret); return ""; } $data = ""; $string = ""; while (1) { $data = mapi_stream_read($stream, 1024); if (strlen($data) == 0) { break; } $string .= $data; } return $string; }
/** * Reads from stream * * @param int $len amount of bytes to be read * * @access public * @return string */ public function stream_read($len) { $len = $this->position + $len > $this->streamlength ? $this->streamlength - $this->position : $len; $data = mapi_stream_read($this->mapistream, $len); $this->position += strlen($data); return $data; }
/** * Reads state from the Importer * * @access public * @return string * @throws StatusException */ public function GetState() { $error = false; if (!isset($this->statestream) || $this->importer === false) { $error = true; } if ($error === false && $this->folderid !== false && function_exists("mapi_importcontentschanges_updatestate")) { if (mapi_importcontentschanges_updatestate($this->importer, $this->statestream) != true) { $error = true; } } if ($error == true) { throw new StatusException(sprintf("ImportChangesICS->GetState(): Error, state not available or unable to update: 0x%X", mapi_last_hresult()), $this->folderid ? SYNC_STATUS_FOLDERHIERARCHYCHANGED : SYNC_FSSTATUS_CODEUNKNOWN, null, LOGLEVEL_WARN); } mapi_stream_seek($this->statestream, 0, STREAM_SEEK_SET); $state = ""; while (true) { $data = mapi_stream_read($this->statestream, 4096); if (strlen($data)) { $state .= $data; } else { break; } } return $state; }
/** * Copies attachments from one message to another. * * @param MAPIMessage $toMessage * @param MAPIMessage $fromMessage * * @return void */ private function copyAttachments(&$toMessage, $fromMessage) { $attachtable = mapi_message_getattachmenttable($fromMessage); $rows = mapi_table_queryallrows($attachtable, array(PR_ATTACH_NUM)); foreach ($rows as $row) { if (isset($row[PR_ATTACH_NUM])) { $attach = mapi_message_openattach($fromMessage, $row[PR_ATTACH_NUM]); $newattach = mapi_message_createattach($toMessage); // Copy all attachments from old to new attachment $attachprops = mapi_getprops($attach); mapi_setprops($newattach, $attachprops); if (isset($attachprops[mapi_prop_tag(PT_ERROR, mapi_prop_id(PR_ATTACH_DATA_BIN))])) { // Data is in a stream $srcstream = mapi_openpropertytostream($attach, PR_ATTACH_DATA_BIN); $dststream = mapi_openpropertytostream($newattach, PR_ATTACH_DATA_BIN, MAPI_MODIFY | MAPI_CREATE); while (1) { $data = mapi_stream_read($srcstream, 4096); if (strlen($data) == 0) { break; } mapi_stream_write($dststream, $data); } mapi_stream_commit($dststream); } mapi_savechanges($newattach); } } }
function GetAttachmentData($attname) { list($folderid, $id, $attachnum) = explode(":", $attname); if (!isset($id) || !isset($attachnum)) { return false; } $sourcekey = hex2bin($id); $foldersourcekey = hex2bin($folderid); $entryid = mapi_msgstore_entryidfromsourcekey($this->_defaultstore, $foldersourcekey, $sourcekey); if (!$entryid) { debugLog("Attachment requested for non-existing item {$attname}"); return false; } $message = mapi_msgstore_openentry($this->_defaultstore, $entryid); if (!$message) { debugLog("Unable to open item for attachment data for " . bin2hex($entryid)); return false; } $attach = mapi_message_openattach($message, $attachnum); if (!$attach) { debugLog("Unable to open attachment number {$attachnum}"); return false; } $stream = mapi_openpropertytostream($attach, PR_ATTACH_DATA_BIN); if (!$stream) { debugLog("Unable to open attachment data stream"); return false; } while (1) { $data = mapi_stream_read($stream, 4096); if (strlen($data) == 0) { break; } print $data; } return true; }
function buildEMLAttachment($attach) { $msgembedded = mapi_attach_openobj($attach); $msgprops = mapi_getprops($msgembedded, array(PR_MESSAGE_CLASS, PR_CLIENT_SUBMIT_TIME, PR_DISPLAY_TO, PR_SUBJECT, PR_SENT_REPRESENTING_NAME, PR_SENT_REPRESENTING_EMAIL_ADDRESS)); $msgembeddedrcpttable = mapi_message_getrecipienttable($msgembedded); $msgto = $msgprops[PR_DISPLAY_TO]; if ($msgembeddedrcpttable) { $msgembeddedrecipients = mapi_table_queryrows($msgembeddedrcpttable, array(PR_ADDRTYPE, PR_ENTRYID, PR_DISPLAY_NAME, PR_EMAIL_ADDRESS, PR_SMTP_ADDRESS, PR_RECIPIENT_TYPE, PR_RECIPIENT_FLAGS, PR_PROPOSEDNEWTIME, PR_PROPOSENEWTIME_START, PR_PROPOSENEWTIME_END, PR_RECIPIENT_TRACKSTATUS), 0, 99999999); foreach ($msgembeddedrecipients as $rcpt) { if ($rcpt[PR_DISPLAY_NAME] == $msgprops[PR_DISPLAY_TO]) { $msgto = $rcpt[PR_DISPLAY_NAME]; if (isset($rcpt[PR_EMAIL_ADDRESS]) && $rcpt[PR_EMAIL_ADDRESS] != $msgprops[PR_DISPLAY_TO]) { $msgto .= " <" . $rcpt[PR_EMAIL_ADDRESS] . ">"; } break; } } } $msgsubject = $msgprops[PR_SUBJECT]; $msgfrom = $msgprops[PR_SENT_REPRESENTING_NAME]; if (isset($msgprops[PR_SENT_REPRESENTING_EMAIL_ADDRESS]) && $msgprops[PR_SENT_REPRESENTING_EMAIL_ADDRESS] != $msgprops[PR_SENT_REPRESENTING_NAME]) { $msgfrom .= " <" . $msgprops[PR_SENT_REPRESENTING_EMAIL_ADDRESS] . ">"; } $msgtime = $msgprops[PR_CLIENT_SUBMIT_TIME]; $msgembeddedbody = eml_ReadMessage($msgembedded); $msgembeddedattachtable = mapi_message_getattachmenttable($msgembedded); $msgembeddedattachtablerows = mapi_table_queryallrows($msgembeddedattachtable, array(PR_ATTACH_NUM, PR_ATTACH_METHOD)); if ($msgembeddedattachtablerows) { $boundary = '=_zpush_static'; $headercontenttype = "multipart/mixed"; $msgembeddedbody['body'] = "Unfortunately your mobile is not able to handle MIME Messages\n" . "--" . $boundary . "\n" . "Content-Type: " . $msgembeddedbody['content'] . "; charset=utf-8\n" . "Content-Transfer-Encoding: quoted-printable\n\n" . $msgembeddedbody['body'] . "\n"; foreach ($msgembeddedattachtablerows as $msgembeddedattachtablerow) { $msgembeddedattach = mapi_message_openattach($msgembedded, $msgembeddedattachtablerow[PR_ATTACH_NUM]); if (!$msgembeddedattach) { debugLog("Unable to open attachment number {$attachnum}"); } else { $msgembeddedattachprops = mapi_getprops($msgembeddedattach, array(PR_ATTACH_MIME_TAG, PR_ATTACH_LONG_FILENAME, PR_ATTACH_FILENAME, PR_DISPLAY_NAME)); if (isset($msgembeddedattachprops[PR_ATTACH_LONG_FILENAME])) { $attachfilename = w2u($msgembeddedattachprops[PR_ATTACH_LONG_FILENAME]); } else { if (isset($msgembeddedattachprops[PR_ATTACH_FILENAME])) { $attachfilename = w2u($msgembeddedattachprops[PR_ATTACH_FILENAME]); } else { if (isset($msgembeddedattachprops[PR_DISPLAY_NAME])) { $attachfilename = w2u($msgembeddedattachprops[PR_DISPLAY_NAME]); } else { $attachfilename = w2u("untitled"); } } } if ($msgembeddedattachtablerow[PR_ATTACH_METHOD] == ATTACH_EMBEDDED_MSG) { $attachfilename .= w2u(".eml"); } $msgembeddedbody['body'] .= "--" . $boundary . "\n" . "Content-Type: " . $msgembeddedattachprops[PR_ATTACH_MIME_TAG] . ";\n" . " name=\"" . $attachfilename . "\"\n" . "Content-Transfer-Encoding: base64\n" . "Content-Disposition: attachment;\n" . " filename=\"" . $attachfilename . "\"\n\n"; $msgembeddedattachstream = mapi_openpropertytostream($msgembeddedattach, PR_ATTACH_DATA_BIN); $msgembeddedattachment = ""; while (1) { $msgembeddedattachdata = mapi_stream_read($msgembeddedattachstream, 4096); if (byte_strlen($msgembeddedattachdata) == 0) { break; } $msgembeddedattachment .= $msgembeddedattachdata; } $msgembeddedbody['body'] .= chunk_split(base64_encode($msgembeddedattachment)) . "\n"; unset($msgembeddedattachment); } } $msgembeddedbody['body'] .= "--" . $boundary . "--\n"; } else { $headercontenttype = $msgembeddedbody['content'] . "; charset=utf-8"; $boundary = ''; } $msgembeddedheader = "Subject: " . $msgsubject . "\n" . "From: " . $msgfrom . "\n" . "To: " . $msgto . "\n" . "Date: " . gmstrftime("%a, %d %b %Y %T +0000", $msgprops[PR_CLIENT_SUBMIT_TIME]) . "\n" . "MIME-Version: 1.0\n" . "Content-Type: " . $headercontenttype . ";\n" . ($boundary ? " boundary=\"" . $boundary . "\"\n" : "") . "\n"; $stream = mapi_stream_create(); mapi_stream_setsize($stream, byte_strlen($msgembeddedheader . $msgembeddedbody['body'])); mapi_stream_write($stream, $msgembeddedheader . $msgembeddedbody['body']); mapi_stream_seek($stream, 0, STREAM_SEEK_SET); return $stream; }
function GetAttachmentData($attname) { list($folderid, $id, $attachnum) = explode(":", $attname); if (!isset($id) || !isset($attachnum)) { return false; } $sourcekey = hex2bin($id); $foldersourcekey = hex2bin($folderid); $entryid = mapi_msgstore_entryidfromsourcekey($this->_defaultstore, $foldersourcekey, $sourcekey); if (!$entryid) { debugLog("Attachment requested for non-existing item {$attname}"); return false; } $message = mapi_msgstore_openentry($this->_defaultstore, $entryid); if (!$message) { debugLog("Unable to open item for attachment data for " . bin2hex($entryid)); return false; } $attach = mapi_message_openattach($message, $attachnum); if (!$attach) { debugLog("Unable to open attachment number {$attachnum}"); return false; } $attachtable = mapi_message_getattachmenttable($message); // START CHANGED dw2412 EML Attachment $rows = mapi_table_queryallrows($attachtable, array(PR_ATTACH_NUM, PR_ATTACH_METHOD)); foreach ($rows as $row) { if (isset($row[PR_ATTACH_NUM]) && $row[PR_ATTACH_NUM] == $attachnum) { if ($row[PR_ATTACH_METHOD] == ATTACH_EMBEDDED_MSG) { $stream = buildEMLAttachment($attach); } else { $stream = mapi_openpropertytostream($attach, PR_ATTACH_DATA_BIN); } } } // END CHANGED dw2412 EML Attachment if (!$stream) { debugLog("Unable to open attachment data stream"); return false; } while (1) { $data = mapi_stream_read($stream, 4096); if (strlen($data) == 0) { break; } print $data; } return true; }
/** * A wrapper for mapi_inetmapi_imtoinet function * * @param MAPIMessage $mapimessage * @param SyncObject $message * * @access private * @return boolean */ private function imtoinet($mapimessage, &$message) { if (function_exists("mapi_inetmapi_imtoinet")) { $addrBook = mapi_openaddressbook($this->session); $mstream = mapi_inetmapi_imtoinet($this->session, $addrBook, $mapimessage, array()); $mstreamstat = mapi_stream_stat($mstream); if ($mstreamstat['cb'] < MAX_EMBEDDED_SIZE) { if (Request::GetProtocolVersion() >= 12.0) { if (!isset($message->asbody)) { $message->asbody = new SyncBaseBody(); } //TODO data should be wrapped in a MapiStreamWrapper $message->asbody->data = mapi_stream_read($mstream, MAX_EMBEDDED_SIZE); $message->asbody->estimatedDataSize = $mstreamstat["cb"]; $message->asbody->truncated = 0; } else { $message->mimetruncated = 0; //TODO mimedata should be a wrapped in a MapiStreamWrapper $message->mimedata = mapi_stream_read($mstream, MAX_EMBEDDED_SIZE); $message->mimesize = $mstreamstat["cb"]; } unset($message->body, $message->bodytruncated); return true; } } return false; }
/** * Reads from a mapi stream, if it's set. If not, returns an empty string. * * @param resource $stream * @param int $size * * @access private * @return string */ private function mapiReadStream($stream, $size) { if (!$stream || $size == 0) { return ""; } return mapi_stream_read($stream, $size); }
/** * Reads from stream * * @param int $len amount of bytes to be read * * @access public * @return string */ public function stream_read($len) { $data = mapi_stream_read($this->mapistream, $len); $this->position += strlen($data); return $data; }
/** * Reads data of large properties from a stream * * @access public * * @param MAPIMessage $message * @param long $prop * @return string */ public static function readPropStream($message, $prop) { $stream = mapi_openproperty($message, $prop, IID_IStream, 0, 0); $data = ""; $string = ""; while (1) { $data = mapi_stream_read($stream, 1024); if (strlen($data) == 0) { break; } $string .= $data; } return $string; }
/** * Reads from stream * * @param int $len amount of bytes to be read * * @access public * @return string */ public function stream_read($len) { $len = $this->position + $len > $this->streamlength ? $this->streamlength - $this->position : $len; // read 4 additional bytes from the stream so we can always truncate correctly if ($this->toTruncate && $this->position + $len >= $this->streamlength) { $len += 4; } if ($this->mapistream) { $data = mapi_stream_read($this->mapistream, $len); } else { $data = ""; } $this->position += strlen($data); // we need to truncate UTF8 compatible if ftruncate() was called if ($this->toTruncate && $this->position >= $this->streamlength) { $data = Utils::Utf8_truncate($data, $this->streamlength); } return $data; }
/** * Reads data of large properties from a stream. * * @param MAPIMessage $message * @param long $prop * * @access private * @return string */ private function readPropStream($message, $prop) { $stream = mapi_openproperty($message, $prop, IID_IStream, 0, 0); $ret = mapi_last_hresult(); if ($ret == MAPI_E_NOT_FOUND) { $this->Log(sprintf("Kopano>readPropStream: property 0x%s not found. It is either empty or not set. It will be ignored.", str_pad(dechex($prop), 8, 0, STR_PAD_LEFT))); return ""; } elseif ($ret) { $this->Log("Kopano->readPropStream error opening stream: 0x%08X", $ret); return ""; } $data = ""; $string = ""; while (1) { $data = mapi_stream_read($stream, 1024); if (strlen($data) == 0) { break; } $string .= $data; } return $string; }