This commit is contained in:
zeffy
2018-03-16 06:48:50 -07:00
parent 772fdbc25b
commit 31cefc29a5
22 changed files with 356 additions and 148 deletions

14
FAQ.md
View File

@@ -13,6 +13,20 @@
These must be used from an elevated command line prompt. These must be used from an elevated command line prompt.
## How to restore Windows Update to its default configuration
Windows Update by default is configured to run as `SERVICE_WIN32_SHARE_PROCESS`, which means it shares a single `svchost.exe` process with several other Windows services.
It can also be configured as `SERVICE_WIN32_OWN_PROCESS`, which means it runs in its own process, which doesn't start until Windows Update does.
Normally, either of these configurations is supported.
However, if you have used another third-party solution for the CPU fix (such as UpdatePack7R2 or WuaCpuFix) either knowingly or unknowingly, wufuc will not function correctly if Windows Update is configured as `SERVICE_WIN32_OWN_PROCESS`.
You have two ways to work around this limitation, either:
- You can remove the other third-party solution yourself.
- Alternatively, go to the directory that you installed wufuc to, open the `Troubleshooting` subdirectory, and merge the `Restore_wuauserv.reg` file with your registry by double-clicking it, and then restart your PC.
## How to manually remove wufuc v0.8.0.143 when it is impossible to uninstall it normally ## How to manually remove wufuc v0.8.0.143 when it is impossible to uninstall it normally
This applies exclusively to a very buggy version of wufuc that was only available for download for a short period of time, other versions are unaffected. This applies exclusively to a very buggy version of wufuc that was only available for download for a short period of time, other versions are unaffected.

View File

@@ -35,7 +35,9 @@ Some people with older Intel and AMD processors are also affected! I've received
- [Intel Atom D525](https://github.com/zeffy/wufuc/issues/34) - [Intel Atom D525](https://github.com/zeffy/wufuc/issues/34)
- [Intel Core i5-M 560](https://github.com/zeffy/wufuc/issues/23) - [Intel Core i5-M 560](https://github.com/zeffy/wufuc/issues/23)
- [Intel Core i5-4300M](https://github.com/zeffy/wufuc/issues/24) - [Intel Core i5-4300M](https://github.com/zeffy/wufuc/issues/24)
- [Intel Core i7-4930K](https://github.com/zeffy/wufuc/issues/126)
- [Intel Pentium B940](https://github.com/zeffy/wufuc/issues/63) - [Intel Pentium B940](https://github.com/zeffy/wufuc/issues/63)
- [AMD FX-6300](https://github.com/zeffy/wufuc/issues/135#issuecomment-367054217)
- [AMD FX-8350](https://github.com/zeffy/wufuc/issues/32) - [AMD FX-8350](https://github.com/zeffy/wufuc/issues/32)
- [AMD Turion 64 Mobile Technology ML-34](https://github.com/zeffy/wufuc/issues/80) - [AMD Turion 64 Mobile Technology ML-34](https://github.com/zeffy/wufuc/issues/80)

View File

@@ -5,9 +5,11 @@
#include "modulehelper.h" #include "modulehelper.h"
#include "registryhelper.h" #include "registryhelper.h"
#include "servicehelper.h" #include "servicehelper.h"
#include "versionhelper.h"
#include "ptrlist.h" #include "ptrlist.h"
#include "wufuc.h" #include "wufuc.h"
#include <VersionHelpers.h>
#include <minhook.h> #include <minhook.h>
VOID CALLBACK cb_service_notify(PSERVICE_NOTIFYW pNotifyBuffer) VOID CALLBACK cb_service_notify(PSERVICE_NOTIFYW pNotifyBuffer)
@@ -38,25 +40,30 @@ DWORD WINAPI cb_start(HANDLE *pParam)
DWORD dwProcessId; DWORD dwProcessId;
LPQUERY_SERVICE_CONFIGW pServiceConfig; LPQUERY_SERVICE_CONFIGW pServiceConfig;
DWORD dwServiceType; 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; int tmp;
LPVOID pTarget = NULL; LPVOID pv1 = NULL;
LPVOID pv2 = NULL;
wchar_t *str; wchar_t *str;
HMODULE hModule; HMODULE hModule;
if ( !pParam ) { if ( !pParam ) {
trace(L"Parameter argument is null!"); log_error(L"Parameter argument is null!");
goto unload; goto unload;
} }
handles[0] = pParam[0]; // main mutex handles[0] = pParam[0]; // main mutex
handles[1] = pParam[1]; // unload event handles[1] = pParam[1]; // unload event
hCrashMutex = pParam[2]; // crash mutex hCrashMutex = pParam[2]; // crash mutex
hProceedEvent = pParam[3]; // proceed event 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. // acquire child mutex, this should be immediate.
if ( WaitForSingleObject(hCrashMutex, 5000) != WAIT_OBJECT_0 ) { 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; goto close_handles;
} }
SetEvent(hProceedEvent); SetEvent(hProceedEvent);
@@ -64,12 +71,10 @@ DWORD WINAPI cb_start(HANDLE *pParam)
hSCM = OpenSCManagerW(NULL, NULL, SC_MANAGER_CONNECT); hSCM = OpenSCManagerW(NULL, NULL, SC_MANAGER_CONNECT);
if ( !hSCM ) { if ( !hSCM ) {
trace(L"Failed to open SCM. (GetLastError=%lu)", GetLastError()); log_error(L"Failed to open SCM. (GetLastError=%lu)", GetLastError());
goto release; 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); dwProcessId = svc_heuristic_process_id(hSCM, hService);
pServiceConfig = svc_query_config_alloc(hSCM, hService, NULL); pServiceConfig = svc_query_config_alloc(hSCM, hService, NULL);
dwServiceType = pServiceConfig->dwServiceType; dwServiceType = pServiceConfig->dwServiceType;
@@ -79,23 +84,33 @@ DWORD WINAPI cb_start(HANDLE *pParam)
CloseServiceHandle(hSCM); CloseServiceHandle(hSCM);
if ( tmp || dwProcessId != GetCurrentProcessId() ) { 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; goto release;
} }
if ( dwServiceType == SERVICE_WIN32_SHARE_PROCESS ) { if ( dwServiceType == SERVICE_WIN32_SHARE_PROCESS ) {
// assume wuaueng.dll hasn't been loaded yet, apply // assume wuaueng.dll hasn't been loaded yet, apply
// RegQueryValueExW hook to fix incompatibility with // RegQueryValueExW hook to fix incompatibility with
// UpdatePack7R2 and other patches that modify the // UpdatePack7R2 and other patches that modify the
// Windows Update ServiceDll path in the registry. // Windows Update ServiceDll path in the registry.
MH_CreateHookApiEx(L"kernel32.dll", pszModule = IsWindows8OrGreater()
? szKernelBaseDll
: szKernel32Dll;
status = MH_CreateHookApiEx(pszModule,
"RegQueryValueExW", "RegQueryValueExW",
RegQueryValueExW_hook, RegQueryValueExW_hook,
&(PVOID)g_pfnRegQueryValueExW, &(PVOID)g_pfnRegQueryValueExW,
&pTarget); &pv1);
MH_EnableHook(pTarget); 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 // query the ServiceDll path after applying our compat hook so that it
// is correct // is correct
str = (wchar_t *)reg_query_value_alloc(HKEY_LOCAL_MACHINE, str = (wchar_t *)reg_query_value_alloc(HKEY_LOCAL_MACHINE,
@@ -103,18 +118,25 @@ DWORD WINAPI cb_start(HANDLE *pParam)
L"ServiceDll", NULL, NULL); L"ServiceDll", NULL, NULL);
if ( !str ) { if ( !str ) {
abort_hook: abort_hook:
if ( pTarget ) if ( pv1 )
MH_RemoveHook(pTarget); MH_RemoveHook(pv1);
goto release; goto release;
} }
g_pszWUServiceDll = env_expand_strings_alloc(str, NULL); g_pszWUServiceDll = env_expand_strings_alloc(str, NULL);
free(str); free(str);
if ( !g_pszWUServiceDll ) goto abort_hook; if ( !g_pszWUServiceDll ) goto abort_hook;
MH_CreateHookApi(L"kernel32.dll", status = MH_CreateHookApiEx(szKernelBaseDll,
"LoadLibraryExW", "LoadLibraryExW",
LoadLibraryExW_hook, 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) if ( GetModuleHandleExW(0, g_pszWUServiceDll, &hModule)
|| GetModuleHandleExW(0, PathFindFileNameW(g_pszWUServiceDll), &hModule) ) { || GetModuleHandleExW(0, PathFindFileNameW(g_pszWUServiceDll), &hModule) ) {
@@ -122,14 +144,11 @@ abort_hook:
// hook IsDeviceServiceable if wuaueng.dll is already loaded // hook IsDeviceServiceable if wuaueng.dll is already loaded
wufuc_hook(hModule); wufuc_hook(hModule);
FreeLibrary(hModule); FreeLibrary(hModule);
} }
MH_EnableHook(MH_ALL_HOOKS);
// wait for unload event or the main mutex to be released or abandoned, // wait for unload event or the main mutex to be released or abandoned,
// for example if the user killed rundll32.exe with task manager. // for example if the user killed rundll32.exe with task manager.
WaitForMultipleObjects(_countof(handles), handles, FALSE, INFINITE); 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); MH_DisableHook(MH_ALL_HOOKS);
free(g_pszWUServiceDll); free(g_pszWUServiceDll);
@@ -140,7 +159,7 @@ close_handles:
CloseHandle(handles[0]); CloseHandle(handles[0]);
CloseHandle(handles[1]); CloseHandle(handles[1]);
unload: unload:
trace(L"Unloading wufuc and exiting thread."); log_info(L"Unloading wufuc and exiting thread.");
FreeLibraryAndExitThread(PIMAGEBASE, 0); FreeLibraryAndExitThread(PIMAGEBASE, 0);
} }

View File

@@ -16,6 +16,7 @@ BOOL APIENTRY DllMain(HMODULE hModule,
break; break;
case DLL_PROCESS_DETACH: case DLL_PROCESS_DETACH:
MH_Uninitialize(); MH_Uninitialize();
log_close();
break; break;
} }
return TRUE; return TRUE;

View File

@@ -19,7 +19,7 @@ LSTATUS WINAPI RegQueryValueExW_hook(HKEY hKey, LPCWSTR lpValueName, LPDWORD lpR
ULONG ResultLength; ULONG ResultLength;
PKEY_NAME_INFORMATION pkni; PKEY_NAME_INFORMATION pkni;
size_t NameCount; size_t NameCount;
int current; unsigned int current;
int pos; int pos;
wchar_t *fname; wchar_t *fname;
const wchar_t realpath[] = L"%systemroot%\\system32\\wuaueng.dll"; 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; MaximumLength = *lpcbData;
result = g_pfnRegQueryValueExW(hKey, lpValueName, lpReserved, lpType, lpData, lpcbData); result = g_pfnRegQueryValueExW(hKey, lpValueName, lpReserved, lpType, lpData, lpcbData);
if ( result != ERROR_SUCCESS if ( result != ERROR_SUCCESS
|| !MaximumLength || !MaximumLength
|| !lpValueName || !lpValueName
@@ -51,7 +50,7 @@ LSTATUS WINAPI RegQueryValueExW_hook(HKEY hKey, LPCWSTR lpValueName, LPDWORD lpR
for ( size_t i = 0; i < NameCount; i++ ) for ( size_t i = 0; i < NameCount; i++ )
pkni->Name[i] = towlower(pkni->Name[i]); pkni->Name[i] = towlower(pkni->Name[i]);
if ( _snwscanf_s(pkni->Name, NameCount, L"\\registry\\machine\\system\\controlset%03d\\services\\wuauserv\\parameters%n", &current, &pos) == 1 if ( _snwscanf_s(pkni->Name, NameCount, L"\\registry\\machine\\system\\controlset%03u\\services\\wuauserv\\parameters%n", &current, &pos) == 1
&& pos == NameCount ) { && pos == NameCount ) {
fname = PathFindFileNameW(pBuffer); fname = PathFindFileNameW(pBuffer);
@@ -66,7 +65,7 @@ LSTATUS WINAPI RegQueryValueExW_hook(HKEY hKey, LPCWSTR lpValueName, LPDWORD lpR
&& SUCCEEDED(StringCbCopyW(pBuffer, MaximumLength, expandedpath)) ) { && SUCCEEDED(StringCbCopyW(pBuffer, MaximumLength, expandedpath)) ) {
*lpcbData = cchLength * (sizeof *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); free(expandedpath);
} }
@@ -82,9 +81,10 @@ HMODULE WINAPI LoadLibraryExW_hook(LPCWSTR lpFileName, HANDLE hFile, DWORD dwFla
result = g_pfnLoadLibraryExW(lpFileName, hFile, dwFlags); result = g_pfnLoadLibraryExW(lpFileName, hFile, dwFlags);
if ( !result ) return result; 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, g_pszWUServiceDll)
|| !_wcsicmp(lpFileName, PathFindFileNameW(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) BOOL WINAPI IsDeviceServiceable_hook(void)
{ {
trace(L"Entered stub function."); log_debug(L"Entered stub function.");
return TRUE; return TRUE;
} }

View File

@@ -1,39 +1,153 @@
#include "stdafx.h" #include "stdafx.h"
#include "log.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; va_list ap;
wchar_t *buf;
int ret;
int count; 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 datebuf[9];
wchar_t timebuf[9]; wchar_t timebuf[9];
va_list ap;
const wchar_t fmt[] = L"%ls %ls [%ls:%lu] %ls"; const wchar_t fmt[] = L"%ls %ls [%ls:%lu] %ls";
int count;
wchar_t *buf1;
int ret;
wchar_t *buf2;
DWORD written;
pid = GetCurrentProcessId(); bStatus = InitOnceExecuteOnce(&InitOnce,
GetModuleFileNameW(NULL, exepath, _countof(exepath)); (PINIT_ONCE_FN)init_file_handle,
exename = PathFindFileNameW(exepath); &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); va_start(ap, format);
count = _vscwprintf(format, ap) + 1; count = _vscwprintf(format, ap);
va_end(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); va_start(ap, format);
vswprintf_s(buffer1, count, format, ap); ret = vswprintf_s(buf1, count + 1, format, ap);
va_end(ap); va_end(ap);
if ( ret == -1 ) goto free_buf1;
_wstrdate_s(datebuf, _countof(datebuf)); count = _scwprintf(fmt, datebuf, timebuf, data.pszExeName, data.dwProcessId, buf1);
_wstrtime_s(timebuf, _countof(timebuf)); if ( count == -1 ) goto free_buf1;
count = _scwprintf(fmt, datebuf, timebuf, exename, pid, buffer1) + 1;
buffer2 = calloc(count, sizeof *buffer2); buf2 = calloc(count + 1, sizeof *buf2);
swprintf_s(buffer2, count, fmt, datebuf, timebuf, exename, pid, buffer1); if ( !buf2 ) goto free_buf1;
free(buffer1); ret = swprintf_s(buf2, count + 1, fmt, datebuf, timebuf, data.pszExeName, data.dwProcessId, buf1);
OutputDebugStringW(buffer2); if ( ret == -1 ) goto free_buf2;
free(buffer2);
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);
} }

View File

@@ -1,6 +1,17 @@
#pragma once #pragma once
void logp_debug_write(const wchar_t *const format, ...); typedef struct
#define log_debug_write(format, ...) \ {
logp_debug_write(__FUNCTIONW__ L"(" _CRT_WIDE(_CRT_STRINGIZE(__LINE__)) L"): " format L"\r\n", ##__VA_ARGS__) DWORD dwProcessId;
#define trace log_debug_write 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__)

View File

@@ -362,14 +362,20 @@ leave:
void ptrlist_for(ptrlist_t *list, size_t index, size_t count, void(__cdecl *f)(void *)) void ptrlist_for(ptrlist_t *list, size_t index, size_t count, void(__cdecl *f)(void *))
{ {
if ( !list || !f ) return;
ptrlist_lock(list); ptrlist_lock(list);
if ( index + count <= list->count ) {
for ( size_t i = index; i < count; i++ ) for ( size_t i = index; i < count; i++ )
f(list->values[i]); f(list->values[i]);
}
ptrlist_unlock(list); ptrlist_unlock(list);
} }
void ptrlist_for_each(ptrlist_t *list, void(__cdecl *f)(void *)) void ptrlist_for_each(ptrlist_t *list, void(__cdecl *f)(void *))
{ {
if ( !list || !f ) return;
ptrlist_lock(list); ptrlist_lock(list);
ptrlist_for(list, 0, list->count, f); ptrlist_for(list, 0, list->count, f);
ptrlist_unlock(list); 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 *)) void ptrlist_for_stdcall(ptrlist_t *list, size_t index, size_t count, void(__stdcall *f)(void *))
{ {
if ( !list || !f ) return;
ptrlist_lock(list); ptrlist_lock(list);
if ( index + count <= list->count ) {
for ( size_t i = index; i < count; i++ ) for ( size_t i = index; i < count; i++ )
f(list->values[i]); f(list->values[i]);
}
ptrlist_unlock(list); ptrlist_unlock(list);
} }
void ptrlist_for_each_stdcall(ptrlist_t *list, void(__stdcall *f)(void *)) void ptrlist_for_each_stdcall(ptrlist_t *list, void(__stdcall *f)(void *))
{ {
if ( !list || !f ) return;
ptrlist_lock(list); ptrlist_lock(list);
ptrlist_for_stdcall(list, 0, list->count, f); ptrlist_for_stdcall(list, 0, list->count, f);
ptrlist_unlock(list); ptrlist_unlock(list);

18
src/wufuc/resource.h Normal file
View 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

View File

@@ -101,16 +101,16 @@ void CALLBACK RUNDLL32_StartW(HWND hwnd,
CloseHandle(values[index]); CloseHandle(values[index]);
crashes++; 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]); crashes, crashes != 1 ? L"s" : L"", tags[index]);
if ( crashes >= SVCHOST_CRASH_THRESHOLD ) { 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; Unloading = true;
Suspending = true; Suspending = true;
} }
} else if ( r == WAIT_FAILED ) { } else if ( r == WAIT_FAILED ) {
trace(L"Wait function failed!"); log_error(L"Wait function failed!");
Unloading = true; Unloading = true;
} }
free(values); free(values);
@@ -118,11 +118,11 @@ void CALLBACK RUNDLL32_StartW(HWND hwnd,
} while ( r != WAIT_IO_COMPLETION && !Unloading ); } while ( r != WAIT_IO_COMPLETION && !Unloading );
break; break;
case ERROR_SERVICE_NOTIFY_CLIENT_LAGGING: case ERROR_SERVICE_NOTIFY_CLIENT_LAGGING:
trace(L"Client lagging!"); log_warning(L"Client lagging!");
Lagging = true; Lagging = true;
break; break;
default: default:
trace(L"NotifyServiceStatusChange failed, return value: %lu (%08X)", e); log_error(L"NotifyServiceStatusChange failed! (Return value=%lu)", e);
Unloading = true; Unloading = true;
break; break;
} }

View File

@@ -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) bool ver_verify_version_info(WORD wMajorVersion, WORD wMinorVersion, WORD wServicePackMajor)
{ {
DWORDLONG dwlConditionMask = 0;
OSVERSIONINFOEXW osvi = { sizeof osvi }; OSVERSIONINFOEXW osvi = { sizeof osvi };
DWORDLONG dwlConditionMask = 0;
VER_SET_CONDITION(dwlConditionMask, VER_MAJORVERSION, VER_EQUAL); VER_SET_CONDITION(dwlConditionMask, VER_MAJORVERSION, VER_EQUAL);
VER_SET_CONDITION(dwlConditionMask, VER_MINORVERSION, VER_EQUAL); VER_SET_CONDITION(dwlConditionMask, VER_MINORVERSION, VER_EQUAL);
VER_SET_CONDITION(dwlConditionMask, VER_SERVICEPACKMAJOR, VER_GREATER_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, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR,
dwlConditionMask) != FALSE; 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);
}

View File

@@ -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); 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); 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_version_info(WORD wMajorVersion, WORD wMinorVersion, WORD wServicePackMajor);
bool ver_verify_windows_7_sp1(void);
bool ver_verify_windows_8_1(void);

View File

@@ -93,7 +93,9 @@ close_mutex:
CloseHandle(hCrashMutex); CloseHandle(hCrashMutex);
} }
if ( result ) 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; return result;
} }
@@ -108,17 +110,15 @@ bool wufuc_hook(HMODULE hModule)
UINT cbInternalName; UINT cbInternalName;
VS_FIXEDFILEINFO *pffi; VS_FIXEDFILEINFO *pffi;
UINT cbffi; UINT cbffi;
int tmp; bool tmp;
MODULEINFO modinfo; MODULEINFO modinfo;
size_t offset; size_t offset;
LPVOID pTarget; LPVOID pTarget = NULL;
MH_STATUS status;
if ( !ver_verify_windows_7_sp1() && !ver_verify_windows_8_1() )
return false;
ptl = ver_get_version_info_from_hmodule_alloc(hModule, L"\\VarFileInfo\\Translation", &cbtl); ptl = ver_get_version_info_from_hmodule_alloc(hModule, L"\\VarFileInfo\\Translation", &cbtl);
if ( !ptl ) { if ( !ptl ) {
trace(L"Failed to get translation info from hModule."); log_error(L"ver_get_version_info_from_hmodule_alloc failed!");
return false; return false;
} }
hProcess = GetCurrentProcess(); hProcess = GetCurrentProcess();
@@ -133,58 +133,58 @@ bool wufuc_hook(HMODULE hModule)
pInternalName = ver_get_version_info_from_hmodule_alloc(hModule, SubBlock, &cbInternalName); pInternalName = ver_get_version_info_from_hmodule_alloc(hModule, SubBlock, &cbInternalName);
if ( !pInternalName ) { if ( !pInternalName ) {
trace(L"Failed to get internal name from hModule."); log_error(L"ver_get_version_info_from_hmodule_alloc failed!");
continue; continue;
} }
// identify wuaueng.dll by its resource data // identify wuaueng.dll by its resource data
if ( _wcsicmp(pInternalName, L"wuaueng.dll") ) { 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; goto free_iname;
} }
pffi = ver_get_version_info_from_hmodule_alloc(hModule, L"\\", &cbffi); pffi = ver_get_version_info_from_hmodule_alloc(hModule, L"\\", &cbffi);
if ( !pffi ) { if ( !pffi ) {
trace(L"Failed to get version info from hModule."); log_error(L"ver_get_version_info_from_hmodule_alloc failed!");
break; 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), HIWORD(pffi->dwProductVersionMS),
LOWORD(pffi->dwProductVersionMS), LOWORD(pffi->dwProductVersionMS),
HIWORD(pffi->dwProductVersionLS), HIWORD(pffi->dwProductVersionLS),
LOWORD(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); free(pffi);
if ( !tmp ) { if ( !tmp ) break;
trace(L"Windows Update Agent does not meet the minimum supported version.");
break;
}
if ( !GetModuleInformation(hProcess, hModule, &modinfo, sizeof modinfo) ) { 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; break;
} }
offset = patternfind(modinfo.lpBaseOfDll, modinfo.SizeOfImage, offset = patternfind(modinfo.lpBaseOfDll, modinfo.SizeOfImage,
#ifdef _WIN64 #ifdef _WIN64
"FFF3 4883EC?? 33DB 391D???????? 7508 8B05????????" "FFF3 4883EC?? 33DB 391D???????? 7508 8B05????????"
#else #else
ver_verify_windows_7_sp1() ver_verify_version_info(6, 1, 0)
? "833D????????00 743E E8???????? A3????????" ? "833D????????00 743E E8???????? A3????????"
: "8BFF 51 833D????????00 7507 A1????????" : "8BFF 51 833D????????00 7507 A1????????"
#endif #endif
); );
if ( offset != -1 ) { if ( offset != -1 ) {
pTarget = (LPVOID)RtlOffsetToPointer(modinfo.lpBaseOfDll, offset); 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) status = MH_CreateHook(pTarget, IsDeviceServiceable_hook, NULL);
&& (MH_EnableHook(pTarget) == MH_OK); if ( status == MH_OK ) {
if ( result ) status = MH_EnableHook(pTarget);
trace(L"Successfully hooked IsDeviceServiceable!"); if ( status == MH_OK )
} else { log_info(L"Hooked IsDeviceServiceable! (Address=%p)", pTarget);
trace(L"Could not find function offset!"); 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_iname:
free(pInternalName); free(pInternalName);
break; break;

View File

@@ -7,7 +7,6 @@ typedef struct
} LANGANDCODEPAGE, *PLANGANDCODEPAGE; } LANGANDCODEPAGE, *PLANGANDCODEPAGE;
#define SVCHOST_CRASH_THRESHOLD 3 #define SVCHOST_CRASH_THRESHOLD 3
extern HANDLE g_hMainMutex; extern HANDLE g_hMainMutex;
bool wufuc_inject(DWORD dwProcessId, bool wufuc_inject(DWORD dwProcessId,

View File

@@ -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

View File

@@ -58,12 +58,12 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="exports.def" /> <None Include="exports.def" />
<None Include="wufuc.rch"> <None Include="resource.h">
<FileType>Document</FileType> <FileType>Document</FileType>
</None> </None>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ResourceCompile Include="wufuc.rc" /> <ResourceCompile Include="resource.rc" />
</ItemGroup> </ItemGroup>
<PropertyGroup Label="Globals"> <PropertyGroup Label="Globals">
<VCProjectVersion>15.0</VCProjectVersion> <VCProjectVersion>15.0</VCProjectVersion>

View File

@@ -106,16 +106,16 @@
</ClCompile> </ClCompile>
</ItemGroup> </ItemGroup>
<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"> <None Include="exports.def">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</None> </None>
<None Include="resource.h">
<Filter>Header Files</Filter>
</None>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="resource.rc">
<Filter>Resource Files</Filter>
</ResourceCompile>
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@@ -5,12 +5,16 @@
</COMPONENT> </COMPONENT>
<COMPONENT cid="caphyon.advinst.msicomp.MsiPropsComponent"> <COMPONENT cid="caphyon.advinst.msicomp.MsiPropsComponent">
<ROW Property="AI_BITMAP_DISPLAY_MODE" Value="0"/> <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="AI_ThemeStyle" Value="aero" MsiKey="AI_ThemeStyle"/>
<ROW Property="ALLUSERS" Value="1"/> <ROW Property="ALLUSERS" Value="1"/>
<ROW Property="ARPCOMMENTS" Value="Enables Windows Update on PCs with unsupported processors." ValueLocId="*"/> <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="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="ARPPRODUCTICON" Value="msiexec.exe" Type="8"/>
<ROW Property="ARPURLINFOABOUT" Value="https://github.com/zeffy/wufuc"/> <ROW Property="ARPURLINFOABOUT" Value="https://github.com/zeffy/wufuc"/>
<ROW Property="ARPURLUPDATEINFO" Value="https://github.com/zeffy/wufuc/releases/latest"/> <ROW Property="ARPURLUPDATEINFO" Value="https://github.com/zeffy/wufuc/releases/latest"/>
@@ -39,31 +43,46 @@
</COMPONENT> </COMPONENT>
<COMPONENT cid="caphyon.advinst.msicomp.MsiDirsComponent"> <COMPONENT cid="caphyon.advinst.msicomp.MsiDirsComponent">
<ROW Directory="APPDIR" Directory_Parent="TARGETDIR" DefaultDir="APPDIR:." IsPseudoRoot="1"/> <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="SHORTCUTDIR" Directory_Parent="TARGETDIR" DefaultDir="SHORTC~1|SHORTCUTDIR" IsPseudoRoot="1"/>
<ROW Directory="TARGETDIR" DefaultDir="SourceDir"/> <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="X64FeatureItems_Dir" Directory_Parent="APPDIR" DefaultDir=".:X64FEA~1|X64FeatureItems"/>
<ROW Directory="X86FeatureItems_Dir" Directory_Parent="APPDIR" DefaultDir=".:X86FEA~1|X86FeatureItems"/> <ROW Directory="X86FeatureItems_Dir" Directory_Parent="APPDIR" DefaultDir=".:X86FEA~1|X86FeatureItems"/>
<ROW Directory="wufuc_Dir" Directory_Parent="CommonAppDataFolder" DefaultDir="wufuc"/>
</COMPONENT> </COMPONENT>
<COMPONENT cid="caphyon.advinst.msicomp.MsiCompsComponent"> <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="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="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="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="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="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"/> <ROW Component="wufuc64.dll" ComponentId="{0407D471-998A-4FD3-BC2D-72EE56FBEEF4}" Directory_="APPDIR" Attributes="256" KeyPath="wufuc64.dll"/>
</COMPONENT> </COMPONENT>
<COMPONENT cid="caphyon.advinst.msicomp.MsiFeatsComponent"> <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="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"/> <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"/> <ATTRIBUTE name="CurrentFeature" value="MainFeature"/>
</COMPONENT> </COMPONENT>
<COMPONENT cid="caphyon.advinst.msicomp.MsiFilesComponent"> <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="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>
<COMPONENT cid="caphyon.advinst.custcomp.MsiShortcutPropertyComponent"> <COMPONENT cid="caphyon.advinst.custcomp.MsiShortcutPropertyComponent">
<ROW MsiShortcutProperty="Uninstallwufuc1" Shortcut_="Uninstallwufuc" PropertyKey="[AiPreventAutoPin]" PropVariantValue="1"/> <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 = &quot;1&quot;) AND (NOT UPGRADINGPRODUCTCODE)" Options="1"/>
<ROW RemoveFile="_" Condition="(AI_CLEAN_RESOURCES_UNINSTALL = &quot;1&quot;) AND (NOT UPGRADINGPRODUCTCODE)" Options="0"/>
</COMPONENT> </COMPONENT>
<COMPONENT cid="caphyon.advinst.msicomp.BootstrOptComponent"> <COMPONENT cid="caphyon.advinst.msicomp.BootstrOptComponent">
<ROW BootstrOptKey="GlobalOptions" DownloadFolder="[AppDataFolder][|Manufacturer]\[|ProductName]\prerequisites" Options="2"/> <ROW BootstrOptKey="GlobalOptions" DownloadFolder="[AppDataFolder][|Manufacturer]\[|ProductName]\prerequisites" Options="2"/>
@@ -109,6 +128,11 @@
<ROW Fragment="WelcomeDlg.aip" Path="&lt;AI_THEMES&gt;classic\fragments\WelcomeDlg.aip"/> <ROW Fragment="WelcomeDlg.aip" Path="&lt;AI_THEMES&gt;classic\fragments\WelcomeDlg.aip"/>
</COMPONENT> </COMPONENT>
<COMPONENT cid="caphyon.advinst.msicomp.MsiActionTextComponent"> <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_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: &quot;[1]&quot;" TemplateLocId="ActionText.Template.AI_XmlConfig"/> <ROW Action="AI_XmlConfig" Description="Executing XML file configurations" DescriptionLocId="ActionText.Description.AI_XmlConfig" Template="Configuring XML file: &quot;[1]&quot;" TemplateLocId="ActionText.Template.AI_XmlConfig"/>
<ROW Action="AI_XmlInstall" Description="Generating actions to configure XML files" DescriptionLocId="ActionText.Description.AI_XmlInstall"/> <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"> <COMPONENT cid="caphyon.advinst.msicomp.MsiBinaryComponent">
<ROW Name="AdvancedInstallerHelper.dll" SourcePath="AdvancedInstallerHelper.dll"/> <ROW Name="AdvancedInstallerHelper.dll" SourcePath="AdvancedInstallerHelper.dll"/>
<ROW Name="Prereq.dll" SourcePath="&lt;AI_CUSTACTS&gt;Prereq.dll"/> <ROW Name="Prereq.dll" SourcePath="&lt;AI_CUSTACTS&gt;Prereq.dll"/>
<ROW Name="ResourceCleaner.dll" SourcePath="&lt;AI_CUSTACTS&gt;ResourceCleaner.dll"/>
<ROW Name="ShortcutFlags.dll" SourcePath="&lt;AI_CUSTACTS&gt;ShortcutFlags.dll"/> <ROW Name="ShortcutFlags.dll" SourcePath="&lt;AI_CUSTACTS&gt;ShortcutFlags.dll"/>
<ROW Name="aicustact.dll" SourcePath="&lt;AI_CUSTACTS&gt;aicustact.dll"/> <ROW Name="aicustact.dll" SourcePath="&lt;AI_CUSTACTS&gt;aicustact.dll"/>
<ROW Name="viewer.exe" SourcePath="&lt;AI_CUSTACTS&gt;viewer.exe"/> <ROW Name="viewer.exe" SourcePath="&lt;AI_CUSTACTS&gt;viewer.exe"/>
<ROW Name="xmlCfg.dll" SourcePath="&lt;AI_CUSTACTS&gt;xmlCfg.dll"/> <ROW Name="xmlCfg.dll" SourcePath="&lt;AI_CUSTACTS&gt;xmlCfg.dll"/>
</COMPONENT> </COMPONENT>
<COMPONENT cid="caphyon.advinst.msicomp.MsiCheckBoxComponent">
<ROW Property="AI_CLEAN_RESOURCES_UNINSTALL" Value="1"/>
</COMPONENT>
<COMPONENT cid="caphyon.advinst.msicomp.MsiControlComponent"> <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_="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>
<COMPONENT cid="caphyon.advinst.msicomp.MsiControlEventComponent"> <COMPONENT cid="caphyon.advinst.msicomp.MsiControlEventComponent">
<ROW Dialog_="WelcomeDlg" Control_="Next" Event="NewDialog" Argument="LicenseAgreementDlg" Condition="AI_INSTALL" Ordering="1"/> <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_="SHORTCUTDIR" Component_="SHORTCUTDIR" ManualDelete="false"/>
<ROW Directory_="X86FeatureItems_Dir" Component_="X86FeatureItems" ManualDelete="false"/> <ROW Directory_="X86FeatureItems_Dir" Component_="X86FeatureItems" ManualDelete="false"/>
<ROW Directory_="X64FeatureItems_Dir" Component_="X64FeatureItems" 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>
<COMPONENT cid="caphyon.advinst.msicomp.MsiCustActComponent"> <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_AppSearchEx" Type="1" Source="Prereq.dll" Target="DoAppSearchEx"/>
<ROW Action="AI_ApplyShortcutFlags" Type="3073" Source="ShortcutFlags.dll" Target="UpdateShortcutFlags" WithoutSeq="true"/> <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]"/> <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_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_PinToTaskbar" Type="1025" Source="ShortcutFlags.dll" Target="PinToTaskbar" WithoutSeq="true"/>
<ROW Action="AI_PrepareShortcutFlags" Type="1" Source="ShortcutFlags.dll" Target="PrepareActionData"/> <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_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_RESTORE_LOCATION" Type="65" Source="aicustact.dll" Target="RestoreLocation"/>
<ROW Action="AI_ResolveKnownFolders" Type="1" Source="aicustact.dll" Target="AI_ResolveKnownFolders"/> <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"/> <ROW Action="StopWindowsUpdateService" Type="3073" Source="aicustact.dll" Target="StopWinService" Options="1" AdditionalSeq="AI_DATA_SETTER_2"/>
</COMPONENT> </COMPONENT>
<COMPONENT cid="caphyon.advinst.msicomp.MsiIconsComponent"> <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>
<COMPONENT cid="caphyon.advinst.msicomp.MsiIniFileComponent"> <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" 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_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" 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_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>
<COMPONENT cid="caphyon.advinst.msicomp.MsiInstExSeqComponent"> <COMPONENT cid="caphyon.advinst.msicomp.MsiInstExSeqComponent">
<ROW Action="AI_DOWNGRADE" Condition="AI_NEWERPRODUCTFOUND AND (UILevel &lt;&gt; 5)" Sequence="210"/> <ROW Action="AI_DOWNGRADE" Condition="AI_NEWERPRODUCTFOUND AND (UILevel &lt;&gt; 5)" Sequence="210"/>
@@ -241,6 +280,9 @@
<ROW Action="SetRebootProperty" Condition="NONDEFAULT_SERVICEDLL" Sequence="201"/> <ROW Action="SetRebootProperty" Condition="NONDEFAULT_SERVICEDLL" Sequence="201"/>
<ROW Action="StartWindowsUpdateService" Condition="( ( NOT Installed ) OR ( Installed AND REMOVE &lt;&gt; &quot;ALL&quot; AND AI_INSTALL_MODE &lt;&gt; &quot;Remove&quot; ) )" Sequence="6402"/> <ROW Action="StartWindowsUpdateService" Condition="( ( NOT Installed ) OR ( Installed AND REMOVE &lt;&gt; &quot;ALL&quot; AND AI_INSTALL_MODE &lt;&gt; &quot;Remove&quot; ) )" Sequence="6402"/>
<ROW Action="AI_DATA_SETTER_3" Condition="( ( NOT Installed ) OR ( Installed AND REMOVE &lt;&gt; &quot;ALL&quot; AND AI_INSTALL_MODE &lt;&gt; &quot;Remove&quot; ) )" Sequence="6401"/> <ROW Action="AI_DATA_SETTER_3" Condition="( ( NOT Installed ) OR ( Installed AND REMOVE &lt;&gt; &quot;ALL&quot; AND AI_INSTALL_MODE &lt;&gt; &quot;Remove&quot; ) )" Sequence="6401"/>
<ROW Action="AI_AiRemoveFilesImmediate" Sequence="3499"/>
<ROW Action="AI_AiRemoveFilesRollback" Sequence="3099"/>
<ROW Action="AI_PromptUserBasicUI" Condition="((REMOVE = &quot;ALL&quot;) AND (NOT UPGRADINGPRODUCTCODE))" Sequence="2501"/>
</COMPONENT> </COMPONENT>
<COMPONENT cid="caphyon.advinst.msicomp.MsiInstallUISequenceComponent"> <COMPONENT cid="caphyon.advinst.msicomp.MsiInstallUISequenceComponent">
<ROW Action="AI_RESTORE_LOCATION" Condition="APPDIR=&quot;&quot;" Sequence="749"/> <ROW Action="AI_RESTORE_LOCATION" Condition="APPDIR=&quot;&quot;" Sequence="749"/>
@@ -265,7 +307,13 @@
<ROW Registry="Path" Root="-1" Key="Software\[ProductName]" Name="Path" Value="[APPDIR]" Component_="ProductInformation"/> <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"/> <ROW Registry="Version" Root="-1" Key="Software\[ProductName]" Name="Version" Value="[ProductVersion]" Component_="ProductInformation"/>
</COMPONENT> </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"> <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"/> <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>
<COMPONENT cid="caphyon.advinst.msicomp.MsiThemeComponent"> <COMPONENT cid="caphyon.advinst.msicomp.MsiThemeComponent">

View File

@@ -134,7 +134,6 @@ goto :cancel
:install :install
call :uninstall call :uninstall
net start Schedule
schtasks /Create /XML "%wufuc_xml%" /TN "%wufuc_task%" /F 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%" /TR "'%systemroot%\System32\rundll32.exe' """%wufuc_dll_fullpath%""",RUNDLL32_Start"
schtasks /Change /TN "%wufuc_task%" /ENABLE schtasks /Change /TN "%wufuc_task%" /ENABLE
@@ -166,8 +165,8 @@ goto :confirm_restart
sfc /SCANFILE="%systemfolder%\wuaueng.dll" sfc /SCANFILE="%systemfolder%\wuaueng.dll"
:: remove traces of wufuc 0.6-0.7, 0.9.999+ :: remove traces of wufuc 0.6-0.7, 0.9.999+
schtasks /Query /TN "%wufuc_task%" >nul 2>&1 && ( net start Schedule
schtasks /Delete /TN "%wufuc_task%" /F ) schtasks /Delete /TN "%wufuc_task%" /F
rundll32 "%wufuc_dll_fullpath%",RUNDLL32_Unload rundll32 "%wufuc_dll_fullpath%",RUNDLL32_Unload
:: remove traces of wufuc 0.8.x :: remove traces of wufuc 0.8.x