forked from uup-dump/api
Compare commits
99 Commits
sha256-san
...
master
Author | SHA1 | Date | |
---|---|---|---|
7b3cd4eb10 | |||
c1f00cecbd | |||
8b576e4496 | |||
21b1500490 | |||
fb2c89b2f8 | |||
846feb2629 | |||
5e31a6f724 | |||
faa3b7fa45 | |||
42b1091c0b | |||
aa2dbd2938 | |||
42c1c12405 | |||
092e968f0c | |||
d58f53de42 | |||
ca81835609 | |||
d10e24cf5b | |||
140613f657 | |||
4694c8dc00 | |||
0477fd5fa6 | |||
1ef84cb879 | |||
9e618c405a | |||
7711645f23 | |||
d597a83422 | |||
d0bad95c11 | |||
2a57ae0fe6 | |||
7bdc01bdb9 | |||
b13403cf59 | |||
5777ff09b6 | |||
954547ea84 | |||
db1e155c8d | |||
543e4c52e4 | |||
3855dc9ac4 | |||
8959eb14a4 | |||
|
ada8ae6011 | ||
492fd22e46 | |||
|
03258c7bfe | ||
c7512dd40d | |||
|
b1d8121507 | ||
|
1fc14b6fd4 | ||
|
c5d4090bac | ||
|
b0f78dedbc | ||
|
2cfa0422c1 | ||
|
d089aa698c | ||
|
aeb86d4333 | ||
|
cf34eea8e1 | ||
|
c025da99dc | ||
|
f5f4795cd9 | ||
|
1cc48ae9d8 | ||
|
79730cdd24 | ||
|
cf57876aca | ||
|
541f8d9515 | ||
|
6831bb17e9 | ||
|
0d06ee36f5 | ||
|
76092ff092 | ||
|
9e3c1c574b | ||
|
16b3bc786d | ||
|
8894bd9cc0 | ||
|
54b605c1d4 | ||
|
6d5f3a80f9 | ||
|
980863c20e | ||
|
e310ab4246 | ||
|
6a524aa0c0 | ||
|
749fd65769 | ||
|
a3c0065706 | ||
|
0ea0de8c2c | ||
|
6e55605fb2 | ||
|
4a29784380 | ||
|
6cd9c0c414 | ||
|
64959ebf3d | ||
|
6c00b7c16f | ||
|
be2a2f2877 | ||
|
067f7f2937 | ||
|
7011b1ead2 | ||
|
547aa1512a | ||
|
2d5fcf1f15 | ||
|
4971a19b8a | ||
|
2dbb52dc7f | ||
|
82070f9c15 | ||
|
4dbe52a32b | ||
|
c85957b8a9 | ||
|
9a80701470 | ||
|
d5769f635c | ||
|
99f6e8d940 | ||
|
c14287dcbd | ||
|
aa86232bd3 | ||
|
6e4e53ade8 | ||
|
12db118aae | ||
|
16d048df08 | ||
|
a0f0574a81 | ||
|
89209ff40c | ||
d007804b5e | |||
e4b33f0465 | |||
a3c35f89fa | |||
47b7ee6703 | |||
a46a5628c0 | |||
|
972cff36a5 | ||
|
bcabed0d33 | ||
|
e889ec6629 | ||
0665adf5f6 | |||
3b884e2086 |
1
.gitignore
vendored
1
.gitignore
vendored
@ -1 +0,0 @@
|
|||||||
shared/cookie.json
|
|
220
fetchupd.php
220
fetchupd.php
@ -17,8 +17,87 @@ limitations under the License.
|
|||||||
|
|
||||||
require_once dirname(__FILE__).'/shared/main.php';
|
require_once dirname(__FILE__).'/shared/main.php';
|
||||||
require_once dirname(__FILE__).'/shared/requests.php';
|
require_once dirname(__FILE__).'/shared/requests.php';
|
||||||
|
require_once dirname(__FILE__).'/shared/cache.php';
|
||||||
|
require_once dirname(__FILE__).'/shared/fileinfo.php';
|
||||||
require_once dirname(__FILE__).'/listid.php';
|
require_once dirname(__FILE__).'/listid.php';
|
||||||
|
|
||||||
|
function uupApiPrivateParseFlags($str) {
|
||||||
|
$split = explode('+', $str);
|
||||||
|
$flagsSafe = [];
|
||||||
|
|
||||||
|
if(isset($split[1])) {
|
||||||
|
$flags = array_unique(explode(',', strtolower($split[1])));
|
||||||
|
$flagsSafe = array_intersect(getAllowedFlags(), $flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
return [$split[0], $flagsSafe];
|
||||||
|
}
|
||||||
|
|
||||||
|
function uupApiPrivateGetLatestBuild() {
|
||||||
|
$builds = array('22000.1');
|
||||||
|
|
||||||
|
$ids = uupListIds();
|
||||||
|
if(isset($ids['error'])) {
|
||||||
|
$ids['builds'] = array();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(empty($ids['builds'])) {
|
||||||
|
$build = $builds[0];
|
||||||
|
} else {
|
||||||
|
$build = $ids['builds'][0]['build'];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $build;
|
||||||
|
}
|
||||||
|
|
||||||
|
function uupApiPrivateGetAcceptableBranches() {
|
||||||
|
return [
|
||||||
|
'auto',
|
||||||
|
'rs2_release',
|
||||||
|
'rs3_release',
|
||||||
|
'rs4_release',
|
||||||
|
'rs5_release',
|
||||||
|
'rs5_release_svc_hci',
|
||||||
|
'19h1_release',
|
||||||
|
'vb_release',
|
||||||
|
'fe_release_10x',
|
||||||
|
'fe_release',
|
||||||
|
'co_release',
|
||||||
|
'ni_release',
|
||||||
|
'zn_release',
|
||||||
|
'ge_release',
|
||||||
|
'rs_prerelease',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
function uupApiPrivateNormalizeFetchParams($params) {
|
||||||
|
$np = array_replace([
|
||||||
|
'arch' => 'amd64',
|
||||||
|
'ring' => 'WIF',
|
||||||
|
'flight' => 'Active',
|
||||||
|
'branch' => 'ge_release',
|
||||||
|
'build' => 'latest',
|
||||||
|
'minor' => 0,
|
||||||
|
'sku' => 48,
|
||||||
|
'type' => 'Production',
|
||||||
|
'flags' => [],
|
||||||
|
], $params);
|
||||||
|
|
||||||
|
if(!is_array($np['flags'])) $np['flags'] = [];
|
||||||
|
|
||||||
|
$np['arch'] = strtolower($np['arch']);
|
||||||
|
$np['ring'] = strtoupper($np['ring']);
|
||||||
|
$np['flight'] = ucwords(strtolower($np['flight']));
|
||||||
|
$np['branch'] = strtolower($np['branch']);
|
||||||
|
$np['build'] = strtolower($np['build']);
|
||||||
|
$np['minor'] = intval($np['minor']);
|
||||||
|
$np['sku'] = intval($np['sku']);
|
||||||
|
$np['type'] = ucwords(strtolower($np['type']));
|
||||||
|
$np['flags'] = array_map('strtolower', $np['flags']);
|
||||||
|
|
||||||
|
return $np;
|
||||||
|
}
|
||||||
|
|
||||||
function uupFetchUpd(
|
function uupFetchUpd(
|
||||||
$arch = 'amd64',
|
$arch = 'amd64',
|
||||||
$ring = 'WIF',
|
$ring = 'WIF',
|
||||||
@ -29,35 +108,52 @@ function uupFetchUpd(
|
|||||||
$type = 'Production',
|
$type = 'Production',
|
||||||
$cacheRequests = 0
|
$cacheRequests = 0
|
||||||
) {
|
) {
|
||||||
uupApiPrintBrand();
|
[$build, $flags] = uupApiPrivateParseFlags($build);
|
||||||
|
|
||||||
$arch = strtolower($arch);
|
$params = [
|
||||||
$ring = strtoupper($ring);
|
'arch' => $arch,
|
||||||
$flight = ucwords(strtolower($flight));
|
'ring' => $ring,
|
||||||
$flight = 'Active';
|
'flight' => $flight,
|
||||||
|
'build' => $build,
|
||||||
|
'minor' => $minor,
|
||||||
|
'sku' => $sku,
|
||||||
|
'type' => $type,
|
||||||
|
'flags' => $flags,
|
||||||
|
];
|
||||||
|
|
||||||
if($build == 'latest' || (!$build)) {
|
return uupFetchUpd2($params, $cacheRequests);
|
||||||
$builds = array('17134.1');
|
|
||||||
|
|
||||||
$ids = uupListIds();
|
|
||||||
if(isset($ids['error'])) {
|
|
||||||
$ids['builds'] = array();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$build = $ids['builds'][0]['build'];
|
function uupFetchUpd2($params, $cacheRequests = 0) {
|
||||||
unset($builds, $ids);
|
uupApiPrintBrand();
|
||||||
|
|
||||||
|
$np = uupApiPrivateNormalizeFetchParams($params);
|
||||||
|
|
||||||
|
$arch = $np['arch'];
|
||||||
|
$ring = $np['ring'];
|
||||||
|
$flight = 'Active';
|
||||||
|
$branch = $np['branch'];
|
||||||
|
$build = $np['build'];
|
||||||
|
$minor = $np['minor'];
|
||||||
|
$sku = $np['sku'];
|
||||||
|
$type = $np['type'];
|
||||||
|
$flags = $np['flags'];
|
||||||
|
|
||||||
|
$flagsStr = implode(',', $flags);
|
||||||
|
|
||||||
|
if(strtolower($build) == 'latest' || (!$build)) {
|
||||||
|
$build = uupApiPrivateGetLatestBuild();
|
||||||
}
|
}
|
||||||
|
|
||||||
$build = explode('.', $build);
|
$build = explode('.', $build);
|
||||||
if(isset($build[1])) $minor = intval($build[1]);
|
if(isset($build[1])) $minor = intval($build[1]);
|
||||||
$build = intval($build[0]);
|
$build = intval($build[0]);
|
||||||
$sku = intval($sku);
|
|
||||||
|
|
||||||
if(!($arch == 'amd64' || $arch == 'x86' || $arch == 'arm64' || $arch == 'arm' || $arch == 'all')) {
|
if(!($arch == 'amd64' || $arch == 'x86' || $arch == 'arm64' || $arch == 'arm' || $arch == 'all')) {
|
||||||
return array('error' => 'UNKNOWN_ARCH');
|
return array('error' => 'UNKNOWN_ARCH');
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!($ring == 'DEV' || $ring == 'BETA' || $ring == 'RELEASEPREVIEW' || $ring == 'WIF' || $ring == 'WIS' || $ring == 'RP' || $ring == 'RETAIL' || $ring == 'MSIT')) {
|
if(!($ring == 'CANARY' || $ring == 'DEV' || $ring == 'BETA' || $ring == 'RELEASEPREVIEW' || $ring == 'WIF' || $ring == 'WIS' || $ring == 'RP' || $ring == 'RETAIL' || $ring == 'MSIT')) {
|
||||||
return array('error' => 'UNKNOWN_RING');
|
return array('error' => 'UNKNOWN_RING');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,6 +173,9 @@ function uupFetchUpd(
|
|||||||
return array('error' => 'ILLEGAL_MINOR');
|
return array('error' => 'ILLEGAL_MINOR');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!in_array($branch, uupApiPrivateGetAcceptableBranches()))
|
||||||
|
$branch = 'auto';
|
||||||
|
|
||||||
if($ring == 'DEV') $ring = 'WIF';
|
if($ring == 'DEV') $ring = 'WIF';
|
||||||
if($ring == 'BETA') $ring = 'WIS';
|
if($ring == 'BETA') $ring = 'WIS';
|
||||||
if($ring == 'RELEASEPREVIEW') $ring = 'RP';
|
if($ring == 'RELEASEPREVIEW') $ring = 'RP';
|
||||||
@ -90,45 +189,22 @@ function uupFetchUpd(
|
|||||||
$type = 'Production';
|
$type = 'Production';
|
||||||
}
|
}
|
||||||
|
|
||||||
$cacheHash = hash('sha256', strtolower("api-fetch-$arch-$ring-$flight-$build-$minor-$sku-$type"));
|
$res = "api-fetch-$arch-$ring-$flight-$branch-$build-$flagsStr-$minor-$sku-$type";
|
||||||
$cached = 0;
|
$cache = new UupDumpCache($res);
|
||||||
|
$fromCache = $cache->get();
|
||||||
|
if($fromCache !== false) return $fromCache;
|
||||||
|
|
||||||
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'];
|
|
||||||
$cached = 1;
|
|
||||||
} else {
|
|
||||||
$cached = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
unset($cache);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!$cached) {
|
|
||||||
consoleLogger('Fetching information from the server...');
|
consoleLogger('Fetching information from the server...');
|
||||||
$postData = composeFetchUpdRequest(uupDevice(), uupEncryptedData(), $arch, $flight, $ring, $build, $sku, $type);
|
$composerArgs = [$arch, $flight, $ring, $build, $sku, $type, $flags, $branch];
|
||||||
$out = sendWuPostRequest('https://fe3cr.delivery.mp.microsoft.com/ClientWebService/client.asmx', $postData);
|
$out = sendWuPostRequestHelper('client', 'composeFetchUpdRequest', $composerArgs);
|
||||||
|
if($out === false || $out['error'] != 200) {
|
||||||
|
consoleLogger('The request has failed');
|
||||||
|
return array('error' => 'WU_REQUEST_FAILED');
|
||||||
|
}
|
||||||
|
|
||||||
$out = html_entity_decode($out);
|
$out = html_entity_decode($out['out']);
|
||||||
consoleLogger('Information has been successfully fetched.');
|
consoleLogger('Information has been successfully fetched.');
|
||||||
|
|
||||||
if($cacheRequests == 1) {
|
|
||||||
$cache = array(
|
|
||||||
'expires' => time()+120,
|
|
||||||
'content' => $out,
|
|
||||||
);
|
|
||||||
|
|
||||||
if(!file_exists('cache')) mkdir('cache');
|
|
||||||
@file_put_contents('cache/'.$cacheHash.'.json.gz', gzencode(json_encode($cache)."\n"));
|
|
||||||
|
|
||||||
unset($cache);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
preg_match_all('/<UpdateInfo>.*?<\/UpdateInfo>/', $out, $updateInfos);
|
preg_match_all('/<UpdateInfo>.*?<\/UpdateInfo>/', $out, $updateInfos);
|
||||||
$updateInfo = preg_grep('/<IsLeaf>true<\/IsLeaf>/', $updateInfos[0]);
|
$updateInfo = preg_grep('/<IsLeaf>true<\/IsLeaf>/', $updateInfos[0]);
|
||||||
sort($updateInfo);
|
sort($updateInfo);
|
||||||
@ -147,7 +223,7 @@ function uupFetchUpd(
|
|||||||
$num++;
|
$num++;
|
||||||
consoleLogger("Checking build information for update {$num} of {$updatesNum}...");
|
consoleLogger("Checking build information for update {$num} of {$updatesNum}...");
|
||||||
|
|
||||||
$info = parseFetchUpdate($val, $out, $arch, $ring, $flight, $build, $sku, $type);
|
$info = parseFetchUpdate($val, $out, $arch, $ring, $flight, $build, $sku, $type, $flags, $branch);
|
||||||
if(isset($info['error'])) {
|
if(isset($info['error'])) {
|
||||||
$errorCount++;
|
$errorCount++;
|
||||||
continue;
|
continue;
|
||||||
@ -160,7 +236,7 @@ function uupFetchUpd(
|
|||||||
return array('error' => 'EMPTY_FILELIST');
|
return array('error' => 'EMPTY_FILELIST');
|
||||||
}
|
}
|
||||||
|
|
||||||
return array(
|
$data = [
|
||||||
'apiVersion' => uupApiVersion(),
|
'apiVersion' => uupApiVersion(),
|
||||||
'updateId' => $updateArray[0]['updateId'],
|
'updateId' => $updateArray[0]['updateId'],
|
||||||
'updateTitle' => $updateArray[0]['updateTitle'],
|
'updateTitle' => $updateArray[0]['updateTitle'],
|
||||||
@ -168,10 +244,16 @@ function uupFetchUpd(
|
|||||||
'arch' => $updateArray[0]['arch'],
|
'arch' => $updateArray[0]['arch'],
|
||||||
'fileWrite' => $updateArray[0]['fileWrite'],
|
'fileWrite' => $updateArray[0]['fileWrite'],
|
||||||
'updateArray' => $updateArray,
|
'updateArray' => $updateArray,
|
||||||
);
|
];
|
||||||
|
|
||||||
|
if($cacheRequests == 1) {
|
||||||
|
$cache->put($data, 120);
|
||||||
}
|
}
|
||||||
|
|
||||||
function parseFetchUpdate($updateInfo, $out, $arch, $ring, $flight, $build, $sku, $type) {
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseFetchUpdate($updateInfo, $out, $arch, $ring, $flight, $build, $sku, $type, $flags, $branch) {
|
||||||
$updateNumId = preg_replace('/<UpdateInfo><ID>|<\/ID>.*/i', '', $updateInfo);
|
$updateNumId = preg_replace('/<UpdateInfo><ID>|<\/ID>.*/i', '', $updateInfo);
|
||||||
|
|
||||||
$updates = preg_replace('/<Update>/', "\n<Update>", $out);
|
$updates = preg_replace('/<Update>/', "\n<Update>", $out);
|
||||||
@ -213,6 +295,15 @@ function parseFetchUpdate($updateInfo, $out, $arch, $ring, $flight, $build, $sku
|
|||||||
$foundBuild = @$info[3];
|
$foundBuild = @$info[3];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$isNet = 0;
|
||||||
|
if(strpos($foundArch, 'netfx') !== false) {
|
||||||
|
$isNet = 1;
|
||||||
|
preg_match('/ProductReleaseInstalled Name\=".*\.(.*?)\.(.*?)" Version\=".*\.\d{5}\.(.*?)"/', $updateInfo, $info);
|
||||||
|
$foundType = @strtolower($info[1]);
|
||||||
|
$foundArch = @strtolower($info[2]);
|
||||||
|
$foundBuild = @$info[3];
|
||||||
|
}
|
||||||
|
|
||||||
$updateTitle = preg_grep('/<Title>.*<\/Title>/', $updateMeta);
|
$updateTitle = preg_grep('/<Title>.*<\/Title>/', $updateMeta);
|
||||||
sort($updateTitle);
|
sort($updateTitle);
|
||||||
|
|
||||||
@ -232,13 +323,19 @@ function parseFetchUpdate($updateInfo, $out, $arch, $ring, $flight, $build, $sku
|
|||||||
$isCumulativeUpdate = 0;
|
$isCumulativeUpdate = 0;
|
||||||
if(preg_match('/\d{4}-\d{2}.+Update|Cumulative Update|Microsoft Edge|Windows Feature Experience Pack|Cumulative security Hotpatch/i', $updateTitle)) {
|
if(preg_match('/\d{4}-\d{2}.+Update|Cumulative Update|Microsoft Edge|Windows Feature Experience Pack|Cumulative security Hotpatch/i', $updateTitle)) {
|
||||||
$isCumulativeUpdate = 1;
|
$isCumulativeUpdate = 1;
|
||||||
|
if($isNet) {
|
||||||
|
$updateTitle = preg_replace("/3.5 and 4.8.1 |3.5 and 4.8 | for $foundArch| for x64| \(KB.*?\)/i", '', $updateTitle);
|
||||||
|
} else {
|
||||||
$updateTitle = preg_replace('/ for .{3,5}-based systems| \(KB.*?\)/i', '', $updateTitle);
|
$updateTitle = preg_replace('/ for .{3,5}-based systems| \(KB.*?\)/i', '', $updateTitle);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$updateTitle = preg_replace("/ ?\d{4}-\d{2}\D ?| ?$foundArch ?| ?x64 ?/i", '', $updateTitle);
|
$updateTitle = preg_replace("/ ?\d{4}-\d{2}\D ?| ?$foundArch ?| ?x64 ?/i", '', $updateTitle);
|
||||||
|
|
||||||
if($foundType == 'server')
|
if($foundType == 'server') {
|
||||||
$updateTitle = str_replace('Windows 10', 'Windows Server', $updateTitle);
|
$updateTitle = str_replace('Windows 10', 'Windows Server', $updateTitle);
|
||||||
|
$updateTitle = str_replace('Windows 11', 'Windows Server', $updateTitle);
|
||||||
|
}
|
||||||
|
|
||||||
if($sku == 406)
|
if($sku == 406)
|
||||||
$updateTitle = str_replace('Microsoft server operating system', 'Azure Stack HCI', $updateTitle);
|
$updateTitle = str_replace('Microsoft server operating system', 'Azure Stack HCI', $updateTitle);
|
||||||
@ -300,16 +397,16 @@ function parseFetchUpdate($updateInfo, $out, $arch, $ring, $flight, $build, $sku
|
|||||||
return array('error' => 'BROKEN_UPDATE');
|
return array('error' => 'BROKEN_UPDATE');
|
||||||
}
|
}
|
||||||
|
|
||||||
if(preg_match('/Corpnet Required/i', $updateTitle)) {
|
$isCorpnet = preg_match('/Corpnet Required/i', $updateTitle);
|
||||||
|
if($isCorpnet && !uupApiConfigIsTrue('allow_corpnet')) {
|
||||||
consoleLogger('Skipping corpnet only update...');
|
consoleLogger('Skipping corpnet only update...');
|
||||||
return array('error' => 'CORPNET_ONLY_UPDATE');
|
return array('error' => 'CORPNET_ONLY_UPDATE');
|
||||||
}
|
}
|
||||||
|
|
||||||
$fileWrite = 'NO_SAVE';
|
$fileWrite = 'NO_SAVE';
|
||||||
if(!file_exists('fileinfo/'.$updateString.'.json')) {
|
if(!uupApiFileInfoExists($updateId)) {
|
||||||
consoleLogger('WARNING: This build is NOT in the database. It will be saved now.');
|
consoleLogger('WARNING: This build is NOT in the database. It will be saved now.');
|
||||||
consoleLogger('Parsing information to write...');
|
consoleLogger('Parsing information to write...');
|
||||||
if(!file_exists('fileinfo')) mkdir('fileinfo');
|
|
||||||
|
|
||||||
$fileList = preg_replace('/<Files>|<\/Files>/', '', $fileList[0]);
|
$fileList = preg_replace('/<Files>|<\/Files>/', '', $fileList[0]);
|
||||||
preg_match_all('/<File.*?<\/File>/', $fileList, $fileList);
|
preg_match_all('/<File.*?<\/File>/', $fileList, $fileList);
|
||||||
@ -347,7 +444,9 @@ function parseFetchUpdate($updateInfo, $out, $arch, $ring, $flight, $build, $sku
|
|||||||
$temp['title'] = $updateTitle;
|
$temp['title'] = $updateTitle;
|
||||||
$temp['ring'] = $ring;
|
$temp['ring'] = $ring;
|
||||||
$temp['flight'] = $flight;
|
$temp['flight'] = $flight;
|
||||||
|
$temp['branch'] = $branch;
|
||||||
$temp['arch'] = $foundArch;
|
$temp['arch'] = $foundArch;
|
||||||
|
$temp['fetchArch'] = $arch == 'all' ? 'amd64' : $arch;
|
||||||
$temp['build'] = $foundBuild;
|
$temp['build'] = $foundBuild;
|
||||||
$temp['checkBuild'] = $build;
|
$temp['checkBuild'] = $build;
|
||||||
$temp['sku'] = $sku;
|
$temp['sku'] = $sku;
|
||||||
@ -360,6 +459,10 @@ function parseFetchUpdate($updateInfo, $out, $arch, $ring, $flight, $build, $sku
|
|||||||
$temp['releasetype'] = $type;
|
$temp['releasetype'] = $type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!empty($flags)) {
|
||||||
|
$temp['flags'] = $flags;
|
||||||
|
}
|
||||||
|
|
||||||
$temp['created'] = time();
|
$temp['created'] = time();
|
||||||
$temp['sha256ready'] = true;
|
$temp['sha256ready'] = true;
|
||||||
$temp['files'] = $shaArray;
|
$temp['files'] = $shaArray;
|
||||||
@ -367,10 +470,11 @@ function parseFetchUpdate($updateInfo, $out, $arch, $ring, $flight, $build, $sku
|
|||||||
consoleLogger('Successfully parsed the information.');
|
consoleLogger('Successfully parsed the information.');
|
||||||
consoleLogger('Writing new build information to the disk...');
|
consoleLogger('Writing new build information to the disk...');
|
||||||
|
|
||||||
$success = file_put_contents('fileinfo/'.$updateString.'.json', json_encode($temp)."\n");
|
$success = uupApiWriteFileinfo($updateString, $temp);
|
||||||
if($success) {
|
if($success) {
|
||||||
consoleLogger('Successfully written build information to the disk.');
|
consoleLogger('Successfully written build information to the disk.');
|
||||||
$fileWrite = 'INFO_WRITTEN';
|
$fileWrite = 'INFO_WRITTEN';
|
||||||
|
uupApiPrivateInvalidateFileinfoCache();
|
||||||
} else {
|
} else {
|
||||||
consoleLogger('An error has occured while writing the information to the disk.');
|
consoleLogger('An error has occured while writing the information to the disk.');
|
||||||
}
|
}
|
||||||
|
186
get.php
186
get.php
@ -18,6 +18,8 @@ limitations under the License.
|
|||||||
require_once dirname(__FILE__).'/shared/main.php';
|
require_once dirname(__FILE__).'/shared/main.php';
|
||||||
require_once dirname(__FILE__).'/shared/requests.php';
|
require_once dirname(__FILE__).'/shared/requests.php';
|
||||||
require_once dirname(__FILE__).'/shared/packs.php';
|
require_once dirname(__FILE__).'/shared/packs.php';
|
||||||
|
require_once dirname(__FILE__).'/shared/cache.php';
|
||||||
|
require_once dirname(__FILE__).'/shared/fileinfo.php';
|
||||||
|
|
||||||
/*
|
/*
|
||||||
$updateId = Update Identifier
|
$updateId = Update Identifier
|
||||||
@ -45,7 +47,13 @@ function uupGetFiles(
|
|||||||
return array('error' => 'INCORRECT_ID');
|
return array('error' => 'INCORRECT_ID');
|
||||||
}
|
}
|
||||||
|
|
||||||
$info = @file_get_contents('fileinfo/'.$updateId.'.json');
|
$edition = is_array($desiredEdition) ? implode('_', $desiredEdition) : $desiredEdition;
|
||||||
|
$res = "api-get-{$updateId}_{$usePack}_{$edition}_{$requestType}";
|
||||||
|
$cache = new UupDumpCache($res);
|
||||||
|
$fromCache = $cache->get();
|
||||||
|
if($fromCache !== false) return $fromCache;
|
||||||
|
|
||||||
|
$info = uupApiReadFileinfo($updateId);
|
||||||
if(empty($info)) {
|
if(empty($info)) {
|
||||||
$info = array(
|
$info = array(
|
||||||
'ring' => 'WIF',
|
'ring' => 'WIF',
|
||||||
@ -55,8 +63,6 @@ function uupGetFiles(
|
|||||||
'sku' => '48',
|
'sku' => '48',
|
||||||
'files' => array(),
|
'files' => array(),
|
||||||
);
|
);
|
||||||
} else {
|
|
||||||
$info = json_decode($info, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(isset($info['build'])) {
|
if(isset($info['build'])) {
|
||||||
@ -70,8 +76,10 @@ function uupGetFiles(
|
|||||||
$info['sku'] = 48;
|
$info['sku'] = 48;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$genPack = [];
|
||||||
|
|
||||||
if($usePack) {
|
if($usePack) {
|
||||||
$genPack = uupGetGenPacks($build, $info['arch'], $updateId);
|
$genPack = uupApiGetPacks($updateId);
|
||||||
if(empty($genPack)) return array('error' => 'UNSUPPORTED_COMBINATION');
|
if(empty($genPack)) return array('error' => 'UNSUPPORTED_COMBINATION');
|
||||||
|
|
||||||
if(!isset($genPack[$usePack])) {
|
if(!isset($genPack[$usePack])) {
|
||||||
@ -79,6 +87,8 @@ function uupGetFiles(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$appEdition = 0;
|
||||||
|
|
||||||
if(!is_array($desiredEdition)) {
|
if(!is_array($desiredEdition)) {
|
||||||
$desiredEdition = strtoupper($desiredEdition);
|
$desiredEdition = strtoupper($desiredEdition);
|
||||||
$fileListSource = $desiredEdition;
|
$fileListSource = $desiredEdition;
|
||||||
@ -104,13 +114,19 @@ function uupGetFiles(
|
|||||||
|
|
||||||
case 'UPDATEONLY': break;
|
case 'UPDATEONLY': break;
|
||||||
|
|
||||||
|
case 'APP': $appEdition = 1;
|
||||||
|
case 'APP_MOMENT': $appEdition = 1;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if(!isset($genPack[$usePack][$desiredEdition])) {
|
if(!isset($genPack[$usePack][$desiredEdition])) {
|
||||||
return array('error' => 'UNSUPPORTED_COMBINATION');
|
return array('error' => 'UNSUPPORTED_COMBINATION');
|
||||||
}
|
}
|
||||||
|
|
||||||
$filesPacksList = $genPack[$usePack][$desiredEdition];
|
|
||||||
$fileListSource = 'GENERATEDPACKS';
|
$fileListSource = 'GENERATEDPACKS';
|
||||||
|
$filesPacksList = $genPack[$usePack][$desiredEdition];
|
||||||
|
if($desiredEdition == 'APP' && isset($genPack[$usePack]['APP_MOMENT'])) {
|
||||||
|
$filesPacksList = array_merge($filesPacksList, $genPack[$usePack]['APP_MOMENT']);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -123,6 +139,7 @@ function uupGetFiles(
|
|||||||
return array('error' => 'UNSUPPORTED_COMBINATION');
|
return array('error' => 'UNSUPPORTED_COMBINATION');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if($edition == 'APP' || $edition == 'APP_MOMENT') $appEdition = 1;
|
||||||
$filesPacksList = array_merge($filesPacksList, $genPack[$usePack][$edition]);
|
$filesPacksList = array_merge($filesPacksList, $genPack[$usePack][$edition]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -138,6 +155,7 @@ function uupGetFiles(
|
|||||||
$updateBuild = (isset($info['build'])) ? $info['build'] : 'UNKNOWN';
|
$updateBuild = (isset($info['build'])) ? $info['build'] : 'UNKNOWN';
|
||||||
$updateName = (isset($info['title'])) ? $info['title'] : 'Unknown update: '.$updateId;
|
$updateName = (isset($info['title'])) ? $info['title'] : 'Unknown update: '.$updateId;
|
||||||
$sha256capable = isset($info['sha256ready']);
|
$sha256capable = isset($info['sha256ready']);
|
||||||
|
$hasUpdates = false;
|
||||||
|
|
||||||
if(isset($info['releasetype'])) {
|
if(isset($info['releasetype'])) {
|
||||||
$type = $info['releasetype'];
|
$type = $info['releasetype'];
|
||||||
@ -164,16 +182,34 @@ function uupGetFiles(
|
|||||||
if(isset($filesInfoList[$val])) unset($filesInfoList[$val]);
|
if(isset($filesInfoList[$val])) unset($filesInfoList[$val]);
|
||||||
}
|
}
|
||||||
|
|
||||||
$baseless = preg_grep('/^baseless_|Windows10\.0-KB.*-EXPRESS|SSU-.*-EXPRESS/i', array_keys($filesInfoList));
|
$baseless = preg_grep('/^baseless_/i', array_keys($filesInfoList));
|
||||||
foreach($baseless as $val) {
|
foreach($baseless as $val) {
|
||||||
if(isset($filesInfoList[$val])) unset($filesInfoList[$val]);
|
if(isset($filesInfoList[$val])) unset($filesInfoList[$val]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$expresscab = preg_grep('/Windows(10|11)\.0-KB.*-EXPRESS|SSU-.*-EXPRESS/i', array_keys($filesInfoList));
|
||||||
|
|
||||||
|
$expresspsf = array();
|
||||||
|
foreach($expresscab as $val) {
|
||||||
|
$name = preg_replace('/-EXPRESS.cab$/i', '', $val);
|
||||||
|
$expresspsf[] = $name;
|
||||||
|
if(isset($filesInfoList[$val])) unset($filesInfoList[$val]);
|
||||||
|
}
|
||||||
|
unset($index, $name, $expresscab);
|
||||||
|
|
||||||
|
foreach($expresspsf as $val) {
|
||||||
|
if(isset($filesInfoList[$val.'.cab'])) {
|
||||||
|
if(isset($filesInfoList[$val.'.psf'])) unset($filesInfoList[$val.'.psf']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
unset($expresspsf);
|
||||||
|
|
||||||
$psf = array_keys($filesInfoList);
|
$psf = array_keys($filesInfoList);
|
||||||
$psf = preg_grep('/\.psf$/i', $psf);
|
$psf = preg_grep('/\.psf$/i', $psf);
|
||||||
|
|
||||||
$psfk = preg_grep('/Windows10\.0-KB.*/i', $psf);
|
$psfk = preg_grep('/Windows(10|11)\.0-KB.*/i', $psf);
|
||||||
$psfk = preg_grep('/.*-EXPRESS/i', $psfk, PREG_GREP_INVERT);
|
$psfk = preg_grep('/.*-EXPRESS/i', $psfk, PREG_GREP_INVERT);
|
||||||
|
if($build < 17763) $psfk = preg_grep('/Windows(10|11)\.0-KB.*_\d\.psf$/i', $psfk, PREG_GREP_INVERT);
|
||||||
foreach($psfk as $key => $val) {
|
foreach($psfk as $key => $val) {
|
||||||
if(isset($psf[$key])) unset($psf[$key]);
|
if(isset($psf[$key])) unset($psf[$key]);
|
||||||
}
|
}
|
||||||
@ -201,24 +237,46 @@ function uupGetFiles(
|
|||||||
}
|
}
|
||||||
unset($removeFiles);
|
unset($removeFiles);
|
||||||
|
|
||||||
|
$msu = array_keys($filesInfoList);
|
||||||
|
$msu = preg_grep('/\.msu$/i', $msu);
|
||||||
|
$removeMSUs = array();
|
||||||
|
foreach($msu as $val) {
|
||||||
|
$name = preg_replace('/\.msu$/i', '', $val);
|
||||||
|
$removeMSUs[] = $name;
|
||||||
|
}
|
||||||
|
unset($index, $name, $msu);
|
||||||
|
|
||||||
$filesInfoKeys = array_keys($filesInfoList);
|
$filesInfoKeys = array_keys($filesInfoList);
|
||||||
|
$updatesRegex = '/Windows(10|11)\.0-KB|SSU-.*?\....$/i';
|
||||||
|
|
||||||
switch($fileListSource) {
|
switch($fileListSource) {
|
||||||
case 'UPDATEONLY':
|
case 'UPDATEONLY':
|
||||||
$skipPackBuild = 1;
|
$skipPackBuild = 1;
|
||||||
$removeFiles = preg_grep('/Windows10\.0-KB.*-EXPRESS|Windows10\.0-KB.*-baseless|SSU-\d*?\.\d*?-.{3,5}-EXPRESS/i', $filesInfoKeys);
|
$removeFiles = preg_grep('/Windows(10|11)\.0-KB.*-baseless/i', $filesInfoKeys);
|
||||||
|
|
||||||
foreach($removeFiles as $val) {
|
foreach($removeFiles as $val) {
|
||||||
if(isset($filesInfoList[$val])) unset($filesInfoList[$val]);
|
if(isset($filesInfoList[$val])) unset($filesInfoList[$val]);
|
||||||
}
|
}
|
||||||
unset($removeFiles);
|
unset($removeFiles);
|
||||||
|
|
||||||
$filesInfoKeys = array_keys($filesInfoList);
|
foreach($removeMSUs as $val) {
|
||||||
|
if(isset($filesInfoList[$val.'.cab']) && isset($filesInfoList[$val.'.msu'])) {
|
||||||
|
unset($filesInfoList[$val.'.msu']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
unset($removeMSUs);
|
||||||
|
|
||||||
$filesInfoKeys = preg_grep('/Windows10\.0-KB|SSU-\d*?\.\d*?-.*?\.cab/i', $filesInfoKeys);
|
$filesInfoKeys = array_keys($filesInfoList);
|
||||||
|
$temp = preg_grep('/.*?AggregatedMetadata.*?\.cab|.*?DesktopDeployment.*?\.cab/i', $filesInfoKeys);
|
||||||
|
|
||||||
|
$filesInfoKeys = preg_grep($updatesRegex, $filesInfoKeys);
|
||||||
if(count($filesInfoKeys) == 0) {
|
if(count($filesInfoKeys) == 0) {
|
||||||
return array('error' => 'NOT_CUMULATIVE_UPDATE');
|
return array('error' => 'NOT_CUMULATIVE_UPDATE');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if($build > 21380) $filesInfoKeys = array_merge($filesInfoKeys, $temp);
|
||||||
|
unset($temp);
|
||||||
|
$hasUpdates = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'WUBFILE':
|
case 'WUBFILE':
|
||||||
@ -232,8 +290,24 @@ function uupGetFiles(
|
|||||||
if($updateSku == 135) $uupCleanFunc = 'uupCleanHolo';
|
if($updateSku == 135) $uupCleanFunc = 'uupCleanHolo';
|
||||||
|
|
||||||
if($fileListSource == 'GENERATEDPACKS') {
|
if($fileListSource == 'GENERATEDPACKS') {
|
||||||
$temp = preg_grep('/Windows10\.0-KB.*-EXPRESS|Windows10\.0-KB.*-baseless|SSU-\d*?\.\d*?-.{3,5}-EXPRESS/i', $filesInfoKeys, PREG_GREP_INVERT);
|
foreach($removeMSUs as $val) {
|
||||||
$temp = preg_grep('/Windows10\.0-KB|SSU-\d*?\.\d*?-.*?\.cab/i', $temp);
|
if(isset($filesInfoList[$val.'.cab']) && isset($filesInfoList[$val.'.msu'])) {
|
||||||
|
unset($filesInfoList[$val.'.msu']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
unset($removeMSUs);
|
||||||
|
$filesInfoKeys = array_keys($filesInfoList);
|
||||||
|
|
||||||
|
$temp = preg_grep('/Windows(10|11)\.0-KB.*-baseless/i', $filesInfoKeys, PREG_GREP_INVERT);
|
||||||
|
if($appEdition) {
|
||||||
|
$temp = preg_grep('/.*?AggregatedMetadata.*?\.cab/i', $temp);
|
||||||
|
} else if($build > 21380) {
|
||||||
|
$temp = preg_grep('/Windows(10|11)\.0-KB|SSU-.*?\....$|.*?AggregatedMetadata.*?\.cab|.*?DesktopDeployment.*?\.cab/i', $temp);
|
||||||
|
} else {
|
||||||
|
$temp = preg_grep($updatesRegex, $temp);
|
||||||
|
}
|
||||||
|
|
||||||
|
$hasUpdates = !empty(preg_grep($updatesRegex, $temp));
|
||||||
$filesPacksList = array_merge($filesPacksList, $temp);
|
$filesPacksList = array_merge($filesPacksList, $temp);
|
||||||
|
|
||||||
$newFiles = array();
|
$newFiles = array();
|
||||||
@ -285,6 +359,7 @@ function uupGetFiles(
|
|||||||
$filesNew = array();
|
$filesNew = array();
|
||||||
foreach($filesInfoKeys as $val) {
|
foreach($filesInfoKeys as $val) {
|
||||||
$filesNew[$val] = $filesInfoList[$val];
|
$filesNew[$val] = $filesInfoList[$val];
|
||||||
|
$filesNew[$val]['url'] = uupApiFixDownloadLink($filesInfoList[$val]['url']);
|
||||||
}
|
}
|
||||||
|
|
||||||
$files = $filesNew;
|
$files = $filesNew;
|
||||||
@ -292,48 +367,54 @@ function uupGetFiles(
|
|||||||
|
|
||||||
consoleLogger('Successfully parsed the information.');
|
consoleLogger('Successfully parsed the information.');
|
||||||
|
|
||||||
return array(
|
$data = [
|
||||||
'apiVersion' => uupApiVersion(),
|
'apiVersion' => uupApiVersion(),
|
||||||
'updateName' => $updateName,
|
'updateName' => $updateName,
|
||||||
'arch' => $updateArch,
|
'arch' => $updateArch,
|
||||||
'build' => $updateBuild,
|
'build' => $updateBuild,
|
||||||
'sku' => $updateSku,
|
'sku' => $updateSku,
|
||||||
|
'hasUpdates' => $hasUpdates,
|
||||||
|
'appxPresent' => uupAreAppxPresent($genPack),
|
||||||
'files' => $files,
|
'files' => $files,
|
||||||
);
|
];
|
||||||
|
|
||||||
|
if($requestType > 0) {
|
||||||
|
$cacheData = $data;
|
||||||
|
$cache->put($cacheData, 30);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $data;
|
||||||
}
|
}
|
||||||
|
|
||||||
function uupGetOnlineFiles($updateId, $rev, $info, $cacheRequests, $type) {
|
function uupGetOnlineFiles($updateId, $rev, $info, $cacheRequests, $type) {
|
||||||
$cacheHash = hash('sha256', strtolower("api-get-${updateId}_rev.$rev"));
|
$res = "api-get-online-{$updateId}_rev.$rev";
|
||||||
$cached = 0;
|
$cache = new UupDumpCache($res);
|
||||||
|
$fromCache = $cache->get();
|
||||||
|
$cached = ($fromCache !== false);
|
||||||
|
|
||||||
if(file_exists('cache/'.$cacheHash.'.json.gz') && $cacheRequests == 1) {
|
if($cached) {
|
||||||
$cache = @gzdecode(@file_get_contents('cache/'.$cacheHash.'.json.gz'));
|
$out = $fromCache['out'];
|
||||||
$cache = json_decode($cache, 1);
|
$fetchTime = $fromCache['fetchTime'];
|
||||||
|
|
||||||
if(!empty($cache['content']) && ($cache['expires'] > time())) {
|
|
||||||
consoleLogger('Using cached response...');
|
|
||||||
$out = $cache['content'];
|
|
||||||
$fetchTime = $cache['fetchTime'];
|
|
||||||
$cached = 1;
|
|
||||||
} else {
|
} else {
|
||||||
$cached = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
unset($cache);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!$cached) {
|
|
||||||
$fetchTime = time();
|
$fetchTime = time();
|
||||||
consoleLogger('Fetching information from the server...');
|
consoleLogger('Fetching information from the server...');
|
||||||
$postData = composeFileGetRequest($updateId, uupDevice(), $info, $rev, $type);
|
|
||||||
$out = sendWuPostRequest('https://fe3cr.delivery.mp.microsoft.com/ClientWebService/client.asmx/secured', $postData);
|
$composerArgs = [$updateId, $info, $rev, $type];
|
||||||
|
$out = sendWuPostRequestHelper('clientSecured', 'composeFileGetRequest', $composerArgs);
|
||||||
|
|
||||||
|
if($out === false || $out['error'] != 200) {
|
||||||
|
consoleLogger('The request has failed');
|
||||||
|
return array('error' => 'WU_REQUEST_FAILED');
|
||||||
|
}
|
||||||
|
|
||||||
|
$out = $out['out'];
|
||||||
consoleLogger('Information has been successfully fetched.');
|
consoleLogger('Information has been successfully fetched.');
|
||||||
}
|
}
|
||||||
|
|
||||||
consoleLogger('Parsing information...');
|
consoleLogger('Parsing information...');
|
||||||
$xmlOut = @simplexml_load_string($out);
|
$xmlOut = @simplexml_load_string($out);
|
||||||
if($xmlOut === false) {
|
if($xmlOut === false) {
|
||||||
@unlink('cache/'.$cacheHash.'.json.gz');
|
$cache->delete();
|
||||||
return array('error' => 'XML_PARSE_ERROR');
|
return array('error' => 'XML_PARSE_ERROR');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -381,15 +462,11 @@ function uupGetOnlineFiles($updateId, $rev, $info, $cacheRequests, $type) {
|
|||||||
if($sha256capable) {
|
if($sha256capable) {
|
||||||
$tempname = uupCleanSha256($name);
|
$tempname = uupCleanSha256($name);
|
||||||
if(isset($files[$tempname])) {
|
if(isset($files[$tempname])) {
|
||||||
if(preg_match('/\.cab$/i', $tempname)) {
|
|
||||||
if($size > $files[$tempname]['size']) {
|
if($size > $files[$tempname]['size']) {
|
||||||
$express = 'baseless_'.$tempname;
|
$smaller = uupAppendSha1($tempname, $files[$tempname]['sha1']);
|
||||||
$files[$express] = $files[$tempname];
|
$files[$smaller] = $files[$tempname];
|
||||||
unset($files[$tempname]);
|
unset($files[$tempname]);
|
||||||
$newName = $tempname;
|
$newName = $tempname;
|
||||||
} else {
|
|
||||||
$newName = 'baseless_'.$tempname;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
$newName = uupAppendSha1($tempname, $sha1);
|
$newName = uupAppendSha1($tempname, $sha1);
|
||||||
}
|
}
|
||||||
@ -433,14 +510,12 @@ function uupGetOnlineFiles($updateId, $rev, $info, $cacheRequests, $type) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if($cacheRequests == 1 && $cached == 0) {
|
if($cacheRequests == 1 && $cached == 0) {
|
||||||
$cache = array(
|
$cacheData = [
|
||||||
'expires' => time()+90,
|
'out' => $out,
|
||||||
'content' => $out,
|
|
||||||
'fetchTime' => $fetchTime,
|
'fetchTime' => $fetchTime,
|
||||||
);
|
];
|
||||||
|
|
||||||
if(!file_exists('cache')) mkdir('cache');
|
$cache->put($cacheData, 90);
|
||||||
@file_put_contents('cache/'.$cacheHash.'.json.gz', gzencode(json_encode($cache)."\n"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $files;
|
return $files;
|
||||||
@ -462,24 +537,14 @@ function uupGetOfflineFiles($info) {
|
|||||||
$sha256 = isset($val['sha256']) ? $val['sha256'] : null;
|
$sha256 = isset($val['sha256']) ? $val['sha256'] : null;
|
||||||
|
|
||||||
if($sha256capable) {
|
if($sha256capable) {
|
||||||
// clean file name
|
|
||||||
$tempname = uupCleanSha256($name);
|
$tempname = uupCleanSha256($name);
|
||||||
if(isset($files[$tempname])) {
|
if(isset($files[$tempname])) {
|
||||||
// check existing file with the same name
|
|
||||||
if(preg_match('/\.cab$/i', $tempname)) {
|
|
||||||
// compare cab files only
|
|
||||||
if($size > $files[$tempname]['size']) {
|
if($size > $files[$tempname]['size']) {
|
||||||
// if the existing file is smaller, rename it
|
$smaller = uupAppendSha1($tempname, $files[$tempname]['sha1']);
|
||||||
$express = 'baseless_'.$tempname;
|
$files[$smaller] = $files[$tempname];
|
||||||
$files[$express] = $files[$tempname];
|
|
||||||
unset($files[$tempname]);
|
unset($files[$tempname]);
|
||||||
$newName = $tempname;
|
$newName = $tempname;
|
||||||
} else {
|
} else {
|
||||||
// if the new file is smaller, rename it
|
|
||||||
$newName = 'baseless_'.$tempname;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// not a cab file, append hash to differentiate
|
|
||||||
$newName = uupAppendSha1($tempname, $sha1);
|
$newName = uupAppendSha1($tempname, $sha1);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -518,8 +583,7 @@ function uupAppendSha1($name, $sha1) {
|
|||||||
|
|
||||||
function uupCleanSha256($name) {
|
function uupCleanSha256($name) {
|
||||||
$replace = array(
|
$replace = array(
|
||||||
'MetadataESD_' => null,
|
'prss_signed_appx_' => null,
|
||||||
'metadataesd_' => null,
|
|
||||||
'~31bf3856ad364e35' => null,
|
'~31bf3856ad364e35' => null,
|
||||||
'~~.' => '.',
|
'~~.' => '.',
|
||||||
'~.' => '.',
|
'~.' => '.',
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
/*
|
/*
|
||||||
Copyright 2019 UUP dump API authors
|
Copyright 2023 UUP dump API authors
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
@ -17,59 +17,35 @@ limitations under the License.
|
|||||||
|
|
||||||
require_once dirname(__FILE__).'/shared/main.php';
|
require_once dirname(__FILE__).'/shared/main.php';
|
||||||
require_once dirname(__FILE__).'/shared/packs.php';
|
require_once dirname(__FILE__).'/shared/packs.php';
|
||||||
require_once dirname(__FILE__).'/updateinfo.php';
|
|
||||||
|
|
||||||
function uupListEditions($lang = 'en-us', $updateId = 0) {
|
function uupListEditions($lang = 'en-us', $updateId = 0) {
|
||||||
if($updateId) {
|
|
||||||
$info = uupUpdateInfo($updateId);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!$lang) {
|
if(!$lang) {
|
||||||
return array('error' => 'UNSUPPORTED_LANG');
|
return array('error' => 'UNSUPPORTED_LANG');
|
||||||
}
|
}
|
||||||
|
|
||||||
if(isset($info['info'])) $info = $info['info'];
|
|
||||||
|
|
||||||
if(isset($info['build'])) {
|
|
||||||
$build = explode('.', $info['build']);
|
|
||||||
$build = $build[0];
|
|
||||||
} else {
|
|
||||||
$build = 15063;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!isset($info['arch'])) {
|
|
||||||
$info['arch'] = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
$genPack = uupGetGenPacks($build, $info['arch'], $updateId);
|
|
||||||
$fancyTexts = uupGetInfoTexts();
|
|
||||||
$fancyEditionNames = $fancyTexts['fancyEditionNames'];
|
|
||||||
|
|
||||||
if($lang) {
|
|
||||||
$lang = strtolower($lang);
|
$lang = strtolower($lang);
|
||||||
|
$genPack = uupApiGetPacks($updateId);
|
||||||
|
$fancyEditionNames = uupGetInfoTexts()['fancyEditionNames'];
|
||||||
|
|
||||||
if(!isset($genPack[$lang])) {
|
if(!isset($genPack[$lang])) {
|
||||||
return array('error' => 'UNSUPPORTED_LANG');
|
return array('error' => 'UNSUPPORTED_LANG');
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
$editionList = array();
|
$editionList = [];
|
||||||
$editionListFancy = array();
|
$editionListFancy = [];
|
||||||
|
|
||||||
foreach(array_keys($genPack[$lang]) as $edition) {
|
foreach(array_keys($genPack[$lang]) as $edition) {
|
||||||
if($edition == 'LXP') continue;
|
if(in_array($edition, ['LXP', 'FOD'])) continue;
|
||||||
|
|
||||||
if(isset($fancyEditionNames[$edition])) {
|
$fancyName = isset($fancyEditionNames[$edition]) ? $fancyEditionNames[$edition] : $edition;
|
||||||
$fancyName = $fancyEditionNames[$edition];
|
|
||||||
} else {
|
|
||||||
$fancyName = $edition;
|
|
||||||
}
|
|
||||||
|
|
||||||
$editionList[] = $edition;
|
$editionList[] = $edition;
|
||||||
$editionListFancy[$edition] = $fancyName;
|
$editionListFancy[$edition] = $fancyName;
|
||||||
}
|
}
|
||||||
|
|
||||||
return array(
|
return [
|
||||||
'apiVersion' => uupApiVersion(),
|
'apiVersion' => uupApiVersion(),
|
||||||
'editionList' => $editionList,
|
'editionList' => $editionList,
|
||||||
'editionFancyNames' => $editionListFancy,
|
'editionFancyNames' => $editionListFancy,
|
||||||
);
|
];
|
||||||
}
|
}
|
||||||
|
59
listid.php
59
listid.php
@ -16,22 +16,31 @@ limitations under the License.
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
require_once dirname(__FILE__).'/shared/main.php';
|
require_once dirname(__FILE__).'/shared/main.php';
|
||||||
|
require_once dirname(__FILE__).'/shared/cache.php';
|
||||||
|
require_once dirname(__FILE__).'/shared/fileinfo.php';
|
||||||
|
|
||||||
function uupListIds($search = null, $sortByDate = 0) {
|
function uupApiPrivateInvalidateFileinfoCache() {
|
||||||
uupApiPrintBrand();
|
$cache1 = new UupDumpCache('listid-0', false);
|
||||||
|
$cache2 = new UupDumpCache('listid-1', false);
|
||||||
|
|
||||||
if(!file_exists('fileinfo')) return array('error' => 'NO_FILEINFO_DIR');
|
$cache1->delete();
|
||||||
|
$cache2->delete();
|
||||||
|
}
|
||||||
|
|
||||||
$files = scandir('fileinfo');
|
function uupApiPrivateGetFromFileinfo($sortByDate = 0) {
|
||||||
|
$dirs = uupApiGetFileinfoDirs();
|
||||||
|
$fileinfo = $dirs['fileinfoData'];
|
||||||
|
$fileinfoRoot = $dirs['fileinfo'];
|
||||||
|
|
||||||
|
$files = scandir($fileinfo);
|
||||||
$files = preg_grep('/\.json$/', $files);
|
$files = preg_grep('/\.json$/', $files);
|
||||||
|
|
||||||
consoleLogger('Parsing database info...');
|
consoleLogger('Parsing database info...');
|
||||||
|
|
||||||
$cacheFile = 'cache/fileinfo_v2.json';
|
$cacheFile = $fileinfoRoot.'/cache.json';
|
||||||
$cacheV2Version = 1;
|
$cacheV2Version = 1;
|
||||||
|
|
||||||
$database = @file_get_contents($cacheFile);
|
$database = uupApiReadJson($cacheFile);
|
||||||
$database = json_decode($database, true);
|
|
||||||
|
|
||||||
if(isset($database['version'])) {
|
if(isset($database['version'])) {
|
||||||
$version = $database['version'];
|
$version = $database['version'];
|
||||||
@ -50,12 +59,13 @@ function uupListIds($search = null, $sortByDate = 0) {
|
|||||||
$newDb = array();
|
$newDb = array();
|
||||||
$builds = array();
|
$builds = array();
|
||||||
foreach($files as $file) {
|
foreach($files as $file) {
|
||||||
if($file == '.' || $file == '..') continue;
|
if($file == '.' || $file == '..')
|
||||||
|
continue;
|
||||||
|
|
||||||
$uuid = preg_replace('/\.json$/', '', $file);
|
$uuid = preg_replace('/\.json$/', '', $file);
|
||||||
|
|
||||||
if(!isset($database[$uuid])) {
|
if(!isset($database[$uuid])) {
|
||||||
$info = @file_get_contents('fileinfo/'.$file);
|
$info = uupApiReadFileinfoMeta($uuid);
|
||||||
$info = json_decode($info, true);
|
|
||||||
|
|
||||||
$title = isset($info['title']) ? $info['title'] : 'UNKNOWN';
|
$title = isset($info['title']) ? $info['title'] : 'UNKNOWN';
|
||||||
$build = isset($info['build']) ? $info['build'] : 'UNKNOWN';
|
$build = isset($info['build']) ? $info['build'] : 'UNKNOWN';
|
||||||
@ -105,12 +115,7 @@ function uupListIds($search = null, $sortByDate = 0) {
|
|||||||
$builds[$tmp.$arch.$title.$uuid] = $temp;
|
$builds[$tmp.$arch.$title.$uuid] = $temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(empty($buildAssoc)) {
|
if(empty($buildAssoc)) return [];
|
||||||
return array(
|
|
||||||
'apiVersion' => uupApiVersion(),
|
|
||||||
'builds' => array(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
krsort($buildAssoc);
|
krsort($buildAssoc);
|
||||||
$buildsNew = array();
|
$buildsNew = array();
|
||||||
@ -141,7 +146,27 @@ function uupListIds($search = null, $sortByDate = 0) {
|
|||||||
if(!$success) consoleLogger('Failed to update database cache.');
|
if(!$success) consoleLogger('Failed to update database cache.');
|
||||||
}
|
}
|
||||||
|
|
||||||
if($search) {
|
return $builds;
|
||||||
|
}
|
||||||
|
|
||||||
|
function uupListIds($search = null, $sortByDate = 0) {
|
||||||
|
uupApiPrintBrand();
|
||||||
|
|
||||||
|
$sortByDate = $sortByDate ? 1 : 0;
|
||||||
|
|
||||||
|
$res = "listid-$sortByDate";
|
||||||
|
$cache = new UupDumpCache($res, false);
|
||||||
|
$builds = $cache->get();
|
||||||
|
$cached = ($builds !== false);
|
||||||
|
|
||||||
|
if(!$cached) {
|
||||||
|
$builds = uupApiPrivateGetFromFileinfo($sortByDate);
|
||||||
|
if($builds === false) return ['error' => 'NO_FILEINFO_DIR'];
|
||||||
|
|
||||||
|
$cache->put($builds, 60);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(count($builds) && $search != null) {
|
||||||
if(!preg_match('/^regex:/', $search)) {
|
if(!preg_match('/^regex:/', $search)) {
|
||||||
$searchSafe = preg_quote($search, '/');
|
$searchSafe = preg_quote($search, '/');
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
/*
|
/*
|
||||||
Copyright 2019 UUP dump API authors
|
Copyright 2023 UUP dump API authors
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
@ -19,60 +19,45 @@ require_once dirname(__FILE__).'/shared/main.php';
|
|||||||
require_once dirname(__FILE__).'/shared/packs.php';
|
require_once dirname(__FILE__).'/shared/packs.php';
|
||||||
require_once dirname(__FILE__).'/updateinfo.php';
|
require_once dirname(__FILE__).'/updateinfo.php';
|
||||||
|
|
||||||
function uupListLangs($updateId = 0) {
|
function uupListLangsInternal($updateId) {
|
||||||
if($updateId) {
|
$genPack = uupApiGetPacks($updateId);
|
||||||
$info = uupUpdateInfo($updateId);
|
$fancyLangNames = uupGetInfoTexts()['fancyLangNames'];
|
||||||
}
|
|
||||||
|
|
||||||
if(isset($info['info'])) {
|
$langList = [];
|
||||||
$info = $info['info'];
|
$langListFancy = [];
|
||||||
unset($info['files']);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(isset($info['build'])) {
|
|
||||||
$build = explode('.', $info['build']);
|
|
||||||
$build = $build[0];
|
|
||||||
} else {
|
|
||||||
$build = 15063;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!isset($info['arch'])) {
|
|
||||||
$info['arch'] = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
$genPack = uupGetGenPacks($build, $info['arch'], $updateId);
|
|
||||||
$fancyTexts = uupGetInfoTexts();
|
|
||||||
$fancyLangNames = $fancyTexts['fancyLangNames'];
|
|
||||||
|
|
||||||
$langList = array();
|
|
||||||
$langListFancy = array();
|
|
||||||
foreach($genPack as $key => $val) {
|
foreach($genPack as $key => $val) {
|
||||||
if(!count(array_diff(array_keys($val), array('LXP')))) {
|
if(!count(array_diff(array_keys($val), ['LXP', 'FOD']))) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(isset($fancyLangNames[$key])) {
|
$fancyName = isset($fancyLangNames[$key]) ? $fancyLangNames[$key] : $key;
|
||||||
$fancyName = $fancyLangNames[$key];
|
|
||||||
} else {
|
|
||||||
$fancyName = $key;
|
|
||||||
}
|
|
||||||
|
|
||||||
$langList[] = $key;
|
$langList[] = $key;
|
||||||
$langListFancy[$key] = $fancyName;
|
$langListFancy[$key] = $fancyName;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(isset($info)) {
|
return [
|
||||||
return array(
|
|
||||||
'apiVersion' => uupApiVersion(),
|
|
||||||
'langList' => $langList,
|
'langList' => $langList,
|
||||||
'langFancyNames' => $langListFancy,
|
'langFancyNames' => $langListFancy,
|
||||||
'updateInfo' => $info
|
'appxPresent' => uupAreAppxPresent($genPack),
|
||||||
);
|
];
|
||||||
} else {
|
|
||||||
return array(
|
|
||||||
'apiVersion' => uupApiVersion(),
|
|
||||||
'langList' => $langList,
|
|
||||||
'langFancyNames' => $langListFancy
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function uupListLangs($updateId = 0, $returnInfo = true) {
|
||||||
|
if($returnInfo) {
|
||||||
|
$info = uupUpdateInfo($updateId, ignoreFiles: true);
|
||||||
|
$info = isset($info['info']) ? $info['info'] : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$langList = uupListLangsInternal($updateId);
|
||||||
|
|
||||||
|
$response = array_merge(
|
||||||
|
['apiVersion' => uupApiVersion()],
|
||||||
|
$langList
|
||||||
|
);
|
||||||
|
|
||||||
|
if($returnInfo) $response['updateInfo'] = $info;
|
||||||
|
|
||||||
|
return $response;
|
||||||
}
|
}
|
||||||
|
38
readme.md
38
readme.md
@ -10,7 +10,7 @@ Parameters:
|
|||||||
- **Supported values:** `amd64`, `x86`, `arm64`, `all`
|
- **Supported values:** `amd64`, `x86`, `arm64`, `all`
|
||||||
|
|
||||||
- `ring` - Channel to use when fetching information (Previously called Ring)
|
- `ring` - Channel to use when fetching information (Previously called Ring)
|
||||||
- **Supported values:** `Dev`, `Beta`, `ReleasePreview`, `Retail`
|
- **Supported values:** `Canary`, `Dev`, `Beta`, `ReleasePreview`, `Retail`
|
||||||
- **Supported Ring values :** `WIF`, `WIS`, `RP`
|
- **Supported Ring values :** `WIF`, `WIS`, `RP`
|
||||||
|
|
||||||
- `flight` - Content type to use when fetching information (Previously called Flight)
|
- `flight` - Content type to use when fetching information (Previously called Flight)
|
||||||
@ -18,10 +18,10 @@ Parameters:
|
|||||||
- **Supported Flight values:** `Active`, `Skip`, `Current`
|
- **Supported Flight values:** `Active`, `Skip`, `Current`
|
||||||
- **NOTE:** `Skip` is for `WIF` ring only. `Current` is for `RP` ring only.
|
- **NOTE:** `Skip` is for `WIF` ring only. `Current` is for `RP` ring only.
|
||||||
|
|
||||||
- `build` - Build number to use when fetching information
|
- `build` - Build number to use when fetching information. Can also be used to provide optional fetch flags in `major.minor+flag1,flag2` format.
|
||||||
- **Supported values:** >= 9841 and <= PHP_INT_MAX-1
|
- **Supported values:** Any correctly formatted build (`major` or `major.minor`) from range of 9841 and `PHP_INT_MAX-1`.
|
||||||
|
|
||||||
- `minor` - Build minor to use when fetching information
|
- `minor` - Build minor to use when fetching information. Unused when build is formatted in `major.minor` format
|
||||||
- **Supported values:** >= 0 and <= PHP_INT_MAX-1
|
- **Supported values:** >= 0 and <= PHP_INT_MAX-1
|
||||||
|
|
||||||
- `sku` - SKU number to use when fetching information
|
- `sku` - SKU number to use when fetching information
|
||||||
@ -80,9 +80,11 @@ Outputs list of languages supported for specified Update ID.
|
|||||||
Parameters:
|
Parameters:
|
||||||
- `updateId` - Update identifier (optional)
|
- `updateId` - Update identifier (optional)
|
||||||
- **Supported values:** any update UUID
|
- **Supported values:** any update UUID
|
||||||
|
- `returnInfo` - Should the full update inforation be returned with a list of languages
|
||||||
|
- **Supported values:** `true` or `false`
|
||||||
|
|
||||||
|
|
||||||
#### updateinfo.php: `uupUpdateInfo($updateId, $onlyInfo);`
|
#### updateinfo.php: `uupUpdateInfo($updateId, $onlyInfo, $ignoreFiles);`
|
||||||
Outputs specified information of specified `updateId`.
|
Outputs specified information of specified `updateId`.
|
||||||
|
|
||||||
Parameters:
|
Parameters:
|
||||||
@ -92,12 +94,36 @@ Parameters:
|
|||||||
- `onlyInfo` - Key to output
|
- `onlyInfo` - Key to output
|
||||||
- **Supported values:** any string
|
- **Supported values:** any string
|
||||||
|
|
||||||
|
- `ignoreFiles` - Skips the `files` key in the output
|
||||||
|
- **Supported values:** `true` or `false`
|
||||||
|
|
||||||
#### shared/main.php: `uupApiVersion();`
|
#### shared/main.php: `uupApiVersion();`
|
||||||
Returns version of the API.
|
Returns version of the API.
|
||||||
|
|
||||||
Parameters:
|
Parameters:
|
||||||
- None
|
- None
|
||||||
|
|
||||||
|
#### shared/utils.php: `uupApiCheckUpdateId($updateId);`
|
||||||
|
Checks if the provided update ID is correctly formatted.
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
- `updateId` - update ID to check
|
||||||
|
- **Supported values:** Any string
|
||||||
|
|
||||||
|
#### shared/utils.php: `uupApiIsServer($skuId);`
|
||||||
|
Checks if the provided SKU ID is a Windows Sever SKU.
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
- `skuId` - SKU ID to check
|
||||||
|
- **Supported values:** Any integer
|
||||||
|
|
||||||
|
#### shared/utils.php: `uupApiBuildMajor($build);`
|
||||||
|
Returns a build major of the build number.
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
- `build` - Build number (for example 22621.1) to split
|
||||||
|
- **Supported values:** Any correctly formatted build number
|
||||||
|
|
||||||
### Error codes thrown by API
|
### Error codes thrown by API
|
||||||
**fetchupd.php**
|
**fetchupd.php**
|
||||||
- UNKNOWN_ARCH
|
- UNKNOWN_ARCH
|
||||||
@ -108,6 +134,7 @@ Parameters:
|
|||||||
- ILLEGAL_MINOR
|
- ILLEGAL_MINOR
|
||||||
- NO_UPDATE_FOUND
|
- NO_UPDATE_FOUND
|
||||||
- EMPTY_FILELIST
|
- EMPTY_FILELIST
|
||||||
|
- WU_REQUEST_FAILED
|
||||||
|
|
||||||
**get.php**
|
**get.php**
|
||||||
- UNSUPPORTED_LANG
|
- UNSUPPORTED_LANG
|
||||||
@ -118,6 +145,7 @@ Parameters:
|
|||||||
- MISSING_FILES
|
- MISSING_FILES
|
||||||
- NO_FILES
|
- NO_FILES
|
||||||
- XML_PARSE_ERROR
|
- XML_PARSE_ERROR
|
||||||
|
- WU_REQUEST_FAILED
|
||||||
|
|
||||||
**listeditions.php**
|
**listeditions.php**
|
||||||
- UNSUPPORTED_LANG
|
- UNSUPPORTED_LANG
|
||||||
|
@ -25,19 +25,46 @@ function uupDevice() {
|
|||||||
return base64_encode(chunk_split($data, 1, "\0"));
|
return base64_encode(chunk_split($data, 1, "\0"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function uupSaveCookieFromResponse($out) {
|
||||||
|
$outDecoded = html_entity_decode($out);
|
||||||
|
preg_match('/<NewCookie>.*?<\/NewCookie>|<GetCookieResult>.*?<\/GetCookieResult>/', $outDecoded, $cookieData);
|
||||||
|
|
||||||
|
if(empty($cookieData))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
preg_match('/<Expiration>.*<\/Expiration>/', $cookieData[0], $expirationDate);
|
||||||
|
preg_match('/<EncryptedData>.*<\/EncryptedData>/', $cookieData[0], $encryptedData);
|
||||||
|
|
||||||
|
$expirationDate = preg_replace('/<Expiration>|<\/Expiration>/', '', $expirationDate[0]);
|
||||||
|
$encryptedData = preg_replace('/<EncryptedData>|<\/EncryptedData>/', '', $encryptedData[0]);
|
||||||
|
|
||||||
|
$cookieData = array(
|
||||||
|
'expirationDate' => $expirationDate,
|
||||||
|
'encryptedData' => $encryptedData,
|
||||||
|
);
|
||||||
|
|
||||||
|
$cookieStorage = new UupDumpCache('WuRequestCookie', false);
|
||||||
|
$cookieStorage->put($cookieData, false);
|
||||||
|
|
||||||
|
return $cookieData;
|
||||||
|
}
|
||||||
|
|
||||||
|
function uupInvalidateCookie() {
|
||||||
|
$cookieStorage = new UupDumpCache('WuRequestCookie', false);
|
||||||
|
$cookieInfo = $cookieStorage->delete();
|
||||||
|
}
|
||||||
|
|
||||||
function uupEncryptedData() {
|
function uupEncryptedData() {
|
||||||
$cookieInfo = @file_get_contents(dirname(__FILE__).'/cookie.json');
|
$cookieStorage = new UupDumpCache('WuRequestCookie', false);
|
||||||
$cookieInfo = json_decode($cookieInfo, 1);
|
$cookieInfo = $cookieStorage->get();
|
||||||
|
|
||||||
if(empty($cookieInfo)) {
|
if(empty($cookieInfo)) {
|
||||||
$postData = composeGetCookieRequest(uupDevice());
|
$data = sendWuPostRequestHelper('client', 'composeGetCookieRequest', [], false);
|
||||||
sendWuPostRequest('https://fe3.delivery.mp.microsoft.com/ClientWebService/client.asmx', $postData);
|
if($data === false || $data['error'] != 200)
|
||||||
|
return false;
|
||||||
|
|
||||||
$encData = uupEncryptedData();
|
$cookieInfo = uupSaveCookieFromResponse($data['out']);
|
||||||
} else {
|
|
||||||
$encData = $cookieInfo['encryptedData'];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $encData;
|
return $cookieInfo['encryptedData'];
|
||||||
}
|
}
|
||||||
?>
|
|
||||||
|
76
shared/cache.php
Normal file
76
shared/cache.php
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
Copyright 2022 eraseyourknees
|
||||||
|
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class UupDumpCache {
|
||||||
|
private $cacheFile;
|
||||||
|
private $newCacheVersion = 1;
|
||||||
|
|
||||||
|
public function __construct($resource, private $isCompressed = true) {
|
||||||
|
$res = $resource."+cache_v".$this->newCacheVersion;
|
||||||
|
$cacheHash = hash('sha256', strtolower($res));
|
||||||
|
$ext = $isCompressed ? '.json.gz' : '.json';
|
||||||
|
$this->cacheFile = 'cache/'.$cacheHash.$ext;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getFileName() {
|
||||||
|
return $this->cacheFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function delete() {
|
||||||
|
@unlink($this->cacheFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get() {
|
||||||
|
$cacheFile = $this->cacheFile;
|
||||||
|
|
||||||
|
if(!file_exists($cacheFile)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$cache = @file_get_contents($cacheFile);
|
||||||
|
if($this->isCompressed) $cache = @gzdecode($cache);
|
||||||
|
|
||||||
|
$cache = json_decode($cache, 1);
|
||||||
|
|
||||||
|
$expires = $cache['expires'];
|
||||||
|
$isExpired = ($expires !== false) && (time() > $expires);
|
||||||
|
|
||||||
|
if(empty($cache['content']) || $isExpired) {
|
||||||
|
$this->delete();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $cache['content'];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function put($content, $validity) {
|
||||||
|
$cacheFile = $this->cacheFile;
|
||||||
|
$expires = $validity ? time() + $validity : false;
|
||||||
|
|
||||||
|
$cache = array(
|
||||||
|
'expires' => $expires,
|
||||||
|
'content' => $content,
|
||||||
|
);
|
||||||
|
|
||||||
|
if(!file_exists('cache')) mkdir('cache');
|
||||||
|
|
||||||
|
$cacheContent = json_encode($cache)."\n";
|
||||||
|
if($this->isCompressed) $cacheContent = @gzencode($cacheContent);
|
||||||
|
|
||||||
|
@file_put_contents($cacheFile, $cacheContent);
|
||||||
|
}
|
||||||
|
}
|
94
shared/fileinfo.php
Normal file
94
shared/fileinfo.php
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
Copyright 2022 UUP dump API authors
|
||||||
|
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
require_once dirname(__FILE__).'/utils.php';
|
||||||
|
|
||||||
|
function uupApiGetFileinfoDirs() {
|
||||||
|
$dirs = [];
|
||||||
|
$dirs['fileinfo'] = 'fileinfo';
|
||||||
|
$dirs['fileinfoMeta'] = $dirs['fileinfo'].'/metadata';
|
||||||
|
$dirs['fileinfoData'] = $dirs['fileinfo'].'/full';
|
||||||
|
|
||||||
|
foreach($dirs as $dir) {
|
||||||
|
if(!file_exists($dir)) mkdir($dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $dirs;
|
||||||
|
}
|
||||||
|
|
||||||
|
function uupApiGetFileinfoName($updateId, $meta = false) {
|
||||||
|
$fileName = $updateId.'.json';
|
||||||
|
$dirs = uupApiGetFileinfoDirs();
|
||||||
|
|
||||||
|
$fileinfoMeta = $dirs['fileinfoMeta'].'/'.$fileName;
|
||||||
|
$fileinfoData = $dirs['fileinfoData'].'/'.$fileName;
|
||||||
|
|
||||||
|
return $meta ? $fileinfoMeta : $fileinfoData;
|
||||||
|
}
|
||||||
|
|
||||||
|
function uupApiFileInfoExists($updateId) {
|
||||||
|
return file_exists(uupApiGetFileinfoName($updateId));
|
||||||
|
}
|
||||||
|
|
||||||
|
function uupApiWriteFileinfoMeta($updateId, $info) {
|
||||||
|
if(isset($info['files']))
|
||||||
|
unset($info['files']);
|
||||||
|
|
||||||
|
$file = uupApiGetFileinfoName($updateId, true);
|
||||||
|
return uupApiWriteJson($file, $info);
|
||||||
|
}
|
||||||
|
|
||||||
|
function uupApiWriteFileinfo($updateId, $info) {
|
||||||
|
$file = uupApiGetFileinfoName($updateId);
|
||||||
|
|
||||||
|
if(uupApiWriteJson($file, $info) === false)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return uupApiWriteFileinfoMeta($updateId, $info);
|
||||||
|
}
|
||||||
|
|
||||||
|
function uupApiReadFileinfoMeta($updateId) {
|
||||||
|
$file = uupApiGetFileinfoName($updateId, true);
|
||||||
|
|
||||||
|
if(file_exists($file))
|
||||||
|
return uupApiReadJson($file);
|
||||||
|
|
||||||
|
$info = uupApiReadFileinfo($updateId, false);
|
||||||
|
if($info === false)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if(isset($info['files']))
|
||||||
|
unset($info['files']);
|
||||||
|
|
||||||
|
if(uupApiWriteFileinfoMeta($updateId, $info) === false)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return $info;
|
||||||
|
}
|
||||||
|
|
||||||
|
function uupApiReadFileinfo($updateId, $meta = false) {
|
||||||
|
if(!uupApiFileInfoExists($updateId))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if($meta === true)
|
||||||
|
return uupApiReadFileinfoMeta($updateId);
|
||||||
|
|
||||||
|
$file = uupApiGetFileinfoName($updateId);
|
||||||
|
$info = uupApiReadJson($file);
|
||||||
|
|
||||||
|
return $info;
|
||||||
|
}
|
@ -16,7 +16,7 @@ limitations under the License.
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
function uupApiVersion() {
|
function uupApiVersion() {
|
||||||
return '1.32.0';
|
return '1.48.0';
|
||||||
}
|
}
|
||||||
|
|
||||||
require_once dirname(__FILE__).'/auths.php';
|
require_once dirname(__FILE__).'/auths.php';
|
||||||
|
170
shared/packs.php
170
shared/packs.php
@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
/*
|
/*
|
||||||
Copyright 2021 UUP dump API authors
|
Copyright 2022 UUP dump API authors
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
@ -19,6 +19,7 @@ require_once dirname(__FILE__).'/../listid.php';
|
|||||||
|
|
||||||
function uupGetInfoTexts() {
|
function uupGetInfoTexts() {
|
||||||
$fancyLangNames = array(
|
$fancyLangNames = array(
|
||||||
|
'neutral' => 'Any Language',
|
||||||
'ar-sa' => 'Arabic (Saudi Arabia)',
|
'ar-sa' => 'Arabic (Saudi Arabia)',
|
||||||
'bg-bg' => 'Bulgarian',
|
'bg-bg' => 'Bulgarian',
|
||||||
'cs-cz' => 'Czech',
|
'cs-cz' => 'Czech',
|
||||||
@ -61,6 +62,9 @@ function uupGetInfoTexts() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
$fancyEditionNames = array(
|
$fancyEditionNames = array(
|
||||||
|
'APP' => 'Microsoft Store Inbox Apps',
|
||||||
|
'APP_MOMENT' => 'Microsoft Store Moment Apps',
|
||||||
|
'FOD' => 'Features on Demand (Capabilities)',
|
||||||
'CLOUD' => 'Windows S',
|
'CLOUD' => 'Windows S',
|
||||||
'CLOUDN' => 'Windows S N',
|
'CLOUDN' => 'Windows S N',
|
||||||
'CLOUDE' => 'Windows Lean',
|
'CLOUDE' => 'Windows Lean',
|
||||||
@ -79,6 +83,7 @@ function uupGetInfoTexts() {
|
|||||||
'PPIPRO' => 'Windows Team',
|
'PPIPRO' => 'Windows Team',
|
||||||
'PROFESSIONAL' => 'Windows Pro',
|
'PROFESSIONAL' => 'Windows Pro',
|
||||||
'PROFESSIONALN' => 'Windows Pro N',
|
'PROFESSIONALN' => 'Windows Pro N',
|
||||||
|
'PROFESSIONALCOUNTRYSPECIFIC' => 'Windows Pro China Only',
|
||||||
'SERVERSTANDARD' => 'Windows Server Standard',
|
'SERVERSTANDARD' => 'Windows Server Standard',
|
||||||
'SERVERSTANDARDCORE' => 'Windows Server Standard, Core',
|
'SERVERSTANDARDCORE' => 'Windows Server Standard, Core',
|
||||||
'SERVERDATACENTER' => 'Windows Server Datacenter',
|
'SERVERDATACENTER' => 'Windows Server Datacenter',
|
||||||
@ -198,166 +203,17 @@ function uupGetInfoTexts() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function uupGetGenPacks($build = 15063, $arch = null, $updateId = null) {
|
function uupApiGetPacks($updateId) {
|
||||||
$internalPacks = dirname(__FILE__).'/packs';
|
if(empty($updateId)) return [];
|
||||||
|
if(!file_exists('packs/'.$updateId.'.json.gz')) return [];
|
||||||
|
|
||||||
if(!file_exists($internalPacks.'/metadata.json')) {
|
|
||||||
if(!uupCreateInternalPacksMetadata($internalPacks)) {
|
|
||||||
return array();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!empty($updateId)) {
|
|
||||||
if(file_exists('packs/'.$updateId.'.json.gz')) {
|
|
||||||
$genPack = @gzdecode(@file_get_contents('packs/'.$updateId.'.json.gz'));
|
$genPack = @gzdecode(@file_get_contents('packs/'.$updateId.'.json.gz'));
|
||||||
if(empty($genPack)) return array();
|
if(empty($genPack)) return [];
|
||||||
|
|
||||||
$genPack = json_decode($genPack, 1);
|
$genPack = json_decode($genPack, 1);
|
||||||
return $genPack;
|
return $genPack;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
function uupGetGenPacks($build = 15063, $arch = null, $updateId = null) {
|
||||||
$metadata = @file_get_contents($internalPacks.'/metadata.json');
|
return uupApiGetPacks($updateId);
|
||||||
if(empty($metadata)) {
|
|
||||||
return array();
|
|
||||||
} else {
|
|
||||||
$metadata = json_decode($metadata, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
$hashDetermined = 0;
|
|
||||||
$useAllHashesForBuild = 0;
|
|
||||||
|
|
||||||
if($updateId) {
|
|
||||||
if(isset($metadata['knownIds'][$updateId])) {
|
|
||||||
$hash = $metadata['knownIds'][$updateId];
|
|
||||||
$hashDetermined = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!$hashDetermined) {
|
|
||||||
foreach($metadata['knownBuilds'] as $buildNum => $val) {
|
|
||||||
if($build < $buildNum) continue;
|
|
||||||
$useBuild = $buildNum;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!isset($useBuild)) {
|
|
||||||
return array();
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!$arch && !isset($metadata['knownBuilds'][$useBuild][$arch])) {
|
|
||||||
$genPack = array();
|
|
||||||
foreach($metadata['knownBuilds'][$useBuild] as $hash) {
|
|
||||||
$temp = @gzdecode(@file_get_contents($internalPacks.'/'.$hash.'.json.gz'));
|
|
||||||
if(!empty($temp)) {
|
|
||||||
$temp = json_decode($temp, 1);
|
|
||||||
$genPack = array_merge_recursive($genPack, $temp);
|
|
||||||
unset($temp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} elseif(!isset($metadata['knownBuilds'][$useBuild][$arch])) {
|
|
||||||
return array();
|
|
||||||
} else {
|
|
||||||
$hash = $metadata['knownBuilds'][$useBuild][$arch];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!isset($genPack)) {
|
|
||||||
$genPack = @gzdecode(@file_get_contents($internalPacks.'/'.$hash.'.json.gz'));
|
|
||||||
if(!empty($genPack)) {
|
|
||||||
$genPack = json_decode($genPack, 1);
|
|
||||||
} else {
|
|
||||||
$genPack = array();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $genPack;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Function to regenerate internal packs. Should not be used when not needed.
|
|
||||||
function uupCreateInternalPacksMetadata($internalPacks) {
|
|
||||||
$metadataCreationAllowed = 0;
|
|
||||||
if(!$metadataCreationAllowed) return false;
|
|
||||||
|
|
||||||
$builds = uupListIds();
|
|
||||||
if(isset($ids['error'])) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$builds = $builds['builds'];
|
|
||||||
|
|
||||||
if(!file_exists('packs')) return false;
|
|
||||||
|
|
||||||
if(!file_exists($internalPacks)) {
|
|
||||||
if(!mkdir($internalPacks)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
rmdir($internalPacks);
|
|
||||||
mkdir($internalPacks);
|
|
||||||
}
|
|
||||||
|
|
||||||
$files = scandir('packs');
|
|
||||||
$files = preg_grep('/\.json.gz$/', $files);
|
|
||||||
|
|
||||||
$packs = array();
|
|
||||||
foreach($builds as $build) {
|
|
||||||
$uuid = $build['uuid'];
|
|
||||||
$file = $uuid.'.json.gz';
|
|
||||||
|
|
||||||
if(!file_exists('packs/'.$file)) continue;
|
|
||||||
|
|
||||||
$genPack = @gzdecode(@file_get_contents('packs/'.$file));
|
|
||||||
$hash = hash('sha1', $genPack);
|
|
||||||
|
|
||||||
if(!file_exists($internalPacks.'/'.$hash.'.json.gz')) {
|
|
||||||
if(!copy('packs/'.$file, $internalPacks.'/'.$hash.'.json.gz')) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$packs['knownIds'][$uuid] = $hash;
|
|
||||||
|
|
||||||
$buildNum = explode('.', $build['build']);
|
|
||||||
$buildNum = $buildNum[0];
|
|
||||||
|
|
||||||
$packs['knownBuilds'][$buildNum][$build['arch']] = $hash;
|
|
||||||
}
|
|
||||||
|
|
||||||
file_put_contents($internalPacks.'/metadata.json', json_encode($packs)."\n");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Emulation of legacy packs. Do not use in new scripts due to extremely slow process.
|
|
||||||
function uupGetPacks($build = 15063) {
|
|
||||||
$returnArray = uupGetInfoTexts();
|
|
||||||
$genPack = uupGetGenPacks($build);
|
|
||||||
|
|
||||||
foreach($genPack as $lang => $editions) {
|
|
||||||
$packsForLangs[$lang] = array_keys($editions);
|
|
||||||
$packsForLangs[$lang][] = $lang;
|
|
||||||
|
|
||||||
foreach(array_keys($editions) as $edition) {
|
|
||||||
foreach($editions[$edition] as $name) {
|
|
||||||
$newName = preg_replace('/^cabs_|^metadataesd_|~31bf3856ad364e35/i', '', $name);
|
|
||||||
$newName = preg_replace('/~~\.|~\./', '.', $newName);
|
|
||||||
$newName = preg_replace('/~/', '-', $newName);
|
|
||||||
$newName = strtolower($newName);
|
|
||||||
$packs[$lang][$edition][] = $newName;
|
|
||||||
}
|
|
||||||
|
|
||||||
$editionPacks[$edition] = $edition;
|
|
||||||
$packs[$edition][$edition] = array();
|
|
||||||
$skipNeutral[$edition] = 1;
|
|
||||||
$skipLangPack[$edition] = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$returnArray['packs'] = $packs;
|
|
||||||
$returnArray['packsForLangs'] = $packsForLangs;
|
|
||||||
$returnArray['editionPacks'] = $editionPacks;
|
|
||||||
$returnArray['skipNeutral'] = $skipNeutral;
|
|
||||||
$returnArray['skipLangPack'] = $skipLangPack;
|
|
||||||
|
|
||||||
return $returnArray;
|
|
||||||
}
|
}
|
||||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user