2017-09-22 21:24:31 +02:00
|
|
|
<?php
|
|
|
|
/*
|
2019-01-05 01:25:25 +01:00
|
|
|
Copyright 2019 UUP dump API authors
|
2017-09-22 21:24:31 +02:00
|
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
you may not use this file except in compliance with the License.
|
|
|
|
You may obtain a copy of the License at
|
|
|
|
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
See the License for the specific language governing permissions and
|
|
|
|
limitations under the License.
|
|
|
|
*/
|
|
|
|
|
2017-09-29 23:40:56 +02:00
|
|
|
require_once dirname(__FILE__).'/shared/main.php';
|
|
|
|
require_once dirname(__FILE__).'/shared/requests.php';
|
2017-12-20 17:35:14 +01:00
|
|
|
require_once dirname(__FILE__).'/shared/packs.php';
|
2017-09-23 17:47:19 +02:00
|
|
|
|
2018-11-16 17:59:48 +01:00
|
|
|
function uupGetFiles(
|
|
|
|
$updateId = 'c2a1d787-647b-486d-b264-f90f3782cdc6',
|
|
|
|
$usePack = 0,
|
|
|
|
$desiredEdition = 0,
|
|
|
|
$cacheRequests = 0
|
|
|
|
) {
|
2017-09-23 17:47:19 +02:00
|
|
|
uupApiPrintBrand();
|
2017-09-22 21:24:31 +02:00
|
|
|
|
2017-12-20 17:35:14 +01:00
|
|
|
$info = @file_get_contents('fileinfo/'.$updateId.'.json');
|
|
|
|
if(empty($info)) {
|
|
|
|
$info = array(
|
|
|
|
'ring' => 'WIF',
|
|
|
|
'flight' => 'Active',
|
2018-04-11 18:01:27 +02:00
|
|
|
'arch' => 'amd64',
|
2017-12-20 17:35:14 +01:00
|
|
|
'checkBuild' => '10.0.16251.0',
|
2018-04-29 21:33:19 +02:00
|
|
|
'sku' => '48',
|
2017-12-20 17:35:14 +01:00
|
|
|
'files' => array(),
|
|
|
|
);
|
|
|
|
} else {
|
|
|
|
$info = json_decode($info, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
if(isset($info['build'])) {
|
|
|
|
$build = explode('.', $info['build']);
|
|
|
|
$build = $build[0];
|
|
|
|
} else {
|
|
|
|
$build = 9841;
|
|
|
|
}
|
|
|
|
|
2018-04-29 21:33:19 +02:00
|
|
|
if(!isset($info['sku'])) {
|
|
|
|
$info['sku'] = 48;
|
|
|
|
}
|
|
|
|
|
2017-09-22 21:24:31 +02:00
|
|
|
if($usePack) {
|
2019-01-05 01:25:25 +01:00
|
|
|
$genPack = uupGetGenPacks($build, $info['arch'], $updateId);
|
|
|
|
if(empty($genPack)) return array('error' => 'UNSUPPORTED_COMBINATION');
|
|
|
|
|
|
|
|
if(!isset($genPack[$usePack])) {
|
2017-09-22 21:24:31 +02:00
|
|
|
return array('error' => 'UNSUPPORTED_LANG');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-10-16 18:03:26 +02:00
|
|
|
$desiredEdition = strtoupper($desiredEdition);
|
2019-01-05 01:25:25 +01:00
|
|
|
$fileListSource = $desiredEdition;
|
2017-09-22 21:24:31 +02:00
|
|
|
|
2018-03-17 22:20:20 +01:00
|
|
|
switch($desiredEdition) {
|
2018-04-29 21:33:19 +02:00
|
|
|
case '0':
|
2019-01-05 01:25:25 +01:00
|
|
|
if($usePack) {
|
|
|
|
$fileListSource = 'GENERATEDPACKS';
|
2018-04-29 21:33:19 +02:00
|
|
|
|
|
|
|
$filesList = array();
|
|
|
|
foreach($genPack[$usePack] as $val) {
|
|
|
|
foreach($val as $package) {
|
|
|
|
$filesList[] = $package;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
array_unique($filesList);
|
|
|
|
sort($filesList);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2018-03-17 22:20:20 +01:00
|
|
|
case 'WUBFILE': break;
|
2017-09-22 21:24:31 +02:00
|
|
|
|
2018-10-31 18:21:10 +01:00
|
|
|
case 'UPDATEONLY': break;
|
2017-09-22 21:24:31 +02:00
|
|
|
|
2018-03-17 22:20:20 +01:00
|
|
|
default:
|
2019-01-05 01:25:25 +01:00
|
|
|
if(!isset($genPack[$usePack][$desiredEdition])) {
|
2018-03-17 22:20:20 +01:00
|
|
|
return array('error' => 'UNSUPPORTED_COMBINATION');
|
|
|
|
}
|
|
|
|
|
2019-01-05 01:25:25 +01:00
|
|
|
$filesList = $genPack[$usePack][$desiredEdition];
|
|
|
|
$fileListSource = 'GENERATEDPACKS';
|
2018-03-17 22:20:20 +01:00
|
|
|
break;
|
2017-10-16 18:03:26 +02:00
|
|
|
}
|
|
|
|
|
2018-11-16 17:59:48 +01:00
|
|
|
$cacheHash = hash('sha1', strtolower("api-get-$updateId"));
|
|
|
|
$cached = 0;
|
|
|
|
|
2017-10-23 22:53:33 +02:00
|
|
|
$rev = 1;
|
|
|
|
if(preg_match('/_rev\./', $updateId)) {
|
|
|
|
$rev = preg_replace('/.*_rev\./', '', $updateId);
|
|
|
|
$updateId = preg_replace('/_rev\..*/', '', $updateId);
|
|
|
|
}
|
|
|
|
|
2018-10-11 21:48:46 +02:00
|
|
|
$updateArch = (isset($info['arch'])) ? $info['arch'] : 'UNKNOWN';
|
|
|
|
$updateBuild = (isset($info['build'])) ? $info['build'] : 'UNKNOWN';
|
|
|
|
$updateName = (isset($info['title'])) ? $info['title'] : 'Unknown update: '.$updateId;
|
|
|
|
|
2018-11-16 17:59:48 +01:00
|
|
|
if(file_exists('cache/'.$cacheHash.'.json.gz') && $cacheRequests == 1) {
|
|
|
|
$cache = @gzdecode(@file_get_contents('cache/'.$cacheHash.'.json.gz'));
|
|
|
|
$cache = json_decode($cache, 1);
|
|
|
|
|
|
|
|
if(!empty($cache['content']) && ($cache['expires'] > time())) {
|
|
|
|
consoleLogger('Using cached response...');
|
|
|
|
$out = $cache['content'];
|
|
|
|
$fetchTime = $cache['fetchTime'];
|
|
|
|
$cached = 1;
|
|
|
|
} else {
|
|
|
|
$cached = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
unset($cache);
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!$cached) {
|
|
|
|
$fetchTime = time();
|
|
|
|
consoleLogger('Fetching information from the server...');
|
|
|
|
$postData = composeFileGetRequest($updateId, uupDevice(), $info, $rev);
|
|
|
|
$out = sendWuPostRequest('https://fe3.delivery.mp.microsoft.com/ClientWebService/client.asmx/secured', $postData);
|
|
|
|
consoleLogger('Information has been successfully fetched.');
|
|
|
|
|
|
|
|
if($cacheRequests == 1) {
|
|
|
|
$cache = array(
|
|
|
|
'expires' => time()+90,
|
|
|
|
'content' => $out,
|
|
|
|
'fetchTime' => $fetchTime,
|
|
|
|
);
|
|
|
|
|
|
|
|
if(!file_exists('cache')) mkdir('cache');
|
|
|
|
@file_put_contents('cache/'.$cacheHash.'.json.gz', gzencode(json_encode($cache)."\n"));
|
|
|
|
|
|
|
|
unset($cache);
|
|
|
|
}
|
|
|
|
}
|
2017-09-22 21:24:31 +02:00
|
|
|
|
|
|
|
consoleLogger('Parsing information...');
|
2018-11-16 21:29:29 +01:00
|
|
|
$xmlOut = @simplexml_load_string($out);
|
|
|
|
if($xmlOut === false) {
|
2018-11-16 21:51:54 +01:00
|
|
|
@unlink('cache/'.$cacheHash.'.json.gz');
|
|
|
|
return array('error' => 'XML_PARSE_ERROR');
|
2018-11-16 21:29:29 +01:00
|
|
|
}
|
|
|
|
|
2018-10-11 21:48:46 +02:00
|
|
|
$xmlBody = $xmlOut->children('s', true)->Body->children();
|
|
|
|
|
|
|
|
if(!isset($xmlBody->GetExtendedUpdateInfo2Response)) {
|
2017-10-01 16:06:01 +02:00
|
|
|
consoleLogger('An error has occurred');
|
2017-09-22 21:24:31 +02:00
|
|
|
return array('error' => 'EMPTY_FILELIST');
|
|
|
|
}
|
|
|
|
|
2018-10-11 21:48:46 +02:00
|
|
|
$getResponse = $xmlBody->GetExtendedUpdateInfo2Response;
|
|
|
|
$getResult = $getResponse->GetExtendedUpdateInfo2Result;
|
|
|
|
|
|
|
|
if(!isset($getResult->FileLocations)) {
|
|
|
|
consoleLogger('An error has occurred');
|
|
|
|
return array('error' => 'EMPTY_FILELIST');
|
|
|
|
}
|
2018-03-29 19:41:22 +02:00
|
|
|
|
2018-10-11 21:48:46 +02:00
|
|
|
$fileLocations = $getResult->FileLocations;
|
2017-09-22 21:24:31 +02:00
|
|
|
$info = $info['files'];
|
|
|
|
|
|
|
|
$files = array();
|
2018-10-11 21:48:46 +02:00
|
|
|
foreach($fileLocations->FileLocation as $val) {
|
|
|
|
$sha1 = bin2hex(base64_decode((string)$val->FileDigest));
|
|
|
|
$url = (string)$val->Url;
|
2017-09-22 21:24:31 +02:00
|
|
|
|
2018-10-11 21:48:46 +02:00
|
|
|
preg_match('/files\/(.{8}-.{4}-.{4}-.{4}-.{12})/', $url, $guid);
|
|
|
|
$guid = $guid[1];
|
2017-09-22 21:24:31 +02:00
|
|
|
|
|
|
|
if(empty($info[$sha1]['name'])) {
|
|
|
|
$name = $guid;
|
|
|
|
} else {
|
|
|
|
$name = $info[$sha1]['name'];
|
|
|
|
}
|
|
|
|
|
|
|
|
if(empty($info[$sha1]['name'])) {
|
2017-11-03 19:33:17 +01:00
|
|
|
$size = -1;
|
2017-09-22 21:24:31 +02:00
|
|
|
} else {
|
|
|
|
$size = $info[$sha1]['size'];
|
|
|
|
}
|
|
|
|
|
2017-11-03 19:33:17 +01:00
|
|
|
if(!isset($fileSizes[$name])) $fileSizes[$name] = -2;
|
2017-09-22 21:24:31 +02:00
|
|
|
|
2017-10-27 21:38:31 +02:00
|
|
|
if($size > $fileSizes[$name]) {
|
2018-10-11 21:48:46 +02:00
|
|
|
preg_match('/P1=(.*?)&/', $url, $expire);
|
2017-10-27 21:38:31 +02:00
|
|
|
if(isset($expire[0])) {
|
2018-10-11 21:48:46 +02:00
|
|
|
$expire = $expire[1];
|
2017-10-16 18:03:26 +02:00
|
|
|
}
|
2017-10-27 21:38:31 +02:00
|
|
|
|
2017-11-03 19:33:17 +01:00
|
|
|
$expire = intval($expire);
|
|
|
|
|
|
|
|
if($size < 0) {
|
|
|
|
$temp = ($expire - $fetchTime) / 600;
|
|
|
|
$size = ($temp - 1) * 31457280;
|
|
|
|
if($size < 0) $size = 0;
|
|
|
|
unset($temp);
|
|
|
|
}
|
|
|
|
|
2017-10-27 21:38:31 +02:00
|
|
|
$fileSizes[$name] = $size;
|
|
|
|
|
|
|
|
$temp = array();
|
|
|
|
$temp['sha1'] = $sha1;
|
|
|
|
$temp['size'] = $size;
|
|
|
|
$temp['url'] = $url;
|
|
|
|
$temp['uuid'] = $guid;
|
2017-11-03 19:33:17 +01:00
|
|
|
$temp['expire'] = $expire;
|
2017-10-27 21:38:31 +02:00
|
|
|
|
2018-09-13 11:43:00 +02:00
|
|
|
$newName = preg_replace('/^cabs_|^metadataesd_|~31bf3856ad364e35/i', '', $name);
|
2017-10-27 21:38:31 +02:00
|
|
|
$newName = preg_replace('/~~\.|~\./', '.', $newName);
|
|
|
|
$newName = preg_replace('/~/', '-', $newName);
|
2018-06-14 20:38:34 +02:00
|
|
|
$newName = strtolower($newName);
|
2017-10-27 21:38:31 +02:00
|
|
|
|
|
|
|
$files[$newName] = $temp;
|
2017-09-22 21:24:31 +02:00
|
|
|
}
|
|
|
|
}
|
2017-10-28 23:10:21 +02:00
|
|
|
unset($temp, $newName);
|
2017-09-22 21:24:31 +02:00
|
|
|
|
2018-08-30 20:17:36 +02:00
|
|
|
$baseless = preg_grep('/^baseless_|-baseless\....$/i', array_keys($files));
|
2018-05-04 21:24:27 +02:00
|
|
|
foreach($baseless as $val) {
|
|
|
|
if(isset($files[$val])) unset($files[$val]);
|
|
|
|
}
|
|
|
|
|
2017-10-27 21:38:31 +02:00
|
|
|
$psf = array_keys($files);
|
|
|
|
$psf = preg_grep('/\.psf$/i', $psf);
|
|
|
|
|
|
|
|
$removeFiles = array();
|
|
|
|
foreach($psf as $val) {
|
|
|
|
$name = preg_replace('/\.psf$/i', '', $val);
|
2018-05-04 21:24:27 +02:00
|
|
|
$removeFiles[] = $name;
|
2017-10-27 21:38:31 +02:00
|
|
|
unset($files[$val]);
|
|
|
|
}
|
2017-10-28 23:10:21 +02:00
|
|
|
unset($index, $name, $psf);
|
2017-10-27 21:38:31 +02:00
|
|
|
|
2017-10-28 23:10:21 +02:00
|
|
|
$temp = preg_grep('/'.$updateArch.'_.*|arm64.arm_.*/i', $removeFiles);
|
|
|
|
foreach($temp as $key => $val) {
|
|
|
|
if(isset($files[$val.'.cab'])) unset($files[$val.'.cab']);
|
|
|
|
unset($removeFiles[$key]);
|
|
|
|
}
|
|
|
|
unset($temp);
|
2017-10-25 20:31:18 +02:00
|
|
|
|
2017-10-28 23:10:21 +02:00
|
|
|
foreach($removeFiles as $val) {
|
|
|
|
if(isset($files[$val.'.esd'])) {
|
2017-10-27 21:38:31 +02:00
|
|
|
if(isset($files[$val.'.cab'])) unset($files[$val.'.cab']);
|
|
|
|
}
|
2017-09-22 21:24:31 +02:00
|
|
|
}
|
2017-10-28 23:10:21 +02:00
|
|
|
unset($removeFiles);
|
2017-09-22 21:24:31 +02:00
|
|
|
|
|
|
|
$filesKeys = array_keys($files);
|
2017-10-16 18:03:26 +02:00
|
|
|
|
2019-01-05 01:25:25 +01:00
|
|
|
switch($fileListSource) {
|
2018-03-17 22:20:20 +01:00
|
|
|
case 'UPDATEONLY':
|
|
|
|
$skipPackBuild = 1;
|
|
|
|
$removeFiles = preg_grep('/Windows10\.0-KB.*-EXPRESS/i', $filesKeys);
|
|
|
|
|
|
|
|
foreach($removeFiles as $val) {
|
|
|
|
if(isset($files[$val])) unset($files[$val]);
|
|
|
|
}
|
|
|
|
|
|
|
|
unset($removeFiles, $temp);
|
|
|
|
$filesKeys = array_keys($files);
|
|
|
|
|
|
|
|
$filesKeys = preg_grep('/Windows10\.0-KB/i', $filesKeys);
|
2018-10-31 18:21:10 +01:00
|
|
|
if(count($filesKeys) == 0) {
|
|
|
|
return array('error' => 'NOT_CUMULATIVE_UPDATE');
|
|
|
|
}
|
2018-03-17 22:20:20 +01:00
|
|
|
break;
|
2017-10-16 18:03:26 +02:00
|
|
|
|
2018-03-17 22:20:20 +01:00
|
|
|
case 'WUBFILE':
|
|
|
|
$skipPackBuild = 1;
|
|
|
|
$filesKeys = preg_grep('/WindowsUpdateBox.exe/i', $filesKeys);
|
|
|
|
break;
|
2017-10-16 18:03:26 +02:00
|
|
|
}
|
|
|
|
|
2019-01-05 01:25:25 +01:00
|
|
|
if($fileListSource == 'GENERATEDPACKS') {
|
2018-05-15 21:17:11 +02:00
|
|
|
$temp = preg_grep('/Windows10\.0-KB.*-EXPRESS/i', $filesKeys, PREG_GREP_INVERT);
|
|
|
|
$temp = preg_grep('/Windows10\.0-KB/i', $temp);
|
|
|
|
$filesList = array_merge($filesList, $temp);
|
|
|
|
|
2018-04-29 21:33:19 +02:00
|
|
|
$newFiles = array();
|
|
|
|
foreach($filesList as $val) {
|
|
|
|
$name = preg_replace('/~31bf3856ad364e35/', '', $val);
|
|
|
|
$name = preg_replace('/~~\.|~\./', '.', $name);
|
|
|
|
$name = preg_replace('/~/', '-', $name);
|
2018-06-14 20:38:34 +02:00
|
|
|
$name = strtolower($name);
|
2018-04-29 21:33:19 +02:00
|
|
|
|
2019-01-05 01:25:25 +01:00
|
|
|
if(isset($files[$name])) {
|
|
|
|
$newFiles[$name] = $files[$name];
|
|
|
|
}
|
2018-04-29 21:33:19 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
$files = $newFiles;
|
|
|
|
$filesKeys = array_keys($files);
|
|
|
|
}
|
|
|
|
|
2017-10-06 16:03:39 +02:00
|
|
|
if(empty($filesKeys)) {
|
|
|
|
return array('error' => 'NO_FILES');
|
|
|
|
}
|
|
|
|
|
2017-09-22 21:24:31 +02:00
|
|
|
foreach($filesKeys as $val) {
|
|
|
|
$filesNew[$val] = $files[$val];
|
|
|
|
}
|
|
|
|
|
|
|
|
$files = $filesNew;
|
|
|
|
ksort($files);
|
|
|
|
|
|
|
|
consoleLogger('Successfully parsed the information.');
|
|
|
|
|
|
|
|
return array(
|
2017-09-23 17:47:19 +02:00
|
|
|
'apiVersion' => uupApiVersion(),
|
|
|
|
'updateName' => $updateName,
|
2017-09-30 23:04:30 +02:00
|
|
|
'arch' => $updateArch,
|
2018-03-29 19:41:22 +02:00
|
|
|
'build' => $updateBuild,
|
2017-09-22 21:24:31 +02:00
|
|
|
'files' => $files,
|
|
|
|
);
|
|
|
|
}
|