1.0
This commit is contained in:
@@ -5,9 +5,11 @@
|
||||
#include "modulehelper.h"
|
||||
#include "registryhelper.h"
|
||||
#include "servicehelper.h"
|
||||
#include "versionhelper.h"
|
||||
#include "ptrlist.h"
|
||||
#include "wufuc.h"
|
||||
|
||||
#include <VersionHelpers.h>
|
||||
#include <minhook.h>
|
||||
|
||||
VOID CALLBACK cb_service_notify(PSERVICE_NOTIFYW pNotifyBuffer)
|
||||
@@ -38,25 +40,30 @@ DWORD WINAPI cb_start(HANDLE *pParam)
|
||||
DWORD dwProcessId;
|
||||
LPQUERY_SERVICE_CONFIGW pServiceConfig;
|
||||
DWORD dwServiceType;
|
||||
const wchar_t szKernel32Dll[] = L"kernel32.dll";
|
||||
const wchar_t szKernelBaseDll[] = L"KernelBase.dll";
|
||||
const wchar_t *pszModule;
|
||||
MH_STATUS status;
|
||||
int tmp;
|
||||
LPVOID pTarget = NULL;
|
||||
LPVOID pv1 = NULL;
|
||||
LPVOID pv2 = NULL;
|
||||
wchar_t *str;
|
||||
HMODULE hModule;
|
||||
|
||||
if ( !pParam ) {
|
||||
trace(L"Parameter argument is null!");
|
||||
log_error(L"Parameter argument is null!");
|
||||
goto unload;
|
||||
}
|
||||
|
||||
handles[0] = pParam[0]; // main mutex
|
||||
handles[1] = pParam[1]; // unload event
|
||||
hCrashMutex = pParam[2]; // crash mutex
|
||||
hProceedEvent = pParam[3]; // proceed event
|
||||
VirtualFree(pParam, 0, MEM_RELEASE);
|
||||
if ( !VirtualFree(pParam, 0, MEM_RELEASE) )
|
||||
log_warning(L"VirtualFree failed! (lpAddress=%p, GLE=%lu)", pParam, GetLastError());
|
||||
|
||||
// acquire child mutex, this should be immediate.
|
||||
if ( WaitForSingleObject(hCrashMutex, 5000) != WAIT_OBJECT_0 ) {
|
||||
trace(L"Failed to acquire child mutex within five seconds. (%p)", hCrashMutex);
|
||||
log_error(L"Failed to acquire child mutex within five seconds. (%p)", hCrashMutex);
|
||||
goto close_handles;
|
||||
}
|
||||
SetEvent(hProceedEvent);
|
||||
@@ -64,12 +71,10 @@ DWORD WINAPI cb_start(HANDLE *pParam)
|
||||
|
||||
hSCM = OpenSCManagerW(NULL, NULL, SC_MANAGER_CONNECT);
|
||||
if ( !hSCM ) {
|
||||
trace(L"Failed to open SCM. (GetLastError=%lu)", GetLastError());
|
||||
log_error(L"Failed to open SCM. (GetLastError=%lu)", GetLastError());
|
||||
goto release;
|
||||
}
|
||||
|
||||
hService = OpenServiceW(hSCM, L"wuauserv",
|
||||
SERVICE_QUERY_STATUS | SERVICE_QUERY_CONFIG);
|
||||
hService = OpenServiceW(hSCM, L"wuauserv", SERVICE_QUERY_STATUS | SERVICE_QUERY_CONFIG);
|
||||
dwProcessId = svc_heuristic_process_id(hSCM, hService);
|
||||
pServiceConfig = svc_query_config_alloc(hSCM, hService, NULL);
|
||||
dwServiceType = pServiceConfig->dwServiceType;
|
||||
@@ -79,23 +84,33 @@ DWORD WINAPI cb_start(HANDLE *pParam)
|
||||
CloseServiceHandle(hSCM);
|
||||
|
||||
if ( tmp || dwProcessId != GetCurrentProcessId() ) {
|
||||
trace(L"Injected into wrong process!");
|
||||
log_error(L"Injected into wrong process!");
|
||||
goto release;
|
||||
}
|
||||
if ( !ver_verify_version_info(6, 1, 0) && !ver_verify_version_info(6, 3, 0) ) {
|
||||
log_error(L"Unsupported operating system!");
|
||||
goto release;
|
||||
}
|
||||
|
||||
if ( dwServiceType == SERVICE_WIN32_SHARE_PROCESS ) {
|
||||
// assume wuaueng.dll hasn't been loaded yet, apply
|
||||
// RegQueryValueExW hook to fix incompatibility with
|
||||
// UpdatePack7R2 and other patches that modify the
|
||||
// Windows Update ServiceDll path in the registry.
|
||||
MH_CreateHookApiEx(L"kernel32.dll",
|
||||
pszModule = IsWindows8OrGreater()
|
||||
? szKernelBaseDll
|
||||
: szKernel32Dll;
|
||||
status = MH_CreateHookApiEx(pszModule,
|
||||
"RegQueryValueExW",
|
||||
RegQueryValueExW_hook,
|
||||
&(PVOID)g_pfnRegQueryValueExW,
|
||||
&pTarget);
|
||||
MH_EnableHook(pTarget);
|
||||
&pv1);
|
||||
if ( status == MH_OK ) {
|
||||
status = MH_EnableHook(pv1);
|
||||
if ( status == MH_OK )
|
||||
log_info(L"Hooked RegQueryValueExW! (Module=%ls, Address=%p)", pszModule, pv1);
|
||||
else log_error(L"Failed to enable RegQueryValueExW hook! (Status=%hs)", MH_StatusToString(status));
|
||||
} else log_error(L"Failed to create RegQueryValueExW hook! (Status=%hs)", MH_StatusToString(status));
|
||||
}
|
||||
|
||||
// query the ServiceDll path after applying our compat hook so that it
|
||||
// is correct
|
||||
str = (wchar_t *)reg_query_value_alloc(HKEY_LOCAL_MACHINE,
|
||||
@@ -103,18 +118,25 @@ DWORD WINAPI cb_start(HANDLE *pParam)
|
||||
L"ServiceDll", NULL, NULL);
|
||||
if ( !str ) {
|
||||
abort_hook:
|
||||
if ( pTarget )
|
||||
MH_RemoveHook(pTarget);
|
||||
if ( pv1 )
|
||||
MH_RemoveHook(pv1);
|
||||
goto release;
|
||||
}
|
||||
g_pszWUServiceDll = env_expand_strings_alloc(str, NULL);
|
||||
free(str);
|
||||
if ( !g_pszWUServiceDll ) goto abort_hook;
|
||||
|
||||
MH_CreateHookApi(L"kernel32.dll",
|
||||
status = MH_CreateHookApiEx(szKernelBaseDll,
|
||||
"LoadLibraryExW",
|
||||
LoadLibraryExW_hook,
|
||||
&(PVOID)g_pfnLoadLibraryExW);
|
||||
&(PVOID)g_pfnLoadLibraryExW,
|
||||
&pv2);
|
||||
if ( status == MH_OK ) {
|
||||
status = MH_EnableHook(pv2);
|
||||
if ( status == MH_OK )
|
||||
log_info(L"Hooked LoadLibraryExW! (Module=%ls, Address=%p)", szKernelBaseDll, pv2);
|
||||
else log_error(L"Failed to enable LoadLibraryExW hook! (Status=%hs)", MH_StatusToString(status));
|
||||
} else log_error(L"Failed to create LoadLibraryExW hook! (Status=%hs)", MH_StatusToString(status));
|
||||
|
||||
if ( GetModuleHandleExW(0, g_pszWUServiceDll, &hModule)
|
||||
|| GetModuleHandleExW(0, PathFindFileNameW(g_pszWUServiceDll), &hModule) ) {
|
||||
@@ -122,14 +144,11 @@ abort_hook:
|
||||
// hook IsDeviceServiceable if wuaueng.dll is already loaded
|
||||
wufuc_hook(hModule);
|
||||
FreeLibrary(hModule);
|
||||
|
||||
}
|
||||
MH_EnableHook(MH_ALL_HOOKS);
|
||||
|
||||
// wait for unload event or the main mutex to be released or abandoned,
|
||||
// for example if the user killed rundll32.exe with task manager.
|
||||
WaitForMultipleObjects(_countof(handles), handles, FALSE, INFINITE);
|
||||
trace(L"Unload condition has been met.");
|
||||
log_info(L"Unload condition has been met.");
|
||||
|
||||
MH_DisableHook(MH_ALL_HOOKS);
|
||||
free(g_pszWUServiceDll);
|
||||
@@ -140,7 +159,7 @@ close_handles:
|
||||
CloseHandle(handles[0]);
|
||||
CloseHandle(handles[1]);
|
||||
unload:
|
||||
trace(L"Unloading wufuc and exiting thread.");
|
||||
log_info(L"Unloading wufuc and exiting thread.");
|
||||
FreeLibraryAndExitThread(PIMAGEBASE, 0);
|
||||
}
|
||||
|
||||
|
@@ -16,6 +16,7 @@ BOOL APIENTRY DllMain(HMODULE hModule,
|
||||
break;
|
||||
case DLL_PROCESS_DETACH:
|
||||
MH_Uninitialize();
|
||||
log_close();
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
|
@@ -19,7 +19,7 @@ LSTATUS WINAPI RegQueryValueExW_hook(HKEY hKey, LPCWSTR lpValueName, LPDWORD lpR
|
||||
ULONG ResultLength;
|
||||
PKEY_NAME_INFORMATION pkni;
|
||||
size_t NameCount;
|
||||
int current;
|
||||
unsigned int current;
|
||||
int pos;
|
||||
wchar_t *fname;
|
||||
const wchar_t realpath[] = L"%systemroot%\\system32\\wuaueng.dll";
|
||||
@@ -31,7 +31,6 @@ LSTATUS WINAPI RegQueryValueExW_hook(HKEY hKey, LPCWSTR lpValueName, LPDWORD lpR
|
||||
MaximumLength = *lpcbData;
|
||||
result = g_pfnRegQueryValueExW(hKey, lpValueName, lpReserved, lpType, lpData, lpcbData);
|
||||
|
||||
|
||||
if ( result != ERROR_SUCCESS
|
||||
|| !MaximumLength
|
||||
|| !lpValueName
|
||||
@@ -51,7 +50,7 @@ LSTATUS WINAPI RegQueryValueExW_hook(HKEY hKey, LPCWSTR lpValueName, LPDWORD lpR
|
||||
for ( size_t i = 0; i < NameCount; i++ )
|
||||
pkni->Name[i] = towlower(pkni->Name[i]);
|
||||
|
||||
if ( _snwscanf_s(pkni->Name, NameCount, L"\\registry\\machine\\system\\controlset%03d\\services\\wuauserv\\parameters%n", ¤t, &pos) == 1
|
||||
if ( _snwscanf_s(pkni->Name, NameCount, L"\\registry\\machine\\system\\controlset%03u\\services\\wuauserv\\parameters%n", ¤t, &pos) == 1
|
||||
&& pos == NameCount ) {
|
||||
|
||||
fname = PathFindFileNameW(pBuffer);
|
||||
@@ -66,7 +65,7 @@ LSTATUS WINAPI RegQueryValueExW_hook(HKEY hKey, LPCWSTR lpValueName, LPDWORD lpR
|
||||
&& SUCCEEDED(StringCbCopyW(pBuffer, MaximumLength, expandedpath)) ) {
|
||||
|
||||
*lpcbData = cchLength * (sizeof *expandedpath);
|
||||
trace(L"Fixed path to Windows Update service library.");
|
||||
log_info(L"Fixed path to Windows Update service library.");
|
||||
}
|
||||
free(expandedpath);
|
||||
}
|
||||
@@ -82,9 +81,10 @@ HMODULE WINAPI LoadLibraryExW_hook(LPCWSTR lpFileName, HANDLE hFile, DWORD dwFla
|
||||
|
||||
result = g_pfnLoadLibraryExW(lpFileName, hFile, dwFlags);
|
||||
if ( !result ) return result;
|
||||
trace(L"Loaded library: %ls (%p)", lpFileName, result);
|
||||
log_debug(L"Loaded library: %ls (%p)", lpFileName, result);
|
||||
|
||||
if ( g_pszWUServiceDll
|
||||
if ( dwFlags == LOAD_WITH_ALTERED_SEARCH_PATH
|
||||
&& g_pszWUServiceDll
|
||||
&& (!_wcsicmp(lpFileName, g_pszWUServiceDll)
|
||||
|| !_wcsicmp(lpFileName, PathFindFileNameW(g_pszWUServiceDll))) ) {
|
||||
|
||||
@@ -95,6 +95,6 @@ HMODULE WINAPI LoadLibraryExW_hook(LPCWSTR lpFileName, HANDLE hFile, DWORD dwFla
|
||||
|
||||
BOOL WINAPI IsDeviceServiceable_hook(void)
|
||||
{
|
||||
trace(L"Entered stub function.");
|
||||
log_debug(L"Entered stub function.");
|
||||
return TRUE;
|
||||
}
|
||||
|
154
src/wufuc/log.c
154
src/wufuc/log.c
@@ -1,39 +1,153 @@
|
||||
#include "stdafx.h"
|
||||
#include "log.h"
|
||||
|
||||
void logp_debug_write(const wchar_t *const format, ...)
|
||||
#include <ShlObj.h>
|
||||
|
||||
HANDLE m_hFile = INVALID_HANDLE_VALUE;
|
||||
|
||||
BOOL CALLBACK init_file_handle(
|
||||
PINIT_ONCE pInitOnce,
|
||||
ParamData *pParam,
|
||||
PVOID *ppContext)
|
||||
{
|
||||
BOOL result = FALSE;
|
||||
HANDLE hFile;
|
||||
HRESULT hr;
|
||||
wchar_t *pszPath;
|
||||
wchar_t szFilePath[MAX_PATH];
|
||||
int ret;
|
||||
|
||||
pParam->dwProcessId = GetCurrentProcessId();
|
||||
if ( !GetModuleFileNameW(NULL, pParam->szExeFilePath, _countof(pParam->szExeFilePath)) ) {
|
||||
log_debug(L"GetModuleFileNameW failed! (GLE=%lu)", GetLastError());
|
||||
return result;
|
||||
}
|
||||
pParam->pszExeName = PathFindFileNameW(pParam->szExeFilePath);
|
||||
|
||||
hr = SHGetKnownFolderPath(&FOLDERID_ProgramData, 0, NULL, &pszPath);
|
||||
if ( hr != S_OK ) {
|
||||
log_debug(L"SHGetKnownFolderPath failed! (HRESULT=0x%08X)", hr);
|
||||
return result;
|
||||
}
|
||||
ret = wcscpy_s(szFilePath, _countof(szFilePath), pszPath);
|
||||
CoTaskMemFree(pszPath);
|
||||
if ( ret ) {
|
||||
log_debug(L"wcscpy_s failed! (Return value=%d)", ret);
|
||||
return result;
|
||||
}
|
||||
|
||||
if ( !PathAppendW(szFilePath, L"wufuc") ) {
|
||||
append_fail:
|
||||
log_debug(L"PathAppendW failed!");
|
||||
return result;
|
||||
}
|
||||
if ( !CreateDirectoryW(szFilePath, NULL)
|
||||
&& GetLastError() != ERROR_ALREADY_EXISTS ) {
|
||||
|
||||
log_debug(L"CreateDirectoryW failed! (GLE=%lu)", GetLastError());
|
||||
return result;
|
||||
}
|
||||
if ( !PathAppendW(szFilePath, L"wufuc.log") )
|
||||
goto append_fail;
|
||||
|
||||
hFile = CreateFileW(szFilePath,
|
||||
FILE_APPEND_DATA,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
||||
NULL,
|
||||
OPEN_ALWAYS,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
NULL);
|
||||
|
||||
if ( hFile != INVALID_HANDLE_VALUE ) {
|
||||
*ppContext = (PVOID)hFile;
|
||||
result = TRUE;
|
||||
} else {
|
||||
log_debug(L"CreateFileW failed! (GLE=%lu)", GetLastError());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void log_debug_(const wchar_t *const format, ...)
|
||||
{
|
||||
DWORD pid;
|
||||
wchar_t exepath[MAX_PATH];
|
||||
wchar_t *exename;
|
||||
va_list ap;
|
||||
wchar_t *buf;
|
||||
int ret;
|
||||
int count;
|
||||
wchar_t *buffer1;
|
||||
wchar_t *buffer2;
|
||||
|
||||
va_start(ap, format);
|
||||
count = _vscwprintf(format, ap);
|
||||
va_end(ap);
|
||||
if ( count == -1 ) return;
|
||||
|
||||
buf = calloc(count + 1, sizeof *buf);
|
||||
if ( !buf ) return;
|
||||
|
||||
va_start(ap, format);
|
||||
ret = vswprintf_s(buf, count + 1, format, ap);
|
||||
va_end(ap);
|
||||
if ( ret != -1 )
|
||||
OutputDebugStringW(buf);
|
||||
free(buf);
|
||||
}
|
||||
|
||||
void log_trace_(const wchar_t *const format, ...)
|
||||
{
|
||||
static INIT_ONCE InitOnce = INIT_ONCE_STATIC_INIT;
|
||||
static ParamData data;
|
||||
BOOL bStatus;
|
||||
errno_t e;
|
||||
wchar_t datebuf[9];
|
||||
wchar_t timebuf[9];
|
||||
va_list ap;
|
||||
const wchar_t fmt[] = L"%ls %ls [%ls:%lu] %ls";
|
||||
int count;
|
||||
wchar_t *buf1;
|
||||
int ret;
|
||||
wchar_t *buf2;
|
||||
DWORD written;
|
||||
|
||||
pid = GetCurrentProcessId();
|
||||
GetModuleFileNameW(NULL, exepath, _countof(exepath));
|
||||
exename = PathFindFileNameW(exepath);
|
||||
bStatus = InitOnceExecuteOnce(&InitOnce,
|
||||
(PINIT_ONCE_FN)init_file_handle,
|
||||
&data,
|
||||
&(LPVOID)m_hFile);
|
||||
|
||||
e = _wstrdate_s(datebuf, _countof(datebuf));
|
||||
if ( e ) return;
|
||||
e = _wstrtime_s(timebuf, _countof(timebuf));
|
||||
if ( e ) return;
|
||||
|
||||
va_start(ap, format);
|
||||
count = _vscwprintf(format, ap) + 1;
|
||||
count = _vscwprintf(format, ap);
|
||||
va_end(ap);
|
||||
buffer1 = calloc(count, sizeof *buffer1);
|
||||
if ( count == -1 ) return;
|
||||
|
||||
buf1 = calloc(count + 1, sizeof *buf1);
|
||||
if ( !buf1 ) return;
|
||||
|
||||
va_start(ap, format);
|
||||
vswprintf_s(buffer1, count, format, ap);
|
||||
ret = vswprintf_s(buf1, count + 1, format, ap);
|
||||
va_end(ap);
|
||||
if ( ret == -1 ) goto free_buf1;
|
||||
|
||||
_wstrdate_s(datebuf, _countof(datebuf));
|
||||
_wstrtime_s(timebuf, _countof(timebuf));
|
||||
count = _scwprintf(fmt, datebuf, timebuf, exename, pid, buffer1) + 1;
|
||||
count = _scwprintf(fmt, datebuf, timebuf, data.pszExeName, data.dwProcessId, buf1);
|
||||
if ( count == -1 ) goto free_buf1;
|
||||
|
||||
buffer2 = calloc(count, sizeof *buffer2);
|
||||
swprintf_s(buffer2, count, fmt, datebuf, timebuf, exename, pid, buffer1);
|
||||
buf2 = calloc(count + 1, sizeof *buf2);
|
||||
if ( !buf2 ) goto free_buf1;
|
||||
|
||||
free(buffer1);
|
||||
OutputDebugStringW(buffer2);
|
||||
free(buffer2);
|
||||
ret = swprintf_s(buf2, count + 1, fmt, datebuf, timebuf, data.pszExeName, data.dwProcessId, buf1);
|
||||
if ( ret == -1 ) goto free_buf2;
|
||||
|
||||
if ( !bStatus || !WriteFile(m_hFile, buf2, count * (sizeof *buf2), &written, NULL) )
|
||||
OutputDebugStringW(buf2);
|
||||
free_buf2:
|
||||
free(buf2);
|
||||
free_buf1:
|
||||
free(buf1);
|
||||
}
|
||||
|
||||
void log_close(void)
|
||||
{
|
||||
if ( m_hFile != INVALID_HANDLE_VALUE )
|
||||
CloseHandle(m_hFile);
|
||||
}
|
||||
|
@@ -1,6 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
void logp_debug_write(const wchar_t *const format, ...);
|
||||
#define log_debug_write(format, ...) \
|
||||
logp_debug_write(__FUNCTIONW__ L"(" _CRT_WIDE(_CRT_STRINGIZE(__LINE__)) L"): " format L"\r\n", ##__VA_ARGS__)
|
||||
#define trace log_debug_write
|
||||
typedef struct
|
||||
{
|
||||
DWORD dwProcessId;
|
||||
wchar_t szExeFilePath[MAX_PATH];
|
||||
wchar_t *pszExeName;
|
||||
} ParamData;
|
||||
|
||||
void log_debug_(const wchar_t *const format, ...);
|
||||
void log_trace_(const wchar_t *const format, ...);
|
||||
void log_close(void);
|
||||
|
||||
#define log_debug(format, ...) log_debug_(__FUNCTIONW__ L"(" _CRT_WIDE(_CRT_STRINGIZE(__LINE__)) L"): [DEBUG] " format L"\r\n", ##__VA_ARGS__)
|
||||
#define log_info(format, ...) log_trace_(__FUNCTIONW__ L"(" _CRT_WIDE(_CRT_STRINGIZE(__LINE__)) L"): [INFO] " format L"\r\n", ##__VA_ARGS__)
|
||||
#define log_warning(format, ...) log_trace_(__FUNCTIONW__ L"(" _CRT_WIDE(_CRT_STRINGIZE(__LINE__)) L"): [WARNING] " format L"\r\n", ##__VA_ARGS__)
|
||||
#define log_error(format, ...) log_trace_(__FUNCTIONW__ L"(" _CRT_WIDE(_CRT_STRINGIZE(__LINE__)) L"): [ERROR] " format L"\r\n", ##__VA_ARGS__)
|
||||
|
@@ -362,14 +362,20 @@ leave:
|
||||
|
||||
void ptrlist_for(ptrlist_t *list, size_t index, size_t count, void(__cdecl *f)(void *))
|
||||
{
|
||||
if ( !list || !f ) return;
|
||||
|
||||
ptrlist_lock(list);
|
||||
for ( size_t i = index; i < count; i++ )
|
||||
f(list->values[i]);
|
||||
if ( index + count <= list->count ) {
|
||||
for ( size_t i = index; i < count; i++ )
|
||||
f(list->values[i]);
|
||||
}
|
||||
ptrlist_unlock(list);
|
||||
}
|
||||
|
||||
void ptrlist_for_each(ptrlist_t *list, void(__cdecl *f)(void *))
|
||||
{
|
||||
if ( !list || !f ) return;
|
||||
|
||||
ptrlist_lock(list);
|
||||
ptrlist_for(list, 0, list->count, f);
|
||||
ptrlist_unlock(list);
|
||||
@@ -377,14 +383,20 @@ void ptrlist_for_each(ptrlist_t *list, void(__cdecl *f)(void *))
|
||||
|
||||
void ptrlist_for_stdcall(ptrlist_t *list, size_t index, size_t count, void(__stdcall *f)(void *))
|
||||
{
|
||||
if ( !list || !f ) return;
|
||||
|
||||
ptrlist_lock(list);
|
||||
for ( size_t i = index; i < count; i++ )
|
||||
f(list->values[i]);
|
||||
if ( index + count <= list->count ) {
|
||||
for ( size_t i = index; i < count; i++ )
|
||||
f(list->values[i]);
|
||||
}
|
||||
ptrlist_unlock(list);
|
||||
}
|
||||
|
||||
void ptrlist_for_each_stdcall(ptrlist_t *list, void(__stdcall *f)(void *))
|
||||
{
|
||||
if ( !list || !f ) return;
|
||||
|
||||
ptrlist_lock(list);
|
||||
ptrlist_for_stdcall(list, 0, list->count, f);
|
||||
ptrlist_unlock(list);
|
||||
|
18
src/wufuc/resource.h
Normal file
18
src/wufuc/resource.h
Normal file
@@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef BUILD_COMMIT_VERSION
|
||||
#define BUILD_COMMIT_VERSION 1.0.0.0
|
||||
#endif
|
||||
|
||||
#ifndef BUILD_VERSION_COMMA
|
||||
#define BUILD_VERSION_COMMA 1,0,0,0
|
||||
#endif
|
||||
|
||||
#define S_(x) #x
|
||||
#define S(x) S_(x)
|
||||
|
||||
#ifdef X64
|
||||
#define FILENAME "wufuc64.dll"
|
||||
#elif defined(X86)
|
||||
#define FILENAME "wufuc32.dll"
|
||||
#endif
|
Binary file not shown.
@@ -101,16 +101,16 @@ void CALLBACK RUNDLL32_StartW(HWND hwnd,
|
||||
CloseHandle(values[index]);
|
||||
|
||||
crashes++;
|
||||
trace(L"A process wufuc injected into has crashed %Iu time%ls! (PID=%lu)",
|
||||
log_warning(L"A process wufuc injected into has crashed %Iu time%ls! (ProcessId=%lu)",
|
||||
crashes, crashes != 1 ? L"s" : L"", tags[index]);
|
||||
|
||||
if ( crashes >= SVCHOST_CRASH_THRESHOLD ) {
|
||||
trace(L"Crash threshold has been reached, disabling wufuc until next reboot!");
|
||||
log_error(L"Crash threshold has been reached, disabling wufuc until next reboot!");
|
||||
Unloading = true;
|
||||
Suspending = true;
|
||||
}
|
||||
} else if ( r == WAIT_FAILED ) {
|
||||
trace(L"Wait function failed!");
|
||||
log_error(L"Wait function failed!");
|
||||
Unloading = true;
|
||||
}
|
||||
free(values);
|
||||
@@ -118,11 +118,11 @@ void CALLBACK RUNDLL32_StartW(HWND hwnd,
|
||||
} while ( r != WAIT_IO_COMPLETION && !Unloading );
|
||||
break;
|
||||
case ERROR_SERVICE_NOTIFY_CLIENT_LAGGING:
|
||||
trace(L"Client lagging!");
|
||||
log_warning(L"Client lagging!");
|
||||
Lagging = true;
|
||||
break;
|
||||
default:
|
||||
trace(L"NotifyServiceStatusChange failed, return value: %lu (%08X)", e);
|
||||
log_error(L"NotifyServiceStatusChange failed! (Return value=%lu)", e);
|
||||
Unloading = true;
|
||||
break;
|
||||
}
|
||||
|
@@ -91,9 +91,9 @@ LPVOID ver_get_version_info_from_hmodule_alloc(HMODULE hModule, const wchar_t *p
|
||||
|
||||
bool ver_verify_version_info(WORD wMajorVersion, WORD wMinorVersion, WORD wServicePackMajor)
|
||||
{
|
||||
DWORDLONG dwlConditionMask = 0;
|
||||
OSVERSIONINFOEXW osvi = { sizeof osvi };
|
||||
|
||||
DWORDLONG dwlConditionMask = 0;
|
||||
VER_SET_CONDITION(dwlConditionMask, VER_MAJORVERSION, VER_EQUAL);
|
||||
VER_SET_CONDITION(dwlConditionMask, VER_MINORVERSION, VER_EQUAL);
|
||||
VER_SET_CONDITION(dwlConditionMask, VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL);
|
||||
@@ -106,13 +106,3 @@ bool ver_verify_version_info(WORD wMajorVersion, WORD wMinorVersion, WORD wServi
|
||||
VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR,
|
||||
dwlConditionMask) != FALSE;
|
||||
}
|
||||
|
||||
bool ver_verify_windows_7_sp1(void)
|
||||
{
|
||||
return ver_verify_version_info(6, 1, 1);
|
||||
}
|
||||
|
||||
bool ver_verify_windows_8_1(void)
|
||||
{
|
||||
return ver_verify_version_info(6, 3, 0);
|
||||
}
|
||||
|
@@ -4,5 +4,3 @@ int ver_compare_product_version(VS_FIXEDFILEINFO *pffi, WORD wMajor, WORD wMinor
|
||||
bool ver_get_version_info_from_hmodule(HMODULE hModule, const wchar_t *pszSubBlock, LPVOID pData, PUINT pcbData);
|
||||
LPVOID ver_get_version_info_from_hmodule_alloc(HMODULE hModule, const wchar_t *pszSubBlock, PUINT pcbData);
|
||||
bool ver_verify_version_info(WORD wMajorVersion, WORD wMinorVersion, WORD wServicePackMajor);
|
||||
bool ver_verify_windows_7_sp1(void);
|
||||
bool ver_verify_windows_8_1(void);
|
@@ -93,7 +93,9 @@ close_mutex:
|
||||
CloseHandle(hCrashMutex);
|
||||
}
|
||||
if ( result )
|
||||
trace(L"Successfully injected into process: %lu", dwProcessId);
|
||||
log_info(L"Successfully injected into process! (ProcessId=%lu)", dwProcessId);
|
||||
else
|
||||
log_warning(L"Failed to inject into process! (ProcessId=%lu)", dwProcessId);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -108,17 +110,15 @@ bool wufuc_hook(HMODULE hModule)
|
||||
UINT cbInternalName;
|
||||
VS_FIXEDFILEINFO *pffi;
|
||||
UINT cbffi;
|
||||
int tmp;
|
||||
bool tmp;
|
||||
MODULEINFO modinfo;
|
||||
size_t offset;
|
||||
LPVOID pTarget;
|
||||
|
||||
if ( !ver_verify_windows_7_sp1() && !ver_verify_windows_8_1() )
|
||||
return false;
|
||||
LPVOID pTarget = NULL;
|
||||
MH_STATUS status;
|
||||
|
||||
ptl = ver_get_version_info_from_hmodule_alloc(hModule, L"\\VarFileInfo\\Translation", &cbtl);
|
||||
if ( !ptl ) {
|
||||
trace(L"Failed to get translation info from hModule.");
|
||||
log_error(L"ver_get_version_info_from_hmodule_alloc failed!");
|
||||
return false;
|
||||
}
|
||||
hProcess = GetCurrentProcess();
|
||||
@@ -133,58 +133,58 @@ bool wufuc_hook(HMODULE hModule)
|
||||
|
||||
pInternalName = ver_get_version_info_from_hmodule_alloc(hModule, SubBlock, &cbInternalName);
|
||||
if ( !pInternalName ) {
|
||||
trace(L"Failed to get internal name from hModule.");
|
||||
log_error(L"ver_get_version_info_from_hmodule_alloc failed!");
|
||||
continue;
|
||||
}
|
||||
|
||||
// identify wuaueng.dll by its resource data
|
||||
if ( _wcsicmp(pInternalName, L"wuaueng.dll") ) {
|
||||
trace(L"Module internal name does not match. (%ls)", pInternalName);
|
||||
log_error(L"Module internal name does not match! (InternalName=%ls)", pInternalName);
|
||||
goto free_iname;
|
||||
}
|
||||
pffi = ver_get_version_info_from_hmodule_alloc(hModule, L"\\", &cbffi);
|
||||
if ( !pffi ) {
|
||||
trace(L"Failed to get version info from hModule.");
|
||||
log_error(L"ver_get_version_info_from_hmodule_alloc failed!");
|
||||
break;
|
||||
}
|
||||
trace(L"Windows Update Agent version: %hu.%hu.%hu.%hu",
|
||||
// assure wuaueng.dll version is supported
|
||||
tmp = ((ver_verify_version_info(6, 1, 0) && ver_compare_product_version(pffi, 7, 6, 7601, 23714) != -1)
|
||||
|| (ver_verify_version_info(6, 3, 0) && ver_compare_product_version(pffi, 7, 9, 9600, 18621) != -1));
|
||||
|
||||
log_info(L"%ls Windows Update Agent version: %hu.%hu.%hu.%hu",
|
||||
tmp ? L"Supported" : L"Unsupported",
|
||||
HIWORD(pffi->dwProductVersionMS),
|
||||
LOWORD(pffi->dwProductVersionMS),
|
||||
HIWORD(pffi->dwProductVersionLS),
|
||||
LOWORD(pffi->dwProductVersionLS));
|
||||
|
||||
// assure wuaueng.dll is at least the minimum supported version
|
||||
tmp = ((ver_verify_windows_7_sp1() && ver_compare_product_version(pffi, 7, 6, 7601, 23714) != -1)
|
||||
|| (ver_verify_windows_8_1() && ver_compare_product_version(pffi, 7, 9, 9600, 18621) != -1));
|
||||
free(pffi);
|
||||
if ( !tmp ) {
|
||||
trace(L"Windows Update Agent does not meet the minimum supported version.");
|
||||
break;
|
||||
}
|
||||
if ( !tmp ) break;
|
||||
|
||||
if ( !GetModuleInformation(hProcess, hModule, &modinfo, sizeof modinfo) ) {
|
||||
trace(L"Failed to get module info: %p, %p (GLE=%08x)", hProcess, hModule, GetLastError());
|
||||
log_error(L"GetModuleInformation failed! (hModule=%p, GLE=%lu)",
|
||||
hModule, GetLastError());
|
||||
break;
|
||||
}
|
||||
offset = patternfind(modinfo.lpBaseOfDll, modinfo.SizeOfImage,
|
||||
#ifdef _WIN64
|
||||
"FFF3 4883EC?? 33DB 391D???????? 7508 8B05????????"
|
||||
#else
|
||||
ver_verify_windows_7_sp1()
|
||||
ver_verify_version_info(6, 1, 0)
|
||||
? "833D????????00 743E E8???????? A3????????"
|
||||
: "8BFF 51 833D????????00 7507 A1????????"
|
||||
#endif
|
||||
);
|
||||
if ( offset != -1 ) {
|
||||
pTarget = (LPVOID)RtlOffsetToPointer(modinfo.lpBaseOfDll, offset);
|
||||
trace(L"Found IsDeviceServiceable function: %p", pTarget);
|
||||
log_info(L"Matched IsDeviceServiceable function! (Offset=%IX, Address=%p)", offset, pTarget);
|
||||
|
||||
result = (MH_CreateHook(pTarget, IsDeviceServiceable_hook, NULL) == MH_OK)
|
||||
&& (MH_EnableHook(pTarget) == MH_OK);
|
||||
if ( result )
|
||||
trace(L"Successfully hooked IsDeviceServiceable!");
|
||||
} else {
|
||||
trace(L"Could not find function offset!");
|
||||
}
|
||||
status = MH_CreateHook(pTarget, IsDeviceServiceable_hook, NULL);
|
||||
if ( status == MH_OK ) {
|
||||
status = MH_EnableHook(pTarget);
|
||||
if ( status == MH_OK )
|
||||
log_info(L"Hooked IsDeviceServiceable! (Address=%p)", pTarget);
|
||||
else log_error(L"Failed to enable IsDeviceServiceable hook! (Status=%hs)", MH_StatusToString(status));
|
||||
} else log_error(L"Failed to create IsDeviceServiceable hook! (Status=%hs)", MH_StatusToString(status));
|
||||
} else log_info(L"Couldn't match IsDeviceServiceable function! (Already patched?)");
|
||||
free_iname:
|
||||
free(pInternalName);
|
||||
break;
|
||||
|
@@ -7,10 +7,9 @@ typedef struct
|
||||
} LANGANDCODEPAGE, *PLANGANDCODEPAGE;
|
||||
|
||||
#define SVCHOST_CRASH_THRESHOLD 3
|
||||
|
||||
extern HANDLE g_hMainMutex;
|
||||
|
||||
bool wufuc_inject(DWORD dwProcessId,
|
||||
LPTHREAD_START_ROUTINE pStartAddress,
|
||||
ptrlist_t *list);
|
||||
bool wufuc_hook(HMODULE hModule);
|
||||
bool wufuc_hook(HMODULE hModule);
|
||||
|
@@ -1,17 +0,0 @@
|
||||
#ifndef WUFUC_RCH_INCLUDED
|
||||
#define WUFUC_RCH_INCLUDED
|
||||
#pragma once
|
||||
#ifndef BUILD_COMMIT_VERSION
|
||||
#define BUILD_COMMIT_VERSION 1.0.0.0
|
||||
#endif
|
||||
#ifndef BUILD_VERSION_COMMA
|
||||
#define BUILD_VERSION_COMMA 1.0.0.0
|
||||
#endif
|
||||
#define STRINGIZE_(x) #x
|
||||
#define STRINGIZE(x) STRINGIZE_(x)
|
||||
#ifdef X64
|
||||
#define WUFUC_DLL "wufuc64.dll"
|
||||
#elif defined(X86)
|
||||
#define WUFUC_DLL "wufuc32.dll"
|
||||
#endif
|
||||
#endif
|
@@ -58,12 +58,12 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="exports.def" />
|
||||
<None Include="wufuc.rch">
|
||||
<None Include="resource.h">
|
||||
<FileType>Document</FileType>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="wufuc.rc" />
|
||||
<ResourceCompile Include="resource.rc" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>15.0</VCProjectVersion>
|
||||
|
@@ -106,16 +106,16 @@
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="wufuc.rc">
|
||||
<Filter>Resource Files</Filter>
|
||||
</ResourceCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="wufuc.rch">
|
||||
<Filter>Resource Files</Filter>
|
||||
</None>
|
||||
<None Include="exports.def">
|
||||
<Filter>Source Files</Filter>
|
||||
</None>
|
||||
<None Include="resource.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="resource.rc">
|
||||
<Filter>Resource Files</Filter>
|
||||
</ResourceCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
@@ -5,12 +5,16 @@
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiPropsComponent">
|
||||
<ROW Property="AI_BITMAP_DISPLAY_MODE" Value="0"/>
|
||||
<ROW Property="AI_CLEAN_RESOURCES_DISABLE_UPGRADE" Value="1"/>
|
||||
<ROW Property="AI_CLEAN_RESOURCES_UNINSTALL" Value="1"/>
|
||||
<ROW Property="AI_CLEAN_RESOURCES_USER_PROMPT_BASIC_UI" Value="1"/>
|
||||
<ROW Property="AI_CLEAN_RESOURCES_USER_PROMPT_FULL_UI" Value="1"/>
|
||||
<ROW Property="AI_ThemeStyle" Value="aero" MsiKey="AI_ThemeStyle"/>
|
||||
<ROW Property="ALLUSERS" Value="1"/>
|
||||
<ROW Property="ARPCOMMENTS" Value="Enables Windows Update on PCs with unsupported processors." ValueLocId="*"/>
|
||||
<ROW Property="ARPCONTACT" Value="https://t.me/joinchat/HEo6LUvV_83O92WzbYXLeQ"/>
|
||||
<ROW Property="ARPCONTACT" Value="https://discord.gg/G8PD2Wa"/>
|
||||
<ROW Property="ARPHELPLINK" Value="https://github.com/zeffy/wufuc/issues"/>
|
||||
<ROW Property="ARPNOMODIFY" MultiBuildValue="x64Build:1"/>
|
||||
<ROW Property="ARPNOMODIFY" MultiBuildValue="x64Build:1#x86Build:1"/>
|
||||
<ROW Property="ARPPRODUCTICON" Value="msiexec.exe" Type="8"/>
|
||||
<ROW Property="ARPURLINFOABOUT" Value="https://github.com/zeffy/wufuc"/>
|
||||
<ROW Property="ARPURLUPDATEINFO" Value="https://github.com/zeffy/wufuc/releases/latest"/>
|
||||
@@ -39,31 +43,46 @@
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiDirsComponent">
|
||||
<ROW Directory="APPDIR" Directory_Parent="TARGETDIR" DefaultDir="APPDIR:." IsPseudoRoot="1"/>
|
||||
<ROW Directory="CommonAppDataFolder" Directory_Parent="TARGETDIR" DefaultDir="COMMON~1|CommonAppDataFolder" IsPseudoRoot="1"/>
|
||||
<ROW Directory="SHORTCUTDIR" Directory_Parent="TARGETDIR" DefaultDir="SHORTC~1|SHORTCUTDIR" IsPseudoRoot="1"/>
|
||||
<ROW Directory="TARGETDIR" DefaultDir="SourceDir"/>
|
||||
<ROW Directory="Troubleshooting_1_Dir" Directory_Parent="APPDIR" DefaultDir="TROUBL~1|Troubleshooting"/>
|
||||
<ROW Directory="Troubleshooting_Dir" Directory_Parent="SHORTCUTDIR" DefaultDir="TROUBL~1|Troubleshooting"/>
|
||||
<ROW Directory="X64FeatureItems_Dir" Directory_Parent="APPDIR" DefaultDir=".:X64FEA~1|X64FeatureItems"/>
|
||||
<ROW Directory="X86FeatureItems_Dir" Directory_Parent="APPDIR" DefaultDir=".:X86FEA~1|X86FeatureItems"/>
|
||||
<ROW Directory="wufuc_Dir" Directory_Parent="CommonAppDataFolder" DefaultDir="wufuc"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiCompsComponent">
|
||||
<ROW Component="COPYING" ComponentId="{6CA1ECA7-4C30-4BD0-A5E8-6B3E5BCBE31D}" Directory_="APPDIR" Attributes="0" KeyPath="COPYING" Type="0"/>
|
||||
<ROW Component="ProductInformation" ComponentId="{75030EAB-5C17-4F84-B529-28003271CA3F}" Directory_="APPDIR" Attributes="4" KeyPath="Version"/>
|
||||
<ROW Component="Restore_wuauserv.reg" ComponentId="{5CE5C35B-6B0E-4EE4-B92C-7B1D9882DFC0}" Directory_="Troubleshooting_1_Dir" Attributes="0" KeyPath="Restore_wuauserv.reg" Type="0"/>
|
||||
<ROW Component="SHORTCUTDIR" ComponentId="{910396A4-AFDD-4E57-BF00-2FDD4108AC61}" Directory_="SHORTCUTDIR" Attributes="0"/>
|
||||
<ROW Component="Troubleshooting" ComponentId="{D4F7163C-0FD7-4862-BF97-F1693236500C}" Directory_="Troubleshooting_Dir" Attributes="0"/>
|
||||
<ROW Component="X64FeatureItems" ComponentId="{0E189A37-1F40-4756-ACB9-6511067D5B47}" Directory_="X64FeatureItems_Dir" Attributes="0"/>
|
||||
<ROW Component="X86FeatureItems" ComponentId="{CBB84726-9EC3-4570-9012-37BA98719022}" Directory_="X86FeatureItems_Dir" Attributes="0"/>
|
||||
<ROW Component="wufuc" ComponentId="{331CB0F5-F6E7-4712-9F97-3609A0D5AFE6}" Directory_="wufuc_Dir" Attributes="0"/>
|
||||
<ROW Component="wufuc32.dll" ComponentId="{7FBEF396-DCBC-4838-A4EB-336F74A836C7}" Directory_="APPDIR" Attributes="0" KeyPath="wufuc32.dll"/>
|
||||
<ROW Component="wufuc64.dll" ComponentId="{0407D471-998A-4FD3-BC2D-72EE56FBEEF4}" Directory_="APPDIR" Attributes="256" KeyPath="wufuc64.dll"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiFeatsComponent">
|
||||
<ROW Feature="MainFeature" Title="MainFeature" Description="Description" Display="1" Level="1" Directory_="APPDIR" Attributes="0" Components="ProductInformation SHORTCUTDIR"/>
|
||||
<ROW Feature="MainFeature" Title="MainFeature" Description="Description" Display="1" Level="1" Directory_="APPDIR" Attributes="0" Components="COPYING ProductInformation Restore_wuauserv.reg SHORTCUTDIR Troubleshooting wufuc"/>
|
||||
<ROW Feature="X64Feature" Feature_Parent="MainFeature" Title="X64Feature" Display="0" Level="1" Directory_="APPDIR" Attributes="0" Components="X64FeatureItems wufuc64.dll" Builds="x64Build"/>
|
||||
<ROW Feature="X86Feature" Feature_Parent="MainFeature" Title="X86Feature" Display="0" Level="1" Directory_="APPDIR" Attributes="0" Components="X86FeatureItems wufuc32.dll" Builds="x86Build"/>
|
||||
<ATTRIBUTE name="CurrentFeature" value="MainFeature"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiFilesComponent">
|
||||
<ROW File="COPYING" Component_="COPYING" FileName="COPYING.txt" Attributes="0" SourcePath="..\..\COPYING" SelfReg="false" NextFile="Restore_wuauserv.reg"/>
|
||||
<ROW File="Restore_wuauserv.reg" Component_="Restore_wuauserv.reg" FileName="RESTOR~1.REG|Restore_wuauserv.reg" Attributes="0" SourcePath="..\wufuc_setup_bat\Restore_wuauserv.reg" SelfReg="false"/>
|
||||
<ROW File="wufuc32.dll" Component_="wufuc32.dll" FileName="wufuc32.dll" Attributes="0" SourcePath="wufuc32.dll" SelfReg="false" NextFile="wufuc64.dll"/>
|
||||
<ROW File="wufuc64.dll" Component_="wufuc64.dll" FileName="wufuc64.dll" Attributes="0" SourcePath="wufuc64.dll" SelfReg="false"/>
|
||||
<ROW File="wufuc64.dll" Component_="wufuc64.dll" FileName="wufuc64.dll" Attributes="0" SourcePath="wufuc64.dll" SelfReg="false" NextFile="COPYING"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.custcomp.MsiShortcutPropertyComponent">
|
||||
<ROW MsiShortcutProperty="Uninstallwufuc1" Shortcut_="Uninstallwufuc" PropertyKey="[AiPreventAutoPin]" PropVariantValue="1"/>
|
||||
<ROW MsiShortcutProperty="License1" Shortcut_="License" PropertyKey="[AiPreventAutoPin]" PropVariantValue="1"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.AiRemoveFileComponent">
|
||||
<ROW RemoveFile="log" Condition="(AI_CLEAN_RESOURCES_UNINSTALL = "1") AND (NOT UPGRADINGPRODUCTCODE)" Options="1"/>
|
||||
<ROW RemoveFile="_" Condition="(AI_CLEAN_RESOURCES_UNINSTALL = "1") AND (NOT UPGRADINGPRODUCTCODE)" Options="0"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.BootstrOptComponent">
|
||||
<ROW BootstrOptKey="GlobalOptions" DownloadFolder="[AppDataFolder][|Manufacturer]\[|ProductName]\prerequisites" Options="2"/>
|
||||
@@ -109,6 +128,11 @@
|
||||
<ROW Fragment="WelcomeDlg.aip" Path="<AI_THEMES>classic\fragments\WelcomeDlg.aip"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiActionTextComponent">
|
||||
<ROW Action="AI_AiRemoveFilesCommit" Description="Executing file removal operations" DescriptionLocId="ActionText.Description.AI_AiRemoveFilesCommit" Template="Executing file removal: [1]" TemplateLocId="ActionText.Template.AI_AiRemoveFilesCommit"/>
|
||||
<ROW Action="AI_AiRemoveFilesDeferred_Permanent" Description="Preparing files for removal" DescriptionLocId="ActionText.Description.AI_AiRemoveFilesDeferred_Permanent" Template="Preparing file: [1]" TemplateLocId="ActionText.Template.AI_AiRemoveFilesDeferred_Permanent"/>
|
||||
<ROW Action="AI_AiRemoveFilesDeferred_Undoable" Description="Preparing files for removal" DescriptionLocId="ActionText.Description.AI_AiRemoveFilesDeferred_Undoable" Template="Preparing file: [1]" TemplateLocId="ActionText.Template.AI_AiRemoveFilesDeferred_Undoable"/>
|
||||
<ROW Action="AI_AiRemoveFilesImmediate" Description="Preparing files for removal" DescriptionLocId="ActionText.Description.AI_AiRemoveFilesImmediate" Template="Preparing file: [1]" TemplateLocId="ActionText.Template.AI_AiRemoveFilesImmediate"/>
|
||||
<ROW Action="AI_AiRemoveFilesRollback" Description="Restoring removed files" DescriptionLocId="ActionText.Description.AI_AiRemoveFilesRollback" Template="Restoring file: [1]" TemplateLocId="ActionText.Template.AI_AiRemoveFilesRollback"/>
|
||||
<ROW Action="AI_XmlCommit" Description="Committing XML file configurations." DescriptionLocId="ActionText.Description.AI_XmlCommit" Template="Committing XML file configurations." TemplateLocId="ActionText.Template.AI_XmlCommit"/>
|
||||
<ROW Action="AI_XmlConfig" Description="Executing XML file configurations" DescriptionLocId="ActionText.Description.AI_XmlConfig" Template="Configuring XML file: "[1]"" TemplateLocId="ActionText.Template.AI_XmlConfig"/>
|
||||
<ROW Action="AI_XmlInstall" Description="Generating actions to configure XML files" DescriptionLocId="ActionText.Description.AI_XmlInstall"/>
|
||||
@@ -119,13 +143,18 @@
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiBinaryComponent">
|
||||
<ROW Name="AdvancedInstallerHelper.dll" SourcePath="AdvancedInstallerHelper.dll"/>
|
||||
<ROW Name="Prereq.dll" SourcePath="<AI_CUSTACTS>Prereq.dll"/>
|
||||
<ROW Name="ResourceCleaner.dll" SourcePath="<AI_CUSTACTS>ResourceCleaner.dll"/>
|
||||
<ROW Name="ShortcutFlags.dll" SourcePath="<AI_CUSTACTS>ShortcutFlags.dll"/>
|
||||
<ROW Name="aicustact.dll" SourcePath="<AI_CUSTACTS>aicustact.dll"/>
|
||||
<ROW Name="viewer.exe" SourcePath="<AI_CUSTACTS>viewer.exe"/>
|
||||
<ROW Name="xmlCfg.dll" SourcePath="<AI_CUSTACTS>xmlCfg.dll"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiCheckBoxComponent">
|
||||
<ROW Property="AI_CLEAN_RESOURCES_UNINSTALL" Value="1"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiControlComponent">
|
||||
<ROW Dialog_="LicenseAgreementDlg" Control="AgreementText" Type="ScrollableText" X="20" Y="60" Width="330" Height="120" Attributes="7" Text="LICENSE.rtf" Order="400" TextLocId="-" MsiKey="LicenseAgreementDlg#AgreementText"/>
|
||||
<ROW Dialog_="VerifyRemoveDlg" Control="UnistallCleanupCheckBox" Type="CheckBox" X="25" Y="150" Width="320" Height="11" Attributes="3" Property="AI_CLEAN_RESOURCES_UNINSTALL" Text="Remove [ProductName] settings and temporary files." Order="1100"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiControlEventComponent">
|
||||
<ROW Dialog_="WelcomeDlg" Control_="Next" Event="NewDialog" Argument="LicenseAgreementDlg" Condition="AI_INSTALL" Ordering="1"/>
|
||||
@@ -157,8 +186,15 @@
|
||||
<ROW Directory_="SHORTCUTDIR" Component_="SHORTCUTDIR" ManualDelete="false"/>
|
||||
<ROW Directory_="X86FeatureItems_Dir" Component_="X86FeatureItems" ManualDelete="false"/>
|
||||
<ROW Directory_="X64FeatureItems_Dir" Component_="X64FeatureItems" ManualDelete="false"/>
|
||||
<ROW Directory_="Troubleshooting_Dir" Component_="Troubleshooting" ManualDelete="false"/>
|
||||
<ROW Directory_="wufuc_Dir" Component_="wufuc" ManualDelete="true"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiCustActComponent">
|
||||
<ROW Action="AI_AiRemoveFilesCommit" Type="11777" Source="ResourceCleaner.dll" Target="OnAiRemoveFilesCommit" WithoutSeq="true"/>
|
||||
<ROW Action="AI_AiRemoveFilesDeferred_Permanent" Type="11265" Source="ResourceCleaner.dll" Target="OnAiRemoveFilesPermanent" WithoutSeq="true"/>
|
||||
<ROW Action="AI_AiRemoveFilesDeferred_Undoable" Type="11265" Source="ResourceCleaner.dll" Target="OnAiRemoveFilesUndoable" WithoutSeq="true"/>
|
||||
<ROW Action="AI_AiRemoveFilesImmediate" Type="1" Source="ResourceCleaner.dll" Target="OnAiRemoveFilesImmediate"/>
|
||||
<ROW Action="AI_AiRemoveFilesRollback" Type="11521" Source="ResourceCleaner.dll" Target="OnAiUndoRemoveFiles"/>
|
||||
<ROW Action="AI_AppSearchEx" Type="1" Source="Prereq.dll" Target="DoAppSearchEx"/>
|
||||
<ROW Action="AI_ApplyShortcutFlags" Type="3073" Source="ShortcutFlags.dll" Target="UpdateShortcutFlags" WithoutSeq="true"/>
|
||||
<ROW Action="AI_BACKUP_AI_SETUPEXEPATH" Type="51" Source="AI_SETUPEXEPATH_ORIGINAL" Target="[AI_SETUPEXEPATH]"/>
|
||||
@@ -175,6 +211,7 @@
|
||||
<ROW Action="AI_PinToStartScreen" Type="1025" Source="ShortcutFlags.dll" Target="PinToStartScreen" WithoutSeq="true"/>
|
||||
<ROW Action="AI_PinToTaskbar" Type="1025" Source="ShortcutFlags.dll" Target="PinToTaskbar" WithoutSeq="true"/>
|
||||
<ROW Action="AI_PrepareShortcutFlags" Type="1" Source="ShortcutFlags.dll" Target="PrepareActionData"/>
|
||||
<ROW Action="AI_PromptUserBasicUI" Type="1" Source="ResourceCleaner.dll" Target="OnPromptUserBasicUI"/>
|
||||
<ROW Action="AI_RESTORE_AI_SETUPEXEPATH" Type="51" Source="AI_SETUPEXEPATH" Target="[AI_SETUPEXEPATH_ORIGINAL]"/>
|
||||
<ROW Action="AI_RESTORE_LOCATION" Type="65" Source="aicustact.dll" Target="RestoreLocation"/>
|
||||
<ROW Action="AI_ResolveKnownFolders" Type="1" Source="aicustact.dll" Target="AI_ResolveKnownFolders"/>
|
||||
@@ -203,17 +240,19 @@
|
||||
<ROW Action="StopWindowsUpdateService" Type="3073" Source="aicustact.dll" Target="StopWinService" Options="1" AdditionalSeq="AI_DATA_SETTER_2"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiIconsComponent">
|
||||
<ROW Name="msiexec.exe" SourcePath="C:\Windows\System32\msiexec.exe" Index="0"/>
|
||||
<ROW Name="msiexec.exe" SourcePath="..\..\..\..\..\..\..\Windows\System32\msiexec.exe" Index="0"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiIniFileComponent">
|
||||
<ROW IniFile="URL" FileName="Donate.url" DirProperty="SHORTCUTDIR" Section="InternetShortcut" Key="URL" Value="https://github.com/zeffy/wufuc/blob/master/DONATE.md" Action="0" Component_="SHORTCUTDIR"/>
|
||||
<ROW IniFile="URL_1" FileName="Homepage.url" DirProperty="SHORTCUTDIR" Section="InternetShortcut" Key="URL" Value="https://github.com/zeffy/wufuc" Action="0" Component_="SHORTCUTDIR"/>
|
||||
<ROW IniFile="URL_2" FileName="Readme.url" DirProperty="SHORTCUTDIR" Section="InternetShortcut" Key="URL" Value="https://github.com/zeffy/wufuc/blob/master/README.md" Action="0" Component_="SHORTCUTDIR"/>
|
||||
<ROW IniFile="URL_3" FileName="TRANSL~1.URL|Translations.url" DirProperty="SHORTCUTDIR" Section="InternetShortcut" Key="URL" Value="https://github.com/zeffy/wufuc/wiki" Action="0" Component_="X64FeatureItems"/>
|
||||
<ROW IniFile="URL_6" FileName="LATEST~1.URL|Latest Release.url" DirProperty="SHORTCUTDIR" Section="InternetShortcut" Key="URL" Value="https://github.com/zeffy/wufuc/releases/latest" Action="0" Component_="SHORTCUTDIR"/>
|
||||
<ROW IniFile="URL_7" FileName="REPORT~1.URL|Report an Issue.url" DirProperty="Troubleshooting_Dir" Section="InternetShortcut" Key="URL" Value="https://github.com/zeffy/wufuc/issues" Action="0" Component_="SHORTCUTDIR"/>
|
||||
<ROW IniFile="URL_8" FileName="FAQ.url" DirProperty="Troubleshooting_Dir" Section="InternetShortcut" Key="URL" Value="https://github.com/zeffy/wufuc/blob/master/FAQ.md" Action="0" Component_="SHORTCUTDIR"/>
|
||||
<ROW IniFile="WorkingDirectory" FileName="Donate.url" DirProperty="SHORTCUTDIR" Section="InternetShortcut" Key="WorkingDirectory" Value="[SHORTCUTDIR]" Action="0" Component_="SHORTCUTDIR"/>
|
||||
<ROW IniFile="WorkingDirectory_1" FileName="Homepage.url" DirProperty="SHORTCUTDIR" Section="InternetShortcut" Key="WorkingDirectory" Value="[SHORTCUTDIR]" Action="0" Component_="SHORTCUTDIR"/>
|
||||
<ROW IniFile="WorkingDirectory_2" FileName="Readme.url" DirProperty="SHORTCUTDIR" Section="InternetShortcut" Key="WorkingDirectory" Value="[SHORTCUTDIR]" Action="0" Component_="SHORTCUTDIR"/>
|
||||
<ROW IniFile="WorkingDirectory_3" FileName="TRANSL~1.URL|Translations.url" DirProperty="SHORTCUTDIR" Section="InternetShortcut" Key="WorkingDirectory" Value="[SHORTCUTDIR]" Action="0" Component_="X64FeatureItems"/>
|
||||
<ROW IniFile="WorkingDirectory_6" FileName="LATEST~1.URL|Latest Release.url" DirProperty="SHORTCUTDIR" Section="InternetShortcut" Key="WorkingDirectory" Value="[SHORTCUTDIR]" Action="0" Component_="SHORTCUTDIR"/>
|
||||
<ROW IniFile="WorkingDirectory_7" FileName="REPORT~1.URL|Report an Issue.url" DirProperty="Troubleshooting_Dir" Section="InternetShortcut" Key="WorkingDirectory" Value="[Troubleshooting_Dir]" Action="0" Component_="SHORTCUTDIR"/>
|
||||
<ROW IniFile="WorkingDirectory_8" FileName="FAQ.url" DirProperty="Troubleshooting_Dir" Section="InternetShortcut" Key="WorkingDirectory" Value="[Troubleshooting_Dir]" Action="0" Component_="SHORTCUTDIR"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiInstExSeqComponent">
|
||||
<ROW Action="AI_DOWNGRADE" Condition="AI_NEWERPRODUCTFOUND AND (UILevel <> 5)" Sequence="210"/>
|
||||
@@ -241,6 +280,9 @@
|
||||
<ROW Action="SetRebootProperty" Condition="NONDEFAULT_SERVICEDLL" Sequence="201"/>
|
||||
<ROW Action="StartWindowsUpdateService" Condition="( ( NOT Installed ) OR ( Installed AND REMOVE <> "ALL" AND AI_INSTALL_MODE <> "Remove" ) )" Sequence="6402"/>
|
||||
<ROW Action="AI_DATA_SETTER_3" Condition="( ( NOT Installed ) OR ( Installed AND REMOVE <> "ALL" AND AI_INSTALL_MODE <> "Remove" ) )" Sequence="6401"/>
|
||||
<ROW Action="AI_AiRemoveFilesImmediate" Sequence="3499"/>
|
||||
<ROW Action="AI_AiRemoveFilesRollback" Sequence="3099"/>
|
||||
<ROW Action="AI_PromptUserBasicUI" Condition="((REMOVE = "ALL") AND (NOT UPGRADINGPRODUCTCODE))" Sequence="2501"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiInstallUISequenceComponent">
|
||||
<ROW Action="AI_RESTORE_LOCATION" Condition="APPDIR=""" Sequence="749"/>
|
||||
@@ -265,7 +307,13 @@
|
||||
<ROW Registry="Path" Root="-1" Key="Software\[ProductName]" Name="Path" Value="[APPDIR]" Component_="ProductInformation"/>
|
||||
<ROW Registry="Version" Root="-1" Key="Software\[ProductName]" Name="Version" Value="[ProductVersion]" Component_="ProductInformation"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiRemoveFileComponent">
|
||||
<ROW FileKey="_" Component_="ProductInformation" DirProperty="wufuc_Dir" InstallMode="2"/>
|
||||
<ROW FileKey="log" Component_="ProductInformation" FileName="*.log" DirProperty="wufuc_Dir" InstallMode="2"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiShortsComponent">
|
||||
<ROW Shortcut="License" Directory_="SHORTCUTDIR" Name="License" Component_="COPYING" Target="[#COPYING]" Hotkey="0" IconIndex="0" ShowCmd="1" WkDir="APPDIR"/>
|
||||
<ROW Shortcut="Openwufuclogfile" Directory_="Troubleshooting_Dir" Name="OPENWU~1|Open wufuc log file" Component_="Restore_wuauserv.reg" Target="[CommonAppDataFolder]wufuc\wufuc.log" Hotkey="0" IconIndex="0" ShowCmd="1"/>
|
||||
<ROW Shortcut="Uninstallwufuc" Directory_="SHORTCUTDIR" Name="UNINST~2|Uninstall [|ProductName]" Component_="ProductInformation" Target="[SystemFolder]msiexec.exe" Arguments="/x [ProductCode]" Hotkey="0" Icon_="msiexec.exe" IconIndex="0" ShowCmd="1" CustomFlags="1"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiThemeComponent">
|
||||
|
@@ -134,7 +134,6 @@ goto :cancel
|
||||
|
||||
:install
|
||||
call :uninstall
|
||||
net start Schedule
|
||||
schtasks /Create /XML "%wufuc_xml%" /TN "%wufuc_task%" /F
|
||||
schtasks /Change /TN "%wufuc_task%" /TR "'%systemroot%\System32\rundll32.exe' """%wufuc_dll_fullpath%""",RUNDLL32_Start"
|
||||
schtasks /Change /TN "%wufuc_task%" /ENABLE
|
||||
@@ -166,8 +165,8 @@ goto :confirm_restart
|
||||
sfc /SCANFILE="%systemfolder%\wuaueng.dll"
|
||||
|
||||
:: remove traces of wufuc 0.6-0.7, 0.9.999+
|
||||
schtasks /Query /TN "%wufuc_task%" >nul 2>&1 && (
|
||||
schtasks /Delete /TN "%wufuc_task%" /F )
|
||||
net start Schedule
|
||||
schtasks /Delete /TN "%wufuc_task%" /F
|
||||
rundll32 "%wufuc_dll_fullpath%",RUNDLL32_Unload
|
||||
|
||||
:: remove traces of wufuc 0.8.x
|
||||
|
Binary file not shown.
Reference in New Issue
Block a user