You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
273 lines
9.8 KiB
273 lines
9.8 KiB
#include "windows.h"
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
|
|
BOOL
|
|
ExtractResourceToFile(
|
|
HMODULE Module,
|
|
PCWSTR ResourceType,
|
|
PCWSTR ResourceName,
|
|
WCHAR* TempFilePath,
|
|
HANDLE* TempFileHandle
|
|
)
|
|
{
|
|
WCHAR TempDirectory[MAX_PATH];
|
|
DWORD Dword = 0;
|
|
int ResourceSize = 0;
|
|
void* ResourceAddress = 0;
|
|
HRSRC ResourceInfo = 0;
|
|
BOOL Success = FALSE;
|
|
|
|
TempFilePath[0] = 0;
|
|
TempDirectory[0] = 0;
|
|
*TempFileHandle = 0;
|
|
|
|
#define X(x) do { if (!(x)) { printf("%s failed\n", #x); goto Exit; } } while(0)
|
|
X(ResourceInfo = FindResourceW(Module, ResourceName, ResourceType));
|
|
X(ResourceAddress = LockResource(LoadResource(Module, ResourceInfo)));
|
|
X(ResourceSize = SizeofResource(Module, ResourceInfo));
|
|
X(GetTempPathW(RTL_NUMBER_OF(TempDirectory), TempDirectory));
|
|
X(GetTempFileNameW(TempDirectory, NULL, 0, TempFilePath));
|
|
*TempFileHandle = CreateFileW(TempFilePath, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
|
X(*TempFileHandle != INVALID_HANDLE_VALUE);
|
|
X(WriteFile(*TempFileHandle, ResourceAddress, ResourceSize, &Dword, NULL));
|
|
#undef X
|
|
Success = TRUE;
|
|
Exit:
|
|
if (!Success)
|
|
{
|
|
int Error;
|
|
printf("%s() failed %d\n", __FUNCTION__, Error = GetLastError());
|
|
}
|
|
return Success;
|
|
}
|
|
|
|
int __cdecl wmain(int argc, wchar_t** argv)
|
|
{
|
|
PCWSTR BaseNames[] = { L"dll", L"DLL", L"Dll" };
|
|
PCWSTR Extensions[] = { L"", L".dll", L".DLL", L".Dll" };
|
|
const static int Flags1[] = { 0, LOAD_LIBRARY_AS_DATAFILE };
|
|
const static int Flags2[] = { LOAD_LIBRARY_AS_DATAFILE, 0 };
|
|
const int* Flags = Flags1;
|
|
const int NumberOfFlags = 2;
|
|
int i=0, j=0, k=0;
|
|
const PCWSTR CommandLine = GetCommandLineW();
|
|
|
|
struct ActivationContext
|
|
{
|
|
HANDLE Handle;
|
|
ULONG Cookie;
|
|
} ActivationContexts[2] = {0}; // INVALID_HANDLE_VALUE is not convenient.
|
|
HANDLE Handle = NULL;
|
|
INT ResourceId = 0;
|
|
INT Error = 0;
|
|
WCHAR Argv0[MAX_PATH];
|
|
PWSTR FilePart = 0;
|
|
//
|
|
// This is to target this test at older sxs without the resource feature.
|
|
//
|
|
DWORD ResourceFlag = ACTCTX_FLAG_RESOURCE_NAME_VALID;
|
|
|
|
if ((wcsstr(CommandLine, L"-swapFlagOrder") != 0) ||
|
|
(wcsstr(CommandLine, L"-swapflagorder") != 0) ||
|
|
(wcsstr(CommandLine, L"-swap-flag-order") != 0) ||
|
|
(wcsstr(CommandLine, L"-alterFlagOrder") != 0) ||
|
|
(wcsstr(CommandLine, L"-alterflagorder") != 0) ||
|
|
(wcsstr(CommandLine, L"-alter-flag-order") != 0))
|
|
{
|
|
Flags = Flags2;
|
|
}
|
|
|
|
if ((wcsstr(CommandLine, L"-filesInsteadOfResources") != 0) ||
|
|
(wcsstr(CommandLine, L"-filesinsteadofresources") != 0) ||
|
|
(wcsstr(CommandLine, L"-files-instead-of-resources") != 0))
|
|
{
|
|
ResourceFlag = 0;
|
|
}
|
|
|
|
if ((wcsstr(CommandLine, L"-alterEmptyExtensionOrder") != 0) ||
|
|
(wcsstr(CommandLine, L"-alteremptyextensionorder") != 0) ||
|
|
(wcsstr(CommandLine, L"-alter-empty-extension-order") != 0))
|
|
{
|
|
Extensions[0] = Extensions[1];
|
|
Extensions[1] = L"";
|
|
}
|
|
|
|
if ((wcsstr(CommandLine, L"-alterCaseOrder") != 0) ||
|
|
(wcsstr(CommandLine, L"-altercaseorder") != 0) ||
|
|
(wcsstr(CommandLine, L"-alter-case-order") != 0))
|
|
{
|
|
// flip the case of each letter, this actually creates previously nonexistant
|
|
// cases: .dLL
|
|
WCHAR* String = 0;
|
|
const WCHAR* ConstString = 0;
|
|
for (i = 0 ; i < RTL_NUMBER_OF(BaseNames) ; ++i)
|
|
{
|
|
ConstString = BaseNames[i];
|
|
#define X \
|
|
if (ConstString) \
|
|
{ \
|
|
String = _wcsdup(ConstString); \
|
|
BaseNames[i] = String; \
|
|
while (*String) \
|
|
if (*String != '.') *String++ ^= 0x20; \
|
|
else String++; \
|
|
}
|
|
X
|
|
}
|
|
for (i = 0 ; i < RTL_NUMBER_OF(Extensions) ; ++i)
|
|
{
|
|
ConstString = Extensions[i];
|
|
X
|
|
#undef X
|
|
}
|
|
}
|
|
|
|
//printf("argv[0]: %ls\n", argv[0]);
|
|
Argv0[0] = 0;
|
|
if (!GetFullPathNameW(argv[0], RTL_NUMBER_OF(Argv0), Argv0, NULL))
|
|
{
|
|
printf("GetFullPathNameW(%ls) failed %d\n", argv[0], Error = GetLastError());
|
|
exit(Error);
|
|
}
|
|
//printf("Argv0: %ls\n", Argv0);
|
|
__try
|
|
{
|
|
for (ResourceId = 0 ; ResourceId < RTL_NUMBER_OF(ActivationContexts) ; ++ResourceId)
|
|
{
|
|
HANDLE ManifestFileHandle = 0;
|
|
WCHAR ManifestFile[MAX_PATH];
|
|
ACTCTXW CreateActivationContextParameters = {sizeof(CreateActivationContextParameters)};
|
|
ManifestFile[0] = 0;
|
|
|
|
CreateActivationContextParameters.dwFlags = ResourceFlag;
|
|
CreateActivationContextParameters.lpResourceName = (PCWSTR)(INT_PTR)(ResourceId + 2);
|
|
CreateActivationContextParameters.lpSource = Argv0;
|
|
|
|
if (!ResourceFlag)
|
|
{
|
|
ExtractResourceToFile(
|
|
NULL,
|
|
//GetModuleHandleW(NULL),
|
|
(PCWSTR)RT_MANIFEST,
|
|
CreateActivationContextParameters.lpResourceName,
|
|
ManifestFile,
|
|
&ManifestFileHandle);
|
|
CreateActivationContextParameters.lpSource = ManifestFile;
|
|
|
|
printf("dwFlags:0x%lx\n", CreateActivationContextParameters.dwFlags);
|
|
printf("lpSource:%ls\n", CreateActivationContextParameters.lpSource);
|
|
}
|
|
|
|
// switch access to readonly
|
|
// keep the file open to prevent deletion
|
|
if (ManifestFileHandle)
|
|
{
|
|
if (!DuplicateHandle(
|
|
GetCurrentProcess(),
|
|
ManifestFileHandle,
|
|
GetCurrentProcess(),
|
|
&ManifestFileHandle,
|
|
GENERIC_READ,
|
|
FALSE,
|
|
DUPLICATE_CLOSE_SOURCE))
|
|
{
|
|
ManifestFileHandle = 0;
|
|
}
|
|
}
|
|
|
|
Handle = CreateActCtxW(&CreateActivationContextParameters);
|
|
|
|
if (Handle == INVALID_HANDLE_VALUE)
|
|
Error = GetLastError();
|
|
if (ManifestFileHandle)
|
|
{
|
|
CloseHandle(ManifestFileHandle);
|
|
ManifestFileHandle = 0;
|
|
}
|
|
if (ManifestFile[0])
|
|
{
|
|
//DeleteFileW(ManifestFile);
|
|
ManifestFile[0] = 0;
|
|
}
|
|
if (Handle == INVALID_HANDLE_VALUE)
|
|
{
|
|
printf("CreateActCtxW(ResourceId:%d) failed %d\n", (ResourceId + 2), Error);
|
|
}
|
|
else
|
|
{
|
|
printf("CreateActCtxW(ResourceId:%d):%p\n", (ResourceId + 2), Handle);
|
|
if (!ActivateActCtx(Handle, &ActivationContexts[ResourceId].Cookie))
|
|
{
|
|
printf("ActivateActCtx(ResourceId:%d, Handle:%p) failed %d\n", (ResourceId + 2), Handle, Error = GetLastError());
|
|
ReleaseActCtx(Handle);
|
|
}
|
|
else
|
|
{
|
|
ActivationContexts[ResourceId].Handle = Handle;
|
|
}
|
|
}
|
|
for (i = 0 ; i < RTL_NUMBER_OF(BaseNames) ; ++i)
|
|
{
|
|
for (j = 0 ; j < RTL_NUMBER_OF(Extensions) ; ++j)
|
|
{
|
|
for (k = 0 ; k < NumberOfFlags ; ++k)
|
|
{
|
|
HRSRC ResourceInfo = NULL;
|
|
WCHAR StringResourceBuffer[2] = {0};
|
|
HANDLE Dll = 0;
|
|
WCHAR Name[8+1+3+1];
|
|
WCHAR ModuleNameBuffer[MAX_PATH];
|
|
Name[0] = 0;
|
|
ModuleNameBuffer[0] = 0;
|
|
|
|
wcscat(Name, BaseNames[i]);
|
|
wcscat(Name, Extensions[j]);
|
|
|
|
Dll = LoadLibraryExW(Name, NULL, Flags[k]);
|
|
Error = GetLastError();
|
|
if (Dll)
|
|
{
|
|
LoadStringW(Dll, 1, StringResourceBuffer, RTL_NUMBER_OF(StringResourceBuffer));
|
|
GetModuleFileNameW(Dll, ModuleNameBuffer, RTL_NUMBER_OF(ModuleNameBuffer));
|
|
ResourceInfo = FindResourceW(Dll, (PCWSTR)1, (PCWSTR)RT_STRING);
|
|
FreeLibrary(Dll);
|
|
}
|
|
printf(
|
|
"LoadLibraryExW(%ls, 0x%x):%p, Error:%d, ResourceInfo:%p, String:%ls, ModuleName:%ls.\n",
|
|
Name,
|
|
Flags[k],
|
|
Dll,
|
|
Error,
|
|
ResourceInfo,
|
|
StringResourceBuffer,
|
|
ModuleNameBuffer);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
for (ResourceId = RTL_NUMBER_OF(ActivationContexts) - 1 ; ResourceId >= 0 ; --ResourceId)
|
|
{
|
|
Handle = ActivationContexts[ResourceId].Handle;
|
|
if (Handle)
|
|
{
|
|
ULONG Cookie = ActivationContexts[ResourceId].Cookie;
|
|
if (!DeactivateActCtx(0, Cookie))
|
|
{
|
|
printf(
|
|
"DeactivateActCtx(ResourceId:%d, Handle:%p, Cookie:0x%lx) failed %d\n",
|
|
ResourceId + 2,
|
|
Handle,
|
|
Cookie,
|
|
Error = GetLastError());
|
|
}
|
|
ReleaseActCtx(Handle);
|
|
}
|
|
}
|
|
}
|
|
__except(EXCEPTION_EXECUTE_HANDLER)
|
|
{
|
|
printf("0x%x\n", Error = GetExceptionCode());
|
|
}
|
|
return 0;
|
|
}
|