Categories
Lumias

The phone that can replace your Whiteboard?

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

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:

  • This requires and will only work smooth on a Lumia 950 XL, while the Lumia 950 can also work, it likely will not be as smooth. For people willing to go through the effort of making this work on newer snapdragon devices, please keep in mind you’ll need the dGPU to be perfectly working, as this shell really is GPU dependent.
  • No it will not work on your HP Elite x3s nor on your Alcatel Idol 4s… or any older Lumia, and if you’re the lucky owner of a Microsoft “””Northstar””” (Lumia 960) it also will not work. Sorry /shrug
  • You will need a few tools, which I made personally to even get such a Windows Teams ISO in the first place. You will not find a genuine Windows 10 Teams ISO for ARM64 in the wild like that.
  • This is not the complete Teams OS even after using my tools, some apps are missing like the PPIWelcome app or PPISkype, the former being sort of critical for the OS to work as it provides the lockscreen UI (see below)
Screenshot of Windows 10 Teams running under a Virtual Machine on an x86_64 processor, depicting PPIWelcome.
  • The settings app will not work
  • You will need both an USB C dongle and a wired Keyboard to get to the shell for reasons I will highlight later in this post
  • You will need lots lots and lots of patience.

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_QC8994.8994_MINIMAL  /Driver:components\QC8994\PLATFORM.SOC_QC8994.BASE  /Driver:components\QC8994\PLATFORM.SOC_QC8994.BASE_MINIMAL  /Driver:components\QC8994\PLATFORM.SOC_QC8994.LATE_SOC  /Driver:components\QC8994\PLATFORM.SOC_QC8994.MMO   /Driver:components\ANYSOC\SUPPORT.DESKTOP.BASE  /Driver:components\ANYSOC\SUPPORT.DESKTOP.EXTRAS  /Driver:components\ANYSOC\SUPPORT.DESKTOP.MMO_EXTRAS  /Driver:components\ANYSOC\SUPPORT.DESKTOP.MOBILE_BRIDGE  /Driver:components\ANYSOC\SUPPORT.DESKTOP.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!

By Gustave

Gustave Monce is an engineering student currently at ENSEIRB-MATMECA. Known for work done with Lumia devices in porting different Operating Systems with other people, Fenice for Twitter, Interop Tools.