00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 require_once ('classes/OLE/PPS.php');
00024
00032 class OLE_PPS_Root extends OLE_PPS
00033 {
00038 var $_tmp_dir;
00039
00047 function OLE_PPS_Root($time_1st, $time_2nd, $raChild)
00048 {
00049 $this->_tmp_dir = '';
00050 $this->OLE_PPS(
00051 null,
00052 OLE::Asc2Ucs('Root Entry'),
00053 OLE_PPS_TYPE_ROOT,
00054 null,
00055 null,
00056 null,
00057 $time_1st,
00058 $time_2nd,
00059 null,
00060 $raChild);
00061 }
00062
00070 function setTempDir($dir)
00071 {
00072 if (is_dir($dir)) {
00073 $this->_tmp_dir = $dir;
00074 return true;
00075 }
00076 return false;
00077 }
00078
00088 function save($filename)
00089 {
00090
00091 $this->_BIG_BLOCK_SIZE = pow(2,
00092 ((isset($this->_BIG_BLOCK_SIZE))? $this->_adjust2($this->_BIG_BLOCK_SIZE) : 9));
00093 $this->_SMALL_BLOCK_SIZE= pow(2,
00094 ((isset($this->_SMALL_BLOCK_SIZE))? $this->_adjust2($this->_SMALL_BLOCK_SIZE): 6));
00095
00096
00097 if (($filename == '-') or ($filename == ''))
00098 {
00099 $this->_tmp_filename = tempnam($this->_tmp_dir, "OLE_PPS_Root");
00100 $this->_FILEH_ = @fopen($this->_tmp_filename,"w+b");
00101 if ($this->_FILEH_ == false) {
00102 return $this->raiseError("Can't create temporary file.");
00103 }
00104 }
00105 else
00106 {
00107 $this->_FILEH_ = @fopen($filename, "wb");
00108 if ($this->_FILEH_ == false) {
00109 return $this->raiseError("Can't open $filename. It may be in use or protected.");
00110 }
00111 }
00112
00113 $aList = array();
00114 $this->_savePpsSetPnt($aList);
00115
00116 list($iSBDcnt, $iBBcnt, $iPPScnt) = $this->_calcSize($aList);
00117
00118 $this->_saveHeader($iSBDcnt, $iBBcnt, $iPPScnt);
00119
00120
00121 $this->_data = $this->_makeSmallData($aList);
00122
00123
00124 $this->_saveBigData($iSBDcnt, $aList);
00125
00126 $this->_savePps($aList);
00127
00128 $this->_saveBbd($iSBDcnt, $iBBcnt, $iPPScnt);
00129
00130 if(($filename == '-') or ($filename == ''))
00131 {
00132 fseek($this->_FILEH_, 0);
00133 fpassthru($this->_FILEH_);
00134 @fclose($this->_FILEH_);
00135
00136 @unlink($this->_tmp_filename);
00137 }
00138 else {
00139 @fclose($this->_FILEH_);
00140 }
00141 return true;
00142 }
00143
00151 function _calcSize(&$raList)
00152 {
00153
00154 list($iSBDcnt, $iBBcnt, $iPPScnt) = array(0,0,0);
00155 $iSmallLen = 0;
00156 $iSBcnt = 0;
00157 for ($i = 0; $i < count($raList); $i++) {
00158 if($raList[$i]->Type == OLE_PPS_TYPE_FILE) {
00159 $raList[$i]->Size = $raList[$i]->_DataLen();
00160 if($raList[$i]->Size < OLE_DATA_SIZE_SMALL) {
00161 $iSBcnt += floor($raList[$i]->Size / $this->_SMALL_BLOCK_SIZE)
00162 + (($raList[$i]->Size % $this->_SMALL_BLOCK_SIZE)? 1: 0);
00163 }
00164 else {
00165 $iBBcnt += (floor($raList[$i]->Size / $this->_BIG_BLOCK_SIZE) +
00166 (($raList[$i]->Size % $this->_BIG_BLOCK_SIZE)? 1: 0));
00167 }
00168 }
00169 }
00170 $iSmallLen = $iSBcnt * $this->_SMALL_BLOCK_SIZE;
00171 $iSlCnt = floor($this->_BIG_BLOCK_SIZE / OLE_LONG_INT_SIZE);
00172 $iSBDcnt = floor($iSBcnt / $iSlCnt) + (($iSBcnt % $iSlCnt)? 1:0);
00173 $iBBcnt += (floor($iSmallLen / $this->_BIG_BLOCK_SIZE) +
00174 (( $iSmallLen % $this->_BIG_BLOCK_SIZE)? 1: 0));
00175 $iCnt = count($raList);
00176 $iBdCnt = $this->_BIG_BLOCK_SIZE / OLE_PPS_SIZE;
00177 $iPPScnt = (floor($iCnt/$iBdCnt) + (($iCnt % $iBdCnt)? 1: 0));
00178
00179 return array($iSBDcnt, $iBBcnt, $iPPScnt);
00180 }
00181
00190 function _adjust2($i2)
00191 {
00192 $iWk = log($i2)/log(2);
00193 return ($iWk > floor($iWk))? floor($iWk)+1:$iWk;
00194 }
00195
00204 function _saveHeader($iSBDcnt, $iBBcnt, $iPPScnt)
00205 {
00206 $FILE = $this->_FILEH_;
00207
00208
00209 $iBlCnt = $this->_BIG_BLOCK_SIZE / OLE_LONG_INT_SIZE;
00210 $i1stBdL = ($this->_BIG_BLOCK_SIZE - 0x4C) / OLE_LONG_INT_SIZE;
00211
00212 $iBdExL = 0;
00213 $iAll = $iBBcnt + $iPPScnt + $iSBDcnt;
00214 $iAllW = $iAll;
00215 $iBdCntW = floor($iAllW / $iBlCnt) + (($iAllW % $iBlCnt)? 1: 0);
00216 $iBdCnt = floor(($iAll + $iBdCntW) / $iBlCnt) + ((($iAllW+$iBdCntW) % $iBlCnt)? 1: 0);
00217
00218
00219 if ($iBdCnt >$i1stBdL)
00220 {
00221 while (1)
00222 {
00223 $iBdExL++;
00224 $iAllW++;
00225 $iBdCntW = floor($iAllW / $iBlCnt) + (($iAllW % $iBlCnt)? 1: 0);
00226 $iBdCnt = floor(($iAllW + $iBdCntW) / $iBlCnt) + ((($iAllW+$iBdCntW) % $iBlCnt)? 1: 0);
00227 if ($iBdCnt <= ($iBdExL*$iBlCnt+ $i1stBdL)) {
00228 break;
00229 }
00230 }
00231 }
00232
00233
00234 fwrite($FILE,
00235 "\xD0\xCF\x11\xE0\xA1\xB1\x1A\xE1"
00236 . "\x00\x00\x00\x00"
00237 . "\x00\x00\x00\x00"
00238 . "\x00\x00\x00\x00"
00239 . "\x00\x00\x00\x00"
00240 . pack("v", 0x3b)
00241 . pack("v", 0x03)
00242 . pack("v", -2)
00243 . pack("v", 9)
00244 . pack("v", 6)
00245 . pack("v", 0)
00246 . "\x00\x00\x00\x00"
00247 . "\x00\x00\x00\x00"
00248 . pack("V", $iBdCnt)
00249 . pack("V", $iBBcnt+$iSBDcnt)
00250 . pack("V", 0)
00251 . pack("V", 0x1000)
00252 . pack("V", 0)
00253 . pack("V", 1)
00254 );
00255
00256 if ($iBdCnt < $i1stBdL)
00257 {
00258 fwrite($FILE,
00259 pack("V", -2).
00260 pack("V", 0)
00261 );
00262 }
00263 else
00264 {
00265 fwrite($FILE, pack("V", $iAll+$iBdCnt) . pack("V", $iBdExL));
00266 }
00267
00268
00269 for ($i=0; $i<$i1stBdL and $i < $iBdCnt; $i++) {
00270 fwrite($FILE, pack("V", $iAll+$i));
00271 }
00272 if ($i < $i1stBdL)
00273 {
00274 for ($j = 0; $j < ($i1stBdL-$i); $j++) {
00275 fwrite($FILE, (pack("V", -1)));
00276 }
00277 }
00278 }
00279
00287 function _saveBigData($iStBlk, &$raList)
00288 {
00289 $FILE = $this->_FILEH_;
00290
00291
00292 for ($i = 0; $i < count($raList); $i++)
00293 {
00294 if($raList[$i]->Type != OLE_PPS_TYPE_DIR)
00295 {
00296 $raList[$i]->Size = $raList[$i]->_DataLen();
00297 if(($raList[$i]->Size >= OLE_DATA_SIZE_SMALL) or
00298 (($raList[$i]->Type == OLE_PPS_TYPE_ROOT) and isset($raList[$i]->_data)))
00299 {
00300
00301 if(isset($raList[$i]->_PPS_FILE))
00302 {
00303 $iLen = 0;
00304 fseek($raList[$i]->_PPS_FILE, 0);
00305 while($sBuff = fread($raList[$i]->_PPS_FILE, 4096))
00306 {
00307 $iLen += strlen($sBuff);
00308 fwrite($FILE, $sBuff);
00309 }
00310 }
00311 else {
00312 fwrite($FILE, $raList[$i]->_data);
00313 }
00314
00315 if ($raList[$i]->Size % $this->_BIG_BLOCK_SIZE)
00316 {
00317 for ($j = 0; $j < ($this->_BIG_BLOCK_SIZE - ($raList[$i]->Size % $this->_BIG_BLOCK_SIZE)); $j++) {
00318 fwrite($FILE, "\x00");
00319 }
00320 }
00321
00322 $raList[$i]->_StartBlock = $iStBlk;
00323 $iStBlk +=
00324 (floor($raList[$i]->Size / $this->_BIG_BLOCK_SIZE) +
00325 (($raList[$i]->Size % $this->_BIG_BLOCK_SIZE)? 1: 0));
00326 }
00327
00328 if (isset($raList[$i]->_PPS_FILE))
00329 {
00330 @fclose($raList[$i]->_PPS_FILE);
00331 $raList[$i]->_PPS_FILE = null;
00332 @unlink($raList[$i]->_tmp_filename);
00333 }
00334 }
00335 }
00336 }
00337
00344 function _makeSmallData(&$raList)
00345 {
00346 $sRes = '';
00347 $FILE = $this->_FILEH_;
00348 $iSmBlk = 0;
00349
00350 for ($i = 0; $i < count($raList); $i++)
00351 {
00352
00353 if ($raList[$i]->Type == OLE_PPS_TYPE_FILE)
00354 {
00355 if ($raList[$i]->Size <= 0) {
00356 continue;
00357 }
00358 if ($raList[$i]->Size < OLE_DATA_SIZE_SMALL)
00359 {
00360 $iSmbCnt = floor($raList[$i]->Size / $this->_SMALL_BLOCK_SIZE)
00361 + (($raList[$i]->Size % $this->_SMALL_BLOCK_SIZE)? 1: 0);
00362
00363 for ($j = 0; $j < ($iSmbCnt-1); $j++) {
00364 fwrite($FILE, pack("V", $j+$iSmBlk+1));
00365 }
00366 fwrite($FILE, pack("V", -2));
00367
00368
00369 if ($raList[$i]->_PPS_FILE)
00370 {
00371 fseek($raList[$i]->_PPS_FILE, 0);
00372 while ($sBuff = fread($raList[$i]->_PPS_FILE, 4096)) {
00373 $sRes .= $sBuff;
00374 }
00375 }
00376 else {
00377 $sRes .= $raList[$i]->_data;
00378 }
00379 if($raList[$i]->Size % $this->_SMALL_BLOCK_SIZE)
00380 {
00381 for ($j = 0; $j < ($this->_SMALL_BLOCK_SIZE - ($raList[$i]->Size % $this->_SMALL_BLOCK_SIZE)); $j++) {
00382 $sRes .= "\x00";
00383 }
00384 }
00385
00386 $raList[$i]->_StartBlock = $iSmBlk;
00387 $iSmBlk += $iSmbCnt;
00388 }
00389 }
00390 }
00391 $iSbCnt = floor($this->_BIG_BLOCK_SIZE / OLE_LONG_INT_SIZE);
00392 if($iSmBlk % $iSbCnt)
00393 {
00394 for ($i = 0; $i < ($iSbCnt - ($iSmBlk % $iSbCnt)); $i++) {
00395 fwrite($FILE, pack("V", -1));
00396 }
00397 }
00398 return $sRes;
00399 }
00400
00407 function _savePps(&$raList)
00408 {
00409
00410 for ($i = 0; $i < count($raList); $i++) {
00411 fwrite($this->_FILEH_, $raList[$i]->_getPpsWk());
00412 }
00413
00414 $iCnt = count($raList);
00415 $iBCnt = $this->_BIG_BLOCK_SIZE / OLE_PPS_SIZE;
00416 if ($iCnt % $iBCnt)
00417 {
00418 for ($i = 0; $i < (($iBCnt - ($iCnt % $iBCnt)) * OLE_PPS_SIZE); $i++) {
00419 fwrite($this->_FILEH_, "\x00");
00420 }
00421 }
00422 }
00423
00432 function _saveBbd($iSbdSize, $iBsize, $iPpsCnt)
00433 {
00434 $FILE = $this->_FILEH_;
00435
00436 $iBbCnt = $this->_BIG_BLOCK_SIZE / OLE_LONG_INT_SIZE;
00437 $i1stBdL = ($this->_BIG_BLOCK_SIZE - 0x4C) / OLE_LONG_INT_SIZE;
00438
00439 $iBdExL = 0;
00440 $iAll = $iBsize + $iPpsCnt + $iSbdSize;
00441 $iAllW = $iAll;
00442 $iBdCntW = floor($iAllW / $iBbCnt) + (($iAllW % $iBbCnt)? 1: 0);
00443 $iBdCnt = floor(($iAll + $iBdCntW) / $iBbCnt) + ((($iAllW+$iBdCntW) % $iBbCnt)? 1: 0);
00444
00445 if ($iBdCnt >$i1stBdL)
00446 {
00447 while (1)
00448 {
00449 $iBdExL++;
00450 $iAllW++;
00451 $iBdCntW = floor($iAllW / $iBbCnt) + (($iAllW % $iBbCnt)? 1: 0);
00452 $iBdCnt = floor(($iAllW + $iBdCntW) / $iBbCnt) + ((($iAllW+$iBdCntW) % $iBbCnt)? 1: 0);
00453 if ($iBdCnt <= ($iBdExL*$iBbCnt+ $i1stBdL)) {
00454 break;
00455 }
00456 }
00457 }
00458
00459
00460
00461 if ($iSbdSize > 0)
00462 {
00463 for ($i = 0; $i<($iSbdSize-1); $i++) {
00464 fwrite($FILE, pack("V", $i+1));
00465 }
00466 fwrite($FILE, pack("V", -2));
00467 }
00468
00469 for ($i = 0; $i<($iBsize-1); $i++) {
00470 fwrite($FILE, pack("V", $i+$iSbdSize+1));
00471 }
00472 fwrite($FILE, pack("V", -2));
00473
00474
00475 for ($i = 0; $i<($iPpsCnt-1); $i++) {
00476 fwrite($FILE, pack("V", $i+$iSbdSize+$iBsize+1));
00477 }
00478 fwrite($FILE, pack("V", -2));
00479
00480 for ($i=0; $i<$iBdCnt;$i++) {
00481 fwrite($FILE, pack("V", 0xFFFFFFFD));
00482 }
00483
00484 for ($i=0; $i<$iBdExL;$i++) {
00485 fwrite($FILE, pack("V", 0xFFFFFFFC));
00486 }
00487
00488 if (($iAllW + $iBdCnt) % $iBbCnt)
00489 {
00490 for ($i = 0; $i < ($iBbCnt - (($iAllW + $iBdCnt) % $iBbCnt)); $i++) {
00491 fwrite($FILE, pack("V", -1));
00492 }
00493 }
00494
00495 if ($iBdCnt > $i1stBdL)
00496 {
00497 $iN=0;
00498 $iNb=0;
00499 for ($i=$i1stBdL;$i<$iBdCnt; $i++, $iN++)
00500 {
00501 if ($iN>=($iBbCnt-1))
00502 {
00503 $iN = 0;
00504 $iNb++;
00505 fwrite($FILE, pack("V", $iAll+$iBdCnt+$iNb));
00506 }
00507 fwrite($FILE, pack("V", $iBsize+$iSbdSize+$iPpsCnt+$i));
00508 }
00509 if (($iBdCnt-$i1stBdL) % ($iBbCnt-1))
00510 {
00511 for ($i = 0; $i < (($iBbCnt-1) - (($iBdCnt-$i1stBdL) % ($iBbCnt-1))); $i++) {
00512 fwrite($FILE, pack("V", -1));
00513 }
00514 }
00515 fwrite($FILE, pack("V", -2));
00516 }
00517 }
00518 }
00519 ?>