The phone that can replace your Whiteboard?

⬅️ Go back

Last updated: November 8, 2020


On November 8th 2020 I began tweeting about a Lumia 950 XL supposedly running the OS the Microsoft Surface Hub runs:


The phone that can replace your whiteboard pic.twitter.com/OJ9AvJJ7Vr

-- Gustave Monce πŸ¦‰ (@gus33000) November 7, 2020

It really becomes harder and harder to find something even more cursed to do...

Prerequisites

But wait, Gus, isn't the Surface Hub an x86_64 machine? Glad you asked! Yes it is, and yes this is in fact Windows 10 "Teams" (also called PPIPro) for ARM64 Processors running on one, so how?

Well before going into the how and possibly the why (for the later you probably already know the answer: because I can) I need to get out of the way the requirements and what this is and what this is not:

Screenshot of Windows 10 Teams running under a Virtual Machine on an x86_64 processor, depicting PPIWelcome.

Acquiring an ISO image

Now that this is out of the way, let me explain how to first obtain the ISO of this thing that clearly shouldn't exist but it clearly does.

You may not know this, but Microsoft Delivers OS upgrades via Windows Update using a platform named UUP (short for Unified Update Platform). It is designed in such a way to be modular enough to adapt to the variety of different OS configurations that exist in the wild and be optimized for users to download. As a result UUP splits the Operating System components into sub packages, with base image files.

Here's a few packages you will find from UUP:


β”œβ”€β”€β”€MetadataESD
β”‚       core_en-us.esd
β”‚       professional_en-us.esd
β”‚
β”œβ”€β”€β”€UUP
β”‚   └───DESKTOP
β”‚       β”œβ”€β”€β”€Apps
β”‚       β”‚       Microsoft.ModernApps.Client.All.esd
β”‚       β”‚       Microsoft.ModernApps.Client.core.esd
β”‚       β”‚       Microsoft.ModernApps.Client.professional.esd
β”‚       β”‚       Microsoft.ModernApps.ClientN.All.esd
β”‚       β”‚
β”‚       β”œβ”€β”€β”€DotNetServicingPackages
β”‚       β”‚       Windows10.0-KB4587025-arm64-NDP48.cab
β”‚       β”‚
β”‚       β”œβ”€β”€β”€editionPackages
β”‚       β”‚   β”œβ”€β”€β”€en-us
β”‚       β”‚   β”‚   └───Client
β”‚       β”‚   β”‚           Microsoft-Windows-Client-LanguagePack-Package_en-us~31bf3856ad364e35~arm64~en-us~.esd
β”‚       β”‚   β”‚
β”‚       β”‚   └───neutral
β”‚       β”‚           Microsoft-Windows-CHPE-Binaries-arm64x86-Package.ESD
β”‚       β”‚           Microsoft-Windows-Client-Desktop-Required-arm64arm-Package.ESD
β”‚       β”‚           Microsoft-Windows-Client-Desktop-Required-Package.ESD
β”‚       β”‚           Microsoft-Windows-Client-Desktop-Required-WOW64-Package.ESD
β”‚       β”‚           Microsoft-Windows-Client-Features-arm64arm-Package.ESD
β”‚       β”‚           Microsoft-Windows-Client-Features-Package.ESD
β”‚       β”‚           Microsoft-Windows-Client-Features-WOW64-Package.ESD
β”‚       β”‚           Microsoft-Windows-EditionPack-Core-arm64arm-Package.ESD
β”‚       β”‚           Microsoft-Windows-EditionPack-Core-Package.ESD
β”‚       β”‚           Microsoft-Windows-EditionPack-Core-WOW64-Package.ESD
β”‚       β”‚           Microsoft-Windows-EditionPack-PPIPro-arm64arm-Package.ESD
β”‚       β”‚           Microsoft-Windows-EditionPack-PPIPro-Package.ESD
β”‚       β”‚           Microsoft-Windows-EditionPack-PPIPro-WOW64-Package.ESD
β”‚       β”‚           Microsoft-Windows-EditionPack-Professional-arm64arm-Package.ESD
β”‚       β”‚           Microsoft-Windows-EditionPack-Professional-Package.ESD
β”‚       β”‚           Microsoft-Windows-EditionPack-Professional-WOW64-Package.ESD
β”‚       β”‚           Microsoft-Windows-EditionSpecific-Core-Package.ESD
β”‚       β”‚           Microsoft-Windows-EditionSpecific-CoreN-Package.ESD
β”‚       β”‚           Microsoft-Windows-EditionSpecific-EnterpriseEval-Package.ESD
β”‚       β”‚           Microsoft-Windows-EditionSpecific-EnterpriseG-Package.ESD
β”‚       β”‚           Microsoft-Windows-EditionSpecific-EnterpriseGN-Package.ESD
β”‚       β”‚           Microsoft-Windows-EditionSpecific-EnterpriseNEval-Package.ESD
β”‚       β”‚           Microsoft-Windows-EditionSpecific-PPIPro-Package.ESD
β”‚       β”‚           Microsoft-Windows-EditionSpecific-Professional-Package.ESD
β”‚       β”‚           Microsoft-Windows-EditionSpecific-ProfessionalN-Package.ESD
β”‚       β”‚           Microsoft-Windows-Foundation-Package.ESD
β”‚       β”‚           Microsoft-Windows-Not-Supported-On-LTSB-arm64arm-Package.ESD
β”‚       β”‚           Microsoft-Windows-Not-Supported-On-LTSB-Package.ESD
β”‚       β”‚           Microsoft-Windows-Not-Supported-On-LTSB-WOW64-Package.ESD
β”‚       β”‚           Microsoft-Windows-RegulatedPackages-arm64arm-Package.ESD
β”‚       β”‚           Microsoft-Windows-RegulatedPackages-Package.ESD
β”‚       β”‚           Microsoft-Windows-RegulatedPackages-WOW64-Package.ESD
β”‚       β”‚           Microsoft-Windows-Required-ShellExperiences-Desktop-arm64arm-Package.ESD
β”‚       β”‚           Microsoft-Windows-Required-ShellExperiences-Desktop-Package.ESD
β”‚       β”‚           Microsoft-Windows-Required-ShellExperiences-Desktop-WOW64-Package.ESD
β”‚       β”‚           Microsoft-Windows-WowPack-CoreARM-arm64arm-Package.ESD
β”‚       β”‚
β”‚       └───FoDMetadata
β”‚               FoDMetadata_Client.cab
β”‚
└───WindowsUpdateBox
        WindowsUpdateBox.exe
        

You may already have noticed by looking at the list I posted above, that there is some packages for PPIPro and for ARM64. If you know a bit about how creating a media using files from an UUP's update you will know however that you need a Base image to be able to get an edition, and we only have Home (core_en-us.esd) and Pro (professional_en-us.esd).

The solution? We can create a Professional image and then use the files from the PPIPro edition packages to change the edition from the Pro image we created. While I will not go into the exact inner workings of such procedure, you can likely find a bit more about it by reading the original thread who discovered this technique over the My Digital Life forums.

However, I did write a few tools to create images from UUP which do in fact automate the entire process.

You will have to download the latest release from Github. You will have to initiate a complete download (this may take a good 30 minutes) using the following command:


uupdownload -s Professional -v 10.0.20241.1005 -r External -c rs_prerelease -b Dev -t arm64 -l en-US -o dlfolder
        

And then you can initiate the conversion process from an admin command prompt using the following command:


for /f %f in ('dir /b .\dlfolder\') do uupmediaconvertercli %CD%\dlfolder\%f Windows_10_Pro_ARM64_English.iso en-US
        

This process will take a while, but in the end you'll have an ISO file with about 14 editions. Usually the last image index is PPIPro (Index 14) but be sure to check the WIM Info XML file to be sure, or use DISM to list all images to find out by the image descriptions.

Installing the image on a Lumia 950 XL

Now that we got ourselves a PPIPro ISO image for ARM64, we need to install it on a Lumia 950 XL.

To make things easier, here we already assume you got a Lumia 950 XL running Windows 10 Desktop on it. (Just be sure the deployment you did is no older than at least a month ago otherwise the OS will not boot up due to critical UEFI firmware changes that are needed to boot newer Windows 10 Builds on MSM8994).

Format the partition that contains the Desktop OS (and only this one), then use DISM to apply the PPIPro image, your dism command will look most likely like mine below, here my PPIPro index is 14 and my phone uses the drive letter I:


dism /Apply-Image /ImageFile:D:\sources\install.wim /Index:14 /ApplyDir:I:
        

Once dism did complete, we now need to install some drivers, or at least the first part of the installation process. You will need to download the latest archive (primary branch) of this repository. Unpack it, and run the following command to add the drivers for the first part of the setup process:


dism /Image:I: /Add-Driver /Recurse /Driver:components\QC8994\DEVICE.INPUT.SYNAPTICS_RMI4_F12_10  /Driver:components\QC8994\DEVICE.SOC_QC8994.CITYMAN  Driver:components\QC8994\DEVICE.USB.MMO_USBC  /Driver:components\QC8994\OEM.SOC_QC8994.MMO  /Driver:components\QC8994\OEM.SOC_QC8994.MMO_GRAPHICS  Driver:components\QC8994\OEM.SOC_QC8994.MMO_SOC8994  /Driver:components\QC8994\PLATFORM.SOC_QC8994.8994  /Driver:components\QC8994\PLATFORM.SOC_QC89948994_MINIMAL  /Driver:components\QC8994\PLATFORM.SOC_QC8994.BASE  /Driver:components\QC8994\PLATFORM.SOC_QC8994.BASE_MINIMAL  /Driver:components\QC8994\PLATFORMSOC_QC8994.LATE_SOC  /Driver:components\QC8994\PLATFORM.SOC_QC8994.MMO   /Driver:components\ANYSOC\SUPPORT.DESKTOP.BASE  /Driver:components\ANYSOC\SUPPORTDESKTOP.EXTRAS  /Driver:components\ANYSOC\SUPPORT.DESKTOP.MMO_EXTRAS  /Driver:components\ANYSOC\SUPPORT.DESKTOP.MOBILE_BRIDGE  /Driver:components\ANYSOC\SUPPORTDESKTOP.MOBILE_COMPONENTS  /Driver:components\ANYSOC\SUPPORT.DESKTOP.MOBILE_RIL  /Driver:components\ANYSOC\SUPPORT.DESKTOP.MOBILE_RIL_EXTRAS  Driver:components\ANYSOC\SUPPORT.DESKTOP.PHONE_SERVICE
        

Let the Setup begin! And not end?

Now you're ready to reboot the phone, and let the first part of the setup process happen til you see the Out of Box Experience (OOBE). Once you do, you must stop interacting the device, and follow the next steps.

Due to the cursed nature of this PPIPro image, some critical components are missing from the Operating System. One of them is responsible for making the OOBE account page of PPIPro work, which is quite critical. Another issue you may have noticed is that right now the device does not have the GPU up and running, due to policies being in place that prevented some post install scripts from running. Now we have to address both of these things.

Edit the SYSTEM registry hive as such:


SYSTEM\Setup:
SetupType=dword:0000002
CmdLine="cmd.exe /c C:\test.cmd"
        

Place a file named test.cmd at the root of the phone Windows partition with the following content in it:


start "" osk.exe
start "" cmd.exe
pause
        

Make sure the SYSTEM hive is unloaded from your host, and reboot the device. The device will reboot to a command prompt and a keyboard (OSK) for you to type on it.

We need to do a few things from here. First execute the following command to launch post installation process that did not run due to policies:


\Windows\Setup\Scripts\Oobe.cmd
        

In case this script fails, you can always launch Device manager manually using below command and install all drivers by hand that are missing (please note MSHW1004 is the OEMPanel device, which will bring up the panel and GPU, and is the most critical one to bring up here)


mmc.exe devmgmt.msc
        

Now that we got all drivers installed, we need to add some accounts that the OS will rely on. To do so, run the following:


net user SurfaceHub /add
net user Admin a /add
net localgroup administrators Admin /add
        

Now that we got some accounts setup, reboot the device and go back to mass storage. To make things easier, to reboot run the following:


shutdown /r /t 0 /f
        

Back to mass storage, remount the SYSTEM hive and this time the SOFTWARE hive as well. We now have to disable OOBE from running and set a few more registry entries so the Shell and OS perform as intended. Below is a list of things to do:


[HKEY_LOCAL_MACHINE\PSYSTEM\Setup\Status\UnattendPasses]
Only keep the oobeSystem value here, and delete the other one. Set oobeSystem to 2
        

In the software hive, make sure the OOBE key looks roughly like the one shown below (you may have more things, just keep them, but be careful to not keep some values telling the OS OOBE failed to run under the Health keys)


Windows Registry Editor Version 5.00
        
[HKEY_LOCAL_MACHINE\PSOFTWARE\Microsoft\Windows\CurrentVersion\OOBE\Health]
"Health"=hex:0e,00,00,00,00,00,00,01,00,00,00,00,00,00,00,00,00,01,00,00,00,00,\
01,00,00,00,00,00,00,00,00,01,00,00,00,00,01,00,00,00,01,00,00,00,01,00,00,\
00,00,00,00,00,00,00,00,00,02,00,00,00,00,00,00,00,01,00,00,00,00,00,00,00,\
01,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,02,00,00,00,00,\
00,00,00,0b,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,06,00,00,00,06,00,\
00,00,00,00,00,00,07,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,\
00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
"HealthEvaluation"=hex:0e,00,00,00,ad,58,54,9f,31,b5,d6,01
"Census"=hex:0e,00,00,00,00,00,00,00,00,00,00,00,01,00,00,00

[HKEY_LOCAL_MACHINE\PSOFTWARE\Microsoft\Windows\CurrentVersion\OOBE\OOBECompletedForOOBEHealth]
"AnyoneReadOOBECompleted"=dword:00000001
"OOBECompleteTimestamp"=hex:e4,07,0b,00,06,00,07,00,10,00,13,00,20,00,2f,00

[HKEY_LOCAL_MACHINE\PSOFTWARE\Microsoft\Windows\CurrentVersion\OOBE\OOBECompleteTimestamp]
"OOBECompleteTimestamp"=hex:e4,07,0b,00,06,00,07,00,12,00,10,00,20,00,a6,02

[HKEY_LOCAL_MACHINE\PSOFTWARE\Microsoft\Windows\CurrentVersion\OOBE\Stats]
"WlanInterfaceGUID"="{8338F268-89DA-4C48-B58C-47FC0906D344}"
"WlanProfileName"="XXXX-36c2"
"EndTimeStamp"=hex:e4,07,0b,00,06,00,07,00,12,00,00,00,07,00,31,00
"OOBEUserSignedIn"=dword:00000001
        


Under HKEY_LOCAL_MACHINE\PSOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon

Set DefaultUserName to "SurfaceHub"
Set DefaultDomainName to "."
set LastUsedUsername to "SurfaceHub"
Set AutoAdminLogon to 1
Set ForceAutoLogon to 1

Create HKEY_LOCAL_MACHINE\PSOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\SpecialAccounts\UserList

In it, create SurfaceHub (Dword 32 bit) set value to 1

Under HKEY_LOCAL_MACHINE\PSOFTWARE\Microsoft\PPI\Settings
Set DefaultUserCreated to 1
        

Make sure the following key looks as follows:


Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\PSOFTWARE\Microsoft\PPI\SetupTasks]
"PPISelfHostTaskHandler_v1_progress"=dword:00000064
"PPISelfHostTaskHandler"=dword:00000001
"PPICrashSettings_v1_progress"=dword:00000064
"PPICrashSettings"=dword:00000001
"PPIIngestDriverSetup_v1_progress"=dword:00000064
"PPIIngestDriverSetup"=dword:00000001
"PPIUpdateManagerPluginSetup_v1_progress"=dword:00000064
"PPIUpdateManagerPluginSetup"=dword:00000001
"PPIPowerSettings_v1_progress"=dword:00000064
"PPIPowerSettings"=dword:00000001
"PPIAdminUserManager"=dword:00000001
"PPIRoomSetupPlugin_v1_progress"=dword:00000064
"PPIDefaultUserManager"=dword:00000001
"PPIDefaultUserManager_v1_progress"=dword:00000064
"PPIRoomSetupPlugin"=dword:00000001
"PPIAdminUserManager_v1_progress"=dword:00000064
"PPIOOBEDefaultUser0Manager"=dword:00000001
"PPIOOBEDefaultUser0Manager_v1_progress"=dword:00000064
        


Under HKEY_LOCAL_MACHINE\PSOFTWARE\Microsoft\PPI\Settings\DeviceAccount

Set EasDeletionCompleted and MigrateEasCompleted to 1
        

Now you're ready, and you can reboot the device, but you may quickly notice something isn't quite right, the device will show the following screen in a loop or show the normal Windows 10 lockscreen and not do much else:

All of that... for this?

Well this is where the issue I highlighted earlier shines. ARM64 PPIPro as it currently is, is missing some components, one of them being PPIWelcome, and this is what is broken here. Thankfully there's a workaround to get to the shell. Plug in an USB dongle and a keyboard on the phone, when you see the Getting things ready screen, press either the windows key the esc key and/or the shift key multiple times, then double tap the phone screen. If you got lucky, the phone will show the PPIPro shell:

This procedure is very hit and miss, but it is the only way I currently found to get the shell to launch.

Conclusion

And here you have it, one more cursed thing this now 5 years old phone can run. Is it useful? No. Should you use this? No absolutely not. Is it pointless? Yes. But did I enjoy doing this? Heck yeah! And now you too can reproduce it. Hope you enjoy this. Feel free to message me if you find improvements that can be made, but I think this may remain as such for the time being, at least til the OS changes to add missing components, if it ever does...

Stay safe!