From 5b62a1699c90bca37a65cce871738ae1ce91b5db Mon Sep 17 00:00:00 2001 From: mkuba50 Date: Sun, 29 Apr 2018 21:33:19 +0200 Subject: [PATCH] UUP dump API 1.14.0 - Added support of pregenerated update packs - Added support of fetching updates that need custom SKU ID --- fetchupd.php | 13 +++++--- get.php | 70 ++++++++++++++++++++++++++++++++++++++++- listeditions.php | 23 ++++++++++++-- listlangs.php | 16 +++++++--- shared/main.php | 2 +- shared/packs.php | 17 ++++++++++ shared/packs/17063.php | 8 ----- shared/packs/17093.php | 8 ----- shared/packs/17623.php | 8 ----- shared/packs/17634.php | 8 ----- shared/packs/17650.php | 9 +----- shared/packs/17655.php | 11 ++----- shared/packs/legacy.php | 15 --------- shared/requests.php | 12 ++++--- 14 files changed, 139 insertions(+), 81 deletions(-) diff --git a/fetchupd.php b/fetchupd.php index 6693189..02b24ea 100644 --- a/fetchupd.php +++ b/fetchupd.php @@ -19,7 +19,7 @@ require_once dirname(__FILE__).'/shared/main.php'; require_once dirname(__FILE__).'/shared/requests.php'; require_once dirname(__FILE__).'/listid.php'; -function uupFetchUpd($arch = 'amd64', $ring = 'WIF', $flight = 'Active', $build = '16251', $minor = '0') { +function uupFetchUpd($arch = 'amd64', $ring = 'WIF', $flight = 'Active', $build = '16251', $minor = '0', $sku = '48') { uupApiPrintBrand(); $arch = strtolower($arch); @@ -30,6 +30,7 @@ function uupFetchUpd($arch = 'amd64', $ring = 'WIF', $flight = 'Active', $build $build = explode('.', $build); if(isset($build[1])) $minor = intval($build[1]); $build = intval($build[0]); + $sku = intval($sku); if(!($arch == 'amd64' || $arch == 'x86' || $arch == 'arm64')) { return array('error' => 'UNKNOWN_ARCH'); @@ -60,7 +61,7 @@ function uupFetchUpd($arch = 'amd64', $ring = 'WIF', $flight = 'Active', $build $build = '10.0.'.$build.'.'.$minor; consoleLogger('Fetching information from the server...'); - $postData = composeFetchUpdRequest(uupDevice(), uupEncryptedData(), $arch, $flight, $ring, $build); + $postData = composeFetchUpdRequest(uupDevice(), uupEncryptedData(), $arch, $flight, $ring, $build, $sku); $out = sendWuPostRequest('https://fe3.delivery.mp.microsoft.com/ClientWebService/client.asmx', $postData); $out = html_entity_decode($out); @@ -84,7 +85,7 @@ function uupFetchUpd($arch = 'amd64', $ring = 'WIF', $flight = 'Active', $build $num++; consoleLogger("Checking build information for update {$num} of {$updatesNum}..."); - $info = parseFetchUpdate($val, $out, $arch, $ring, $flight, $build); + $info = parseFetchUpdate($val, $out, $arch, $ring, $flight, $build, $sku); if(isset($info['error'])) { $errorCount++; continue; @@ -108,7 +109,7 @@ function uupFetchUpd($arch = 'amd64', $ring = 'WIF', $flight = 'Active', $build ); } -function parseFetchUpdate($updateInfo, $out, $arch, $ring, $flight, $build) { +function parseFetchUpdate($updateInfo, $out, $arch, $ring, $flight, $build, $sku = '48') { $updateNumId = preg_replace('/|<\/ID>.*/i', '', $updateInfo); $updates = preg_replace('//', "\n", $out); @@ -218,6 +219,7 @@ function parseFetchUpdate($updateInfo, $out, $arch, $ring, $flight, $build) { $temp['arch'] = $arch; $temp['build'] = $foundBuild; $temp['checkBuild'] = $build; + $temp['sku'] = $sku; if($isCumulativeUpdate) { $temp['containsCU'] = 1; @@ -248,6 +250,9 @@ function parseFetchUpdate($updateInfo, $out, $arch, $ring, $flight, $build) { $testName = $val['build'].' '.$val['title'].' '.$val['arch']; if($buildName == $testName && $val['uuid'] != $updateString) { unlink(realpath('fileinfo/'.$val['uuid'].'.json')); + if(file_exists('packs/'.$val['uuid'].'.json.gz')) { + unlink(realpath('packs/'.$val['uuid'].'.json.gz')); + } consoleLogger('Removed superseded update: '.$val['uuid']); } } diff --git a/get.php b/get.php index 208da9f..965b669 100644 --- a/get.php +++ b/get.php @@ -29,6 +29,7 @@ function uupGetFiles($updateId = 'c2a1d787-647b-486d-b264-f90f3782cdc6', $usePac 'flight' => 'Active', 'arch' => 'amd64', 'checkBuild' => '10.0.16251.0', + 'sku' => '48', 'files' => array(), ); } else { @@ -42,6 +43,10 @@ function uupGetFiles($updateId = 'c2a1d787-647b-486d-b264-f90f3782cdc6', $usePac $build = 9841; } + if(!isset($info['sku'])) { + $info['sku'] = 48; + } + $packs = uupGetPacks($build); $packsForLangs = $packs['packsForLangs']; $editionPacks = $packs['editionPacks']; @@ -53,6 +58,25 @@ function uupGetFiles($updateId = 'c2a1d787-647b-486d-b264-f90f3782cdc6', $usePac $noLangPack = 0; $noNeutral = 0; + $useGeneratedPacks = 0; + + if(file_exists('packs/'.$updateId.'.json.gz') && $usePack) { + $genPack = @gzdecode(@file_get_contents('packs/'.$updateId.'.json.gz')); + + if(!empty($genPack)) { + $genPack = json_decode($genPack, 1); + + if(!isset($genPack[$usePack])) { + return array('error' => 'UNSUPPORTED_LANG'); + } + + $packsForLangs = array(); + $packsForLangs[$usePack] = array(0); + + $useGeneratedPacks = 1; + } + } + if($usePack) { $usePack = strtolower($usePack); if(!isset($packsForLangs[$usePack])) { @@ -63,7 +87,22 @@ function uupGetFiles($updateId = 'c2a1d787-647b-486d-b264-f90f3782cdc6', $usePac $desiredEdition = strtoupper($desiredEdition); switch($desiredEdition) { - case '0': break; + case '0': + if($useGeneratedPacks) { + $desiredEdition = 'GENERATEDPACKS'; + + $filesList = array(); + foreach($genPack[$usePack] as $val) { + foreach($val as $package) { + $filesList[] = $package; + } + } + + array_unique($filesList); + sort($filesList); + } + break; + case 'WUBFILE': break; case 'UPDATEONLY': @@ -73,9 +112,20 @@ function uupGetFiles($updateId = 'c2a1d787-647b-486d-b264-f90f3782cdc6', $usePac break; default: + if($useGeneratedPacks) { + if(!isset($genPack[$usePack][$desiredEdition])) { + return array('error' => 'UNSUPPORTED_COMBINATION'); + } + + $filesList = $genPack[$usePack][$desiredEdition]; + $desiredEdition = 'GENERATEDPACKS'; + break; + } + if(!$usePack) { return array('error' => 'UNSPECIFIED_LANG'); } + if(!isset($editionPacks[$desiredEdition])) { return array('error' => 'UNSUPPORTED_EDITION'); } @@ -253,6 +303,10 @@ function uupGetFiles($updateId = 'c2a1d787-647b-486d-b264-f90f3782cdc6', $usePac $filesKeys = preg_grep('/WindowsUpdateBox.exe/i', $filesKeys); break; + case 'GENERATEDPACKS': + $skipPackBuild = 1; + break; + default: $skipPackBuild = 0; break; @@ -314,6 +368,20 @@ function uupGetFiles($updateId = 'c2a1d787-647b-486d-b264-f90f3782cdc6', $usePac unset($filesTemp, $temp, $val, $num); } + if($desiredEdition == 'GENERATEDPACKS') { + $newFiles = array(); + foreach($filesList as $val) { + $name = preg_replace('/~31bf3856ad364e35/', '', $val); + $name = preg_replace('/~~\.|~\./', '.', $name); + $name = preg_replace('/~/', '-', $name); + + $newFiles[$name] = $files[$name]; + } + + $files = $newFiles; + $filesKeys = array_keys($files); + } + if(empty($filesKeys)) { return array('error' => 'NO_FILES'); } diff --git a/listeditions.php b/listeditions.php index 464164c..7b67e59 100644 --- a/listeditions.php +++ b/listeditions.php @@ -36,6 +36,24 @@ function uupListEditions($lang = 'en-us', $updateId = 0) { $fancyEditionNames = $packs['fancyEditionNames']; $packs = $packs['packs']; + if(file_exists('packs/'.$updateId.'.json.gz')) { + $genPack = @gzdecode(@file_get_contents('packs/'.$updateId.'.json.gz')); + + if(!empty($genPack)) { + $genPack = json_decode($genPack, 1); + + if(!isset($genPack[$lang])) { + return array('error' => 'UNSUPPORTED_LANG'); + } + + $packsForLangs = array(); + $packsForLangs[$lang] = array(0); + + $packs = array(); + $packs[0] = $genPack[$lang]; + } + } + if($lang) { $lang = strtolower($lang); if(!isset($packsForLangs[$lang])) { @@ -55,9 +73,8 @@ function uupListEditions($lang = 'en-us', $updateId = 0) { $fancyName = $edition; } - $temp = array($edition => $fancyName); - $editionList = array_merge($editionList, array($edition)); - $editionListFancy = array_merge($editionListFancy, $temp); + $editionList[] = $edition; + $editionListFancy[$edition] = $fancyName; } } diff --git a/listlangs.php b/listlangs.php index b0eb431..bcd31dc 100644 --- a/listlangs.php +++ b/listlangs.php @@ -35,18 +35,26 @@ function uupListLangs($updateId = 0) { $packsForLangs = $packs['packsForLangs']; $fancyLangNames = $packs['fancyLangNames']; + if(file_exists('packs/'.$updateId.'.json.gz')) { + $genPack = @gzdecode(@file_get_contents('packs/'.$updateId.'.json.gz')); + + if(!empty($genPack)) { + $genPack = json_decode($genPack, 1); + $packsForLangs = $genPack; + } + } + $langList = array(); $langListFancy = array(); foreach($packsForLangs as $key => $val) { - if(isset($packsForLangs[$key])) { + if(isset($fancyLangNames[$key])) { $fancyName = $fancyLangNames[$key]; } else { $fancyName = $key; } - $temp = array($key => $fancyName); - $langList = array_merge($langList, array($key)); - $langListFancy = array_merge($langListFancy, $temp); + $langList[] = $key; + $langListFancy[$key] = $fancyName; } return array( diff --git a/shared/main.php b/shared/main.php index 0272a5f..a2b1031 100644 --- a/shared/main.php +++ b/shared/main.php @@ -16,7 +16,7 @@ limitations under the License. */ function uupApiVersion() { - return '1.13.3'; + return '1.14.0'; } function uupApiPrintBrand() { diff --git a/shared/packs.php b/shared/packs.php index dc48f81..b23d63f 100644 --- a/shared/packs.php +++ b/shared/packs.php @@ -57,6 +57,23 @@ function uupGetPacks($build = 15063) { 'zh-tw' => 'Chinese (Traditional)', ); + $fancyEditionNames = array( + 'CLOUD' => 'Windows 10 S', + 'CLOUDN' => 'Windows 10 S N', + 'CLOUDE' => 'Windows 10 CloudE', + 'CORE' => 'Windows 10 Home', + 'CORECOUNTRYSPECIFIC' => 'Windows 10 Home China', + 'COREN' => 'Windows 10 Home N', + 'CORESINGLELANGUAGE' => 'Windows 10 Home Single Language', + 'EDUCATION' => 'Windows 10 Education', + 'EDUCATIONN' => 'Windows 10 Education N', + 'ENTERPRISE' => 'Windows 10 Enterprise', + 'ENTERPRISEN' => 'Windows 10 Enterprise N', + 'PPIPRO' => 'Windows 10 Team', + 'PROFESSIONAL' => 'Windows 10 Pro', + 'PROFESSIONALN' => 'Windows 10 Pro N', + ); + $allEditions = array( 'ANALOGONECORE', 'ANDROMEDA', diff --git a/shared/packs/17063.php b/shared/packs/17063.php index abce071..11872e1 100644 --- a/shared/packs/17063.php +++ b/shared/packs/17063.php @@ -176,14 +176,6 @@ $editionPacks = array( 'PROFESSIONALN' => 1, ); -$fancyEditionNames = array( - 'CORE' => 'Windows 10 Home', - 'CORECOUNTRYSPECIFIC' => 'Windows 10 Home China', - 'COREN' => 'Windows 10 Home N', - 'PROFESSIONAL' => 'Windows 10 Pro', - 'PROFESSIONALN' => 'Windows 10 Pro N', -); - $skipNeutral = array(); $skipLangPack = array(); ?> diff --git a/shared/packs/17093.php b/shared/packs/17093.php index 6c04a9e..b3051f4 100644 --- a/shared/packs/17093.php +++ b/shared/packs/17093.php @@ -177,14 +177,6 @@ $editionPacks = array( 'PROFESSIONALN' => 1, ); -$fancyEditionNames = array( - 'CORE' => 'Windows 10 Home', - 'CORECOUNTRYSPECIFIC' => 'Windows 10 Home China', - 'COREN' => 'Windows 10 Home N', - 'PROFESSIONAL' => 'Windows 10 Pro', - 'PROFESSIONALN' => 'Windows 10 Pro N', -); - $skipNeutral = array(); $skipLangPack = array(); ?> diff --git a/shared/packs/17623.php b/shared/packs/17623.php index 3144b6b..819e7b8 100644 --- a/shared/packs/17623.php +++ b/shared/packs/17623.php @@ -181,14 +181,6 @@ $editionPacks = array( 'PROFESSIONALN' => 1, ); -$fancyEditionNames = array( - 'CORE' => 'Windows 10 Home', - 'CORECOUNTRYSPECIFIC' => 'Windows 10 Home China', - 'COREN' => 'Windows 10 Home N', - 'PROFESSIONAL' => 'Windows 10 Pro', - 'PROFESSIONALN' => 'Windows 10 Pro N', -); - $skipNeutral = array(); $skipLangPack = array(); ?> diff --git a/shared/packs/17634.php b/shared/packs/17634.php index 378d81e..5a36236 100644 --- a/shared/packs/17634.php +++ b/shared/packs/17634.php @@ -184,14 +184,6 @@ $editionPacks = array( 'PROFESSIONALN' => 1, ); -$fancyEditionNames = array( - 'CORE' => 'Windows 10 Home', - 'CORECOUNTRYSPECIFIC' => 'Windows 10 Home China', - 'COREN' => 'Windows 10 Home N', - 'PROFESSIONAL' => 'Windows 10 Pro', - 'PROFESSIONALN' => 'Windows 10 Pro N', -); - $skipNeutral = array(); $skipLangPack = array(); ?> diff --git a/shared/packs/17650.php b/shared/packs/17650.php index 34daaf2..b8a9dad 100644 --- a/shared/packs/17650.php +++ b/shared/packs/17650.php @@ -186,14 +186,7 @@ $editionPacks = array( 'PROFESSIONALN' => 1, ); -$fancyEditionNames = array( - 'CLOUDE' => 'Windows 10 Lean', - 'CORE' => 'Windows 10 Home', - 'CORECOUNTRYSPECIFIC' => 'Windows 10 Home China', - 'COREN' => 'Windows 10 Home N', - 'PROFESSIONAL' => 'Windows 10 Pro', - 'PROFESSIONALN' => 'Windows 10 Pro N', -); +$fancyEditionNames['CLOUDE'] = 'Windows 10 Lean'; $skipNeutral = array( 'CLOUDE' => 1, diff --git a/shared/packs/17655.php b/shared/packs/17655.php index a8a4bac..1341dca 100644 --- a/shared/packs/17655.php +++ b/shared/packs/17655.php @@ -179,6 +179,8 @@ $packsForLangs = array( 'zh-tw' => array(0, 6), ); +$packsForLangs = array(); + $editionPacks = array( 'CLOUDE' => 0, 'CORE' => 0, @@ -188,14 +190,7 @@ $editionPacks = array( 'PROFESSIONALN' => 1, ); -$fancyEditionNames = array( - 'CLOUDE' => 'Windows 10 Lean', - 'CORE' => 'Windows 10 Home', - 'CORECOUNTRYSPECIFIC' => 'Windows 10 Home China', - 'COREN' => 'Windows 10 Home N', - 'PROFESSIONAL' => 'Windows 10 Pro', - 'PROFESSIONALN' => 'Windows 10 Pro N', -); +$fancyEditionNames['CLOUDE'] = 'Windows 10 Lean'; $skipNeutral = array( 'CLOUDE' => 1, diff --git a/shared/packs/legacy.php b/shared/packs/legacy.php index 653f96d..6a31b8f 100644 --- a/shared/packs/legacy.php +++ b/shared/packs/legacy.php @@ -253,21 +253,6 @@ $editionPacks = array( 'PROFESSIONALN' => 1, ); -$fancyEditionNames = array( - 'CLOUD' => 'Windows 10 S', - 'CLOUDN' => 'Windows 10 S N', - 'CORE' => 'Windows 10 Home', - 'CORECOUNTRYSPECIFIC' => 'Windows 10 Home China', - 'COREN' => 'Windows 10 Home N', - 'CORESINGLELANGUAGE' => 'Windows 10 Home Single Language', - 'EDUCATION' => 'Windows 10 Education', - 'EDUCATIONN' => 'Windows 10 Education N', - 'ENTERPRISE' => 'Windows 10 Enterprise', - 'ENTERPRISEN' => 'Windows 10 Enterprise N', - 'PROFESSIONAL' => 'Windows 10 Pro', - 'PROFESSIONALN' => 'Windows 10 Pro N', -); - $skipNeutral = array(); $skipLangPack = array(); ?> diff --git a/shared/requests.php b/shared/requests.php index ff91f8b..3a5e6ff 100644 --- a/shared/requests.php +++ b/shared/requests.php @@ -16,7 +16,7 @@ limitations under the License. */ // Composes DeviceAttributes parameter needed to fetch data -function composeDeviceAttributes($flight, $ring, $build, $arch) { +function composeDeviceAttributes($flight, $ring, $build, $arch, $sku) { $branch = branchFromBuild($build); if($ring == 'RETAIL') { @@ -46,7 +46,7 @@ function composeDeviceAttributes($flight, $ring, $build, $arch) { 'OEMModel=Microsoft', 'OEMName_Uncleaned=Microsoft', 'OSArchitecture='.$arch, - 'OSSkuId=48', + 'OSSkuId='.$sku, 'OSUILocale=en-US', 'OSVersion='.$build, 'PonchAllow=1', @@ -100,14 +100,15 @@ function composeFileGetRequest($updateId, $device, $info, $rev = 1) { $info['flight'], $info['ring'], $info['checkBuild'], - $info['arch'] + $info['arch'], + $info['sku'] ); return 'http://www.microsoft.com/SoftwareDistribution/Server/ClientWebService/GetExtendedUpdateInfo2urn:uuid:'.$uuid.'https://fe3.delivery.mp.microsoft.com/ClientWebService/client.asmx/secured'.$created.''.$expires.''.$device.''.$updateId.''.$rev.'FileUrlFileDecryption'.$deviceAttributes.''; } // Composes POST data for fetching the latest update information from Windows Update -function composeFetchUpdRequest($device, $encData, $arch, $flight, $ring, $build) { +function composeFetchUpdRequest($device, $encData, $arch, $flight, $ring, $build, $sku = 48) { $uuid = randStr(8).'-'.randStr(4).'-'.randStr(4).'-'.randStr(4).'-'.randStr(12); $createdTime = time(); @@ -138,7 +139,8 @@ function composeFetchUpdRequest($device, $encData, $arch, $flight, $ring, $build $flight, $ring, $build, - $arch + $arch, + $sku ); return 'http://www.microsoft.com/SoftwareDistribution/Server/ClientWebService/SyncUpdatesurn:uuid:'.$uuid.'https://fe3.delivery.mp.microsoft.com/ClientWebService/client.asmx'.$created.''.$expires.''.$device.'2045-04-07T12:38:34Z'.$encData.'falsefalsetruetrueExtendedLocalizedPropertiesEulaen-USfalse'.$deviceAttributes.''.$callerAttrib.''.$products.'';