Exemplo n.º 1
0
function GetPropIDFromString($store, $mapiprop)
{
    if (is_string($mapiprop)) {
        $split = explode(":", $mapiprop);
        if (count($split) != 3) {
            continue;
        }
        if (substr($split[2], 0, 2) == "0x") {
            $id = hexdec(substr($split[2], 2));
        } else {
            $id = $split[2];
        }
        $named = mapi_getidsfromnames($store, array($id), array(makeguid($split[1])));
        $mapiprop = mapi_prop_tag(constant($split[0]), mapi_prop_id($named[0]));
    } else {
        return $mapiprop;
    }
    return $mapiprop;
}
Exemplo n.º 2
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;
 }
Exemplo n.º 3
0
 * versions of the software.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */
define('IID_IStream', makeguid("{0000000c-0000-0000-c000-000000000046}"));
define('IID_IMAPITable', makeguid("{00020301-0000-0000-c000-000000000046}"));
define('IID_IMessage', makeguid("{00020307-0000-0000-c000-000000000046}"));
define('IID_IExchangeExportChanges', makeguid("{a3ea9cc0-d1b2-11cd-80fc-00aa004bba0b}"));
define('IID_IExchangeImportContentsChanges', makeguid("{f75abfa0-d0e0-11cd-80fc-00aa004bba0b}"));
define('IID_IExchangeImportHierarchyChanges', makeguid("{85a66cf0-d0e0-11cd-80fc-00aa004bba0b}"));
define('PSETID_Appointment', makeguid("{00062002-0000-0000-C000-000000000046}"));
define('PSETID_Task', makeguid("{00062003-0000-0000-C000-000000000046}"));
define('PSETID_Address', makeguid("{00062004-0000-0000-C000-000000000046}"));
define('PSETID_Common', makeguid("{00062008-0000-0000-C000-000000000046}"));
define('PSETID_Log', makeguid("{0006200A-0000-0000-C000-000000000046}"));
define('PSETID_Note', makeguid("{0006200E-0000-0000-C000-000000000046}"));
define('PSETID_Meeting', makeguid("{6ED8DA90-450B-101B-98DA-00AA003F1305}"));
define('PSETID_Archive', makeguid("{72E98EBC-57D2-4AB5-B0AA-D50A7B531CB9}"));
define('PS_MAPI', makeguid("{00020328-0000-0000-C000-000000000046}"));
define('PS_PUBLIC_STRINGS', makeguid("{00020329-0000-0000-C000-000000000046}"));
define('PS_INTERNET_HEADERS', makeguid("{00020386-0000-0000-c000-000000000046}"));
// sk added for Z-Push
define('PSETID_AirSync', makeguid("{71035549-0739-4DCB-9163-00F0580DBBDF}"));
Exemplo n.º 4
0
<?php

define('IID_IStream', makeguid("{0000000c-0000-0000-c000-000000000046}"));
define('IID_IMAPITable', makeguid("{00020301-0000-0000-c000-000000000046}"));
define('IID_IMessage', makeguid("{00020307-0000-0000-c000-000000000046}"));
define('IID_IExchangeExportChanges', makeguid("{a3ea9cc0-d1b2-11cd-80fc-00aa004bba0b}"));
define('IID_IExchangeImportContentsChanges', makeguid("{f75abfa0-d0e0-11cd-80fc-00aa004bba0b}"));
define('IID_IExchangeImportHierarchyChanges', makeguid("{85a66cf0-d0e0-11cd-80fc-00aa004bba0b}"));
define('PSETID_Appointment', makeguid("{00062002-0000-0000-C000-000000000046}"));
define('PSETID_Task', makeguid("{00062003-0000-0000-C000-000000000046}"));
define('PSETID_Address', makeguid("{00062004-0000-0000-C000-000000000046}"));
define('PSETID_Common', makeguid("{00062008-0000-0000-C000-000000000046}"));
define('PSETID_Log', makeguid("{0006200A-0000-0000-C000-000000000046}"));
define('PSETID_Note', makeguid("{0006200E-0000-0000-C000-000000000046}"));
define('PSETID_Meeting', makeguid("{6ED8DA90-450B-101B-98DA-00AA003F1305}"));
define('PSETID_Archive', makeguid("{72E98EBC-57D2-4AB5-B0AA-D50A7B531CB9}"));
define('PS_MAPI', makeguid("{00020328-0000-0000-C000-000000000046}"));
define('PS_PUBLIC_STRINGS', makeguid("{00020329-0000-0000-C000-000000000046}"));
define('PS_INTERNET_HEADERS', makeguid("{00020386-0000-0000-c000-000000000046}"));
define('MUIDECSAB', makeguid("{50A921AC-D340-48ee-B319-FBA753304425}"));
// Zarafa Contact Provider GUIDs
define('MUIDZCSAB', makeguid("{30047F72-92E3-DA4F-B86A-E52A7FE46571}"));
Exemplo n.º 5
0
 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;
 }
Exemplo n.º 6
0
/**
 * Parses properties from an array of strings. Each "string" may be either an ULONG, which is a direct property ID,
 * or a string with format "PT_TYPE:{GUID}:StringId" or "PT_TYPE:{GUID}:0xXXXX" for named
 * properties.
 *
 * @returns array of properties
 */
function getPropIdsFromStrings($store, $mapping)
{
    $props = array();
    $ids = array("name" => array(), "id" => array(), "guid" => array(), "type" => array());
    // this array stores all the information needed to retrieve a named property
    $num = 0;
    // caching
    $guids = array();
    foreach ($mapping as $name => $val) {
        if (is_string($val)) {
            $split = explode(":", $val);
            if (count($split) != 3) {
                // invalid string, ignore
                trigger_error(sprintf("Invalid property: %s \"%s\"", $name, $val), E_USER_NOTICE);
                continue;
            }
            if (substr($split[2], 0, 2) == "0x") {
                $id = hexdec(substr($split[2], 2));
            } else {
                $id = $split[2];
            }
            // have we used this guid before?
            if (!defined($split[1])) {
                if (!array_key_exists($split[1], $guids)) {
                    $guids[$split[1]] = makeguid($split[1]);
                }
                $guid = $guids[$split[1]];
            } else {
                $guid = constant($split[1]);
            }
            // temp store info about named prop, so we have to call mapi_getidsfromnames just one time
            $ids["name"][$num] = $name;
            $ids["id"][$num] = $id;
            $ids["guid"][$num] = $guid;
            $ids["type"][$num] = $split[0];
            $num++;
        } else {
            // not a named property
            $props[$name] = $val;
        }
    }
    if (empty($ids["id"])) {
        return $props;
    }
    // get the ids
    $named = mapi_getidsfromnames($store, $ids["id"], $ids["guid"]);
    foreach ($named as $num => $prop) {
        $props[$ids["name"][$num]] = mapi_prop_tag(constant($ids["type"][$num]), mapi_prop_id($prop));
    }
    return $props;
}
function mapidefs()
{
    define("ZARAFA_SERVICE_GUID", makeguid("{3C253DCA-D227-443C-94FE-425FAB958C19}"));
    // default store
    define("ZARAFA_STORE_PUBLIC_GUID", makeguid("{D47F4A09-D3BD-493C-B2FC-3C90BBCB48D4}"));
    // public store
    define('RES_PROPERTY', 4);
    define('RELOP_EQ', 4);
    define('VALUE', 0);
    // propval
    define('RELOP', 1);
    // compare method
    define('ULPROPTAG', 6);
    // property
    define('MV_FLAG', 0x1000);
    define('PT_STRING8', 30);
    /* Null terminated 8-bit character string */
    define('PT_TSTRING', PT_STRING8);
    define('PT_LONG', 3);
    /* Signed 32-bit value */
    define('PT_BINARY', 258);
    /* Uninterpreted (counted byte array) */
    define('PT_MV_LONG', MV_FLAG | PT_LONG);
    define('DEL_ASSOCIATED', 0x8);
    define('PT_BOOLEAN', 11);
    /* 16-bit boolean (non-zero true) */
    define('PT_SYSTIME', 64);
    /* FILETIME 64-bit int w/ number of 100ns periods since Jan 1,1601 */
    define('PT_MV_STRING8', MV_FLAG | PT_STRING8);
    define('PT_MV_BINARY', MV_FLAG | PT_BINARY);
    define('PSETID_Address', makeguid("{00062004-0000-0000-C000-000000000046}"));
    define('PSETID_Common', makeguid("{00062008-0000-0000-C000-000000000046}"));
    define('PS_PUBLIC_STRINGS', makeguid("{00020329-0000-0000-C000-000000000046}"));
    define('STORE_UNICODE_OK', 0x40000);
    // The message store supports properties containing Unicode characters.
}