From e5440343c51c1341775f8b22d65315158ddfe877 Mon Sep 17 00:00:00 2001 From: mkuba50 Date: Fri, 22 Sep 2017 21:24:31 +0200 Subject: [PATCH] Initial commit --- LICENSE | 202 +++++++++++++++++++++++++++++++++++ fetchupd.php | 155 +++++++++++++++++++++++++++ get.php | 224 +++++++++++++++++++++++++++++++++++++++ listid.php | 67 ++++++++++++ readme.md | 5 + shared/main.php | 68 ++++++++++++ shared/packs.php | 253 ++++++++++++++++++++++++++++++++++++++++++++ shared/requests.php | 29 +++++ 8 files changed, 1003 insertions(+) create mode 100644 LICENSE create mode 100644 fetchupd.php create mode 100644 get.php create mode 100644 listid.php create mode 100644 readme.md create mode 100644 shared/main.php create mode 100644 shared/packs.php create mode 100644 shared/requests.php diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff --git a/fetchupd.php b/fetchupd.php new file mode 100644 index 0000000..5517491 --- /dev/null +++ b/fetchupd.php @@ -0,0 +1,155 @@ + 'UNKNOWN_ARCH'); + } + + if(!($ring == 'WIF' || $ring == 'WIS' || $ring == 'RP')) { + return array('error' => 'UNKNOWN_RING'); + } + + if(!($flight == 'Skip' || $flight == 'Active')) { + return array('error' => 'UNKNOWN_FLIGHT'); + } + + if($flight == 'Skip' && $ring != 'WIF') { + return array('error' => 'UNKNOWN_COMBINATION'); + } + + if($build < 15063 || $build > 65536) { + return array('error' => 'ILLEGAL_BUILD'); + } + + if($flight == 'Active' && $ring == 'RP') $flight = 'Current'; + + $build = '10.0.'.$build.'.0'; + + consoleLogger('Fetching information from the server...'); + $postData = composeFetchUpdRequest($device, $encData, $arch, $flight, $ring, $build); + $out = sendWuPostRequest('https://fe3.delivery.mp.microsoft.com/ClientWebService/client.asmx', $postData); + + $out = html_entity_decode($out); + consoleLogger('Information was successfully fetched.'); + + consoleLogger('Checking build information...'); + preg_match('/.*<\/Files>/', $out, $fileList); + if(empty($fileList[0])) { + consoleLogger('An error has occured'); + return array('error' => 'ERROR'); + } + + preg_match('/.*?/', $out, $out2); + + preg_match('/"BuildFlightVersion":".*"}/', $out2[0], $foundBuild); + $foundBuild = preg_replace('/"BuildFlightVersion":"10\.0\.|"}/', '', $foundBuild[0]); + preg_match_all('/.*?<\/Title>/i', $out, $updateTitle); + $updateTitle = preg_replace('/<Title>|<\/Title>/i', '', $updateTitle[0]); + $updateTitle = preg_grep('/'.$foundBuild.'/', $updateTitle); + sort($updateTitle); + + if(isset($updateTitle[0])) { + $updateTitle = $updateTitle[0]; + } else { + $updateTitle = 'Windows 10 build '.$foundBuild; + } + + $out = preg_replace('/>/', ">\n", $out2[0]); + + preg_match('/UpdateID=".*?"/', $out, $updateId); + $updateId = preg_replace('/UpdateID="|"$/', '', $updateId[0]); + consoleLogger('Successfully checked build information.'); + consoleLogger('BUILD: '.$updateTitle.' '.$arch); + + $fileWrite = 'NO_SAVE'; + if(!file_exists('fileinfo/'.$updateId.'.json')) { + consoleLogger('WARNING: This build is NOT in the database. It will be saved now.'); + consoleLogger('Parsing information to write'); + if(!file_exists('fileinfo')) mkdir('fileinfo'); + + $fileList = preg_replace('/<Files>|<\/Files>/', '', $fileList[0]); + preg_match_all('/<File .*?>/', $fileList, $fileList); + + $shaArray = array(); + + foreach($fileList[0] as $val) { + preg_match('/Digest=".*?"/', $val, $sha1); + $sha1 = preg_replace('/Digest="|"$/', '', $sha1[0]); + $sha1 = bin2hex(base64_decode($sha1)); + + preg_match('/FileName=".*?"/', $val, $name); + $name = preg_replace('/FileName="|"$/', '', $name[0]); + + preg_match('/Size=".*?"/', $val, $size); + $size = preg_replace('/Size="|"$/', '', $size[0]); + + $temp = array( + 'name' => $name, + 'size' => $size, + ); + + $shaArray = array_merge($shaArray, array($sha1 => $temp)); + } + + unset($temp, $sha1, $name, $size); + + ksort($shaArray); + + $temp = array( + 'title' => $updateTitle, + 'ring' => $ring, + 'flight' => $flight, + 'arch' => $arch, + 'build' => $foundBuild, + 'checkBuild' => $build, + 'files' => $shaArray, + ); + + consoleLogger('Successfully parsed the information.'); + consoleLogger('Writing new build information to the disk...'); + + $success = file_put_contents('fileinfo/'.$updateId.'.json', json_encode($temp)."\n"); + if($success) { + consoleLogger('Successfully written build information to the disk.'); + $fileWrite = 'INFO_WRITTEN'; + } else { + consoleLogger('An error has occured while writing the information to the disk.'); + } + } else { + consoleLogger('This build already exists in the database.'); + } + + return array( + 'apiVersion' => $apiVersion, + 'updateId' => $updateId, + 'updateTitle' => $updateTitle, + 'foundBuild' => $foundBuild, + 'arch' => $arch, + 'fileWrite' => $fileWrite, + ); +} +?> diff --git a/get.php b/get.php new file mode 100644 index 0000000..36b46df --- /dev/null +++ b/get.php @@ -0,0 +1,224 @@ +<?php +/* +Copyright 2017 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. +*/ + +function uupGetFiles($updateId = 'c2a1d787-647b-486d-b264-f90f3782cdc6', $usePack = 0, $desiredEdition = 0) { + require_once 'shared/main.php'; + require_once 'shared/requests.php'; + require_once 'shared/packs.php'; + brand(); + + function packsByEdition($edition, $pack, $lang, $filesKeys) { + $filesTemp = array(); + + if($edition != 'editionNeutral') { + $temp = preg_grep('/'.$edition.'_'.$lang.'\.esd/i', $filesKeys); + $filesTemp = array_merge($filesTemp, $temp); + } + + foreach($pack as $val) { + $temp = preg_grep('/'.$val.'\./i', $filesKeys); + $filesTemp = array_merge($filesTemp, $temp); + } + + return $filesTemp; + } + + if($usePack) { + $usePack = strtolower($usePack); + if(!isset($packsForLangs[$usePack])) { + return array('error' => 'UNSUPPORTED_LANG'); + } + } + + if($desiredEdition) { + if(!$usePack) { + return array('error' => 'UNSPECIFIED_LANG'); + } + + $desiredEdition = strtoupper($desiredEdition); + if(!isset($editionPacks[$desiredEdition])) { + return array('error' => 'UNSUPPORTED_EDITION'); + } + + $supported = 0; + foreach($packsForLangs[$usePack] as $val) { + if($editionPacks[$desiredEdition] == $val) $supported = 1; + } + + if(!$supported) { + return array('error' => 'UNSUPPORTED_COMBINATION'); + } + unset($supported); + } + + $info = @file_get_contents('fileinfo/'.$updateId.'.json'); + if(empty($info)) { + $info = array( + 'ring' => 'WIF', + 'flight' => 'Skip', + 'checkBuild' => '10.0.16232.0', + 'files' => array(), + ); + } else { + $info = json_decode($info, true); + } + + $uupFix = 0; + if(isset($info['needsFix'])) { + if($info['needsFix'] == true) $uupFix = 1; + } + + consoleLogger('Fetching information from the server...'); + $postData = composeFileGetRequest($updateId, $device, $info); + $out = sendWuPostRequest('https://fe3.delivery.mp.microsoft.com/ClientWebService/client.asmx/secured', $postData); + consoleLogger('Information was successfully fetched.'); + + consoleLogger('Parsing information...'); + preg_match_all('/<FileLocation>.*?<\/FileLocation>/', $out, $out); + if(empty($out[0])) { + consoleLogger('An error has occured'); + return array('error' => 'EMPTY_FILELIST'); + } + + $updateName = (isset($info['title'])) ? $info['title'] : 'Unknown update: '.$updateId; + $info = $info['files']; + $out = preg_replace('/<FileLocation>|<\/FileLocation>/', '', $out[0]); + + $files = array(); + $removeFiles = array(); + + foreach($out as $val) { + preg_match('/<FileDigest>.*<\/FileDigest>/', $val, $sha1); + $sha1 = preg_replace('/<FileDigest>|<\/FileDigest>/', '', $sha1[0]); + $sha1 = bin2hex(base64_decode($sha1)); + + preg_match('/<Url>.*<\/Url>/', $val, $url); + $url = preg_replace('/<Url>|<\/Url>/', '', $url[0]); + $url = html_entity_decode($url); + + preg_match('/P1=.*?&/', $url, $expire); + if(isset($expire[0])) $expire = preg_replace('/P1=|&$/', '', $expire[0]); + + preg_match('/files\/.{8}-.{4}-.{4}-.{4}-.{12}/', $url, $guid); + $guid = preg_replace('/files\/|\?$/', '', $guid[0]); + + if(empty($info[$sha1]['name'])) { + $name = $guid; + } else { + $name = $info[$sha1]['name']; + } + + if(empty($info[$sha1]['name'])) { + $size = 0; + } else { + $size = $info[$sha1]['size']; + } + + if($uupFix && !isset($fileSizes[$name])) $fileSizes[$name] = 0; + + $temp = array( + 'sha1' => $sha1, + 'size' => $size, + 'url' => $url, + 'guid' => $guid, + 'expire' => intval($expire), + ); + + if(!preg_match('/\.psf$/', $name)) { + if($uupFix) { + if($size > $fileSizes[$name]) { + $fileSizes[$name] = $size; + $files = array_merge($files, array($name => $temp)); + } + } else { + $files = array_merge($files, array($name => $temp)); + } + } else { + $name = preg_replace('/\.psf$/', '', $name); + $removeFiles = array_merge($removeFiles, array($name)); + } + } + + if(!$uupFix) { + foreach($removeFiles as $val) { + if(isset($files[$val.'.cab'])) unset($files[$val.'.cab']); + } + unset($removeFiles); + } + + $filesKeys = array_keys($files); + + if($uupFix) { + $removeFiles = preg_grep('/\.esd$/i', $filesKeys); + + foreach($removeFiles as $val) { + $temp = preg_replace('/\.esd$/i', '', $val); + if(isset($files[$temp.'.cab'])) unset($files[$temp.'.cab']); + } + + unset($removeFiles, $temp); + $filesKeys = array_keys($files); + } + + if($usePack) { + $removeFiles = preg_grep('/RetailDemo-OfflineContent/i', $filesKeys); + + foreach($removeFiles as $val) { + if(isset($files[$val])) unset($files[$val]); + } + + unset($removeFiles, $temp); + $filesKeys = array_keys($files); + + $filesTemp = array(); + + $temp = preg_grep('/.*'.$usePack.'-Package.*/i', $filesKeys); + $filesTemp = array_merge($filesTemp, $temp); + + $temp = preg_grep('/.*'.$usePack.'_lp..../i', $filesKeys); + $filesTemp = array_merge($filesTemp, $temp); + + foreach($packsForLangs[$usePack] as $num) { + foreach($packs[$num] as $key => $val) { + if($key == 'editionNeutral' + || $key == $desiredEdition + || !$desiredEdition) { + $temp = packsByEdition($key, $val, $usePack, $filesKeys); + $filesTemp = array_merge($filesTemp, $temp); + } + } + } + + $filesKeys = array_unique($filesTemp); + unset($filesTemp, $temp, $val, $num); + } + + foreach($filesKeys as $val) { + $filesNew[$val] = $files[$val]; + } + + $files = $filesNew; + ksort($files); + + consoleLogger('Successfully parsed the information.'); + + return array( + 'apiVersion' => $apiVersion, + 'files' => $files, + ); +} +?> diff --git a/listid.php b/listid.php new file mode 100644 index 0000000..af2fdb3 --- /dev/null +++ b/listid.php @@ -0,0 +1,67 @@ +<?php +/* +Copyright 2017 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. +*/ + +function uupListIds() { + require_once 'shared/main.php'; + brand(); + + if(!file_exists('fileinfo')) return array('error' => 'NO_FILEINFO_DIR'); + + $files = scandir('fileinfo'); + $files = preg_grep('/\.json$/', $files); + + consoleLogger('Parsing database info...'); + $builds = array(); + foreach($files as $file) { + if($file == '.' || $file == '..') continue; + + $info = @file_get_contents('fileinfo/'.$file); + $info = json_decode($info, true); + + $uuid = preg_replace('/\.json$/', '', $file); + + $title = isset($info['title']) ? $info['title'] : 'UNKNOWN'; + $build = isset($info['build']) ? $info['build'] : 'UNKNOWN'; + $arch = isset($info['arch']) ? $info['arch'] : 'UNKNOWN'; + + $temp = array( + 'title' => $title, + 'build' => $build, + 'arch' => $arch, + 'uuid' => $uuid, + ); + + $builds = array_merge($builds, array($build.$arch.$title.$uuid => $temp)); + } + + krsort($builds); + + $buildsNew = array(); + foreach($builds as $val) { + $buildsNew = array_merge($buildsNew, array($val)); + } + + $builds = $buildsNew; + + consoleLogger('Done parsing database info.'); + + return array( + 'apiVersion' => $apiVersion, + 'builds' => $builds, + ); +} +?> diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..6ae549a --- /dev/null +++ b/readme.md @@ -0,0 +1,5 @@ +UUP dump API +------------ + +Work in progress project to provide needed queries for other UUP dump projects in easy way. + \ No newline at end of file diff --git a/shared/main.php b/shared/main.php new file mode 100644 index 0000000..605a646 --- /dev/null +++ b/shared/main.php @@ -0,0 +1,68 @@ +<?php +/* +Copyright 2017 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. +*/ + +global $apiVersion; +$apiVersion = '0.1.0-alpha'; + +function brand() { + global $apiVersion; + consoleLogger('UUP dump API v'.$apiVersion); +} + +function randStr($length = 4) { + $characters = '0123456789abcdef'; + $charactersLength = strlen($characters); + $randomString = ''; + for ($i = 0; $i < $length; $i++) { + $randomString .= $characters[rand(0, $charactersLength - 1)]; + } + return $randomString; +} + +function sendWuPostRequest($url, $postData) { + $req = curl_init($url); + + curl_setopt($req, CURLOPT_HEADER, 0); + curl_setopt($req, CURLOPT_POST, 1); + curl_setopt($req, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($req, CURLOPT_POSTFIELDS, $postData); + curl_setopt($req, CURLOPT_SSL_VERIFYPEER, 0); + curl_setopt($req, CURLOPT_HTTPHEADER, array( + 'User-Agent: Windows-Update-Agent/10.0.10011.16384 Client-Protocol/1.70', + 'Content-Type: application/soap+xml; charset=utf-8', + )); + + $out = curl_exec($req); + curl_close($req); + + return $out; +} + +function consoleLogger($message, $showTime = 1) { + if(php_sapi_name() != 'cli') return + $currTime = ''; + if($showTime) { + $currTime = '['.date('Y-m-d H:i:s T', time()).'] '; + } + + $msg = $currTime.$message; + fwrite(STDERR, $msg."\n"); +} + +$device = 'dAA9AEUAdwBBAHcAQQBzAE4AMwBCAEEAQQBVADEAYgB5AHMAZQBtAGIAZQBEAFYAQwArADMAZgBtADcAbwBXAHkASAA3AGIAbgBnAEcAWQBtAEEAQQBHADcAVwBtAGUAWQBmAGkAdwAxAGMAdgByAEoAbwBvAGkAUQBzAFoAZABqAHEAawBQAEkARwA5AHUAVQBQAFcAMQB3ADMAQgBVAE8ALwBKAC8AdwBwAGUAcgBhAHQAZAB2AFgAQgB6AFkAbABaAHAAYgBzAHQANAB4AHkAbABHADcAQwBSADQANABBAFoARwB4AG4ARAAvAHIAYwBVAGoAdwBEAFAAVQBXAHkAMABPAEwAaABqAFAAZABWAEgAOQBVAFkATAA4AE0AVgBJAFIAbQA5ADEALwAwAGwATQBjAHUAMwBQAFMAOQB5AFoARwBFADIAZgBOAEcAWAA2AE8AbABrAFoAaABiAG0AbAB1AGsAdwBXAEsAdQBQAHcAcABGADQARQB5AFgAcgBTAHgALwBwAEsATgArAFoANgBOAEoAdQArAFYASwBqAFoANwBoADIAUgBBADIAWQBBAEEAQQBpAEUAWQBjADgAawBnAFoAYQBsAEgAWQBBAEIASwBIADEAZAAvAEoAZABEAFUAeAB5ADIAegBkAEoAMwA0AEIAbABYAGMAYwBsAFoANABJAE4ANQBuAHcAYQBLAE4AWgA3ADEAcQA4AEMAcQBVAFgAYwBQAGMAQgBjAGEAVQBXAFgAVgBGAEMASgBsAEEAegBTAGwAQQBtAHEALwBvAFQAQQBVAFcAYQBOAEgAWQBRADAAWQBNADEAVQAzAHEATAAvAFEAdQBhAEcAMgBuAE4AdQBvADYAVwBqAFEAcQBFAFgAYwBUAGMAWAA3AGMAdgAyAHEANABzADcAWgBpADkAWQB1ACsANwBYADAAeQA1AFgAeQAvAE4AbgBLAGUAeABRAHEAdwA3AG8AKwBjAGIAMwB1AGYAQQBFAEYAdABWAHAAawB3AGwAagBZAHYAZgBvADcAdQBwAFkANQBnAGEAdABlADUAWABwADkALwBoAFoAdQBYAFIANgAwAEoAMQBUAHEATQBGADYAVQBOAEIATQB6AC8ATABCAEMAUABPAEcAWABIAGkAWgBJAEUAZQBIAE8ASwBiAEIAUAB1AFAASwBZAGMAUQBUAFkAZwBIAEkARwA3AFIAegBnAGIAMAAzAGQARABrAFUANgByAHUASQA1AHQAYgBIAHoAaQBmAHoAVgBHAHAAVABGAGcANABrAEoAYgBQAHkARQBXAHcAcwBOAEMARgA4AFQATQBuAHAARABhAHcAeAAvAEUARgBUADcAeQBLAFQAQwBYAFkAbgBhADQASQBJAFAAMABtAFcAMABYADIAdABDAHEANgA1AEUASwBlAFkAcQBBAEYARQA1AEMASABmAFEAMQBvAHIAYgBBAGEASgBWAGkAaQBFAGsARQB3AEEANwBuADMAcgAxAFIAUQB1AHgARgBlAG4ARwBkAHgAdQByAFoAdwByADAAMABEADgATQBoAGwAUQAvAFcAYQBaAGwANgBvAFgAdgBkAHUATgBXAEIAZwBPAFMANgBLAGEARwBpAC8AYgBLADEAZwBWAEgAcABzAEcAcwBFAC8AQgA4AGkAbQBsAGYAcAAzAFEATQBWAGkAUABEAEgANgBhADMANQBCAGYAOABpAHkAMgAyAG4ASABQADAATgBIADkASwBEAHoAWAB5AGkAeABnAGsARQBlAGwAaABKAEcANgAyAHUAMgBjAFQAMgBmAFgAMQA0AEwAdwBSAFkATwArAGkAcgBWAGQAYwBqAEUAQgBoAGQASwA1ADQAYgBPAFcAdgBUAHcAbQBUAFMAVwBHAE8AaAB2ADIAbwBiADIAawBQAEEANgBpADEAVgBRAFUAaQA4AEQASwB1AEsANAA4AGYAWgBIADcASQBKAGEAZQBxAHMAdwBFAD0AJgBwAD0A'; +$encData = 'mWAGiUaiYgHfsAeIJgLgiRDyjNbyIThm35CJYPrxVEh9HAeQmequNwXuWtOJFOlHv5yT96WmtFLTh7ubpLl9H3pO4F4eCmkNqI1rWQ+CRwCUg8s5IX/mWRN1xCN3vMIl8Smkunz7/+PJ63/or2AsuDPd+bjdU0lO4tSY94mbvqJgI5mnLuRPqHY3ad+QGXBx7ipPKTt5g+g='; +?> diff --git a/shared/packs.php b/shared/packs.php new file mode 100644 index 0000000..d5aa160 --- /dev/null +++ b/shared/packs.php @@ -0,0 +1,253 @@ +<?php +/* +Copyright 2017 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. +*/ + +$packs = array( + // Base pack + 0 => array( + 'editionNeutral' => array( + 'Microsoft-Windows-Foundation-Package', + 'Microsoft-Windows-Client-Features-Package', + 'Microsoft-Windows-Client-Features-WOW64-Package', + 'Microsoft-Windows-Client-Features-arm64arm-Package', + 'Microsoft-Windows-WowPack-CoreARM-arm64arm-Package', + 'Microsoft-Windows-ContactSupport-Package', + 'Microsoft-Windows-RegulatedPackages-Package', + 'Microsoft-Windows-RegulatedPackages-WOW64-Package', + 'Microsoft-Windows-RegulatedPackages-arm64arm-Package', + 'Microsoft-Windows-Holographic-Desktop-Merged-Package', + 'Microsoft-Windows-Holographic-Desktop-Merged-WOW64-Package', + 'Microsoft-Windows-Holographic-Desktop-Analog-Package', + 'Microsoft-Windows-QuickAssist-Package', + 'Microsoft-Windows-InternetExplorer-Optional-Package', + 'Microsoft-Windows-MediaPlayer-Package', + 'Microsoft-OneCore-ApplicationModel-Sync-Desktop-FOD-Package', + ), + 'CLOUD' => array( + 'Microsoft-Windows-EditionPack-Professional-Package', + 'Microsoft-Windows-EditionPack-Professional-WOW64-Package', + 'Microsoft-Windows-EditionPack-Professional-arm64arm-Package', + 'Microsoft-Windows-EditionSpecific-Cloud-Package', + 'Microsoft-Windows-EditionSpecific-Cloud-WOW64-Package', + 'Microsoft-Windows-EditionSpecific-Cloud-arm64arm-Package', + 'Microsoft\.ModernApps\.Client\.All', + 'Microsoft\.ModernApps\.Client\.cloud', + ), + 'CORE' => array( + 'Microsoft-Windows-EditionPack-Core-Package', + 'Microsoft-Windows-EditionPack-Core-WOW64-Package', + 'Microsoft-Windows-EditionPack-Core-arm64arm-Package', + 'Microsoft-Windows-EditionSpecific-Core-Package', + 'Microsoft-Windows-EditionSpecific-Core-WOW64-Package', + 'Microsoft-Windows-EditionSpecific-Core-arm64arm-Package', + 'Microsoft\.ModernApps\.Client\.All', + 'Microsoft\.ModernApps\.Client\.core', + ), + 'EDUCATION' => array( + 'Microsoft-Windows-EditionPack-Enterprise-Package', + 'Microsoft-Windows-EditionPack-Enterprise-WOW64-Package', + 'Microsoft-Windows-EditionPack-Enterprise-arm64arm-Package', + 'Microsoft-Windows-EditionSpecific-Education-Package', + 'Microsoft-Windows-EditionSpecific-Education-WOW64-Package', + 'Microsoft-Windows-EditionSpecific-Education-arm64arm-Package', + 'Microsoft\.ModernApps\.Client\.All', + 'Microsoft\.ModernApps\.Client\.education', + ), + 'ENTERPRISE' => array( + 'Microsoft-Windows-EditionPack-Enterprise-Package', + 'Microsoft-Windows-EditionPack-Enterprise-WOW64-Package', + 'Microsoft-Windows-EditionPack-Enterprise-arm64arm-Package', + 'Microsoft-Windows-EditionSpecific-Enterprise-Package', + 'Microsoft-Windows-EditionSpecific-Enterprise-WOW64-Package', + 'Microsoft-Windows-EditionSpecific-Enterprise-arm64arm-Package', + 'Microsoft\.ModernApps\.Client\.All', + 'Microsoft\.ModernApps\.Client\.enterprise', + ), + 'PROFESSIONAL' => array( + 'Microsoft-Windows-EditionPack-Professional-Package', + 'Microsoft-Windows-EditionPack-Professional-WOW64-Package', + 'Microsoft-Windows-EditionPack-Professional-arm64arm-Package', + 'Microsoft-Windows-EditionSpecific-Professional-Package', + 'Microsoft-Windows-EditionSpecific-Professional-WOW64-Package', + 'Microsoft-Windows-EditionSpecific-Professional-arm64arm-Package', + 'Microsoft\.ModernApps\.Client\.All', + 'Microsoft\.ModernApps\.Client\.professional', + ), + ), + + // European "N" Editions + 1 => array( + 'CLOUDN' => array( + 'Microsoft-Windows-EditionPack-Professional-Package', + 'Microsoft-Windows-EditionPack-Professional-WOW64-Package', + 'Microsoft-Windows-EditionPack-Professional-arm64arm-Package', + 'Microsoft-Windows-EditionSpecific-CloudN-Package', + 'Microsoft-Windows-EditionSpecific-CloudN-WOW64-Package', + 'Microsoft-Windows-EditionSpecific-CloudN-arm64arm-Package', + 'Microsoft\.ModernApps\.ClientN\.All', + ), + 'COREN' => array( + 'Microsoft-Windows-EditionPack-Core-Package', + 'Microsoft-Windows-EditionPack-Core-WOW64-Package', + 'Microsoft-Windows-EditionPack-Core-arm64arm-Package', + 'Microsoft-Windows-EditionSpecific-CoreN-Package', + 'Microsoft-Windows-EditionSpecific-CoreN-WOW64-Package', + 'Microsoft-Windows-EditionSpecific-CoreN-arm64arm-Package', + 'Microsoft\.ModernApps\.ClientN\.All', + ), + 'EDUCATIONN' => array( + 'Microsoft-Windows-EditionPack-Enterprise-Package', + 'Microsoft-Windows-EditionPack-Enterprise-WOW64-Package', + 'Microsoft-Windows-EditionPack-Enterprise-arm64arm-Package', + 'Microsoft-Windows-EditionSpecific-EducationN-Package', + 'Microsoft-Windows-EditionSpecific-EducationN-WOW64-Package', + 'Microsoft-Windows-EditionSpecific-EducationN-arm64arm-Package', + 'Microsoft\.ModernApps\.ClientN\.All', + ), + 'ENTERPRISEN' => array( + 'Microsoft-Windows-EditionPack-Enterprise-Package', + 'Microsoft-Windows-EditionPack-Enterprise-WOW64-Package', + 'Microsoft-Windows-EditionPack-Enterprise-arm64arm-Package', + 'Microsoft-Windows-EditionSpecific-EnterpriseN-Package', + 'Microsoft-Windows-EditionSpecific-EnterpriseN-WOW64-Package', + 'Microsoft-Windows-EditionSpecific-EnterpriseN-arm64arm-Package', + 'Microsoft\.ModernApps\.ClientN\.All', + ), + 'PROFESSIONALN' => array( + 'Microsoft-Windows-EditionPack-Professional-Package', + 'Microsoft-Windows-EditionPack-Professional-WOW64-Package', + 'Microsoft-Windows-EditionPack-Professional-arm64arm-Package', + 'Microsoft-Windows-EditionSpecific-ProfessionalN-Package', + 'Microsoft-Windows-EditionSpecific-ProfessionalN-WOW64-Package', + 'Microsoft-Windows-EditionSpecific-ProfessionalN-arm64arm-Package', + 'Microsoft\.ModernApps\.ClientN\.All', + ), + ), + + // CoreSingleLanguage + 2 => array( + 'CORESINGLELANGUAGE' => array( + 'Microsoft-Windows-EditionPack-Core-Package', + 'Microsoft-Windows-EditionPack-Core-WOW64-Package', + 'Microsoft-Windows-EditionPack-Core-arm64arm-Package', + 'Microsoft-Windows-EditionSpecific-CoreSingleLanguage-Package', + 'Microsoft-Windows-EditionSpecific-CoreSingleLanguage-WOW64-Package', + 'Microsoft-Windows-EditionSpecific-CoreSingleLanguage-arm64arm-Package', + 'Microsoft\.ModernApps\.Client\.All', + 'Microsoft\.ModernApps\.Client\.coresinglelanguage', + ), + ), + + // China specific editions + 3 => array( + 'CORECOUNTRYSPECIFIC' => array( + 'Microsoft-Windows-EditionPack-Core-Package', + 'Microsoft-Windows-EditionPack-Core-WOW64-Package', + 'Microsoft-Windows-EditionPack-Core-arm64arm-Package', + 'Microsoft-Windows-EditionSpecific-CoreCountrySpecific-Package', + 'Microsoft-Windows-EditionSpecific-CoreCountrySpecific-WOW64-Package', + 'Microsoft-Windows-EditionSpecific-CoreCountrySpecific-arm64arm-Package', + 'Microsoft\.ModernApps\.Client\.All', + ), + ), + + // Additional packages for some languages + 4 => array( + 'editionNeutral' => array( + 'Microsoft-Windows-LanguageFeatures-Basic-en-us-Package', + 'Microsoft-Windows-LanguageFeatures-OCR-en-us-Package', + ), + ), + + // Additional packages for ar-sa language + 5 => array( + 'editionNeutral' => array( + 'Microsoft-Windows-LanguageFeatures-TextToSpeech-ar-eg-Package', + ), + ), + + // Additional packages for fr-ca language + 6 => array( + 'editionNeutral' => array( + 'Microsoft-Windows-LanguageFeatures-Basic-fr-fr-Package', + 'Microsoft-Windows-LanguageFeatures-Handwriting-fr-fr-Package', + ), + ), + + // Additional packages for zh-tw language + 7 => array( + 'editionNeutral' => array( + 'Microsoft-Windows-LanguageFeatures-Speech-zh-hk-Package', + 'Microsoft-Windows-LanguageFeatures-TextToSpeech-zh-hk-Package', + ), + ), +); + +$packsForLangs = array( + 'ar-sa' => array(0, 2, 4, 5), + 'bg-bg' => array(0, 1, 4), + 'cs-cz' => array(0, 1), + 'da-dk' => array(0, 1, 4), + 'de-de' => array(0, 1), + 'el-gr' => array(0, 1, 4), + 'en-gb' => array(0, 1, 2), + 'en-us' => array(0, 1, 2), + 'es-es' => array(0, 1, 2), + 'es-mx' => array(0, 2), + 'et-ee' => array(0, 1), + 'fi-fi' => array(0, 1), + 'fr-ca' => array(0, 4, 6), + 'fr-fr' => array(0, 1, 2), + 'he-il' => array(0, 4), + 'hr-hr' => array(0, 1), + 'hu-hu' => array(0, 1), + 'it-it' => array(0, 1), + 'ja-jp' => array(0), + 'ko-kr' => array(0, 1), + 'lt-lt' => array(0, 1), + 'lv-lv' => array(0, 1), + 'nb-no' => array(0, 1), + 'nl-nl' => array(0, 1), + 'pl-pl' => array(0, 1), + 'pt-br' => array(0, 2), + 'pt-pt' => array(0, 1, 2), + 'ro-ro' => array(0, 1), + 'ru-ru' => array(0, 2, 4), + 'sk-sk' => array(0, 1), + 'sl-si' => array(0, 1), + 'sv-se' => array(0, 1), + 'th-th' => array(0, 2, 4), + 'tr-tr' => array(0, 2), + 'uk-ua' => array(0, 2, 4), + 'zh-cn' => array(0, 2, 3), + 'zh-tw' => array(0, 7), +); + +$editionPacks = array( + 'CLOUD' => 0, + 'CLOUDN' => 1, + 'CORE' => 0, + 'CORECOUNTRYSPECIFIC' => 3, + 'COREN' => 1, + 'CORESINGLELANGUAGE' => 2, + 'EDUCATION' => 0, + 'EDUCATIONN' => 1, + 'ENTERPRISE' => 0, + 'ENTERPRISEN' => 1, + 'PROFESSIONAL' => 0, + 'PROFESSIONALN' => 1, +); +?> diff --git a/shared/requests.php b/shared/requests.php new file mode 100644 index 0000000..bdb360b --- /dev/null +++ b/shared/requests.php @@ -0,0 +1,29 @@ +<?php +/* +Copyright 2017 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. +*/ + +// Composes POST data for gathering list of urls for download +function composeFileGetRequest($updateId, $device, $info) { + $uuid = randStr(8).'-'.randStr(4).'-'.randStr(4).'-'.randStr(4).'-'.randStr(12); + return '<s:Envelope xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:s="http://www.w3.org/2003/05/soap-envelope"><s:Header><a:Action s:mustUnderstand="1">http://www.microsoft.com/SoftwareDistribution/Server/ClientWebService/GetExtendedUpdateInfo2</a:Action><a:MessageID>urn:uuid:'.$uuid.'</a:MessageID><a:To s:mustUnderstand="1">https://fe3.delivery.mp.microsoft.com/ClientWebService/client.asmx/secured</a:To><o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"><Timestamp xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"><Created>2017-01-01T01:00:00.000Z</Created><Expires>2020-01-01T02:00:00.000Z</Expires></Timestamp><wuws:WindowsUpdateTicketsToken wsu:id="ClientMSA" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wuws="http://schemas.microsoft.com/msus/2014/10/WindowsUpdateAuthorization"><TicketType Name="MSA" Version="1.0" Policy="MBI_SSL"><Device>'.$device.'</Device></TicketType></wuws:WindowsUpdateTicketsToken></o:Security></s:Header><s:Body><GetExtendedUpdateInfo2 xmlns="http://www.microsoft.com/SoftwareDistribution/Server/ClientWebService"><updateIDs><UpdateIdentity><UpdateID>'.$updateId.'</UpdateID><RevisionNumber>1</RevisionNumber></UpdateIdentity></updateIDs><infoTypes><XmlUpdateFragmentType>FileUrl</XmlUpdateFragmentType><XmlUpdateFragmentType>FileDecryption</XmlUpdateFragmentType></infoTypes><deviceAttributes>App=WU;AppVer=10.0.16251.1000;AttrDataVer=22;BranchReadinessLevel=CB;CurrentBranch=rs_prerelease;DeviceFamily=Windows.Desktop;FirmwareVersion=6.00;FlightContent='.$info['flight'].';FlightingBranchName=external;FlightRing='.$info['ring'].';InstallationType=Client;InstallLanguage=en-US;IsDeviceRetailDemo=0;IsFlightingEnabled=1;OSSkuId=48;OSUILocale=en-US;OSVersion='.$info['checkBuild'].';TelemetryLevel=3;UpdateManagementGroup=2;</deviceAttributes></GetExtendedUpdateInfo2></s:Body></s:Envelope>'; +} + +// Composes POST data for fetching the latest update information from Windows Update +function composeFetchUpdRequest($device, $encData, $arch, $flight, $ring, $build) { + $uuid = randStr(8).'-'.randStr(4).'-'.randStr(4).'-'.randStr(4).'-'.randStr(12); + return '<s:Envelope xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:s="http://www.w3.org/2003/05/soap-envelope"><s:Header><a:Action s:mustUnderstand="1">http://www.microsoft.com/SoftwareDistribution/Server/ClientWebService/SyncUpdates</a:Action><a:MessageID>urn:uuid:'.$uuid.'</a:MessageID><a:To s:mustUnderstand="1">https://fe3.delivery.mp.microsoft.com/ClientWebService/client.asmx</a:To><o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"><Timestamp xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"><Created>2017-01-01T01:00:00.000Z</Created><Expires>2020-01-01T02:00:00.000Z</Expires></Timestamp><wuws:WindowsUpdateTicketsToken wsu:id="ClientMSA" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wuws="http://schemas.microsoft.com/msus/2014/10/WindowsUpdateAuthorization"><TicketType Name="MSA" Version="1.0" Policy="MBI_SSL"><Device>'.$device.'</Device></TicketType></wuws:WindowsUpdateTicketsToken></o:Security></s:Header><s:Body><SyncUpdates xmlns="http://www.microsoft.com/SoftwareDistribution/Server/ClientWebService"><cookie><Expiration>2045-04-07T12:38:34Z</Expiration><EncryptedData>'.$encData.'</EncryptedData></cookie><parameters><ExpressQuery>false</ExpressQuery><InstalledNonLeafUpdateIDs></InstalledNonLeafUpdateIDs><OtherCachedUpdateIDs></OtherCachedUpdateIDs><SkipSoftwareSync>false</SkipSoftwareSync><NeedTwoGroupOutOfScopeUpdates>true</NeedTwoGroupOutOfScopeUpdates><AlsoPerformRegularSync>true</AlsoPerformRegularSync><ComputerSpec/><ExtendedUpdateInfoParameters><XmlUpdateFragmentTypes><XmlUpdateFragmentType>Extended</XmlUpdateFragmentType><XmlUpdateFragmentType>LocalizedProperties</XmlUpdateFragmentType><XmlUpdateFragmentType>Eula</XmlUpdateFragmentType></XmlUpdateFragmentTypes><Locales><string>en-US</string><string>pl</string></Locales></ExtendedUpdateInfoParameters><ClientPreferredLanguages><string>pl</string></ClientPreferredLanguages><ProductsParameters><SyncCurrentVersionOnly>false</SyncCurrentVersionOnly><DeviceAttributes>App=WU;AppVer='.$build.';AttrDataVer=22;BranchReadinessLevel=CB;CurrentBranch=rs_prerelease;DeviceFamily=Windows.Desktop;FirmwareVersion=6.00;FlightContent='.$flight.';FlightingBranchName=external;FlightRing='.$ring.';InstallationType=Client;InstallLanguage=en-US;IsDeviceRetailDemo=0;IsFlightingEnabled=1;OSSkuId=48;OSUILocale=en-US;OSVersion='.$build.';TelemetryLevel=3;UpdateManagementGroup=2;</DeviceAttributes><CallerAttributes>Interactive=1;IsSeeker=0;</CallerAttributes><Products>PN=Client.OS.rs2.'.$arch.'&Branch=rs_prerelease&PrimaryOSProduct=1&V='.$build.';</Products></ProductsParameters></parameters></SyncUpdates></s:Body></s:Envelope>'; +} +?>