Skip to content

Instantly share code, notes, and snippets.

@Aetopia
Created September 27, 2024 05:45
Show Gist options
  • Save Aetopia/aa80a7fceffdecb6f920e78f0a3aa0a1 to your computer and use it in GitHub Desktop.
Save Aetopia/aa80a7fceffdecb6f920e78f0a3aa0a1 to your computer and use it in GitHub Desktop.
UWP Loader: A stub dynamic link library to load other dynamic link libraries into a UWP app in one go.
#define _MINAPPMODEL_H_
#include <initguid.h>
#include <windows.h>
#include <windows.data.json.h>
#include <roapi.h>
#include <winstring.h>
#include <appmodel.h>
DWORD ThreadProc(LPVOID lpParameter)
{
RoInitialize(RO_INIT_SINGLETHREADED);
WCHAR szPathName[MAX_PATH] = {};
ExpandEnvironmentStringsW(L"%LOCALAPPDATA%\\..\\RoamingState\\UWP.Loader\\", szPathName, MAX_PATH);
WCHAR szFileName[MAX_PATH] = {};
HANDLE hFile =
CreateFile2(lstrcatW(lstrcpyW(szFileName, szPathName), L".json"), FILE_READ_DATA, 0, OPEN_EXISTING, NULL);
if (hFile == INVALID_HANDLE_VALUE)
goto _;
INT cbMultiByte = GetFileSize(hFile, NULL);
LPSTR lpMultiByteStr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cbMultiByte + 1);
ReadFile(hFile, lpMultiByteStr, cbMultiByte, NULL, NULL);
CloseHandle(hFile);
INT cchWideChar = MultiByteToWideChar(CP_UTF8, 0, lpMultiByteStr, cbMultiByte, NULL, 0);
LPWSTR lpWideCharStr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WCHAR) * (cchWideChar + 1));
MultiByteToWideChar(CP_UTF8, 0, lpMultiByteStr, cbMultiByte, lpWideCharStr, cchWideChar);
HeapFree(GetProcessHeap(), 0, lpMultiByteStr);
HSTRING hString = NULL;
WindowsCreateString(lpWideCharStr, cchWideChar, &hString);
HeapFree(GetProcessHeap(), 0, lpWideCharStr);
HSTRING pActivatableClassId = NULL;
WindowsCreateString(RuntimeClass_Windows_Data_Json_JsonValue, lstrlenW(RuntimeClass_Windows_Data_Json_JsonValue),
&pActivatableClassId);
__x_ABI_CWindows_CData_CJson_CIJsonValueStatics *pJsonValueStatics = NULL;
RoGetActivationFactory(pActivatableClassId, &IID___x_ABI_CWindows_CData_CJson_CIJsonValueStatics,
(void **)&pJsonValueStatics);
WindowsDeleteString(pActivatableClassId);
boolean fSuccess = FALSE;
__x_ABI_CWindows_CData_CJson_CIJsonValue *pJsonValue = NULL;
pJsonValueStatics->lpVtbl->TryParse(pJsonValueStatics, hString, &pJsonValue, &fSuccess);
pJsonValueStatics->lpVtbl->Release(pJsonValueStatics);
WindowsDeleteString(hString);
if (fSuccess)
{
__x_ABI_CWindows_CData_CJson_CIJsonArray *pJsonArray = NULL;
pJsonValue->lpVtbl->GetArray(pJsonValue, &pJsonArray);
if (pJsonArray)
{
__FIVector_1_Windows__CData__CJson__CIJsonValue *pVector = NULL;
pJsonArray->lpVtbl->QueryInterface(pJsonArray, &IID___FIVector_1_Windows__CData__CJson__CIJsonValue,
(void **)&pVector);
UINT32 nLength = 0;
pVector->lpVtbl->get_Size(pVector, &nLength);
pVector->lpVtbl->Release(pVector);
for (UINT32 _ = 0; _ < nLength; _++)
{
HSTRING hString = NULL;
pJsonArray->lpVtbl->GetStringAt(pJsonArray, _, &hString);
if (hString)
LoadLibraryW(
lstrcatW(lstrcpyW(szFileName, szPathName),
WindowsGetStringRawBuffer(hString, &((UINT32){WindowsGetStringLen(hString)}))));
}
pJsonArray->lpVtbl->Release(pJsonArray);
}
pJsonValue->lpVtbl->Release(pJsonValue);
}
_:
RoUninitialize();
FreeLibraryAndExitThread(lpParameter, 0);
return 0;
}
BOOL DllMainCRTStartup(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
if (fdwReason == DLL_PROCESS_ATTACH)
{
if (GetCurrentPackageFamilyName(&((UINT32){}), NULL) == APPMODEL_ERROR_NO_PACKAGE)
return FALSE;
DisableThreadLibraryCalls(hinstDLL);
CloseHandle(CreateThread(NULL, 0, ThreadProc, hinstDLL, 0, NULL));
}
return TRUE;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment