diff --git a/fetchupd.php b/fetchupd.php
index f308d7e..922108f 100644
--- a/fetchupd.php
+++ b/fetchupd.php
@@ -64,7 +64,7 @@ function uupFetchUpd(
return array('error' => 'UNKNOWN_ARCH');
}
- if(!($ring == 'WIF' || $ring == 'WIS' || $ring == 'RP' || $ring == 'RETAIL')) {
+ if(!($ring == 'WIF' || $ring == 'WIS' || $ring == 'RP' || $ring == 'RETAIL' || $ring == 'MSIT')) {
return array('error' => 'UNKNOWN_RING');
}
diff --git a/shared/auths.php b/shared/auths.php
index 23cfe1f..6468ce4 100644
--- a/shared/auths.php
+++ b/shared/auths.php
@@ -16,16 +16,21 @@ limitations under the License.
*/
function uupDevice() {
- return 'dAA9AEUAdwBBAHcAQQBzAE4AMwBCAEEAQQBVADEAYgB5AHMAZQBtAGIAZQBEAFYAQwArADMAZgBtADcAbwBXAHkASAA3AGIAbgBnAEcAWQBtAEEAQQBHADcAVwBtAGUAWQBmAGkAdwAxAGMAdgByAEoAbwBvAGkAUQBzAFoAZABqAHEAawBQAEkARwA5AHUAVQBQAFcAMQB3ADMAQgBVAE8ALwBKAC8AdwBwAGUAcgBhAHQAZAB2AFgAQgB6AFkAbABaAHAAYgBzAHQANAB4AHkAbABHADcAQwBSADQANABBAFoARwB4AG4ARAAvAHIAYwBVAGoAdwBEAFAAVQBXAHkAMABPAEwAaABqAFAAZABWAEgAOQBVAFkATAA4AE0AVgBJAFIAbQA5ADEALwAwAGwATQBjAHUAMwBQAFMAOQB5AFoARwBFADIAZgBOAEcAWAA2AE8AbABrAFoAaABiAG0AbAB1AGsAdwBXAEsAdQBQAHcAcABGADQARQB5AFgAcgBTAHgALwBwAEsATgArAFoANgBOAEoAdQArAFYASwBqAFoANwBoADIAUgBBADIAWQBBAEEAQQBpAEUAWQBjADgAawBnAFoAYQBsAEgAWQBBAEIASwBIADEAZAAvAEoAZABEAFUAeAB5ADIAegBkAEoAMwA0AEIAbABYAGMAYwBsAFoANABJAE4ANQBuAHcAYQBLAE4AWgA3ADEAcQA4AEMAcQBVAFgAYwBQAGMAQgBjAGEAVQBXAFgAVgBGAEMASgBsAEEAegBTAGwAQQBtAHEALwBvAFQAQQBVAFcAYQBOAEgAWQBRADAAWQBNADEAVQAzAHEATAAvAFEAdQBhAEcAMgBuAE4AdQBvADYAVwBqAFEAcQBFAFgAYwBUAGMAWAA3AGMAdgAyAHEANABzADcAWgBpADkAWQB1ACsANwBYADAAeQA1AFgAeQAvAE4AbgBLAGUAeABRAHEAdwA3AG8AKwBjAGIAMwB1AGYAQQBFAEYAdABWAHAAawB3AGwAagBZAHYAZgBvADcAdQBwAFkANQBnAGEAdABlADUAWABwADkALwBoAFoAdQBYAFIANgAwAEoAMQBUAHEATQBGADYAVQBOAEIATQB6AC8ATABCAEMAUABPAEcAWABIAGkAWgBJAEUAZQBIAE8ASwBiAEIAUAB1AFAASwBZAGMAUQBUAFkAZwBIAEkARwA3AFIAegBnAGIAMAAzAGQARABrAFUANgByAHUASQA1AHQAYgBIAHoAaQBmAHoAVgBHAHAAVABGAGcANABrAEoAYgBQAHkARQBXAHcAcwBOAEMARgA4AFQATQBuAHAARABhAHcAeAAvAEUARgBUADcAeQBLAFQAQwBYAFkAbgBhADQASQBJAFAAMABtAFcAMABYADIAdABDAHEANgA1AEUASwBlAFkAcQBBAEYARQA1AEMASABmAFEAMQBvAHIAYgBBAGEASgBWAGkAaQBFAGsARQB3AEEANwBuADMAcgAxAFIAUQB1AHgARgBlAG4ARwBkAHgAdQByAFoAdwByADAAMABEADgATQBoAGwAUQAvAFcAYQBaAGwANgBvAFgAdgBkAHUATgBXAEIAZwBPAFMANgBLAGEARwBpAC8AYgBLADEAZwBWAEgAcABzAEcAcwBFAC8AQgA4AGkAbQBsAGYAcAAzAFEATQBWAGkAUABEAEgANgBhADMANQBCAGYAOABpAHkAMgAyAG4ASABQADAATgBIADkASwBEAHoAWAB5AGkAeABnAGsARQBlAGwAaABKAEcANgAyAHUAMgBjAFQAMgBmAFgAMQA0AEwAdwBSAFkATwArAGkAcgBWAGQAYwBqAEUAQgBoAGQASwA1ADQAYgBPAFcAdgBUAHcAbQBUAFMAVwBHAE8AaAB2ADIAbwBiADIAawBQAEEANgBpADEAVgBRAFUAaQA4AEQASwB1AEsANAA4AGYAWgBIADcASQBKAGEAZQBxAHMAdwBFAD0AJgBwAD0A';
+ $tValue = base64_encode(hex2bin(randStr(60)));
+ $data = 't='.$tValue.'&p=';
+ return base64_encode(chunk_split($data, 1, "\0"));
}
function uupEncryptedData() {
- $encData = 'o2vRpZuat2Ot2MKdwG29/fwtUpuU1XOgAr1Lrzo+dWejpj0CZiCSo6v05klhJbSrT0iylYNs8JXPA0owZvOmvvWYSs5+8u/hqUFtMgT/6Z99nhPNYD0Y00jol58NwB1RJcYWy3hzJz/5cAiZ60GRwa8zMDVbsI8qgF1AT/XKjbwsoOQNRTW5gVPDX/Fs/uICWI968NXQjiV7p2AP8poB/CCwA1cpgZPx';
-
$cookieInfo = @file_get_contents(dirname(__FILE__).'/cookie.json');
$cookieInfo = json_decode($cookieInfo, 1);
- if(!empty($cookieInfo)) {
+ if(empty($cookieInfo)) {
+ $postData = composeGetCookieRequest(uupDevice());
+ sendWuPostRequest('https://fe3.delivery.mp.microsoft.com/ClientWebService/client.asmx', $postData);
+
+ $encData = uupEncryptedData();
+ } else {
$encData = $cookieInfo['encryptedData'];
}
diff --git a/shared/main.php b/shared/main.php
index ff71af7..0d3db96 100644
--- a/shared/main.php
+++ b/shared/main.php
@@ -16,7 +16,7 @@ limitations under the License.
*/
function uupApiVersion() {
- return '1.16.2';
+ return '1.17.0';
}
require_once dirname(__FILE__).'/auths.php';
diff --git a/shared/requests.php b/shared/requests.php
index 84dd6e1..20ecb92 100644
--- a/shared/requests.php
+++ b/shared/requests.php
@@ -28,9 +28,9 @@ function composeDeviceAttributes($flight, $ring, $build, $arch, $sku) {
}
$attrib = array(
- 'App=WU',
+ 'App=WU_OS',
'AppVer='.$build,
- 'AttrDataVer=50',
+ 'AttrDataVer=52',
'BranchReadinessLevel=CB',
'CurrentBranch='.$branch,
'DeviceFamily=Windows.Desktop',
@@ -39,8 +39,6 @@ function composeDeviceAttributes($flight, $ring, $build, $arch, $sku) {
'FlightRing='.$ring,
'FlightingBranchName=external',
'Free=32to64',
- 'GStatus_RS3=2',
- 'GStatus_RS4=2',
'GStatus_RS5=2',
'InstallDate=1438196400',
'InstallLanguage=en-US',
@@ -59,8 +57,6 @@ function composeDeviceAttributes($flight, $ring, $build, $arch, $sku) {
'ProcessorManufacturer=GenuineIntel',
'TelemetryLevel=1',
'UpdateManagementGroup=2',
- 'UpgEx_RS3=Green',
- 'UpgEx_RS4=Green',
'UpgEx_RS5=Green',
'WuClientVer='.$build,
);
@@ -96,7 +92,7 @@ function branchFromBuild($build) {
// Composes POST data for gathering list of urls for download
function composeFileGetRequest($updateId, $device, $info, $rev = 1) {
- $uuid = randStr(8).'-'.randStr(4).'-'.randStr(4).'-'.randStr(4).'-'.randStr(12);
+ $uuid = genUUID();
$createdTime = time();
$expiresTime = $createdTime + 120;
@@ -119,7 +115,7 @@ function composeFileGetRequest($updateId, $device, $info, $rev = 1) {
// Composes POST data for fetching the latest update information from Windows Update
function composeFetchUpdRequest($device, $encData, $arch, $flight, $ring, $build, $sku = 48) {
- $uuid = randStr(8).'-'.randStr(4).'-'.randStr(4).'-'.randStr(4).'-'.randStr(12);
+ $uuid = genUUID();
$createdTime = time();
$expiresTime = $createdTime + 120;
@@ -130,12 +126,15 @@ function composeFetchUpdRequest($device, $encData, $arch, $flight, $ring, $build
$branch = branchFromBuild($build);
$products = array(
- 'PN=Client.OS.rs2.'.$arch.'&Branch='.$branch.'&PrimaryOSProduct=1&V='.$build,
- 'PN=Windows.Appraiser.'.$arch.'&V='.$build,
- 'PN=Windows.AppraiserData.'.$arch.'&V='.$build,
- 'PN=Windows.EmergencyUpdate.'.$arch.'&V='.$build,
- 'PN=Windows.OOBE.'.$arch.'&V='.$build,
- 'PN=Windows.UpdateStackPackage.'.$arch.'&Name=Update Stack Package&V='.$build,
+ 'PN=Client.OS.rs2.'.$arch.'&Branch='.$branch.'&PrimaryOSProduct=1&Repairable=1&V='.$build,
+ 'PN=Windows.Appraiser.'.$arch.'&Repairable=1&V='.$build,
+ 'PN=Windows.AppraiserData.'.$arch.'&Repairable=1&V='.$build,
+ 'PN=Windows.EmergencyUpdate.'.$arch.'&Repairable=1&V='.$build,
+ 'PN=Windows.OOBE.'.$arch.'&IsWindowsOOBE=1&Repairable=1&V='.$build,
+ 'PN=Windows.UpdateStackPackage.'.$arch.'&Name=Update Stack Package&Repairable=1&V='.$build,
+ 'PN=Hammer.'.$arch.'&Source=UpdateOrchestrator&V=0.0.0.0',
+ 'PN=MSRT.'.$arch.'&Source=UpdateOrchestrator&V=0.0.0.0',
+ 'PN=SedimentPack.'.$arch.'&Source=UpdateOrchestrator&V=0.0.0.0',
);
$callerAttrib = array(
@@ -158,4 +157,17 @@ function composeFetchUpdRequest($device, $encData, $arch, $flight, $ring, $build
return 'http://www.microsoft.com/SoftwareDistribution/Server/ClientWebService/SyncUpdatesurn:uuid:'.$uuid.'https://fe3.delivery.mp.microsoft.com/ClientWebService/client.asmx'.$created.''.$expires.''.$device.'2046-02-18T21:29:10Z'.$encData.'falsefalsetruetrueExtendedLocalizedPropertiesEulaen-USfalse'.$deviceAttributes.''.$callerAttrib.''.$products.'';
}
+
+// Composes POST data for Get Cookie request
+function composeGetCookieRequest($device) {
+ $uuid = genUUID();
+
+ $createdTime = time();
+ $expiresTime = $createdTime + 120;
+
+ $created = gmdate(DATE_W3C, $createdTime);
+ $expires = gmdate(DATE_W3C, $expiresTime);
+
+ return 'http://www.microsoft.com/SoftwareDistribution/Server/ClientWebService/GetCookieurn:uuid:'.$uuid.'https://fe3.delivery.mp.microsoft.com/ClientWebService/client.asmx'.$created.''.$expires.''.$device.''.$created.''.$created.''.$created.'2.0';
+}
?>
diff --git a/shared/utils.php b/shared/utils.php
index 0d2525d..b5789c3 100644
--- a/shared/utils.php
+++ b/shared/utils.php
@@ -34,6 +34,23 @@ function randStr($length = 4) {
return $randomString;
}
+function genUUID() {
+ return sprintf('%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
+ rand(0, 0xffff),
+ rand(0, 0xffff),
+
+ rand(0, 0xffff),
+
+ rand(0, 0x0fff) | 0x4000,
+
+ rand(0, 0x3fff) | 0x8000,
+
+ rand(0, 0xffff),
+ rand(0, 0xffff),
+ rand(0, 0xffff)
+ );
+}
+
function sendWuPostRequest($url, $postData) {
$req = curl_init($url);
@@ -52,7 +69,7 @@ function sendWuPostRequest($url, $postData) {
curl_close($req);
$outDecoded = html_entity_decode($out);
- preg_match('/.*?<\/NewCookie>/', $outDecoded, $cookieData);
+ preg_match('/.*?<\/NewCookie>|.*?<\/GetCookieResult>/', $outDecoded, $cookieData);
if(!empty($cookieData)) {
preg_match('/.*<\/Expiration>/', $cookieData[0], $expirationDate);