Test
This commit is contained in:
parent
cacf40b6cd
commit
ad8366918e
|
@ -0,0 +1,10 @@
|
|||
# http://editorconfig.org
|
||||
root = true
|
||||
|
||||
[*]
|
||||
indent_style = tab
|
||||
tab_width = 2
|
||||
end_of_line = lf
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
|
@ -0,0 +1,3 @@
|
|||
* text=auto eol=lf
|
||||
*.sln eol=crlf
|
||||
*.vcxproj eol=crlf
|
|
@ -0,0 +1,122 @@
|
|||
## Ignore Visual Studio temporary files, build results, and
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
##
|
||||
## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore
|
||||
|
||||
# User-specific files
|
||||
*.rsuser
|
||||
*.suo
|
||||
*.user
|
||||
*.userosscache
|
||||
*.sln.docstates
|
||||
*.userprefs
|
||||
|
||||
# Build results
|
||||
Debug/
|
||||
Debug-VC08/
|
||||
Debug-VC17/
|
||||
Release/
|
||||
*.exe
|
||||
*.dll
|
||||
!setup/modern_aerowizard.exe
|
||||
!setup/x86-unicode/*.dll
|
||||
setup/x86-unicode/LegacyUpdateNSIS.dll
|
||||
obj/
|
||||
*_layout.inf
|
||||
|
||||
# Visual Studio 2015/2017 cache/options directory
|
||||
.vs/
|
||||
|
||||
# Visual Studio 2017 auto generated files
|
||||
Generated\ Files/
|
||||
|
||||
# Files built by Visual Studio
|
||||
*_i.c
|
||||
*_p.c
|
||||
*_i.h
|
||||
*idl.h
|
||||
*.i
|
||||
*.ilk
|
||||
*.meta
|
||||
*.obj
|
||||
*.iobj
|
||||
*.pch
|
||||
*.pdb
|
||||
*.ipdb
|
||||
*.pgc
|
||||
*.pgd
|
||||
*.rsp
|
||||
*.sbr
|
||||
*.tlb
|
||||
*.tli
|
||||
*.tlh
|
||||
*.tmp
|
||||
*.tmp_proj
|
||||
*_wpftmp.csproj
|
||||
*.log
|
||||
*.tlog
|
||||
*.vspscc
|
||||
*.vssscc
|
||||
.builds
|
||||
*.pidb
|
||||
*.svclog
|
||||
*.scc
|
||||
|
||||
# Visual C++ cache files
|
||||
ipch/
|
||||
*.aps
|
||||
*.ncb
|
||||
*.opendb
|
||||
*.opensdf
|
||||
*.sdf
|
||||
*.cachefile
|
||||
*.VC.db
|
||||
*.VC.VC.opendb
|
||||
|
||||
# NuGet Packages
|
||||
*.nupkg
|
||||
# NuGet Symbol Packages
|
||||
*.snupkg
|
||||
# The packages folder can be ignored because of Package Restore
|
||||
**/[Pp]ackages/*
|
||||
# except build/, which is used as an MSBuild target.
|
||||
!**/[Pp]ackages/build/
|
||||
# Uncomment if necessary however generally it will be regenerated when needed
|
||||
#!**/[Pp]ackages/repositories.config
|
||||
# NuGet v3's project.json files produces more ignorable files
|
||||
*.nuget.props
|
||||
*.nuget.targets
|
||||
|
||||
# Visual Studio cache files
|
||||
# files ending in .cache can be ignored
|
||||
*.[Cc]ache
|
||||
# but keep track of directories ending in .cache
|
||||
!?*.[Cc]ache/
|
||||
|
||||
# Others
|
||||
ClientBin/
|
||||
~$*
|
||||
*~
|
||||
*.dbmdl
|
||||
*.dbproj.schemaview
|
||||
*.jfm
|
||||
*.pfx
|
||||
*.publishsettings
|
||||
orleans.codegen.cs
|
||||
|
||||
# Backup & report files from converting an old project file
|
||||
# to a newer Visual Studio version. Backup files are not needed,
|
||||
# because we have git ;-)
|
||||
_UpgradeReport_Files/
|
||||
Backup*/
|
||||
UpgradeLog*.XML
|
||||
UpgradeLog*.htm
|
||||
ServiceFabricBackup/
|
||||
*.rptproj.bak
|
||||
|
||||
# Windows Installer files from build outputs
|
||||
*.cab
|
||||
*.msi
|
||||
*.msix
|
||||
*.msm
|
||||
*.msp
|
|
@ -0,0 +1,13 @@
|
|||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# Rider ignored files
|
||||
/.idea.LegacyUpdate.iml
|
||||
/modules.xml
|
||||
/contentModel.xml
|
||||
/projectSettingsUpdater.xml
|
||||
# Editor-based HTTP Client requests
|
||||
/httpRequests/
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="DiscordProjectSettings">
|
||||
<option name="show" value="PROJECT" />
|
||||
<option name="description" value="" />
|
||||
</component>
|
||||
</project>
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="32" height="32" fill="none"><image xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAnYSURBVHgBlVdpbFzVFf7u22cfL7HHjkkcQpzYhCw1JBC3bGFLQA1QEK2gLCq/oD+qFlUtQkUt+dNWVZHKnwJCatUWaBGpWhFUmoaWCkJShyROYiBx4gTHdsbL7Ntbb899b8axnQbRJx+/O/Pm3vPd73zn3PMYPv+SOjo6jO7tqzv7H93yoB4zBtSQ1ispUlc6uwY7OtahS+0s9oStidcOTB784a5T+6Z/dcfueDyeKxQKZZpvkfHPc8Au5bi7u1vrevbZWweuPf8DWZO3NB5M5jtxMr0aUaOIzsQE3jq6Aw+sVPHUOg33vWlhbLKc5vn8geqBV57P7915pL+/vzA4OOgwxvgXAnD//ffLe4z+pR23bv3RLf2D3xKOGtdsuQWHPrsGpVocd2/4IyxXJ9N8ELIVp/1KKBZpSZOBlWpp8/QHL5feuOcV0zTP0/QambfYn7zY+XurHu+V+7+6a0vPx7enkhML+AurFaxoOYkQ3ePaLCTmYCTdg0Q4B5MzZMpxcHLBhElaVIlffr3Sva3bPvabIc/zKrSEjUUhkeaP96x6pBerNu9e0Tx75UD7aSQIn9YgiXOMj2zCuRNXI6WfgV2zYVctxNXzKJRDSMXPQVVrYDIPtiVxGjNoHet3JB7a/zx9s6q5uTm6yOccA8JLLPHYC28viZhXPNn7b0QVJ/BLjxxy7pFxz0KNKHZqFSRUF6ViKw6dXYnR6ctxvriU+FXBOK3v1sn2aFmXwmG0dOvLt3WWDr900HXdYp2JCwD6+vo09swHz7FwYsfdy45hc9OU/1Cs4RIEm3g1bQEoA1X6DKpbwgO9j6NVvRq7BkuwXfIoyUQ7LUcAmCeM+QAYFyCIFaO9x3H5uDxz4JTjOKVGKAQdbHL7T9awZOq74ov+SAUGfU17gUqTBaNwPLiWC6toopIpY/vKO2HI7VjZEsETm9vhFmeBagHcrlGknEAEUmN1cScgZJF1T3yHJ9f2JZPJ2HwNaMoVA0+jDmm8ZsCp68Sju+N6sEwbZqmGaq6MaztvwNLkdeQoCOUdVy7FIxvb4JYy8KpFcCcAwQV/lHlcZB+rA9GircamHz+Wy+WW0CdFzFeS9+5MSUp4e0MII6UmdCVCCOkFVD0Xe06ux7GxJGza5bYVKWztW4ayiQXXowM9KBFDb36cAY/QunI9FHUaLoBgUNquuZNGL5KJOBckdfVtNzNXifkxo2vCMrA3vRwFz0beNPHR2RQKGRspRceTN/WhZhsLnDdy6ts39WJdCzkrZYmJMjFhkWhdiPpDRahuQnVaOLzx+9fTKCkgSXL8sm1w6IkTrDY424lZW8KMVcPwVIxUX0GXnsPPv9ZLsbL8ChjSynMA5leynTs2ok2ugldz4CalPW1CgOAigzifmyF33DCgqqoAoEiM61cxm5YhYy5R5nk4PtWB0wVRA05jS/sQXnxwNVKJMCxHQ77SRBlhIB7KIRnOEqgL8YjqKn75wJcQsgrEQh6eSWBc2hn3FnAmhTqX27bdRB9UiXn6UkYM+GYRXTZHrqziT/u34cPja/HULQPobDKgU5Fp7NzjMgrVJHIExnL0BSERQJ+750qgkvdZ4I7pg2B1BsSNGckWWZYTQpYSc9WYv3uq48xiNIlAmESbZeKuvhuRCF1BtT9GmeRCZt5F8WfsovKODcub8cTNy4lVcu7YPqsiBJ7HAy2qiSQVpFA0GlUUbgciCXYGXzScBo+sb8d969v8702HUtNTEKP460qV6oqMsFaBLLn+go4XFNRSNUZOgvG9m5aibOn43T4SoyiNVJxETri+D9+fUiqVJMWtViYVFu4Q4pAoEzxKobiq0QQFv90/SWAEhaZfZHraw9i6oYuKkAlVnqumNPZwaGQI49kpcDkM022iY3k1OdJJFzKKNeZT74uRNuc5FZNCwIkFrni16oSrGB2SyFtFlFAFZUfF7w/WiBESEVVNz6ICU83itjXNGOhb5e9+8XV87DiOpIdhUA3RojreOpiC41CYuUqOme+Yi+3Tn1fL5sh5lRoXR/KqhWGPiogwTpuSHIWyQRTjMCQpAUltJWuBpCQpaUmMColRL18EQDFUGMkQwk1hhJJh3HvfX3DN5kEsWzFOTmVyDt984ZTPTdL/oqZptuSeP/R3bnuUsoG5AoRLILwQnagRAhKlWMeJzog4HaCRRsQ5sbiTkRQZCqWhGtGhRTSE4xxrN3yMrXf8DR2dE/7JJhgQYbAn9x6lOpCdmZmxpdzub7znmXbRswgAGbfEwUNxskRtEGxQR0AhkcSdgLnEkOBHWwRCHDayKkGmMEqkI0mEUw4OoenJFoq754fBF/XIG4epDmRpaAth5p3ZT1/1AVD6iVPPNQMgghm/rRQ/81mRUbE0OLZGACQ6TdgCAEwKjj82D9m+d7fArKhB/MVSU/uPsMrZERrmRFKIGeXKf3a+xE2r3ADBbddnQwDxWRGCdyT/gBFUpksRAqH6IOR5IZDJxK4bVzEfw9CBtbR7jkZLah3auVuSpDHh158nlrbHdo+6M4dfFih9HfiORTGqA7FFEVEpK3S/lNlUNc/lYhQOclpngTpn3wQTDQo+PdrjUy8KjPBvj+56z536cJDoFyK0fObEP9ERDQ8Pr0h8/cTrktG6HnVokizi6BNHZNUQUasIy9T3OVUIWh7/8jFIS2aRNjzYGoE0OLSQhmymDe/vuQ7jo6mgSSUv3KIu4A+XP0PKf3fZsmWnRkZG/EPEX356elokiEkCGJFTA7cwSY0KyEHueoGCKZfFzsumRGe/irKt48Y1aegtJczqNjyd+VkgBLjnzzeT845AG4HzfOkfD73glcf+Rfl/OpPJzBWS+W25684cnJadwlG5/Ss3MUmJzj0RfZ0ffzrv/UaGQkFV7s6NUwinTGR1D0xTqA+RcOLoGhyhuDeUwM1cvvLPh1+wz7//Dn38REgD894P5gPww2RPf5R20vveV5p6l0jhjlUX+ikRWwLBFH8aYypu3zgBvbWEDJXiQjGGV37xMEZPdM85d8bfGazs/eaveX74XXov+KSh/Hk+F76Y1EFYRNWsN/rqQWf68BBruapLMlpSwUMWZD/xGjUcfO+uY6jQKTky1oa3/no9KqWwv4hXOHW2euinr1cOPP2aZ+U+JOci7fKLnYtLwcWX+FGRlHoSY29nzLG3j+iXbVsvX3b7JrVtcz+0ZCvTE00rUiVDVESjxs1P9rdX00Mnzrj50XFz6GcfOMWzJ2mNs2QT9I45c+bMGROXeEm91MvpfIZEEyja6KSiKM1USkUjESMxqbIIOm2YxiKlSvQ8Tz1/NhKJZMrlsoj1/3wf/H8ANK5Gl19XIAIhBPN5LBZzybmTzWb9uomARf5FFv4vtN/QnyTNBIYAAAAASUVORK5CYII=" width="32" height="32"/></svg>
|
After Width: | Height: | Size: 3.6 KiB |
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="UserContentModel">
|
||||
<attachedFolders>
|
||||
<Path>.</Path>
|
||||
</attachedFolders>
|
||||
<explicitIncludes />
|
||||
<explicitExcludes />
|
||||
</component>
|
||||
</project>
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
|
@ -0,0 +1,37 @@
|
|||
{
|
||||
"configurations": [
|
||||
{
|
||||
"name": "MinGW",
|
||||
"includePath": [
|
||||
"${workspaceFolder}/include",
|
||||
"${workspaceFolder}/shared"
|
||||
],
|
||||
"compilerPath": "/usr/bin/i686-w64-mingw32-g++",
|
||||
"cStandard": "c17",
|
||||
"cppStandard": "c++11",
|
||||
"intelliSenseMode": "windows-gcc-x86",
|
||||
"compilerArgs": [
|
||||
"-std=c++11",
|
||||
"-mwindows",
|
||||
"-municode",
|
||||
"-s",
|
||||
"-fPIE",
|
||||
"-ffunction-sections",
|
||||
"-fdata-sections",
|
||||
"-fno-unwind-tables",
|
||||
"-fno-asynchronous-unwind-tables",
|
||||
"-fno-exceptions",
|
||||
"-fno-rtti",
|
||||
"-flto",
|
||||
"-Wno-write-strings",
|
||||
"-include stdafx.h"
|
||||
],
|
||||
"defines": [
|
||||
"UNICODE",
|
||||
"_UNICODE",
|
||||
"_USRDLL"
|
||||
]
|
||||
}
|
||||
],
|
||||
"version": 4
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"files.associations": {
|
||||
"*.rc": "cpp",
|
||||
"*.idl": "cpp"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"version": "1.0",
|
||||
"components": [
|
||||
"Microsoft.VisualStudio.Component.VC.v141.x86.x64",
|
||||
"Microsoft.VisualStudio.Component.WinXP",
|
||||
"Microsoft.VisualStudio.Component.VC.v141.ATL"
|
||||
]
|
||||
}
|
|
@ -0,0 +1,650 @@
|
|||
#pragma once
|
||||
#include <wuapi.h>
|
||||
|
||||
// Copied from wuapi.h in Windows SDK 10.0.19041.0
|
||||
|
||||
#ifndef __IUpdateInstaller3_FWD_DEFINED__
|
||||
#define __IUpdateInstaller3_FWD_DEFINED__
|
||||
typedef interface IUpdateInstaller3 IUpdateInstaller3;
|
||||
|
||||
#endif /* __IUpdateInstaller3_FWD_DEFINED__ */
|
||||
|
||||
#ifndef __IUpdateInstaller4_FWD_DEFINED__
|
||||
#define __IUpdateInstaller4_FWD_DEFINED__
|
||||
typedef interface IUpdateInstaller4 IUpdateInstaller4;
|
||||
|
||||
#endif /* __IUpdateInstaller4_FWD_DEFINED__ */
|
||||
|
||||
// {16d11c35-099a-48d0-8338-5fae64047f8e}
|
||||
DEFINE_GUID(IID_IUpdateInstaller3,0x16d11c35,0x099a,0x48d0,0x83,0x38,0x5f,0xae,0x64,0x04,0x7f,0x8e);
|
||||
|
||||
// {EF8208EA-2304-492D-9109-23813B0958E1}
|
||||
DEFINE_GUID(IID_IUpdateInstaller4, 0xef8208ea, 0x2304, 0x492d, 0x91, 0x9, 0x23, 0x81, 0x3b, 0x9, 0x58, 0xe1);
|
||||
|
||||
#ifndef __IUpdateInstaller3_INTERFACE_DEFINED__
|
||||
#define __IUpdateInstaller3_INTERFACE_DEFINED__
|
||||
|
||||
/* interface IUpdateInstaller3 */
|
||||
/* [hidden][unique][uuid][nonextensible][dual][oleautomation][object][helpstring] */
|
||||
|
||||
|
||||
EXTERN_C const IID IID_IUpdateInstaller3;
|
||||
|
||||
#if defined(__cplusplus) && !defined(CINTERFACE)
|
||||
|
||||
MIDL_INTERFACE("16d11c35-099a-48d0-8338-5fae64047f8e")
|
||||
IUpdateInstaller3 : public IUpdateInstaller2
|
||||
{
|
||||
public:
|
||||
virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_AttemptCloseAppsIfNecessary(
|
||||
/* [retval][out] */ __RPC__out VARIANT_BOOL *retval) = 0;
|
||||
|
||||
virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_AttemptCloseAppsIfNecessary(
|
||||
/* [in] */ VARIANT_BOOL value) = 0;
|
||||
|
||||
};
|
||||
|
||||
|
||||
#else /* C style interface */
|
||||
|
||||
typedef struct IUpdateInstaller3Vtbl
|
||||
{
|
||||
BEGIN_INTERFACE
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
|
||||
__RPC__in IUpdateInstaller3 * This,
|
||||
/* [in] */ __RPC__in REFIID riid,
|
||||
/* [annotation][iid_is][out] */
|
||||
_COM_Outptr_ void **ppvObject);
|
||||
|
||||
ULONG ( STDMETHODCALLTYPE *AddRef )(
|
||||
__RPC__in IUpdateInstaller3 * This);
|
||||
|
||||
ULONG ( STDMETHODCALLTYPE *Release )(
|
||||
__RPC__in IUpdateInstaller3 * This);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *GetTypeInfoCount )(
|
||||
__RPC__in IUpdateInstaller3 * This,
|
||||
/* [out] */ __RPC__out UINT *pctinfo);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *GetTypeInfo )(
|
||||
__RPC__in IUpdateInstaller3 * This,
|
||||
/* [in] */ UINT iTInfo,
|
||||
/* [in] */ LCID lcid,
|
||||
/* [out] */ __RPC__deref_out_opt ITypeInfo **ppTInfo);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *GetIDsOfNames )(
|
||||
__RPC__in IUpdateInstaller3 * This,
|
||||
/* [in] */ __RPC__in REFIID riid,
|
||||
/* [size_is][in] */ __RPC__in_ecount_full(cNames) LPOLESTR *rgszNames,
|
||||
/* [range][in] */ __RPC__in_range(0,16384) UINT cNames,
|
||||
/* [in] */ LCID lcid,
|
||||
/* [size_is][out] */ __RPC__out_ecount_full(cNames) DISPID *rgDispId);
|
||||
|
||||
/* [local] */ HRESULT ( STDMETHODCALLTYPE *Invoke )(
|
||||
IUpdateInstaller3 * This,
|
||||
/* [annotation][in] */
|
||||
_In_ DISPID dispIdMember,
|
||||
/* [annotation][in] */
|
||||
_In_ REFIID riid,
|
||||
/* [annotation][in] */
|
||||
_In_ LCID lcid,
|
||||
/* [annotation][in] */
|
||||
_In_ WORD wFlags,
|
||||
/* [annotation][out][in] */
|
||||
_In_ DISPPARAMS *pDispParams,
|
||||
/* [annotation][out] */
|
||||
_Out_opt_ VARIANT *pVarResult,
|
||||
/* [annotation][out] */
|
||||
_Out_opt_ EXCEPINFO *pExcepInfo,
|
||||
/* [annotation][out] */
|
||||
_Out_opt_ UINT *puArgErr);
|
||||
|
||||
/* [helpstring][propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_ClientApplicationID )(
|
||||
__RPC__in IUpdateInstaller3 * This,
|
||||
/* [retval][out] */ __RPC__deref_out_opt BSTR *retval);
|
||||
|
||||
/* [helpstring][propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_ClientApplicationID )(
|
||||
__RPC__in IUpdateInstaller3 * This,
|
||||
/* [in] */ __RPC__in BSTR value);
|
||||
|
||||
/* [helpstring][propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_IsForced )(
|
||||
__RPC__in IUpdateInstaller3 * This,
|
||||
/* [retval][out] */ __RPC__out VARIANT_BOOL *retval);
|
||||
|
||||
/* [helpstring][propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_IsForced )(
|
||||
__RPC__in IUpdateInstaller3 * This,
|
||||
/* [in] */ VARIANT_BOOL value);
|
||||
|
||||
/* [helpstring][restricted][propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_ParentHwnd )(
|
||||
__RPC__in IUpdateInstaller3 * This,
|
||||
/* [retval][out] */ __RPC__deref_out_opt HWND *retval);
|
||||
|
||||
/* [helpstring][restricted][propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_ParentHwnd )(
|
||||
__RPC__in IUpdateInstaller3 * This,
|
||||
/* [unique][in] */ __RPC__in_opt HWND value);
|
||||
|
||||
/* [helpstring][propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_ParentWindow )(
|
||||
__RPC__in IUpdateInstaller3 * This,
|
||||
/* [unique][in] */ __RPC__in_opt IUnknown *value);
|
||||
|
||||
/* [helpstring][propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_ParentWindow )(
|
||||
__RPC__in IUpdateInstaller3 * This,
|
||||
/* [retval][out] */ __RPC__deref_out_opt IUnknown **retval);
|
||||
|
||||
/* [helpstring][propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_Updates )(
|
||||
__RPC__in IUpdateInstaller3 * This,
|
||||
/* [retval][out] */ __RPC__deref_out_opt IUpdateCollection **retval);
|
||||
|
||||
/* [helpstring][propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_Updates )(
|
||||
__RPC__in IUpdateInstaller3 * This,
|
||||
/* [in] */ __RPC__in_opt IUpdateCollection *value);
|
||||
|
||||
/* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *BeginInstall )(
|
||||
__RPC__in IUpdateInstaller3 * This,
|
||||
/* [in] */ __RPC__in_opt IUnknown *onProgressChanged,
|
||||
/* [in] */ __RPC__in_opt IUnknown *onCompleted,
|
||||
/* [in] */ VARIANT state,
|
||||
/* [retval][out] */ __RPC__deref_out_opt IInstallationJob **retval);
|
||||
|
||||
/* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *BeginUninstall )(
|
||||
__RPC__in IUpdateInstaller3 * This,
|
||||
/* [in] */ __RPC__in_opt IUnknown *onProgressChanged,
|
||||
/* [in] */ __RPC__in_opt IUnknown *onCompleted,
|
||||
/* [in] */ VARIANT state,
|
||||
/* [retval][out] */ __RPC__deref_out_opt IInstallationJob **retval);
|
||||
|
||||
/* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *EndInstall )(
|
||||
__RPC__in IUpdateInstaller3 * This,
|
||||
/* [in] */ __RPC__in_opt IInstallationJob *value,
|
||||
/* [retval][out] */ __RPC__deref_out_opt IInstallationResult **retval);
|
||||
|
||||
/* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *EndUninstall )(
|
||||
__RPC__in IUpdateInstaller3 * This,
|
||||
/* [in] */ __RPC__in_opt IInstallationJob *value,
|
||||
/* [retval][out] */ __RPC__deref_out_opt IInstallationResult **retval);
|
||||
|
||||
/* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *Install )(
|
||||
__RPC__in IUpdateInstaller3 * This,
|
||||
/* [retval][out] */ __RPC__deref_out_opt IInstallationResult **retval);
|
||||
|
||||
/* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *RunWizard )(
|
||||
__RPC__in IUpdateInstaller3 * This,
|
||||
/* [defaultvalue][unique][in] */ __RPC__in_opt BSTR dialogTitle,
|
||||
/* [retval][out] */ __RPC__deref_out_opt IInstallationResult **retval);
|
||||
|
||||
/* [helpstring][propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_IsBusy )(
|
||||
__RPC__in IUpdateInstaller3 * This,
|
||||
/* [retval][out] */ __RPC__out VARIANT_BOOL *retval);
|
||||
|
||||
/* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *Uninstall )(
|
||||
__RPC__in IUpdateInstaller3 * This,
|
||||
/* [retval][out] */ __RPC__deref_out_opt IInstallationResult **retval);
|
||||
|
||||
/* [helpstring][propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_AllowSourcePrompts )(
|
||||
__RPC__in IUpdateInstaller3 * This,
|
||||
/* [retval][out] */ __RPC__out VARIANT_BOOL *retval);
|
||||
|
||||
/* [helpstring][propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_AllowSourcePrompts )(
|
||||
__RPC__in IUpdateInstaller3 * This,
|
||||
/* [in] */ VARIANT_BOOL value);
|
||||
|
||||
/* [helpstring][propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_RebootRequiredBeforeInstallation )(
|
||||
__RPC__in IUpdateInstaller3 * This,
|
||||
/* [retval][out] */ __RPC__out VARIANT_BOOL *retval);
|
||||
|
||||
/* [helpstring][propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_ForceQuiet )(
|
||||
__RPC__in IUpdateInstaller3 * This,
|
||||
/* [retval][out] */ __RPC__out VARIANT_BOOL *retval);
|
||||
|
||||
/* [helpstring][propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_ForceQuiet )(
|
||||
__RPC__in IUpdateInstaller3 * This,
|
||||
/* [in] */ VARIANT_BOOL value);
|
||||
|
||||
/* [helpstring][propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_AttemptCloseAppsIfNecessary )(
|
||||
__RPC__in IUpdateInstaller3 * This,
|
||||
/* [retval][out] */ __RPC__out VARIANT_BOOL *retval);
|
||||
|
||||
/* [helpstring][propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_AttemptCloseAppsIfNecessary )(
|
||||
__RPC__in IUpdateInstaller3 * This,
|
||||
/* [in] */ VARIANT_BOOL value);
|
||||
|
||||
END_INTERFACE
|
||||
} IUpdateInstaller3Vtbl;
|
||||
|
||||
interface IUpdateInstaller3
|
||||
{
|
||||
CONST_VTBL struct IUpdateInstaller3Vtbl *lpVtbl;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#ifdef COBJMACROS
|
||||
|
||||
|
||||
#define IUpdateInstaller3_QueryInterface(This,riid,ppvObject) \
|
||||
( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
|
||||
|
||||
#define IUpdateInstaller3_AddRef(This) \
|
||||
( (This)->lpVtbl -> AddRef(This) )
|
||||
|
||||
#define IUpdateInstaller3_Release(This) \
|
||||
( (This)->lpVtbl -> Release(This) )
|
||||
|
||||
|
||||
#define IUpdateInstaller3_GetTypeInfoCount(This,pctinfo) \
|
||||
( (This)->lpVtbl -> GetTypeInfoCount(This,pctinfo) )
|
||||
|
||||
#define IUpdateInstaller3_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \
|
||||
( (This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo) )
|
||||
|
||||
#define IUpdateInstaller3_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) \
|
||||
( (This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) )
|
||||
|
||||
#define IUpdateInstaller3_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \
|
||||
( (This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) )
|
||||
|
||||
|
||||
#define IUpdateInstaller3_get_ClientApplicationID(This,retval) \
|
||||
( (This)->lpVtbl -> get_ClientApplicationID(This,retval) )
|
||||
|
||||
#define IUpdateInstaller3_put_ClientApplicationID(This,value) \
|
||||
( (This)->lpVtbl -> put_ClientApplicationID(This,value) )
|
||||
|
||||
#define IUpdateInstaller3_get_IsForced(This,retval) \
|
||||
( (This)->lpVtbl -> get_IsForced(This,retval) )
|
||||
|
||||
#define IUpdateInstaller3_put_IsForced(This,value) \
|
||||
( (This)->lpVtbl -> put_IsForced(This,value) )
|
||||
|
||||
#define IUpdateInstaller3_get_ParentHwnd(This,retval) \
|
||||
( (This)->lpVtbl -> get_ParentHwnd(This,retval) )
|
||||
|
||||
#define IUpdateInstaller3_put_ParentHwnd(This,value) \
|
||||
( (This)->lpVtbl -> put_ParentHwnd(This,value) )
|
||||
|
||||
#define IUpdateInstaller3_put_ParentWindow(This,value) \
|
||||
( (This)->lpVtbl -> put_ParentWindow(This,value) )
|
||||
|
||||
#define IUpdateInstaller3_get_ParentWindow(This,retval) \
|
||||
( (This)->lpVtbl -> get_ParentWindow(This,retval) )
|
||||
|
||||
#define IUpdateInstaller3_get_Updates(This,retval) \
|
||||
( (This)->lpVtbl -> get_Updates(This,retval) )
|
||||
|
||||
#define IUpdateInstaller3_put_Updates(This,value) \
|
||||
( (This)->lpVtbl -> put_Updates(This,value) )
|
||||
|
||||
#define IUpdateInstaller3_BeginInstall(This,onProgressChanged,onCompleted,state,retval) \
|
||||
( (This)->lpVtbl -> BeginInstall(This,onProgressChanged,onCompleted,state,retval) )
|
||||
|
||||
#define IUpdateInstaller3_BeginUninstall(This,onProgressChanged,onCompleted,state,retval) \
|
||||
( (This)->lpVtbl -> BeginUninstall(This,onProgressChanged,onCompleted,state,retval) )
|
||||
|
||||
#define IUpdateInstaller3_EndInstall(This,value,retval) \
|
||||
( (This)->lpVtbl -> EndInstall(This,value,retval) )
|
||||
|
||||
#define IUpdateInstaller3_EndUninstall(This,value,retval) \
|
||||
( (This)->lpVtbl -> EndUninstall(This,value,retval) )
|
||||
|
||||
#define IUpdateInstaller3_Install(This,retval) \
|
||||
( (This)->lpVtbl -> Install(This,retval) )
|
||||
|
||||
#define IUpdateInstaller3_RunWizard(This,dialogTitle,retval) \
|
||||
( (This)->lpVtbl -> RunWizard(This,dialogTitle,retval) )
|
||||
|
||||
#define IUpdateInstaller3_get_IsBusy(This,retval) \
|
||||
( (This)->lpVtbl -> get_IsBusy(This,retval) )
|
||||
|
||||
#define IUpdateInstaller3_Uninstall(This,retval) \
|
||||
( (This)->lpVtbl -> Uninstall(This,retval) )
|
||||
|
||||
#define IUpdateInstaller3_get_AllowSourcePrompts(This,retval) \
|
||||
( (This)->lpVtbl -> get_AllowSourcePrompts(This,retval) )
|
||||
|
||||
#define IUpdateInstaller3_put_AllowSourcePrompts(This,value) \
|
||||
( (This)->lpVtbl -> put_AllowSourcePrompts(This,value) )
|
||||
|
||||
#define IUpdateInstaller3_get_RebootRequiredBeforeInstallation(This,retval) \
|
||||
( (This)->lpVtbl -> get_RebootRequiredBeforeInstallation(This,retval) )
|
||||
|
||||
|
||||
#define IUpdateInstaller3_get_ForceQuiet(This,retval) \
|
||||
( (This)->lpVtbl -> get_ForceQuiet(This,retval) )
|
||||
|
||||
#define IUpdateInstaller3_put_ForceQuiet(This,value) \
|
||||
( (This)->lpVtbl -> put_ForceQuiet(This,value) )
|
||||
|
||||
|
||||
#define IUpdateInstaller3_get_AttemptCloseAppsIfNecessary(This,retval) \
|
||||
( (This)->lpVtbl -> get_AttemptCloseAppsIfNecessary(This,retval) )
|
||||
|
||||
#define IUpdateInstaller3_put_AttemptCloseAppsIfNecessary(This,value) \
|
||||
( (This)->lpVtbl -> put_AttemptCloseAppsIfNecessary(This,value) )
|
||||
|
||||
#endif /* COBJMACROS */
|
||||
|
||||
|
||||
#endif /* C style interface */
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* __IUpdateInstaller3_INTERFACE_DEFINED__ */
|
||||
|
||||
|
||||
#ifndef __IUpdateInstaller4_INTERFACE_DEFINED__
|
||||
#define __IUpdateInstaller4_INTERFACE_DEFINED__
|
||||
|
||||
/* interface IUpdateInstaller4 */
|
||||
/* [hidden][unique][uuid][nonextensible][dual][oleautomation][object][helpstring] */
|
||||
|
||||
|
||||
EXTERN_C const IID IID_IUpdateInstaller4;
|
||||
|
||||
#if defined(__cplusplus) && !defined(CINTERFACE)
|
||||
|
||||
MIDL_INTERFACE("EF8208EA-2304-492D-9109-23813B0958E1")
|
||||
IUpdateInstaller4 : public IUpdateInstaller3
|
||||
{
|
||||
public:
|
||||
virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE Commit(
|
||||
/* [in] */ DWORD dwFlags) = 0;
|
||||
|
||||
};
|
||||
|
||||
|
||||
#else /* C style interface */
|
||||
|
||||
typedef struct IUpdateInstaller4Vtbl
|
||||
{
|
||||
BEGIN_INTERFACE
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
|
||||
__RPC__in IUpdateInstaller4 * This,
|
||||
/* [in] */ __RPC__in REFIID riid,
|
||||
/* [annotation][iid_is][out] */
|
||||
_COM_Outptr_ void **ppvObject);
|
||||
|
||||
ULONG ( STDMETHODCALLTYPE *AddRef )(
|
||||
__RPC__in IUpdateInstaller4 * This);
|
||||
|
||||
ULONG ( STDMETHODCALLTYPE *Release )(
|
||||
__RPC__in IUpdateInstaller4 * This);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *GetTypeInfoCount )(
|
||||
__RPC__in IUpdateInstaller4 * This,
|
||||
/* [out] */ __RPC__out UINT *pctinfo);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *GetTypeInfo )(
|
||||
__RPC__in IUpdateInstaller4 * This,
|
||||
/* [in] */ UINT iTInfo,
|
||||
/* [in] */ LCID lcid,
|
||||
/* [out] */ __RPC__deref_out_opt ITypeInfo **ppTInfo);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *GetIDsOfNames )(
|
||||
__RPC__in IUpdateInstaller4 * This,
|
||||
/* [in] */ __RPC__in REFIID riid,
|
||||
/* [size_is][in] */ __RPC__in_ecount_full(cNames) LPOLESTR *rgszNames,
|
||||
/* [range][in] */ __RPC__in_range(0,16384) UINT cNames,
|
||||
/* [in] */ LCID lcid,
|
||||
/* [size_is][out] */ __RPC__out_ecount_full(cNames) DISPID *rgDispId);
|
||||
|
||||
/* [local] */ HRESULT ( STDMETHODCALLTYPE *Invoke )(
|
||||
IUpdateInstaller4 * This,
|
||||
/* [annotation][in] */
|
||||
_In_ DISPID dispIdMember,
|
||||
/* [annotation][in] */
|
||||
_In_ REFIID riid,
|
||||
/* [annotation][in] */
|
||||
_In_ LCID lcid,
|
||||
/* [annotation][in] */
|
||||
_In_ WORD wFlags,
|
||||
/* [annotation][out][in] */
|
||||
_In_ DISPPARAMS *pDispParams,
|
||||
/* [annotation][out] */
|
||||
_Out_opt_ VARIANT *pVarResult,
|
||||
/* [annotation][out] */
|
||||
_Out_opt_ EXCEPINFO *pExcepInfo,
|
||||
/* [annotation][out] */
|
||||
_Out_opt_ UINT *puArgErr);
|
||||
|
||||
/* [helpstring][propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_ClientApplicationID )(
|
||||
__RPC__in IUpdateInstaller4 * This,
|
||||
/* [retval][out] */ __RPC__deref_out_opt BSTR *retval);
|
||||
|
||||
/* [helpstring][propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_ClientApplicationID )(
|
||||
__RPC__in IUpdateInstaller4 * This,
|
||||
/* [in] */ __RPC__in BSTR value);
|
||||
|
||||
/* [helpstring][propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_IsForced )(
|
||||
__RPC__in IUpdateInstaller4 * This,
|
||||
/* [retval][out] */ __RPC__out VARIANT_BOOL *retval);
|
||||
|
||||
/* [helpstring][propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_IsForced )(
|
||||
__RPC__in IUpdateInstaller4 * This,
|
||||
/* [in] */ VARIANT_BOOL value);
|
||||
|
||||
/* [helpstring][restricted][propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_ParentHwnd )(
|
||||
__RPC__in IUpdateInstaller4 * This,
|
||||
/* [retval][out] */ __RPC__deref_out_opt HWND *retval);
|
||||
|
||||
/* [helpstring][restricted][propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_ParentHwnd )(
|
||||
__RPC__in IUpdateInstaller4 * This,
|
||||
/* [unique][in] */ __RPC__in_opt HWND value);
|
||||
|
||||
/* [helpstring][propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_ParentWindow )(
|
||||
__RPC__in IUpdateInstaller4 * This,
|
||||
/* [unique][in] */ __RPC__in_opt IUnknown *value);
|
||||
|
||||
/* [helpstring][propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_ParentWindow )(
|
||||
__RPC__in IUpdateInstaller4 * This,
|
||||
/* [retval][out] */ __RPC__deref_out_opt IUnknown **retval);
|
||||
|
||||
/* [helpstring][propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_Updates )(
|
||||
__RPC__in IUpdateInstaller4 * This,
|
||||
/* [retval][out] */ __RPC__deref_out_opt IUpdateCollection **retval);
|
||||
|
||||
/* [helpstring][propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_Updates )(
|
||||
__RPC__in IUpdateInstaller4 * This,
|
||||
/* [in] */ __RPC__in_opt IUpdateCollection *value);
|
||||
|
||||
/* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *BeginInstall )(
|
||||
__RPC__in IUpdateInstaller4 * This,
|
||||
/* [in] */ __RPC__in_opt IUnknown *onProgressChanged,
|
||||
/* [in] */ __RPC__in_opt IUnknown *onCompleted,
|
||||
/* [in] */ VARIANT state,
|
||||
/* [retval][out] */ __RPC__deref_out_opt IInstallationJob **retval);
|
||||
|
||||
/* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *BeginUninstall )(
|
||||
__RPC__in IUpdateInstaller4 * This,
|
||||
/* [in] */ __RPC__in_opt IUnknown *onProgressChanged,
|
||||
/* [in] */ __RPC__in_opt IUnknown *onCompleted,
|
||||
/* [in] */ VARIANT state,
|
||||
/* [retval][out] */ __RPC__deref_out_opt IInstallationJob **retval);
|
||||
|
||||
/* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *EndInstall )(
|
||||
__RPC__in IUpdateInstaller4 * This,
|
||||
/* [in] */ __RPC__in_opt IInstallationJob *value,
|
||||
/* [retval][out] */ __RPC__deref_out_opt IInstallationResult **retval);
|
||||
|
||||
/* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *EndUninstall )(
|
||||
__RPC__in IUpdateInstaller4 * This,
|
||||
/* [in] */ __RPC__in_opt IInstallationJob *value,
|
||||
/* [retval][out] */ __RPC__deref_out_opt IInstallationResult **retval);
|
||||
|
||||
/* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *Install )(
|
||||
__RPC__in IUpdateInstaller4 * This,
|
||||
/* [retval][out] */ __RPC__deref_out_opt IInstallationResult **retval);
|
||||
|
||||
/* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *RunWizard )(
|
||||
__RPC__in IUpdateInstaller4 * This,
|
||||
/* [defaultvalue][unique][in] */ __RPC__in_opt BSTR dialogTitle,
|
||||
/* [retval][out] */ __RPC__deref_out_opt IInstallationResult **retval);
|
||||
|
||||
/* [helpstring][propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_IsBusy )(
|
||||
__RPC__in IUpdateInstaller4 * This,
|
||||
/* [retval][out] */ __RPC__out VARIANT_BOOL *retval);
|
||||
|
||||
/* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *Uninstall )(
|
||||
__RPC__in IUpdateInstaller4 * This,
|
||||
/* [retval][out] */ __RPC__deref_out_opt IInstallationResult **retval);
|
||||
|
||||
/* [helpstring][propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_AllowSourcePrompts )(
|
||||
__RPC__in IUpdateInstaller4 * This,
|
||||
/* [retval][out] */ __RPC__out VARIANT_BOOL *retval);
|
||||
|
||||
/* [helpstring][propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_AllowSourcePrompts )(
|
||||
__RPC__in IUpdateInstaller4 * This,
|
||||
/* [in] */ VARIANT_BOOL value);
|
||||
|
||||
/* [helpstring][propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_RebootRequiredBeforeInstallation )(
|
||||
__RPC__in IUpdateInstaller4 * This,
|
||||
/* [retval][out] */ __RPC__out VARIANT_BOOL *retval);
|
||||
|
||||
/* [helpstring][propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_ForceQuiet )(
|
||||
__RPC__in IUpdateInstaller4 * This,
|
||||
/* [retval][out] */ __RPC__out VARIANT_BOOL *retval);
|
||||
|
||||
/* [helpstring][propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_ForceQuiet )(
|
||||
__RPC__in IUpdateInstaller4 * This,
|
||||
/* [in] */ VARIANT_BOOL value);
|
||||
|
||||
/* [helpstring][propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_AttemptCloseAppsIfNecessary )(
|
||||
__RPC__in IUpdateInstaller4 * This,
|
||||
/* [retval][out] */ __RPC__out VARIANT_BOOL *retval);
|
||||
|
||||
/* [helpstring][propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_AttemptCloseAppsIfNecessary )(
|
||||
__RPC__in IUpdateInstaller4 * This,
|
||||
/* [in] */ VARIANT_BOOL value);
|
||||
|
||||
/* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *Commit )(
|
||||
__RPC__in IUpdateInstaller4 * This,
|
||||
/* [in] */ DWORD dwFlags);
|
||||
|
||||
END_INTERFACE
|
||||
} IUpdateInstaller4Vtbl;
|
||||
|
||||
interface IUpdateInstaller4
|
||||
{
|
||||
CONST_VTBL struct IUpdateInstaller4Vtbl *lpVtbl;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#ifdef COBJMACROS
|
||||
|
||||
|
||||
#define IUpdateInstaller4_QueryInterface(This,riid,ppvObject) \
|
||||
( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
|
||||
|
||||
#define IUpdateInstaller4_AddRef(This) \
|
||||
( (This)->lpVtbl -> AddRef(This) )
|
||||
|
||||
#define IUpdateInstaller4_Release(This) \
|
||||
( (This)->lpVtbl -> Release(This) )
|
||||
|
||||
|
||||
#define IUpdateInstaller4_GetTypeInfoCount(This,pctinfo) \
|
||||
( (This)->lpVtbl -> GetTypeInfoCount(This,pctinfo) )
|
||||
|
||||
#define IUpdateInstaller4_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \
|
||||
( (This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo) )
|
||||
|
||||
#define IUpdateInstaller4_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) \
|
||||
( (This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) )
|
||||
|
||||
#define IUpdateInstaller4_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \
|
||||
( (This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) )
|
||||
|
||||
|
||||
#define IUpdateInstaller4_get_ClientApplicationID(This,retval) \
|
||||
( (This)->lpVtbl -> get_ClientApplicationID(This,retval) )
|
||||
|
||||
#define IUpdateInstaller4_put_ClientApplicationID(This,value) \
|
||||
( (This)->lpVtbl -> put_ClientApplicationID(This,value) )
|
||||
|
||||
#define IUpdateInstaller4_get_IsForced(This,retval) \
|
||||
( (This)->lpVtbl -> get_IsForced(This,retval) )
|
||||
|
||||
#define IUpdateInstaller4_put_IsForced(This,value) \
|
||||
( (This)->lpVtbl -> put_IsForced(This,value) )
|
||||
|
||||
#define IUpdateInstaller4_get_ParentHwnd(This,retval) \
|
||||
( (This)->lpVtbl -> get_ParentHwnd(This,retval) )
|
||||
|
||||
#define IUpdateInstaller4_put_ParentHwnd(This,value) \
|
||||
( (This)->lpVtbl -> put_ParentHwnd(This,value) )
|
||||
|
||||
#define IUpdateInstaller4_put_ParentWindow(This,value) \
|
||||
( (This)->lpVtbl -> put_ParentWindow(This,value) )
|
||||
|
||||
#define IUpdateInstaller4_get_ParentWindow(This,retval) \
|
||||
( (This)->lpVtbl -> get_ParentWindow(This,retval) )
|
||||
|
||||
#define IUpdateInstaller4_get_Updates(This,retval) \
|
||||
( (This)->lpVtbl -> get_Updates(This,retval) )
|
||||
|
||||
#define IUpdateInstaller4_put_Updates(This,value) \
|
||||
( (This)->lpVtbl -> put_Updates(This,value) )
|
||||
|
||||
#define IUpdateInstaller4_BeginInstall(This,onProgressChanged,onCompleted,state,retval) \
|
||||
( (This)->lpVtbl -> BeginInstall(This,onProgressChanged,onCompleted,state,retval) )
|
||||
|
||||
#define IUpdateInstaller4_BeginUninstall(This,onProgressChanged,onCompleted,state,retval) \
|
||||
( (This)->lpVtbl -> BeginUninstall(This,onProgressChanged,onCompleted,state,retval) )
|
||||
|
||||
#define IUpdateInstaller4_EndInstall(This,value,retval) \
|
||||
( (This)->lpVtbl -> EndInstall(This,value,retval) )
|
||||
|
||||
#define IUpdateInstaller4_EndUninstall(This,value,retval) \
|
||||
( (This)->lpVtbl -> EndUninstall(This,value,retval) )
|
||||
|
||||
#define IUpdateInstaller4_Install(This,retval) \
|
||||
( (This)->lpVtbl -> Install(This,retval) )
|
||||
|
||||
#define IUpdateInstaller4_RunWizard(This,dialogTitle,retval) \
|
||||
( (This)->lpVtbl -> RunWizard(This,dialogTitle,retval) )
|
||||
|
||||
#define IUpdateInstaller4_get_IsBusy(This,retval) \
|
||||
( (This)->lpVtbl -> get_IsBusy(This,retval) )
|
||||
|
||||
#define IUpdateInstaller4_Uninstall(This,retval) \
|
||||
( (This)->lpVtbl -> Uninstall(This,retval) )
|
||||
|
||||
#define IUpdateInstaller4_get_AllowSourcePrompts(This,retval) \
|
||||
( (This)->lpVtbl -> get_AllowSourcePrompts(This,retval) )
|
||||
|
||||
#define IUpdateInstaller4_put_AllowSourcePrompts(This,value) \
|
||||
( (This)->lpVtbl -> put_AllowSourcePrompts(This,value) )
|
||||
|
||||
#define IUpdateInstaller4_get_RebootRequiredBeforeInstallation(This,retval) \
|
||||
( (This)->lpVtbl -> get_RebootRequiredBeforeInstallation(This,retval) )
|
||||
|
||||
|
||||
#define IUpdateInstaller4_get_ForceQuiet(This,retval) \
|
||||
( (This)->lpVtbl -> get_ForceQuiet(This,retval) )
|
||||
|
||||
#define IUpdateInstaller4_put_ForceQuiet(This,value) \
|
||||
( (This)->lpVtbl -> put_ForceQuiet(This,value) )
|
||||
|
||||
|
||||
#define IUpdateInstaller4_get_AttemptCloseAppsIfNecessary(This,retval) \
|
||||
( (This)->lpVtbl -> get_AttemptCloseAppsIfNecessary(This,retval) )
|
||||
|
||||
#define IUpdateInstaller4_put_AttemptCloseAppsIfNecessary(This,value) \
|
||||
( (This)->lpVtbl -> put_AttemptCloseAppsIfNecessary(This,value) )
|
||||
|
||||
|
||||
#define IUpdateInstaller4_Commit(This,dwFlags) \
|
||||
( (This)->lpVtbl -> Commit(This,dwFlags) )
|
||||
|
||||
#endif /* COBJMACROS */
|
||||
|
||||
|
||||
#endif /* C style interface */
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* __IUpdateInstaller4_INTERFACE_DEFINED__ */
|
|
@ -0,0 +1,39 @@
|
|||
import "oaidl.idl";
|
||||
|
||||
// Just types we need from wuapi.idl
|
||||
|
||||
[
|
||||
helpstring("IUpdateInstaller Interface"),
|
||||
object,
|
||||
oleautomation,
|
||||
dual,
|
||||
nonextensible,
|
||||
uuid(7b929c68-ccdc-4226-96b1-8724600b54c2),
|
||||
pointer_default(unique),
|
||||
]
|
||||
interface IUpdateInstaller : IDispatch {
|
||||
[id(0x60020003), propget, restricted]
|
||||
HRESULT ParentHwnd([out, retval] HWND *retval);
|
||||
|
||||
[id(0x60020003), propput, restricted]
|
||||
HRESULT ParentHwnd([in, unique] HWND value);
|
||||
};
|
||||
|
||||
[
|
||||
uuid(B596CC9F-56E5-419E-A622-E01BB457431E),
|
||||
version(2.0),
|
||||
helpstring("WUAPI 2.0 Type Library")
|
||||
]
|
||||
library WUApiLib
|
||||
{
|
||||
importlib("stdole2.tlb");
|
||||
|
||||
[
|
||||
helpstring("UpdateInstaller Class"),
|
||||
uuid(D2E0FE7F-D23E-48E1-93C0-6FA8CC346474)
|
||||
]
|
||||
coclass UpdateInstaller
|
||||
{
|
||||
[default] interface IUpdateInstaller2;
|
||||
};
|
||||
};
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,35 @@
|
|||
#!/bin/bash
|
||||
# Fixes NSIS binaries so they run on Pentium/486. Debian's build of NSIS is compiled with MinGW,
|
||||
# but they lack any -mcpu flag, so the binaries receive a default of i686. To fix this, we'll
|
||||
# download the official Windows build of NSIS and extract its binaries. We only handle stubs though,
|
||||
# because we provide our own plugin builds in this repo.
|
||||
|
||||
set -e
|
||||
|
||||
if [[ $UID != 0 ]]; then
|
||||
echo "This script needs to be run as root (sorry)" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ ! -d /usr/share/nsis/Stubs ]]; then
|
||||
echo "NSIS not installed, or Stubs directory is broken" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ -d /usr/share/nsis/Stubs_old ]]; then
|
||||
echo "NSIS stubs are already fixed" >&2
|
||||
exit 0
|
||||
fi
|
||||
|
||||
apt-get install -qy curl p7zip-full
|
||||
|
||||
mkdir /tmp/nsis
|
||||
cd /tmp/nsis
|
||||
|
||||
curl -fSL https://prdownloads.sourceforge.net/nsis/NSIS%203/3.10/nsis-3.10-setup.exe -o nsis.exe
|
||||
7z x nsis.exe
|
||||
|
||||
mv /usr/share/nsis/Stubs{,_old}
|
||||
cp -ra Stubs /usr/share/nsis/Stubs
|
||||
|
||||
rm -rf /tmp/nsis
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,170 @@
|
|||
|
||||
import "oaidl.idl";
|
||||
|
||||
// Generated .IDL file (by the OLE/COM Object Viewer)
|
||||
//
|
||||
// typelib filename: licdll.dll
|
||||
|
||||
[
|
||||
uuid(C7879482-F798-4A74-AF43-E887FBDCED40),
|
||||
version(1.0),
|
||||
helpstring("licdll 1.0 Type Library")
|
||||
]
|
||||
library LICDLLLib
|
||||
{
|
||||
// TLib : // TLib : OLE Automation : {00020430-0000-0000-C000-000000000046}
|
||||
importlib("stdole2.tlb");
|
||||
|
||||
// Forward declare all types defined in this typelib
|
||||
interface ICOMLicenseAgent;
|
||||
interface ICOMLicenseAgent2;
|
||||
|
||||
[
|
||||
uuid(ACADF079-CBCD-4032-83F2-FA47C4DB096F),
|
||||
helpstring("COMLicenseAgent Class")
|
||||
]
|
||||
coclass COMLicenseAgent {
|
||||
[default] interface ICOMLicenseAgent;
|
||||
interface ICOMLicenseAgent2;
|
||||
};
|
||||
|
||||
[
|
||||
odl,
|
||||
uuid(B8CBAD79-3F1F-481A-BB0C-E7BBD77BDDD1),
|
||||
helpstring("ICOMLicenseAgent Interface"),
|
||||
dual,
|
||||
oleautomation
|
||||
]
|
||||
interface ICOMLicenseAgent : IDispatch {
|
||||
[id(0x00000001), helpstring("method Initialize")]
|
||||
HRESULT Initialize(
|
||||
[in] unsigned long dwBPC,
|
||||
[in] unsigned long dwMode,
|
||||
[in] BSTR bstrLicSource,
|
||||
[out, retval] unsigned long* pdwRetCode);
|
||||
[id(0x00000003), helpstring("method GetFirstName")]
|
||||
HRESULT GetFirstName([out, retval] BSTR* pbstrVal);
|
||||
[id(0x00000004), helpstring("method SetFirstName")]
|
||||
HRESULT SetFirstName([in] BSTR bstrNewVal);
|
||||
[id(0x00000005), helpstring("method GetLastName")]
|
||||
HRESULT GetLastName([out, retval] BSTR* pbstrVal);
|
||||
[id(0x00000006), helpstring("method SetLastName")]
|
||||
HRESULT SetLastName([in] BSTR bstrNewVal);
|
||||
[id(0x00000007), helpstring("method GetOrgName")]
|
||||
HRESULT GetOrgName([out, retval] BSTR* pbstrVal);
|
||||
[id(0x00000008), helpstring("method SetOrgName")]
|
||||
HRESULT SetOrgName([in] BSTR bstrNewVal);
|
||||
[id(0x00000009), helpstring("method GetEmail")]
|
||||
HRESULT GetEmail([out, retval] BSTR* pbstrVal);
|
||||
[id(0x0000000a), helpstring("method SetEmail")]
|
||||
HRESULT SetEmail([in] BSTR bstrNewVal);
|
||||
[id(0x0000000b), helpstring("method GetPhone")]
|
||||
HRESULT GetPhone([out, retval] BSTR* pbstrVal);
|
||||
[id(0x0000000c), helpstring("method SetPhone")]
|
||||
HRESULT SetPhone([in] BSTR bstrNewVal);
|
||||
[id(0x0000000d), helpstring("method GetAddress1")]
|
||||
HRESULT GetAddress1([out, retval] BSTR* pbstrVal);
|
||||
[id(0x0000000e), helpstring("method SetAddress1")]
|
||||
HRESULT SetAddress1([in] BSTR bstrNewVal);
|
||||
[id(0x0000000f), helpstring("method GetCity")]
|
||||
HRESULT GetCity([out, retval] BSTR* pbstrVal);
|
||||
[id(0x00000010), helpstring("method SetCity")]
|
||||
HRESULT SetCity([in] BSTR bstrNewVal);
|
||||
[id(0x00000011), helpstring("method GetState")]
|
||||
HRESULT GetState([out, retval] BSTR* pbstrVal);
|
||||
[id(0x00000012), helpstring("method SetState")]
|
||||
HRESULT SetState([in] BSTR bstrNewVal);
|
||||
[id(0x00000013), helpstring("method GetCountryCode")]
|
||||
HRESULT GetCountryCode([out, retval] BSTR* pbstrVal);
|
||||
[id(0x00000014), helpstring("method SetCountryCode")]
|
||||
HRESULT SetCountryCode([in] BSTR bstrNewVal);
|
||||
[id(0x00000015), helpstring("method GetCountryDesc")]
|
||||
HRESULT GetCountryDesc([out, retval] BSTR* pbstrVal);
|
||||
[id(0x00000016), helpstring("method SetCountryDesc")]
|
||||
HRESULT SetCountryDesc([in] BSTR bstrNewVal);
|
||||
[id(0x00000017), helpstring("method GetZip")]
|
||||
HRESULT GetZip([out, retval] BSTR* pbstrVal);
|
||||
[id(0x00000018), helpstring("method SetZip")]
|
||||
HRESULT SetZip([in] BSTR bstrNewVal);
|
||||
[id(0x00000019), helpstring("method GetIsoLanguage")]
|
||||
HRESULT GetIsoLanguage([out, retval] unsigned long* pdwVal);
|
||||
[id(0x0000001a), helpstring("method SetIsoLanguage")]
|
||||
HRESULT SetIsoLanguage([in] unsigned long dwNewVal);
|
||||
[id(0x00000020), helpstring("method GetMSUpdate")]
|
||||
HRESULT GetMSUpdate([out, retval] BSTR* pbstrVal);
|
||||
[id(0x00000021), helpstring("method SetMSUpdate")]
|
||||
HRESULT SetMSUpdate([in] BSTR bstrNewVal);
|
||||
[id(0x00000022), helpstring("method GetMSOffer")]
|
||||
HRESULT GetMSOffer([out, retval] BSTR* pbstrVal);
|
||||
[id(0x00000023), helpstring("method SetMSOffer")]
|
||||
HRESULT SetMSOffer([in] BSTR bstrNewVal);
|
||||
[id(0x00000024), helpstring("method GetOtherOffer")]
|
||||
HRESULT GetOtherOffer([out, retval] BSTR* pbstrVal);
|
||||
[id(0x00000025), helpstring("method SetOtherOffer")]
|
||||
HRESULT SetOtherOffer([in] BSTR bstrNewVal);
|
||||
[id(0x00000026), helpstring("method GetAddress2")]
|
||||
HRESULT GetAddress2([out, retval] BSTR* pbstrVal);
|
||||
[id(0x00000027), helpstring("method SetAddress2")]
|
||||
HRESULT SetAddress2([in] BSTR bstrNewVal);
|
||||
[id(0x00000052), helpstring("method AsyncProcessHandshakeRequest")]
|
||||
HRESULT AsyncProcessHandshakeRequest([in] long bReviseCustInfo);
|
||||
[id(0x00000053), helpstring("method AsyncProcessNewLicenseRequest")]
|
||||
HRESULT AsyncProcessNewLicenseRequest();
|
||||
[id(0x00000054), helpstring("method AsyncProcessReissueLicenseRequest")]
|
||||
HRESULT AsyncProcessReissueLicenseRequest();
|
||||
[id(0x00000056), helpstring("method AsyncProcessReviseCustInfoRequest")]
|
||||
HRESULT AsyncProcessReviseCustInfoRequest();
|
||||
[id(0x0000005a), helpstring("method GetAsyncProcessReturnCode")]
|
||||
HRESULT GetAsyncProcessReturnCode([out, retval] unsigned long* pdwRetCode);
|
||||
[id(0x0000005d), helpstring("method AsyncProcessDroppedLicenseRequest")]
|
||||
HRESULT AsyncProcessDroppedLicenseRequest();
|
||||
[id(0x00000064), helpstring("method GenerateInstallationId")]
|
||||
HRESULT GenerateInstallationId([out, retval] BSTR* pbstrVal);
|
||||
[id(0x00000065), helpstring("method DepositConfirmationId")]
|
||||
HRESULT DepositConfirmationId(
|
||||
[in] BSTR bstrVal,
|
||||
[out, retval] unsigned long* pdwRetCode);
|
||||
[id(0x00000066), helpstring("method GetExpirationInfo")]
|
||||
HRESULT GetExpirationInfo(
|
||||
[out] unsigned long* pdwWPALeft,
|
||||
[out, retval] unsigned long* pdwEvalLeft);
|
||||
[id(0x00000067), helpstring("method AsyncProcessRegistrationRequest")]
|
||||
HRESULT AsyncProcessRegistrationRequest();
|
||||
[id(0x00000068), helpstring("method ProcessHandshakeRequest")]
|
||||
HRESULT ProcessHandshakeRequest([in] long bReviseCustInfo);
|
||||
[id(0x00000069), helpstring("method ProcessNewLicenseRequest")]
|
||||
HRESULT ProcessNewLicenseRequest();
|
||||
[id(0x0000006a), helpstring("method ProcessDroppedLicenseRequest")]
|
||||
HRESULT ProcessDroppedLicenseRequest();
|
||||
[id(0x0000006b), helpstring("method ProcessReissueLicenseRequest")]
|
||||
HRESULT ProcessReissueLicenseRequest();
|
||||
[id(0x0000006d), helpstring("method ProcessReviseCustInfoRequest")]
|
||||
HRESULT ProcessReviseCustInfoRequest();
|
||||
[id(0x0000006e), helpstring("method EnsureInternetConnection")]
|
||||
HRESULT EnsureInternetConnection();
|
||||
[id(0x0000006f), helpstring("method SetProductKey")]
|
||||
HRESULT SetProductKey([in] LPWSTR pszNewProductKey);
|
||||
[id(0x00000070), helpstring("method GetProductID")]
|
||||
HRESULT GetProductID([out, retval] BSTR* pbstrVal);
|
||||
[id(0x00000071), helpstring("method VerifyCheckDigits")]
|
||||
HRESULT VerifyCheckDigits(
|
||||
BSTR bstrCIDIID,
|
||||
[out, retval] long* pbValue);
|
||||
};
|
||||
|
||||
[
|
||||
odl,
|
||||
uuid(6A07C5A3-9C67-4BB6-B020-ECBE7FDFD326),
|
||||
helpstring("ICOMLicenseAgent Interface 2"),
|
||||
dual,
|
||||
oleautomation
|
||||
]
|
||||
interface ICOMLicenseAgent2 : ICOMLicenseAgent {
|
||||
[id(0x00000072), helpstring("method SetReminders")]
|
||||
HRESULT SetReminders(long bValue);
|
||||
[id(0x00000073), helpstring("method GetReminders")]
|
||||
HRESULT GetReminders(long* pbValue);
|
||||
[id(0x00000074), helpstring("method GetKeyType")]
|
||||
HRESULT GetKeyType([out, retval] unsigned long* pdwKeyType);
|
||||
};
|
||||
};
|
|
@ -0,0 +1,33 @@
|
|||
#pragma once
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef GUID SLID;
|
||||
typedef PVOID HSLC;
|
||||
|
||||
DEFINE_GUID(WINDOWS_SLID, 0x55c92734, 0xd682, 0x4d71, 0x98, 0x3e, 0xd6, 0xec, 0x3f, 0x16, 0x05, 0x9f);
|
||||
|
||||
typedef enum _tagSLLICENSINGSTATUS {
|
||||
SL_LICENSING_STATUS_UNLICENSED,
|
||||
SL_LICENSING_STATUS_LICENSED,
|
||||
SL_LICENSING_STATUS_IN_GRACE_PERIOD,
|
||||
SL_LICENSING_STATUS_NOTIFICATION,
|
||||
SL_LICENSING_STATUS_LAST
|
||||
} SLLICENSINGSTATUS;
|
||||
|
||||
typedef struct _tagSL_LICENSING_STATUS {
|
||||
SLID SkuId;
|
||||
SLLICENSINGSTATUS eStatus;
|
||||
DWORD dwGraceTime;
|
||||
DWORD dwTotalGraceDays;
|
||||
HRESULT hrReason;
|
||||
UINT64 qwValidityExpiration;
|
||||
} SL_LICENSING_STATUS;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,18 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<applications xmlns="http://schemas.microsoft.com/windows/cpltasks/v1" xmlns:sh="http://schemas.microsoft.com/windows/tasks/v1">
|
||||
<application id="{FFBE8D44-E9CF-4DD8-9FD6-976802C94D9C}">
|
||||
<sh:task id="{9943E8C8-748D-47CE-AE10-9FA4A80ED28B}" needsElevation="true">
|
||||
<sh:name>@"%ProgramFiles%\Legacy Update\LegacyUpdate.exe",-3</sh:name>
|
||||
<sh:keywords>legacy update;legacyupdate;update;windows;microsoft;driver;security;software;</sh:keywords>
|
||||
<sh:command>"%ProgramFiles%\Legacy Update\LegacyUpdate.exe"</sh:command>
|
||||
</sh:task>
|
||||
|
||||
<category id="5">
|
||||
<sh:task idref="{9943E8C8-748D-47CE-AE10-9FA4A80ED28B}" />
|
||||
</category>
|
||||
|
||||
<category id="10">
|
||||
<sh:task idref="{9943E8C8-748D-47CE-AE10-9FA4A80ED28B}" />
|
||||
</category>
|
||||
</application>
|
||||
</applications>
|
|
@ -0,0 +1,298 @@
|
|||
#include <windows.h>
|
||||
#include <commctrl.h>
|
||||
#include "MsgBox.h"
|
||||
#include "VersionInfo.h"
|
||||
#include "LoadImage.h"
|
||||
|
||||
#define HK_RUNCMD 1
|
||||
|
||||
typedef DWORD (__fastcall *_ThemeWaitForServiceReady)(DWORD timeout);
|
||||
typedef DWORD (__fastcall *_ThemeWatchForStart)();
|
||||
|
||||
static const COLORREF WallpaperColorWin2k = RGB(58, 110, 165); // #3a6ea5
|
||||
static const COLORREF WallpaperColorWinXP = RGB( 0, 78, 152); // #004e98
|
||||
static const COLORREF WallpaperColorWin8 = RGB(32, 103, 178); // #2067b2
|
||||
static const COLORREF WallpaperColorWin10 = RGB(24, 0, 82); // #180052
|
||||
|
||||
static const WCHAR RunOnceClassName[] = L"LegacyUpdateRunOnce";
|
||||
|
||||
static HANDLE g_cmdHandle;
|
||||
|
||||
static void StartThemes() {
|
||||
// Ask UxInit.dll to ask the Themes service to start a session for this desktop. Themes doesn't automatically start a
|
||||
// session for the SYSTEM desktop, so we need to ask it to. This matches what msoobe.exe does on first boot.
|
||||
|
||||
// Windows 7 moves this to UxInit.dll
|
||||
HMODULE shsvcs = LoadLibrary(L"UxInit.dll");
|
||||
if (!shsvcs) {
|
||||
shsvcs = LoadLibrary(L"shsvcs.dll");
|
||||
if (!shsvcs) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Get functions by ordinals
|
||||
_ThemeWaitForServiceReady $ThemeWaitForServiceReady = (_ThemeWaitForServiceReady)GetProcAddress(shsvcs, MAKEINTRESOURCEA(2));
|
||||
_ThemeWatchForStart $ThemeWatchForStart = (_ThemeWatchForStart)GetProcAddress(shsvcs, MAKEINTRESOURCEA(1));
|
||||
|
||||
// 1. Wait up to 1000ms for Themes to start
|
||||
if ($ThemeWaitForServiceReady) {
|
||||
$ThemeWaitForServiceReady(1000);
|
||||
}
|
||||
|
||||
// 2. Prompt Themes to start a session for the SYSTEM desktop
|
||||
if ($ThemeWatchForStart) {
|
||||
$ThemeWatchForStart();
|
||||
}
|
||||
|
||||
FreeLibrary(shsvcs);
|
||||
}
|
||||
|
||||
static BOOL RunCmd(LPPROCESS_INFORMATION processInfo) {
|
||||
WCHAR cmd[MAX_PATH];
|
||||
ExpandEnvironmentStrings(L"%SystemRoot%\\System32\\cmd.exe", cmd, ARRAYSIZE(cmd));
|
||||
|
||||
STARTUPINFO startupInfo = {0};
|
||||
startupInfo.cb = sizeof(startupInfo);
|
||||
|
||||
if (!CreateProcess(NULL, cmd, NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &startupInfo, processInfo)) {
|
||||
MsgBox(NULL, L"Launching cmd.exe failed", NULL, MB_OK | MB_ICONERROR);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
CloseHandle(processInfo->hThread);
|
||||
g_cmdHandle = processInfo->hProcess;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static LRESULT CALLBACK RunOnceWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
|
||||
switch (message) {
|
||||
case WM_NCHITTEST:
|
||||
// Don't accept any mouse input
|
||||
return HTNOWHERE;
|
||||
|
||||
case WM_HOTKEY: {
|
||||
// Shift-F10 to run cmd
|
||||
if (wParam == HK_RUNCMD) {
|
||||
DWORD exitCode;
|
||||
if (!g_cmdHandle || (GetExitCodeProcess(g_cmdHandle, &exitCode) && exitCode != STILL_ACTIVE)) {
|
||||
PROCESS_INFORMATION processInfo;
|
||||
RunCmd(&processInfo);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_DESTROY:
|
||||
PostQuitMessage(0);
|
||||
break;
|
||||
}
|
||||
|
||||
return DefWindowProc(hwnd, message, wParam, lParam);;
|
||||
}
|
||||
|
||||
static void CreateRunOnceWindow() {
|
||||
// Init common controls
|
||||
INITCOMMONCONTROLSEX initComctl = {0};
|
||||
initComctl.dwSize = sizeof(initComctl);
|
||||
initComctl.dwICC = ICC_WIN95_CLASSES;
|
||||
InitCommonControlsEx(&initComctl);
|
||||
|
||||
// Create window
|
||||
WNDCLASS wndClass = {0};
|
||||
wndClass.style = CS_VREDRAW | CS_HREDRAW | CS_OWNDC | CS_NOCLOSE;
|
||||
wndClass.lpfnWndProc = RunOnceWndProc;
|
||||
wndClass.hInstance = GetModuleHandle(NULL);
|
||||
wndClass.lpszClassName = RunOnceClassName;
|
||||
wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
|
||||
|
||||
if (!RegisterClass(&wndClass)) {
|
||||
TRACE(L"RegisterClass failed: %d", GetLastError());
|
||||
return;
|
||||
}
|
||||
|
||||
HWND hwnd = CreateWindowEx(
|
||||
WS_EX_TOOLWINDOW | WS_EX_NOACTIVATE,
|
||||
wndClass.lpszClassName,
|
||||
L"Legacy Update",
|
||||
WS_POPUP,
|
||||
0, 0, 0, 0,
|
||||
NULL, NULL,
|
||||
wndClass.hInstance,
|
||||
NULL
|
||||
);
|
||||
if (!hwnd) {
|
||||
TRACE(L"CreateWindow failed: %d", GetLastError());
|
||||
return;
|
||||
}
|
||||
|
||||
// Register hotkey
|
||||
RegisterHotKey(hwnd, HK_RUNCMD, MOD_SHIFT, VK_F10);
|
||||
|
||||
// Check if the display is 8-bit color or lower
|
||||
HDC dc = GetDC(NULL);
|
||||
int bpp = GetDeviceCaps(dc, BITSPIXEL);
|
||||
ReleaseDC(NULL, dc);
|
||||
if (bpp >= 8) {
|
||||
// Set the wallpaper color
|
||||
COLORREF color = GetSysColor(COLOR_DESKTOP);
|
||||
if (AtLeastWin10()) {
|
||||
color = WallpaperColorWin10;
|
||||
} else if (AtLeastWin8()) {
|
||||
color = WallpaperColorWin8;
|
||||
} else if ((IsWinXP2002() || IsWinXP2003()) && color == RGB(0, 0, 0)) {
|
||||
// XP uses a black wallpaper in fast user switching mode. Override to the default blue.
|
||||
color = WallpaperColorWinXP;
|
||||
}
|
||||
SetSysColors(1, (const INT[1]){COLOR_DESKTOP}, (const COLORREF[1]){color});
|
||||
|
||||
DWORD width = GetSystemMetrics(SM_CXSCREEN);
|
||||
DWORD height = GetSystemMetrics(SM_CYSCREEN);
|
||||
HBITMAP wallpaper;
|
||||
|
||||
if (IsWin7()) {
|
||||
// 7: Bitmap in oobe dir
|
||||
WCHAR bmpPath[MAX_PATH];
|
||||
ExpandEnvironmentStrings(L"%SystemRoot%\\System32\\oobe\\background.bmp", bmpPath, ARRAYSIZE(bmpPath));
|
||||
wallpaper = LoadImage(NULL, bmpPath, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
|
||||
} else if (IsWinVista()) {
|
||||
// Vista: Resources in ooberesources.dll
|
||||
WCHAR ooberesPath[MAX_PATH];
|
||||
ExpandEnvironmentStrings(L"%SystemRoot%\\System32\\oobe\\ooberesources.dll", ooberesPath, ARRAYSIZE(ooberesPath));
|
||||
HMODULE ooberes = LoadLibrary(ooberesPath);
|
||||
if (ooberes) {
|
||||
// Width logic is the same used by Vista msoobe.dll
|
||||
LPWSTR resource = GetSystemMetrics(SM_CXSCREEN) < 1200 ? L"OOBE_BACKGROUND_0" : L"OOBE_BACKGROUND_LARGE_0";
|
||||
wallpaper = LoadPNGResource(ooberes, resource, RT_RCDATA);
|
||||
}
|
||||
FreeLibrary(ooberes);
|
||||
}
|
||||
|
||||
if (wallpaper) {
|
||||
// Write to disk
|
||||
WCHAR tempPath[MAX_PATH];
|
||||
ExpandEnvironmentStrings(L"%ProgramData%\\Legacy Update\\background.bmp", tempPath, ARRAYSIZE(tempPath));
|
||||
if (GetFileAttributes(tempPath) != INVALID_FILE_ATTRIBUTES || ScaleAndWriteToBMP(wallpaper, width, height, tempPath)) {
|
||||
SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, (PVOID)tempPath, SPIF_SENDWININICHANGE);
|
||||
}
|
||||
|
||||
DeleteObject(wallpaper);
|
||||
}
|
||||
}
|
||||
|
||||
ShowWindow(hwnd, SW_SHOW);
|
||||
UpdateWindow(hwnd);
|
||||
}
|
||||
|
||||
static BOOL IsSystemUser() {
|
||||
BOOL result = FALSE;
|
||||
PTOKEN_USER tokenInfo;
|
||||
PSID systemSid;
|
||||
HANDLE token;
|
||||
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token)) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
DWORD tokenInfoLen;
|
||||
GetTokenInformation(token, TokenUser, NULL, 0, &tokenInfoLen);
|
||||
tokenInfo = (PTOKEN_USER)LocalAlloc(LPTR, tokenInfoLen);
|
||||
if (!GetTokenInformation(token, TokenUser, tokenInfo, tokenInfoLen, &tokenInfoLen)) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
DWORD sidSize = SECURITY_MAX_SID_SIZE;
|
||||
systemSid = LocalAlloc(LPTR, sidSize);
|
||||
if (!CreateWellKnownSid(WinLocalSystemSid, NULL, systemSid, &sidSize)) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
result = EqualSid(tokenInfo->User.Sid, systemSid);
|
||||
|
||||
end:
|
||||
if (tokenInfo) {
|
||||
LocalFree(tokenInfo);
|
||||
}
|
||||
if (systemSid) {
|
||||
LocalFree(systemSid);
|
||||
}
|
||||
if (token) {
|
||||
CloseHandle(token);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void RunOnce() {
|
||||
#ifndef _DEBUG
|
||||
// Only relevant if we're SYSTEM
|
||||
if (!IsSystemUser()) {
|
||||
PostQuitMessage(1);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Start Themes on this desktop
|
||||
StartThemes();
|
||||
|
||||
// Find and hide the FirstUxWnd window, if it exists (Windows 7+)
|
||||
HWND firstUxWnd = FindWindow(L"FirstUxWndClass", NULL);
|
||||
if (firstUxWnd) {
|
||||
ShowWindow(firstUxWnd, SW_HIDE);
|
||||
}
|
||||
|
||||
// Set up our window
|
||||
CreateRunOnceWindow();
|
||||
|
||||
// Construct path to LegacyUpdateSetup.exe
|
||||
WCHAR setupPath[MAX_PATH];
|
||||
GetModuleFileName(NULL, setupPath, ARRAYSIZE(setupPath));
|
||||
wcsrchr(setupPath, L'\\')[1] = L'\0';
|
||||
wcsncat(setupPath, L"LegacyUpdateSetup.exe", ARRAYSIZE(setupPath) - wcslen(setupPath) - 1);
|
||||
|
||||
// Execute and wait for completion
|
||||
STARTUPINFO startupInfo = {0};
|
||||
startupInfo.cb = sizeof(startupInfo);
|
||||
|
||||
PROCESS_INFORMATION processInfo = {0};
|
||||
LPWSTR cmdLine = (LPWSTR)LocalAlloc(LPTR, 4096 * sizeof(WCHAR));
|
||||
wsprintf(cmdLine, L"\"%ls\" /runonce", setupPath);
|
||||
if (!CreateProcess(setupPath, cmdLine, NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &startupInfo, &processInfo)) {
|
||||
#ifdef _DEBUG
|
||||
// Run cmd.exe instead
|
||||
if (!RunCmd(&processInfo)) {
|
||||
PostQuitMessage(0);
|
||||
return;
|
||||
}
|
||||
#else
|
||||
MsgBox(NULL, L"Continuing Legacy Update setup failed", NULL, MB_OK | MB_ICONERROR);
|
||||
PostQuitMessage(0);
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
|
||||
CloseHandle(processInfo.hThread);
|
||||
|
||||
// Wait for it to finish, while running a message loop
|
||||
MSG msg;
|
||||
while (WaitForSingleObject(processInfo.hProcess, 100) == WAIT_TIMEOUT) {
|
||||
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
}
|
||||
|
||||
CloseHandle(processInfo.hProcess);
|
||||
|
||||
// Don't let SYSTEM cmd keep running beyond runonce
|
||||
if (g_cmdHandle) {
|
||||
TerminateProcess(g_cmdHandle, 0);
|
||||
CloseHandle(g_cmdHandle);
|
||||
}
|
||||
|
||||
// Show FirstUxWnd again
|
||||
if (firstUxWnd) {
|
||||
ShowWindow(firstUxWnd, SW_SHOW);
|
||||
}
|
||||
|
||||
PostQuitMessage(0);
|
||||
}
|
|
@ -0,0 +1,205 @@
|
|||
#include "stdafx.h"
|
||||
#include "main.h"
|
||||
#include "resource.h"
|
||||
#include <exdisp.h>
|
||||
#include "Exec.h"
|
||||
#include "HResult.h"
|
||||
#include "MsgBox.h"
|
||||
#include "RegisterServer.h"
|
||||
#include "Registry.h"
|
||||
#include "SelfElevate.h"
|
||||
#include "User.h"
|
||||
#include "VersionInfo.h"
|
||||
|
||||
const LPWSTR UpdateSiteURLHttp = L"http://legacyupdate.net/windowsupdate/v6/";
|
||||
const LPWSTR UpdateSiteURLHttps = L"https://legacyupdate.net/windowsupdate/v6/";
|
||||
const LPWSTR UpdateSiteFirstRunFlag = L"?firstrun=true";
|
||||
|
||||
DEFINE_GUID(IID_ILegacyUpdateCtrl, 0xC33085BB, 0xC3E1, 0x4D27, 0xA2, 0x14, 0xAF, 0x01, 0x95, 0x3D, 0xF5, 0xE5);
|
||||
DEFINE_GUID(CLSID_LegacyUpdateCtrl, 0xAD28E0DF, 0x5F5A, 0x40B5, 0x94, 0x32, 0x85, 0xEF, 0xD9, 0x7D, 0x1F, 0x9F);
|
||||
|
||||
static const LPWSTR GetUpdateSiteURL() {
|
||||
// Fallback: Use SSL only on Vista and up
|
||||
BOOL useHTTPS = AtLeastWinVista();
|
||||
|
||||
// Get the Windows Update website URL set by Legacy Update setup
|
||||
LPWSTR data;
|
||||
DWORD size;
|
||||
HRESULT hr = GetRegistryString(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\WindowsUpdate", L"URL", KEY_WOW64_64KEY, &data, &size);
|
||||
if (SUCCEEDED(hr)) {
|
||||
// Return based on the URL value
|
||||
if (wcscmp(data, UpdateSiteURLHttps) == 0) {
|
||||
useHTTPS = TRUE;
|
||||
} else if (wcscmp(data, UpdateSiteURLHttp) == 0) {
|
||||
useHTTPS = FALSE;
|
||||
}
|
||||
LocalFree(data);
|
||||
}
|
||||
|
||||
return useHTTPS ? UpdateSiteURLHttps : UpdateSiteURLHttp;
|
||||
}
|
||||
|
||||
void LaunchUpdateSite(int argc, LPWSTR *argv, int nCmdShow) {
|
||||
HRESULT hr = S_OK;
|
||||
IWebBrowser2 *browser;
|
||||
VARIANT url;
|
||||
VARIANT flags;
|
||||
VARIANT nullVariant;
|
||||
LPTSTR siteURL;
|
||||
HMONITOR monitor;
|
||||
|
||||
// If running on 2k/XP, make sure we're elevated. If not, show Run As prompt.
|
||||
if (!AtLeastWinVista() && !IsUserAdmin()) {
|
||||
LPWSTR args = (LPWSTR)LocalAlloc(LPTR, 512 * sizeof(WCHAR));
|
||||
wsprintf(args, L"/launch %ls", argc > 0 ? argv[0] : L"");
|
||||
hr = SelfElevate(args, NULL);
|
||||
|
||||
// Access denied happens when the user clicks No/Cancel.
|
||||
if (hr == HRESULT_FROM_WIN32(ERROR_CANCELLED)) {
|
||||
hr = S_OK;
|
||||
}
|
||||
|
||||
goto end;
|
||||
}
|
||||
|
||||
// Can we instantiate our own ActiveX control? If not, try to register it.
|
||||
hr = CoCreateInstance(&CLSID_LegacyUpdateCtrl, NULL, CLSCTX_LOCAL_SERVER, &IID_ILegacyUpdateCtrl, (void **)&browser);
|
||||
if (hr == REGDB_E_CLASSNOTREG) {
|
||||
hr = RegisterServer(0, TRUE, TRUE);
|
||||
if (!SUCCEEDED(hr)) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
hr = CoCreateInstance(&CLSID_LegacyUpdateCtrl, NULL, CLSCTX_LOCAL_SERVER, &IID_ILegacyUpdateCtrl, (void **)&browser);
|
||||
if (!SUCCEEDED(hr)) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
IUnknown_Release(browser);
|
||||
} else if (!SUCCEEDED(hr)) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
// Spawn an IE window via the COM interface. This ensures the page opens in IE (ShellExecute uses
|
||||
// default browser), and avoids hardcoding a path to iexplore.exe. Also conveniently allows testing
|
||||
// on Windows 11 (iexplore.exe redirects to Edge, but COM still works). Same strategy as used by
|
||||
// Wupdmgr.exe and Muweb.dll,LaunchMUSite.
|
||||
hr = CoCreateInstance(&CLSID_InternetExplorer, NULL, CLSCTX_LOCAL_SERVER, &IID_IWebBrowser2, (void **)&browser);
|
||||
if (hr == REGDB_E_CLASSNOTREG) {
|
||||
// Handle case where the user has uninstalled Internet Explorer using Programs and Features.
|
||||
OSVERSIONINFOEX *versionInfo = GetVersionInfo();
|
||||
|
||||
// Windows 8+: Directly prompt to reinstall IE using Fondue.exe.
|
||||
if (AtLeastWin8()) {
|
||||
SYSTEM_INFO systemInfo;
|
||||
GetSystemInfo(&systemInfo);
|
||||
LPCTSTR archSuffix = systemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64 ? L"amd64" : L"x86";
|
||||
|
||||
WCHAR fondue[MAX_PATH];
|
||||
ExpandEnvironmentStrings(L"%SystemRoot%\\System32\\fondue.exe", fondue, ARRAYSIZE(fondue));
|
||||
|
||||
WCHAR fondueArgs[256];
|
||||
wsprintf(fondueArgs, L"/enable-feature:Internet-Explorer-Optional-%ls", archSuffix);
|
||||
hr = Exec(NULL, fondue, fondueArgs, NULL, SW_SHOWDEFAULT, FALSE, NULL);
|
||||
if (SUCCEEDED(hr)) {
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
// Tell the user what they need to do, then open the Optional Features dialog.
|
||||
WCHAR message[4096];
|
||||
LoadString(GetModuleHandle(NULL), IDS_IENOTINSTALLED, message, ARRAYSIZE(message));
|
||||
MsgBox(NULL, message, NULL, MB_OK | MB_ICONEXCLAMATION);
|
||||
|
||||
WCHAR optionalFeatures[MAX_PATH];
|
||||
ExpandEnvironmentStrings(L"%SystemRoot%\\System32\\OptionalFeatures.exe", optionalFeatures, ARRAYSIZE(optionalFeatures));
|
||||
Exec(NULL, optionalFeatures, NULL, NULL, SW_SHOWDEFAULT, FALSE, NULL);
|
||||
hr = S_OK;
|
||||
goto end;
|
||||
} else if (!SUCCEEDED(hr)) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
// Can we connect with https? WinInet will throw an error if not.
|
||||
siteURL = GetUpdateSiteURL();
|
||||
|
||||
// Is this a first run launch? Append first run flag if so.
|
||||
if (argc > 0 && lstrcmpi(argv[0], L"/firstrun") == 0) {
|
||||
WCHAR newSiteURL[256];
|
||||
wsprintf(newSiteURL, L"%s%s", siteURL, UpdateSiteFirstRunFlag);
|
||||
siteURL = newSiteURL;
|
||||
}
|
||||
|
||||
VariantInit(&url);
|
||||
url.vt = VT_BSTR;
|
||||
url.bstrVal = SysAllocString(siteURL);
|
||||
|
||||
VariantInit(&flags);
|
||||
flags.vt = VT_I4;
|
||||
flags.lVal = 0;
|
||||
|
||||
VariantInit(&nullVariant);
|
||||
|
||||
hr = IWebBrowser2_Navigate2(browser, &url, &flags, &nullVariant, &nullVariant, &nullVariant);
|
||||
if (!SUCCEEDED(hr)) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
HWND ieHwnd;
|
||||
hr = IWebBrowser2_get_HWND(browser, (SHANDLE_PTR *)&ieHwnd);
|
||||
if (!SUCCEEDED(hr)) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
// Are we on a small display? If so, resize and maximise the window.
|
||||
monitor = MonitorFromWindow(ieHwnd, MONITOR_DEFAULTTONEAREST);
|
||||
MONITORINFO monitorInfo;
|
||||
monitorInfo.cbSize = sizeof(MONITORINFO);
|
||||
|
||||
if (GetMonitorInfo(monitor, &monitorInfo) > 0) {
|
||||
LONG workWidth = monitorInfo.rcWork.right - monitorInfo.rcWork.left;
|
||||
LONG workHeight = monitorInfo.rcWork.bottom - monitorInfo.rcWork.top;
|
||||
|
||||
LONG width, height;
|
||||
IWebBrowser2_get_Width(browser, &width);
|
||||
IWebBrowser2_get_Height(browser, &height);
|
||||
|
||||
if (width < 800) {
|
||||
width = workWidth < 800 ? workWidth : 800;
|
||||
IWebBrowser2_put_Width(browser, width);
|
||||
}
|
||||
if (height < 600) {
|
||||
height = workHeight < 600 ? workHeight : 600;
|
||||
IWebBrowser2_put_Height(browser, height);
|
||||
}
|
||||
|
||||
LONG left, top;
|
||||
IWebBrowser2_get_Left(browser, &left);
|
||||
IWebBrowser2_get_Top(browser, &top);
|
||||
|
||||
if (left + width > workWidth) {
|
||||
IWebBrowser2_put_Left(browser, 0);
|
||||
}
|
||||
if (top + height > workHeight) {
|
||||
IWebBrowser2_put_Top(browser, 0);
|
||||
}
|
||||
|
||||
if (workWidth <= 1152) {
|
||||
ShowWindow(ieHwnd, SW_MAXIMIZE);
|
||||
}
|
||||
}
|
||||
|
||||
IWebBrowser2_put_Visible(browser, TRUE);
|
||||
|
||||
// Focus the window, since it seems to not always get focus as it should.
|
||||
SetForegroundWindow(ieHwnd);
|
||||
|
||||
end:
|
||||
if (!SUCCEEDED(hr)) {
|
||||
MsgBox(NULL, GetMessageForHresult(hr), NULL, MB_ICONEXCLAMATION);
|
||||
}
|
||||
|
||||
browser = NULL;
|
||||
CoUninitialize();
|
||||
PostQuitMessage(0);
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
#include "WULog.h"
|
||||
#include "MsgBox.h"
|
||||
|
||||
void LaunchLog(int nCmdShow) {
|
||||
HRESULT hr = ViewWindowsUpdateLog(nCmdShow);
|
||||
if (!SUCCEEDED(hr)) {
|
||||
MsgBox(NULL, GetMessageForHresult(hr), NULL, MB_OK);
|
||||
}
|
||||
|
||||
PostQuitMessage(hr);
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
all:
|
||||
+$(MAKE) -f Makefile.actual ARCH=32
|
||||
+$(MAKE) -f Makefile.actual ARCH=64
|
||||
|
||||
clean:
|
||||
rm -rf obj
|
||||
|
||||
.PHONY: all clean
|
|
@ -0,0 +1,126 @@
|
|||
FILES = \
|
||||
$(wildcard *.c) \
|
||||
../shared/Exec.c \
|
||||
../shared/HResult.c \
|
||||
../shared/LegacyUpdate.c \
|
||||
../shared/LoadImage.c \
|
||||
../shared/Registry.c \
|
||||
../shared/VersionInfo.c \
|
||||
../shared/Wow64.c
|
||||
RCFILES = resource.rc
|
||||
DEFFILES = ../LegacyUpdate/LegacyUpdate.def
|
||||
|
||||
ARCH ?= 32
|
||||
|
||||
ifeq ($(ARCH),64)
|
||||
TAG = x86_64
|
||||
else
|
||||
TAG = i686
|
||||
endif
|
||||
|
||||
PREFIX = $(TAG)-w64-mingw32-
|
||||
|
||||
BIN = obj/LegacyUpdate$(ARCH).exe
|
||||
OBJ = $(foreach file,$(FILES),obj/$(notdir $(basename $(file)).$(TAG).o))
|
||||
RES = $(foreach file,$(RCFILES),obj/$(notdir $(basename $(file)).$(TAG).res))
|
||||
DEFDLL = $(foreach file,$(DEFFILES),obj/lib$(notdir $(basename $(file)).$(TAG).a))
|
||||
|
||||
CC = $(PREFIX)g++
|
||||
RC = $(PREFIX)windres
|
||||
DLLTOOL = $(PREFIX)dlltool
|
||||
|
||||
override DEBUG := $(or $(DEBUG),1)
|
||||
|
||||
CFLAGS = \
|
||||
-mwindows \
|
||||
-municode \
|
||||
-DUNICODE \
|
||||
-D_UNICODE \
|
||||
$(if $(filter 1,$(DEBUG)),-D_DEBUG -g,-DNDEBUG -Os) \
|
||||
-s \
|
||||
-fPIE \
|
||||
-ffunction-sections \
|
||||
-fdata-sections \
|
||||
-fno-unwind-tables \
|
||||
-fno-asynchronous-unwind-tables \
|
||||
-fno-exceptions \
|
||||
-flto \
|
||||
-Wno-write-strings \
|
||||
-I../include \
|
||||
-I../shared \
|
||||
-include stdafx.h
|
||||
|
||||
CXXFLAGS = \
|
||||
$(CFLAGS) \
|
||||
-std=c++11 \
|
||||
-fno-rtti
|
||||
|
||||
LDFLAGS = \
|
||||
-nodefaultlibs \
|
||||
-nostartfiles \
|
||||
-nostdlib \
|
||||
-Wl,--gc-sections \
|
||||
-Wl,--no-seh \
|
||||
-Wl,--nxcompat \
|
||||
-Wl,--enable-auto-image-base \
|
||||
-Wl,--enable-stdcall-fixup \
|
||||
-Wl,--strip-all \
|
||||
-Lobj \
|
||||
-lmsvcrt \
|
||||
-lgcc \
|
||||
-lpsapi \
|
||||
-lkernel32 \
|
||||
-luser32 \
|
||||
-lole32 \
|
||||
-loleaut32 \
|
||||
-ladvapi32 \
|
||||
-lcomctl32 \
|
||||
-lshell32 \
|
||||
-lversion \
|
||||
-lgdi32 \
|
||||
-lmsimg32
|
||||
|
||||
RCFLAGS = \
|
||||
-O coff \
|
||||
-I../shared
|
||||
|
||||
ifeq ($(ARCH),64)
|
||||
LDFLAGS += -Wl,-ewWinMain
|
||||
RCFLAGS += -F pe-x86-64
|
||||
else
|
||||
CFLAGS += -march=i486
|
||||
LDFLAGS += -Wl,-e_wWinMain
|
||||
RCFLAGS += -F pe-i386
|
||||
endif
|
||||
|
||||
all: before-all $(DEFDLL) $(BIN)
|
||||
ifeq ($(SIGN),1)
|
||||
../build/sign.sh $(BIN)
|
||||
endif
|
||||
|
||||
before-all:
|
||||
mkdir -p obj
|
||||
|
||||
$(BIN): $(OBJ) $(RES)
|
||||
$(CC) $^ $(CFLAGS) $(LDFLAGS) -o $@
|
||||
|
||||
obj/%.$(TAG).o: %.c
|
||||
$(CC) -x c $< $(CFLAGS) -c -o $@
|
||||
|
||||
obj/%.$(TAG).o: ../shared/%.c
|
||||
$(CC) -x c $< $(CFLAGS) -c -o $@
|
||||
|
||||
obj/%.$(TAG).res: %.rc
|
||||
$(RC) $< $(RCFLAGS) -o $@
|
||||
|
||||
obj/lib%.$(TAG).a: ../LegacyUpdate/%.def
|
||||
$(DLLTOOL) -d $< -l $@ -D $(notdir $(basename $<).dll)
|
||||
|
||||
clean:
|
||||
rm -rf obj
|
||||
|
||||
test:
|
||||
+$(MAKE) DEBUG=$(DEBUG)
|
||||
./obj/LegacyUpdate.exe
|
||||
|
||||
.PHONY: all before-all clean test
|
|
@ -0,0 +1,82 @@
|
|||
#include "stdafx.h"
|
||||
#include "main.h"
|
||||
#include "resource.h"
|
||||
|
||||
#undef _WIN32_WINNT
|
||||
#define _WIN32_WINNT _WIN32_WINNT_VISTA
|
||||
#include <commctrl.h>
|
||||
|
||||
typedef HRESULT (WINAPI *_TaskDialogIndirect)(const TASKDIALOGCONFIG *pTaskConfig, int *pnButton, int *pnRadioButton, BOOL *pfVerificationFlagChecked);
|
||||
|
||||
static BOOL _loadedTaskDialog = FALSE;
|
||||
static _TaskDialogIndirect $TaskDialogIndirect;
|
||||
|
||||
int MsgBox(HWND hwnd, LPCTSTR instruction, LPCTSTR body, UINT type) {
|
||||
if (!_loadedTaskDialog) {
|
||||
_loadedTaskDialog = TRUE;
|
||||
$TaskDialogIndirect = (_TaskDialogIndirect)GetProcAddress(LoadLibrary(L"comctl32.dll"), "TaskDialogIndirect");
|
||||
}
|
||||
|
||||
// Play the sound matching the icon, because MB_USERICON doesn't play a sound
|
||||
MessageBeep(type & 0x000000F0);
|
||||
type = (type & ~0x000000F0) | MB_USERICON;
|
||||
|
||||
if (!$TaskDialogIndirect) {
|
||||
LPWSTR finalBody = (LPWSTR)instruction;
|
||||
if (body && lstrlen(body) > 0) {
|
||||
size_t length = lstrlen(instruction) + lstrlen(body) + 3;
|
||||
finalBody = (LPWSTR)LocalAlloc(LPTR, length * sizeof(TCHAR));
|
||||
wsprintf(finalBody, L"%s\n\n%s", instruction, body);
|
||||
}
|
||||
|
||||
MSGBOXPARAMS params = { 0 };
|
||||
params.cbSize = sizeof(MSGBOXPARAMS);
|
||||
params.hwndOwner = hwnd;
|
||||
params.hInstance = GetModuleHandle(NULL);
|
||||
params.lpszText = finalBody;
|
||||
params.lpszCaption = L"Legacy Update";
|
||||
params.dwStyle = type;
|
||||
params.lpszIcon = MAKEINTRESOURCE(IDI_APPICON);
|
||||
int result = MessageBoxIndirect(¶ms);
|
||||
|
||||
if (finalBody != body) {
|
||||
LocalFree(finalBody);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
TASKDIALOG_COMMON_BUTTON_FLAGS buttons;
|
||||
DWORD flags = TDF_POSITION_RELATIVE_TO_WINDOW;
|
||||
|
||||
switch (type & 0x0000000F) {
|
||||
case MB_OK:
|
||||
buttons = TDCBF_OK_BUTTON;
|
||||
flags |= TDF_ALLOW_DIALOG_CANCELLATION;
|
||||
break;
|
||||
case MB_OKCANCEL:
|
||||
buttons = TDCBF_OK_BUTTON | TDCBF_CANCEL_BUTTON;
|
||||
flags |= TDF_ALLOW_DIALOG_CANCELLATION;
|
||||
break;
|
||||
case MB_YESNO:
|
||||
buttons = TDCBF_YES_BUTTON | TDCBF_NO_BUTTON;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
TASKDIALOGCONFIG config = { 0 };
|
||||
config.cbSize = sizeof(TASKDIALOGCONFIG);
|
||||
config.hwndParent = hwnd;
|
||||
config.hInstance = GetModuleHandle(NULL);
|
||||
config.dwFlags = flags;
|
||||
config.dwCommonButtons = buttons;
|
||||
config.pszWindowTitle = L"Legacy Update";
|
||||
config.pszMainInstruction = instruction;
|
||||
config.pszContent = body;
|
||||
config.pszMainIcon = MAKEINTRESOURCE(IDI_APPICON);
|
||||
|
||||
int button;
|
||||
$TaskDialogIndirect(&config, &button, NULL, NULL);
|
||||
return button;
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
#pragma once
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
int MsgBox(HWND hwnd, LPCTSTR instruction, LPCTSTR body, UINT type);
|
|
@ -0,0 +1,40 @@
|
|||
#include <windows.h>
|
||||
#include "Exec.h"
|
||||
#include "VersionInfo.h"
|
||||
#include "Wow64.h"
|
||||
|
||||
void LaunchOptions(int nCmdShow) {
|
||||
#if !_WIN64
|
||||
// Some issues arise from the working directory being SysWOW64 rather than System32. Notably,
|
||||
// Windows Vista - 8.1 don't have wuauclt.exe in SysWOW64. Disable WOW64 redirection temporarily
|
||||
// to work around this.
|
||||
PVOID oldValue;
|
||||
BOOL isRedirected = DisableWow64FsRedirection(&oldValue);
|
||||
#endif
|
||||
|
||||
HRESULT hr;
|
||||
|
||||
if (AtLeastWin10()) {
|
||||
// Windows 10+: Open Settings app
|
||||
hr = Exec(NULL, L"ms-settings:windowsupdate-options", NULL, NULL, SW_SHOWDEFAULT, FALSE, NULL);
|
||||
} else if (AtLeastWinVista()) {
|
||||
// Windows Vista, 7, 8: Open Windows Update control panel
|
||||
WCHAR wuauclt[MAX_PATH];
|
||||
ExpandEnvironmentStrings(L"%SystemRoot%\\System32\\wuauclt.exe", wuauclt, ARRAYSIZE(wuauclt));
|
||||
hr = Exec(NULL, wuauclt, L"/ShowOptions", NULL, SW_SHOWDEFAULT, FALSE, NULL);
|
||||
} else {
|
||||
// Windows 2000, XP: Open Automatic Updates control panel
|
||||
WCHAR wuaucpl[MAX_PATH];
|
||||
ExpandEnvironmentStrings(L"%SystemRoot%\\System32\\wuaucpl.cpl", wuaucpl, ARRAYSIZE(wuaucpl));
|
||||
hr = Exec(NULL, wuaucpl, NULL, NULL, SW_SHOWDEFAULT, FALSE, NULL);
|
||||
}
|
||||
|
||||
#if !_WIN64
|
||||
// Revert WOW64 redirection if we changed it
|
||||
if (isRedirected) {
|
||||
RevertWow64FsRedirection(oldValue);
|
||||
}
|
||||
#endif
|
||||
|
||||
PostQuitMessage(hr);
|
||||
}
|
|
@ -0,0 +1,153 @@
|
|||
#include <windows.h>
|
||||
#include "Exec.h"
|
||||
#include "HResult.h"
|
||||
#include "LegacyUpdate.h"
|
||||
#include "MsgBox.h"
|
||||
#include "Registry.h"
|
||||
#include "SelfElevate.h"
|
||||
#include "User.h"
|
||||
#include "VersionInfo.h"
|
||||
#include "Wow64.h"
|
||||
|
||||
static HRESULT RegisterDllInternal(LPWSTR path, BOOL state) {
|
||||
HMODULE module = LoadLibrary(path);
|
||||
if (!module) {
|
||||
return HRESULT_FROM_WIN32(GetLastError());
|
||||
}
|
||||
|
||||
HRESULT hr = S_OK;
|
||||
FARPROC proc = GetProcAddress(module, state ? "DllRegisterServer" : "DllUnregisterServer");
|
||||
if (!proc) {
|
||||
hr = HRESULT_FROM_WIN32(GetLastError());
|
||||
goto end;
|
||||
}
|
||||
|
||||
hr = ((HRESULT (WINAPI *)())proc)();
|
||||
|
||||
end:
|
||||
if (module) {
|
||||
FreeLibrary(module);
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT RegisterDllExternal(LPWSTR path, BOOL state) {
|
||||
WCHAR regsvr32[MAX_PATH];
|
||||
ExpandEnvironmentStrings(L"%SystemRoot%\\System32\\regsvr32.exe", regsvr32, ARRAYSIZE(regsvr32));
|
||||
|
||||
LPWSTR args = (LPWSTR)LocalAlloc(LPTR, (lstrlen(path) + 6) * sizeof(WCHAR));
|
||||
wsprintf(args, L"/s %ls\"%ls\"", state ? L"" : L"/u ", path);
|
||||
|
||||
DWORD status;
|
||||
HRESULT hr = Exec(NULL, regsvr32, args, NULL, SW_HIDE, TRUE, &status);
|
||||
if (!SUCCEEDED(hr)) {
|
||||
hr = HRESULT_FROM_WIN32(GetLastError());
|
||||
return hr;
|
||||
}
|
||||
|
||||
if (status != 0) {
|
||||
// Run again without /s, so the user can see the error
|
||||
wsprintf(args, L"%ls\"%ls\"", state ? L"" : L"/u ", path);
|
||||
hr = Exec(NULL, regsvr32, args, NULL, SW_SHOWDEFAULT, TRUE, &status);
|
||||
}
|
||||
|
||||
return status == 0 ? S_OK : E_FAIL;
|
||||
}
|
||||
|
||||
HRESULT RegisterServer(HWND hwnd, BOOL state, BOOL forLaunch) {
|
||||
// Ensure elevation
|
||||
HRESULT hr = S_OK;
|
||||
LPWSTR installPath;
|
||||
LPWSTR dllPath;
|
||||
|
||||
if (!IsUserAdmin()) {
|
||||
LPWSTR args = (LPWSTR)LocalAlloc(LPTR, 512 * sizeof(WCHAR));
|
||||
wsprintf(args, L"%ls %i", state ? L"/regserver" : L"/unregserver", hwnd);
|
||||
DWORD code;
|
||||
hr = SelfElevate(args, &code);
|
||||
if (!SUCCEEDED(hr)) {
|
||||
// Ignore error on cancelling UAC dialog
|
||||
if (hr == HRESULT_FROM_WIN32(ERROR_CANCELLED)) {
|
||||
hr = S_OK;
|
||||
}
|
||||
goto end;
|
||||
}
|
||||
|
||||
hr = HRESULT_FROM_WIN32(code);
|
||||
goto end;
|
||||
}
|
||||
|
||||
hr = GetInstallPath(&installPath);
|
||||
if (!SUCCEEDED(hr)) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
dllPath = (LPWSTR)LocalAlloc(LPTR, MAX_PATH * sizeof(WCHAR));
|
||||
wsprintf(dllPath, L"%ls\\LegacyUpdate.dll", installPath);
|
||||
|
||||
#ifdef _DEBUG
|
||||
// Warn if registration path differs, to help with debugging
|
||||
LPWSTR currentPath;
|
||||
hr = GetRegistryString(HKEY_CLASSES_ROOT, L"CLSID\\{AD28E0DF-5F5A-40B5-9432-85EFD97D1F9F}\\InprocServer32", NULL, KEY_WOW64_64KEY, ¤tPath, NULL);
|
||||
if (SUCCEEDED(hr) && wcscmp(currentPath, dllPath) != 0) {
|
||||
if (MsgBox(hwnd, L"DEBUG: Native dll currently registered at a different path. Override?", currentPath, MB_YESNO) != IDYES) {
|
||||
hr = S_OK;
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
hr = RegisterDllInternal(dllPath, state);
|
||||
if (!SUCCEEDED(hr)) {
|
||||
// Try external registration
|
||||
if (SUCCEEDED(RegisterDllExternal(dllPath, state))) {
|
||||
hr = S_OK;
|
||||
} else {
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
#if _WIN64
|
||||
if (!SUCCEEDED(hr)) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
wsprintf(dllPath, L"%ls\\LegacyUpdate32.dll", installPath);
|
||||
|
||||
#ifdef _DEBUG
|
||||
// Warn if registration path differs, to help with debugging
|
||||
hr = GetRegistryString(HKEY_CLASSES_ROOT, L"CLSID\\{AD28E0DF-5F5A-40B5-9432-85EFD97D1F9F}\\InprocServer32", NULL, KEY_WOW64_32KEY, ¤tPath, NULL);
|
||||
if (SUCCEEDED(hr) && wcscmp(currentPath, dllPath) != 0) {
|
||||
if (MsgBox(hwnd, L"DEBUG: 32-bit dll currently registered at a different path. Override?", currentPath, MB_YESNO) != IDYES) {
|
||||
hr = S_OK;
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
hr = RegisterDllExternal(dllPath, state);
|
||||
#endif
|
||||
|
||||
end:
|
||||
if (installPath) {
|
||||
LocalFree(installPath);
|
||||
}
|
||||
|
||||
if (dllPath) {
|
||||
LocalFree(dllPath);
|
||||
}
|
||||
|
||||
if (!SUCCEEDED(hr)) {
|
||||
LPWSTR title = state
|
||||
? L"Failed to register Legacy Update ActiveX control"
|
||||
: L"Failed to unregister Legacy Update ActiveX control";
|
||||
MsgBox(hwnd, title, GetMessageForHresult(hr), MB_ICONERROR);
|
||||
}
|
||||
|
||||
if (!forLaunch) {
|
||||
PostQuitMessage(hr);
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
#pragma once
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
HRESULT RegisterServer(HWND hwnd, BOOL state, BOOL forLaunch);
|
|
@ -0,0 +1,12 @@
|
|||
#include "SelfElevate.h"
|
||||
#include <windows.h>
|
||||
#include "Exec.h"
|
||||
#include "VersionInfo.h"
|
||||
|
||||
HRESULT SelfElevate(LPWSTR args, LPDWORD code) {
|
||||
LPWSTR fileName;
|
||||
GetOwnFileName(&fileName);
|
||||
HRESULT hr = Exec(L"runas", fileName, args, NULL, SW_SHOWDEFAULT, TRUE, code);
|
||||
LocalFree(fileName);
|
||||
return hr;
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
#pragma once
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
HRESULT SelfElevate(LPWSTR args, LPDWORD code);
|
|
@ -0,0 +1,138 @@
|
|||
#include "stdafx.h"
|
||||
#include "main.h"
|
||||
#include "resource.h"
|
||||
#include <windows.h>
|
||||
#include <commctrl.h>
|
||||
#include "MsgBox.h"
|
||||
#include "RegisterServer.h"
|
||||
#include "Startup.h"
|
||||
|
||||
HINSTANCE g_hInstance;
|
||||
|
||||
extern void LaunchUpdateSite(int argc, LPWSTR *argv, int nCmdShow);
|
||||
extern void LaunchOptions(int nCmdShow);
|
||||
extern void LaunchLog(int nCmdShow);
|
||||
extern void RunOnce();
|
||||
|
||||
typedef enum Action {
|
||||
ActionLaunch,
|
||||
ActionOptions,
|
||||
ActionLog,
|
||||
ActionRunOnce,
|
||||
ActionRegServer,
|
||||
ActionUnregServer
|
||||
} Action;
|
||||
|
||||
static const LPWSTR actions[] = {
|
||||
L"/launch",
|
||||
L"/options",
|
||||
L"/log",
|
||||
L"/runonce",
|
||||
L"/regserver",
|
||||
L"/unregserver",
|
||||
NULL
|
||||
};
|
||||
|
||||
EXTERN_C __declspec(dllexport)
|
||||
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow) {
|
||||
g_hInstance = hInstance;
|
||||
Startup();
|
||||
|
||||
HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
|
||||
if (!SUCCEEDED(hr)) {
|
||||
ExitProcess(hr);
|
||||
return hr;
|
||||
}
|
||||
|
||||
int argc;
|
||||
LPWSTR *argv = CommandLineToArgvW(GetCommandLineW(), &argc);
|
||||
|
||||
LPWSTR actionFlag = L"/launch";
|
||||
if (argc > 1) {
|
||||
actionFlag = argv[1];
|
||||
}
|
||||
|
||||
// All remaining args past the action
|
||||
LPWSTR *flags = {0};
|
||||
int flagsCount = 0;
|
||||
if (argc > 2) {
|
||||
flags = &argv[2];
|
||||
flagsCount = argc - 2;
|
||||
}
|
||||
|
||||
Action action = -1;
|
||||
|
||||
for (int i = 0; actions[i] != NULL; i++) {
|
||||
if (wcscmp(actionFlag, actions[i]) == 0) {
|
||||
action = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch (action) {
|
||||
case ActionLaunch:
|
||||
LaunchUpdateSite(flagsCount, flags, nCmdShow);
|
||||
break;
|
||||
|
||||
case ActionOptions:
|
||||
LaunchOptions(nCmdShow);
|
||||
break;
|
||||
|
||||
case ActionLog:
|
||||
LaunchLog(nCmdShow);
|
||||
break;
|
||||
|
||||
case ActionRunOnce:
|
||||
RunOnce();
|
||||
break;
|
||||
|
||||
case ActionRegServer:
|
||||
case ActionUnregServer: {
|
||||
BOOL state = action == ActionRegServer;
|
||||
HWND hwnd = flagsCount > 0 ? (HWND)(intptr_t)wcstol(flags[0], NULL, 10) : 0;
|
||||
RegisterServer(hwnd, state, FALSE);
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
const LPWSTR usage = L""
|
||||
L"LegacyUpdate.exe [/launch|/regserver|/unregserver]\n"
|
||||
L"\n"
|
||||
L"/launch\n"
|
||||
L" Launch Legacy Update website in Internet Explorer\n"
|
||||
L"\n"
|
||||
L"/options\n"
|
||||
L" Open the Windows Update Options control panel\n"
|
||||
L"\n"
|
||||
L"/log\n"
|
||||
L" Open the Windows Update log file\n"
|
||||
L"\n"
|
||||
L"/regserver\n"
|
||||
L" Register ActiveX control\n"
|
||||
L"\n"
|
||||
L"/unregserver\n"
|
||||
L" Unregister ActiveX control\n"
|
||||
L"\n"
|
||||
L"If no parameters are provided, /launch is assumed.";
|
||||
MsgBox(NULL, L"LegacyUpdate.exe usage", usage, MB_OK);
|
||||
PostQuitMessage(1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
MSG msg;
|
||||
while (GetMessage(&msg, NULL, 0, 0) == 1) {
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
|
||||
switch (msg.message) {
|
||||
case WM_QUIT:
|
||||
case WM_DESTROY:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
CoUninitialize();
|
||||
ExitProcess(msg.wParam);
|
||||
return msg.wParam;
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
EXTERN_C HINSTANCE g_hInstance;
|
|
@ -0,0 +1,30 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<dependency>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity type="Win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*"/>
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
|
||||
<application>
|
||||
<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/> <!-- Windows Vista -->
|
||||
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/> <!-- Windows 7 -->
|
||||
<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/> <!-- Windows 8 -->
|
||||
<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/> <!-- Windows 8.1 -->
|
||||
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/> <!-- Windows 10 -->
|
||||
</application>
|
||||
</compatibility>
|
||||
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||
<security>
|
||||
<requestedPrivileges>
|
||||
<requestedExecutionLevel level="asInvoker" uiAccess="false"/>
|
||||
</requestedPrivileges>
|
||||
</security>
|
||||
</trustInfo>
|
||||
<application xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||
<windowsSettings>
|
||||
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
|
||||
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2</dpiAwareness>
|
||||
</windowsSettings>
|
||||
</application>
|
||||
</assembly>
|
|
@ -0,0 +1,11 @@
|
|||
#define IDR_CPLTASKS 202
|
||||
|
||||
#define IDI_APPICON 100
|
||||
|
||||
#define IDS_LEGACYUPDATEOCX 1
|
||||
#define IDS_LEGACYUPDATE 2
|
||||
#define IDS_CHECKFORUPDATES 3
|
||||
#define IDS_CHECKFORUPDATES_ALT 4
|
||||
#define IDS_IENOTINSTALLED 5
|
||||
|
||||
#define ID_MANIFEST 1
|
|
@ -0,0 +1,95 @@
|
|||
#include "resource.h"
|
||||
|
||||
#define APSTUDIO_READONLY_SYMBOLS
|
||||
#include <windows.h>
|
||||
#include "Version.h"
|
||||
#undef APSTUDIO_READONLY_SYMBOLS
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// English (United States) resources
|
||||
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
|
||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
#pragma code_page(65001)
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Version
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION VERSION_MAJOR,VERSION_MINOR,VERSION_PATCH,VERSION_BUILD
|
||||
PRODUCTVERSION VERSION_MAJOR,VERSION_MINOR,VERSION_PATCH,VERSION_BUILD
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
#else
|
||||
FILEFLAGS 0x0L
|
||||
#endif
|
||||
FILEOS 0x40004L
|
||||
FILETYPE 0x2L
|
||||
FILESUBTYPE 0x0L
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904b0"
|
||||
BEGIN
|
||||
VALUE "CompanyName", "Hashbang Productions"
|
||||
VALUE "FileDescription", "Legacy Update"
|
||||
VALUE "FileVersion", VERSION_STRING
|
||||
VALUE "InternalName", "LegacyUpdate.exe"
|
||||
VALUE "LegalCopyright", "© Hashbang Productions. All rights reserved."
|
||||
VALUE "OriginalFilename", "LegacyUpdate.exe"
|
||||
VALUE "ProductName", "Legacy Update"
|
||||
VALUE "ProductVersion", VERSION_STRING
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x409, 1200
|
||||
END
|
||||
END
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Icon
|
||||
//
|
||||
|
||||
// Icon with lowest ID value placed first to ensure application icon
|
||||
// remains consistent on all systems.
|
||||
IDI_APPICON ICON "../LegacyUpdate/icon.ico"
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// XML
|
||||
//
|
||||
|
||||
IDR_CPLTASKS XML "CplTasks.xml"
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// String Table
|
||||
//
|
||||
|
||||
STRINGTABLE
|
||||
BEGIN
|
||||
IDS_LEGACYUPDATEOCX "Legacy Update Control"
|
||||
IDS_LEGACYUPDATE "Legacy Update"
|
||||
IDS_CHECKFORUPDATES "Check for updates"
|
||||
IDS_CHECKFORUPDATES_ALT "Check for software and driver updates via Legacy Update."
|
||||
IDS_IENOTINSTALLED "Internet Explorer is not installed. Use Optional Features in Control Panel to install it before using Legacy Update."
|
||||
END
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Manifest
|
||||
//
|
||||
|
||||
ID_MANIFEST RT_MANIFEST "manifest.xml"
|
||||
|
||||
#endif // English (United States) resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
|
@ -0,0 +1,23 @@
|
|||
#pragma once
|
||||
|
||||
#ifndef STRICT
|
||||
#define STRICT
|
||||
#endif
|
||||
|
||||
#define WINVER _WIN32_WINNT_WIN2K
|
||||
#define _WIN32_WINNT _WIN32_WINNT_WIN2K
|
||||
|
||||
// Use msvcrt stdio functions
|
||||
#define __USE_MINGW_ANSI_STDIO 0
|
||||
|
||||
// Enable comctl 6.0 (visual styles)
|
||||
#define ISOLATION_AWARE_ENABLED 1
|
||||
|
||||
// Enable COM C interfaces
|
||||
#define CINTERFACE
|
||||
#define COBJMACROS
|
||||
#define INITGUID
|
||||
|
||||
#include "resource.h"
|
||||
#include <windows.h>
|
||||
#include "Trace.h"
|
|
@ -0,0 +1,64 @@
|
|||
#include <windows.h>
|
||||
#include <nsis/pluginapi.h>
|
||||
#include <exdisp.h>
|
||||
|
||||
const LPWSTR LegacyUpdateSiteURLHttp = L"http://legacyupdate.net/";
|
||||
const LPWSTR LegacyUpdateSiteURLHttps = L"https://legacyupdate.net/";
|
||||
|
||||
PLUGIN_METHOD(CloseIEWindows) {
|
||||
PLUGIN_INIT();
|
||||
|
||||
// Find and close IE windows that might have the ActiveX control loaded
|
||||
IShellWindows *windows;
|
||||
HRESULT hr = CoCreateInstance(&CLSID_ShellWindows, NULL, CLSCTX_ALL, &IID_IShellWindows, (void **)&windows);
|
||||
if (!SUCCEEDED(hr)) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
long count;
|
||||
hr = IShellWindows_get_Count(windows, &count);
|
||||
if (!SUCCEEDED(hr)) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
VARIANT index = {0};
|
||||
index.vt = VT_I4;
|
||||
|
||||
for (long i = 0; i <= count; i++) {
|
||||
IDispatch *item;
|
||||
index.lVal = i;
|
||||
|
||||
hr = IShellWindows_Item(windows, index, &item);
|
||||
if (!SUCCEEDED(hr) || !item) {
|
||||
continue;
|
||||
}
|
||||
|
||||
IWebBrowser2 *browser;
|
||||
hr = IDispatch_QueryInterface(item, &IID_IWebBrowser2, (void **)&browser);
|
||||
IDispatch_Release(item);
|
||||
if (!SUCCEEDED(hr)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
BSTR location;
|
||||
hr = IWebBrowser2_get_LocationURL(browser, &location);
|
||||
if (!SUCCEEDED(hr)) {
|
||||
IWebBrowser2_Release(browser);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (wcsstr(location, LegacyUpdateSiteURLHttp) != NULL || wcsstr(location, LegacyUpdateSiteURLHttps) != NULL) {
|
||||
hr = IWebBrowser2_Quit(browser);
|
||||
}
|
||||
|
||||
SysFreeString(location);
|
||||
IWebBrowser2_Release(browser);
|
||||
}
|
||||
|
||||
end:
|
||||
if (windows) {
|
||||
IShellWindows_Release(windows);
|
||||
}
|
||||
|
||||
pushint(hr);
|
||||
}
|
|
@ -0,0 +1,377 @@
|
|||
#include "stdafx.h"
|
||||
|
||||
#undef _WIN32_WINNT
|
||||
#define _WIN32_WINNT _WIN32_WINNT_VISTA
|
||||
|
||||
#include <windows.h>
|
||||
#include <nsis/pluginapi.h>
|
||||
#include <shlwapi.h>
|
||||
#include <uxtheme.h>
|
||||
#include <vsstyle.h>
|
||||
#include <windowsx.h>
|
||||
#include "main.h"
|
||||
#include "LoadImage.h"
|
||||
#include "Registry.h"
|
||||
#include "VersionInfo.h"
|
||||
|
||||
#ifndef WM_DWMCOMPOSITIONCHANGED
|
||||
#define WM_DWMCOMPOSITIONCHANGED 0x031e
|
||||
#endif
|
||||
|
||||
#define DWMWA_USE_IMMERSIVE_DARK_MODE_BEFORE_20H1 19
|
||||
#define DWMWA_USE_IMMERSIVE_DARK_MODE 20
|
||||
#define DWMWA_CAPTION_COLOR 35
|
||||
#define DWMWA_SYSTEMBACKDROP_TYPE 38
|
||||
#define DWMWA_COLOR_NONE 0xFFFFFFFE
|
||||
#define DWMSBT_MAINWINDOW 2
|
||||
|
||||
#define IDI_BANNER_WORDMARK_LIGHT 1337
|
||||
#define IDI_BANNER_WORDMARK_DARK 1338
|
||||
#define IDI_BANNER_WORDMARK_GLOW 1339
|
||||
|
||||
typedef HRESULT (WINAPI *_DwmExtendFrameIntoClientArea)(HWND hWnd, const MARGINS *pMarInset);
|
||||
typedef HRESULT (WINAPI *_DwmIsCompositionEnabled)(BOOL *pfEnabled);
|
||||
typedef HRESULT (WINAPI *_DwmDefWindowProc)(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, LRESULT *plResult);
|
||||
typedef HRESULT (WINAPI *_DwmSetWindowAttribute)(HWND hwnd, DWORD dwAttribute, LPCVOID pvAttribute, DWORD cbAttribute);
|
||||
typedef HRESULT (WINAPI *_SetWindowThemeAttribute)(HWND hwnd, enum WINDOWTHEMEATTRIBUTETYPE eAttribute, PVOID pvAttribute, DWORD cbAttribute);
|
||||
typedef BOOL (WINAPI *_IsThemeActive)();
|
||||
typedef HTHEME (WINAPI *_OpenThemeData)(HWND hwnd, LPCWSTR pszClassList);
|
||||
typedef HRESULT (WINAPI *_CloseThemeData)(HTHEME hTheme);
|
||||
typedef HRESULT (WINAPI *_DrawThemeBackground)(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, const RECT *pRect, const RECT *pClipRect);
|
||||
|
||||
static _DwmExtendFrameIntoClientArea $DwmExtendFrameIntoClientArea;
|
||||
static _DwmIsCompositionEnabled $DwmIsCompositionEnabled;
|
||||
static _DwmDefWindowProc $DwmDefWindowProc;
|
||||
static _DwmSetWindowAttribute $DwmSetWindowAttribute;
|
||||
static _SetWindowThemeAttribute $SetWindowThemeAttribute;
|
||||
static _IsThemeActive $IsThemeActive;
|
||||
static _OpenThemeData $OpenThemeData;
|
||||
static _CloseThemeData $CloseThemeData;
|
||||
static _DrawThemeBackground $DrawThemeBackground;
|
||||
|
||||
typedef enum Theme {
|
||||
ThemeUnknown = -1,
|
||||
ThemeClassic,
|
||||
ThemeBasic,
|
||||
ThemeAeroLight,
|
||||
ThemeAeroDark
|
||||
} Theme;
|
||||
|
||||
static HBITMAP g_bannerWordmark;
|
||||
static HBITMAP g_bannerWordmarkGlow;
|
||||
static HTHEME g_aeroTheme;
|
||||
static Theme g_theme = ThemeUnknown;
|
||||
|
||||
static WNDPROC g_dialogOrigWndProc;
|
||||
static WNDPROC g_bannerOrigWndProc;
|
||||
static WNDPROC g_bottomOrigWndProc;
|
||||
|
||||
static Theme GetTheme() {
|
||||
BOOL enabled;
|
||||
if (!$DwmIsCompositionEnabled || !$IsThemeActive || !SUCCEEDED($DwmIsCompositionEnabled(&enabled))) {
|
||||
return ThemeClassic;
|
||||
}
|
||||
|
||||
if (enabled) {
|
||||
DWORD light = 1;
|
||||
if (AtLeastWin10_1809()) {
|
||||
GetRegistryDword(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize", L"AppsUseLightTheme", 0, &light);
|
||||
}
|
||||
return light ? ThemeAeroLight : ThemeAeroDark;
|
||||
}
|
||||
|
||||
return $IsThemeActive() ? ThemeBasic : ThemeClassic;
|
||||
}
|
||||
|
||||
static void ConfigureWindow() {
|
||||
HWND bannerWindow = GetDlgItem(g_hwndParent, 1046);
|
||||
HWND bannerDivider = GetDlgItem(g_hwndParent, 1047);
|
||||
HWND bottomDivider = GetDlgItem(g_hwndParent, 6900);
|
||||
if (!bannerWindow || !bannerDivider || !bottomDivider) {
|
||||
return;
|
||||
}
|
||||
|
||||
Theme theme = GetTheme();
|
||||
if (g_theme != theme) {
|
||||
g_theme = theme;
|
||||
MARGINS margins = {0};
|
||||
|
||||
if (theme >= ThemeAeroLight) {
|
||||
// Set glass area
|
||||
RECT rect;
|
||||
GetWindowRect(bannerWindow, &rect);
|
||||
margins.cyTopHeight = rect.bottom - rect.top;
|
||||
}
|
||||
|
||||
if ($DwmExtendFrameIntoClientArea) {
|
||||
$DwmExtendFrameIntoClientArea(g_hwndParent, &margins);
|
||||
}
|
||||
|
||||
ShowWindow(bannerDivider, theme >= ThemeBasic ? SW_HIDE : SW_SHOW);
|
||||
ShowWindow(bottomDivider, theme >= ThemeBasic ? SW_HIDE : SW_SHOW);
|
||||
|
||||
if (g_theme >= ThemeBasic) {
|
||||
DWORD wordmark = g_theme == ThemeAeroDark ? IDI_BANNER_WORDMARK_DARK : IDI_BANNER_WORDMARK_LIGHT;
|
||||
g_bannerWordmark = LoadPNGResource(NULL, MAKEINTRESOURCE(wordmark), L"PNG");
|
||||
if (g_theme >= ThemeAeroLight && AtMostWin7()) {
|
||||
g_bannerWordmarkGlow = LoadPNGResource(NULL, MAKEINTRESOURCE(IDI_BANNER_WORDMARK_GLOW), L"PNG");
|
||||
}
|
||||
} else {
|
||||
DeleteObject(g_bannerWordmark);
|
||||
DeleteObject(g_bannerWordmarkGlow);
|
||||
g_bannerWordmark = NULL;
|
||||
g_bannerWordmarkGlow = NULL;
|
||||
}
|
||||
|
||||
// Set dark mode state
|
||||
if (AtLeastWin10_1809() && $DwmSetWindowAttribute) {
|
||||
DWORD attr = AtLeastWin10_2004() ? DWMWA_USE_IMMERSIVE_DARK_MODE : DWMWA_USE_IMMERSIVE_DARK_MODE_BEFORE_20H1;
|
||||
DWORD value = g_theme == ThemeAeroDark;
|
||||
$DwmSetWindowAttribute(g_hwndParent, attr, &value, sizeof(value));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static LRESULT CALLBACK BannerWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
|
||||
if (g_theme < ThemeBasic) {
|
||||
return CallWindowProc(g_bannerOrigWndProc, hwnd, uMsg, wParam, lParam);
|
||||
}
|
||||
|
||||
switch (uMsg) {
|
||||
case WM_PAINT: {
|
||||
PAINTSTRUCT ps;
|
||||
HDC hdc = BeginPaint(hwnd, &ps);
|
||||
RECT rect;
|
||||
GetClientRect(hwnd, &rect);
|
||||
|
||||
// Draw base color for glass area
|
||||
FillRect(hdc, &rect, GetStockObject(BLACK_BRUSH));
|
||||
|
||||
// Draw Aero Basic titlebar
|
||||
if (g_theme == ThemeBasic && g_aeroTheme && $DrawThemeBackground) {
|
||||
int state = GetActiveWindow() == g_hwndParent ? AW_S_TITLEBAR_ACTIVE : AW_S_TITLEBAR_INACTIVE;
|
||||
$DrawThemeBackground(g_aeroTheme, hdc, AW_TITLEBAR, state, &rect, NULL);
|
||||
}
|
||||
|
||||
float scale = (float)GetDeviceCaps(hdc, LOGPIXELSX) / 96.0f;
|
||||
|
||||
BLENDFUNCTION blendFunc;
|
||||
blendFunc.BlendOp = AC_SRC_OVER;
|
||||
blendFunc.BlendFlags = 0;
|
||||
blendFunc.SourceConstantAlpha = 0xFF;
|
||||
blendFunc.AlphaFormat = AC_SRC_ALPHA;
|
||||
|
||||
// Draw wordmark with alpha blending
|
||||
if (g_bannerWordmarkGlow) {
|
||||
HDC hdcMem = CreateCompatibleDC(hdc);
|
||||
HBITMAP hbmOld = (HBITMAP)SelectObject(hdcMem, g_bannerWordmarkGlow);
|
||||
|
||||
BITMAP bitmap;
|
||||
GetObject(g_bannerWordmarkGlow, sizeof(bitmap), &bitmap);
|
||||
|
||||
LONG width = bitmap.bmWidth * scale;
|
||||
LONG height = bitmap.bmHeight * scale;
|
||||
LONG x = (rect.right - rect.left - width) / 2;
|
||||
LONG y = (rect.bottom - rect.top - height) / 2;
|
||||
|
||||
SetStretchBltMode(hdc, HALFTONE);
|
||||
AlphaBlend(hdc,
|
||||
x, y, width, height, hdcMem,
|
||||
0, 0, bitmap.bmWidth, bitmap.bmHeight, blendFunc);
|
||||
|
||||
SelectObject(hdcMem, hbmOld);
|
||||
DeleteDC(hdcMem);
|
||||
}
|
||||
|
||||
if (g_bannerWordmark) {
|
||||
HDC hdcMem = CreateCompatibleDC(hdc);
|
||||
HBITMAP hbmOld = (HBITMAP)SelectObject(hdcMem, g_bannerWordmark);
|
||||
|
||||
BITMAP bitmap;
|
||||
GetObject(g_bannerWordmark, sizeof(bitmap), &bitmap);
|
||||
|
||||
LONG width = bitmap.bmWidth * scale;
|
||||
LONG height = bitmap.bmHeight * scale;
|
||||
LONG x = (rect.right - rect.left - width) / 2;
|
||||
LONG y = ((rect.bottom - rect.top - height) / 2) - (1 * scale);
|
||||
|
||||
SetStretchBltMode(hdc, HALFTONE);
|
||||
AlphaBlend(hdc,
|
||||
x, y, width, height, hdcMem,
|
||||
0, 0, bitmap.bmWidth, bitmap.bmHeight, blendFunc);
|
||||
|
||||
SelectObject(hdcMem, hbmOld);
|
||||
DeleteDC(hdcMem);
|
||||
}
|
||||
|
||||
EndPaint(hwnd, &ps);
|
||||
return 0;
|
||||
}
|
||||
|
||||
case WM_ERASEBKGND:
|
||||
return DefWindowProc(hwnd, uMsg, wParam, lParam);
|
||||
|
||||
case WM_NCHITTEST:
|
||||
// Pass through to parent
|
||||
return HTTRANSPARENT;
|
||||
}
|
||||
|
||||
if (!g_bannerOrigWndProc) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return CallWindowProc(g_bannerOrigWndProc, hwnd, uMsg, wParam, lParam);
|
||||
}
|
||||
|
||||
static LRESULT CALLBACK BottomWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
|
||||
switch (uMsg) {
|
||||
case WM_PAINT: {
|
||||
// Draw command area background (grey with divider line)
|
||||
if (g_theme < ThemeBasic || !g_aeroTheme || !$DrawThemeBackground) {
|
||||
break;
|
||||
}
|
||||
|
||||
PAINTSTRUCT ps;
|
||||
HDC hdc = BeginPaint(hwnd, &ps);
|
||||
|
||||
RECT rect;
|
||||
GetClientRect(hwnd, &rect);
|
||||
$DrawThemeBackground(g_aeroTheme, hdc, AW_COMMANDAREA, 0, &rect, NULL);
|
||||
|
||||
EndPaint(hwnd, &ps);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!g_bottomOrigWndProc) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return CallWindowProc(g_bottomOrigWndProc, hwnd, uMsg, wParam, lParam);
|
||||
}
|
||||
|
||||
static LRESULT CALLBACK MainWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
|
||||
if (g_theme >= ThemeAeroLight && $DwmDefWindowProc) {
|
||||
LRESULT lRet = 0;
|
||||
if ($DwmDefWindowProc(hwnd, uMsg, wParam, lParam, &lRet)) {
|
||||
return lRet;
|
||||
}
|
||||
}
|
||||
|
||||
switch (uMsg) {
|
||||
case WM_THEMECHANGED:
|
||||
case WM_DWMCOMPOSITIONCHANGED:
|
||||
ConfigureWindow();
|
||||
break;
|
||||
|
||||
case WM_ACTIVATE:
|
||||
case WM_NCACTIVATE:
|
||||
// Redraw banner on activation
|
||||
if (g_theme == ThemeBasic) {
|
||||
InvalidateRect(GetDlgItem(hwnd, 1046), NULL, FALSE);
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_NCHITTEST: {
|
||||
if (g_theme < ThemeBasic) {
|
||||
break;
|
||||
}
|
||||
|
||||
// Allow drag in the header area
|
||||
HWND bannerWindow = GetDlgItem(hwnd, 1046);
|
||||
if (!bannerWindow) {
|
||||
break;
|
||||
}
|
||||
|
||||
POINT hit = {GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)};
|
||||
ScreenToClient(hwnd, &hit);
|
||||
|
||||
RECT rect;
|
||||
GetWindowRect(bannerWindow, &rect);
|
||||
rect.right -= rect.left;
|
||||
rect.bottom -= rect.top;
|
||||
rect.left = 0;
|
||||
rect.top = 0;
|
||||
|
||||
if (PtInRect(&rect, hit)) {
|
||||
return HTCAPTION;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!g_dialogOrigWndProc) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return CallWindowProc(g_dialogOrigWndProc, hwnd, uMsg, wParam, lParam);
|
||||
}
|
||||
|
||||
static UINT_PTR NSISPluginCallback(enum NSPIM event) {
|
||||
// Does nothing, but keeping a callback registered prevents NSIS from unloading the plugin
|
||||
return 0;
|
||||
}
|
||||
|
||||
PLUGIN_METHOD(DialogInit) {
|
||||
PLUGIN_INIT();
|
||||
|
||||
if (g_dialogOrigWndProc) {
|
||||
return;
|
||||
}
|
||||
|
||||
extra->RegisterPluginCallback(g_hInstance, NSISPluginCallback);
|
||||
|
||||
// Get symbols
|
||||
HMODULE dwmapi = LoadLibrary(L"dwmapi.dll");
|
||||
if (dwmapi) {
|
||||
$DwmExtendFrameIntoClientArea = (_DwmExtendFrameIntoClientArea)GetProcAddress(dwmapi, "DwmExtendFrameIntoClientArea");
|
||||
$DwmIsCompositionEnabled = (_DwmIsCompositionEnabled)GetProcAddress(dwmapi, "DwmIsCompositionEnabled");
|
||||
$DwmDefWindowProc = (_DwmDefWindowProc)GetProcAddress(dwmapi, "DwmDefWindowProc");
|
||||
$DwmSetWindowAttribute = (_DwmSetWindowAttribute)GetProcAddress(dwmapi, "DwmSetWindowAttribute");
|
||||
}
|
||||
|
||||
HMODULE uxtheme = LoadLibrary(L"uxtheme.dll");
|
||||
if (uxtheme) {
|
||||
$SetWindowThemeAttribute = (_SetWindowThemeAttribute)GetProcAddress(uxtheme, "SetWindowThemeAttribute");
|
||||
$IsThemeActive = (_IsThemeActive)GetProcAddress(uxtheme, "IsThemeActive");
|
||||
$OpenThemeData = (_OpenThemeData)GetProcAddress(uxtheme, "OpenThemeData");
|
||||
$CloseThemeData = (_CloseThemeData)GetProcAddress(uxtheme, "CloseThemeData");
|
||||
$DrawThemeBackground = (_DrawThemeBackground)GetProcAddress(uxtheme, "DrawThemeBackground");
|
||||
}
|
||||
|
||||
// Get AeroWizard theme
|
||||
if ($OpenThemeData) {
|
||||
g_aeroTheme = $OpenThemeData(g_hwndParent, L"AeroWizard");
|
||||
}
|
||||
|
||||
// Hide title caption/icon
|
||||
if ($SetWindowThemeAttribute) {
|
||||
WTA_OPTIONS options;
|
||||
options.dwFlags = WTNCA_NODRAWCAPTION | WTNCA_NODRAWICON;
|
||||
options.dwMask = WTNCA_NODRAWCAPTION | WTNCA_NODRAWICON;
|
||||
$SetWindowThemeAttribute(g_hwndParent, WTA_NONCLIENT, &options, sizeof(options));
|
||||
}
|
||||
|
||||
// Enable Acrylic blur
|
||||
if (AtLeastWin11_21H1() && $DwmSetWindowAttribute) {
|
||||
// I stole this undocumented 1029 attr from Microsoft Store's StoreInstaller.exe
|
||||
BOOL modern = AtLeastWin11_22H2();
|
||||
DWORD attr = modern ? DWMWA_SYSTEMBACKDROP_TYPE : 1029;
|
||||
DWORD value = modern ? DWMSBT_MAINWINDOW : 1;
|
||||
$DwmSetWindowAttribute(g_hwndParent, attr, &value, sizeof(value));
|
||||
|
||||
// Hide caption background
|
||||
value = DWMWA_COLOR_NONE;
|
||||
$DwmSetWindowAttribute(g_hwndParent, DWMWA_CAPTION_COLOR, &value, sizeof(value));
|
||||
}
|
||||
|
||||
// Set up extended client frame
|
||||
ConfigureWindow();
|
||||
|
||||
// Set up window procedures
|
||||
HWND bannerWindow = GetDlgItem(g_hwndParent, 1046);
|
||||
HWND bottomWindow = GetDlgItem(g_hwndParent, 6901);
|
||||
g_dialogOrigWndProc = (WNDPROC)SetWindowLongPtr(g_hwndParent, GWLP_WNDPROC, (LONG_PTR)MainWndProc);
|
||||
g_bannerOrigWndProc = (WNDPROC)SetWindowLongPtr(bannerWindow, GWLP_WNDPROC, (LONG_PTR)BannerWndProc);
|
||||
g_bottomOrigWndProc = (WNDPROC)SetWindowLongPtr(bottomWindow, GWLP_WNDPROC, (LONG_PTR)BottomWndProc);
|
||||
}
|
|
@ -0,0 +1,602 @@
|
|||
/*
|
||||
Copyright (C) 2002 Robert Rainwater <rrainwater@yahoo.com>
|
||||
Copyright (C) 2002-2023 Nullsoft and Contributors
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
*/
|
||||
#include <windows.h>
|
||||
#include <commctrl.h>
|
||||
#include <winnt.h>
|
||||
#include <nsis/pluginapi.h> // nsis plugin
|
||||
#include "main.h"
|
||||
|
||||
#if defined(_MSC_VER) && !defined(GetVersion)
|
||||
#if _MSC_VER >= 1500
|
||||
FORCEINLINE DWORD NoDepr_GetVersion() { __pragma(warning(push))__pragma(warning(disable:4996)) DWORD r = GetVersion(); __pragma(warning(pop)) return r; }
|
||||
#define GetVersion NoDepr_GetVersion
|
||||
#endif //~ _MSC_VER >= 1500
|
||||
#endif //~ _MSC_VER
|
||||
|
||||
#define TAB_REPLACE _T(" ")
|
||||
#define TAB_REPLACE_SIZE (sizeof(TAB_REPLACE) - sizeof(_T("")))
|
||||
#define TAB_REPLACE_CCH (TAB_REPLACE_SIZE / sizeof(_T("")))
|
||||
enum { MODE_IGNOREOUTPUT = 0, MODE_LINES = 1, MODE_STACK = 2 };
|
||||
|
||||
#define LOOPTIMEOUT 100
|
||||
static HWND g_hwndList;
|
||||
|
||||
static void ExecScript(BOOL log);
|
||||
static TCHAR *my_strstr(TCHAR *a, TCHAR *b);
|
||||
static unsigned int my_atoi(TCHAR *s);
|
||||
static int WINAPI AsExeWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow);
|
||||
|
||||
PLUGIN_METHOD(Exec) {
|
||||
PLUGIN_INIT();
|
||||
ExecScript(MODE_IGNOREOUTPUT);
|
||||
}
|
||||
|
||||
PLUGIN_METHOD(ExecToLog) {
|
||||
PLUGIN_INIT();
|
||||
ExecScript(extra->exec_flags->status_update & 1 ? MODE_LINES : MODE_IGNOREOUTPUT);
|
||||
}
|
||||
|
||||
PLUGIN_METHOD(ExecToStack) {
|
||||
PLUGIN_INIT();
|
||||
ExecScript(MODE_STACK);
|
||||
}
|
||||
|
||||
static BOOL IsLeadSurrogateUTF16(unsigned short c) { return c >= 0xd800 && c <= 0xdbff; }
|
||||
static BOOL IsTrailSurrogateUTF16(unsigned short c) { return c >= 0xdc00 && c <= 0xdfff; }
|
||||
|
||||
static PWSTR MyCharNext(PCWSTR p)
|
||||
{
|
||||
// Note: This is wrong for surrogate pair combining characters but CharNextW does
|
||||
// not support surrogate pairs correctly so we have to manually handle the pairs.
|
||||
if (!p[0]) return (PWSTR) p;
|
||||
if (IsLeadSurrogateUTF16(p[0]) && IsTrailSurrogateUTF16(p[1])) return (PWSTR) p + 2; // Current is a surrogate pair, we incorrectly assume that it is not followed by combining characters.
|
||||
if (IsLeadSurrogateUTF16(p[1]) && IsTrailSurrogateUTF16(p[2])) return (PWSTR) p + 1; // Next is a surrogate pair, we incorrectly assume that it is not a combining character for the current character.
|
||||
return (CharNextW)(p);
|
||||
}
|
||||
#define CharNextW MyCharNext
|
||||
|
||||
static void TruncateStringUTF16LE(LPWSTR Buffer, SIZE_T Length, LPCWSTR Overflow, SIZE_T lenOver) {
|
||||
if (Length) {
|
||||
LPWSTR p = &Buffer[Length - 1];
|
||||
UINT stripBaseCharIfCuttingCombining = TRUE;
|
||||
|
||||
// CharNextW is buggy on XP&2003 but we don't care enough to call GetStringTypeW (http://archives.miloush.net/michkap/archive/2005/01/30/363420.html)
|
||||
if (stripBaseCharIfCuttingCombining && lenOver) {
|
||||
WCHAR buf[] = { *p, Overflow[0], lenOver > 1 ? Overflow[1] : L' ', L'\0' };
|
||||
for (;;) {
|
||||
BOOL comb = CharNextW(buf) > buf + 1;
|
||||
if (!comb || p < Buffer) break;
|
||||
*((WORD*)((BYTE*)&buf[1])) = *((WORD*)((BYTE*)&buf[0]));
|
||||
buf[0] = *p;
|
||||
*p-- = L'\0';
|
||||
}
|
||||
}
|
||||
|
||||
if (IsLeadSurrogateUTF16(*p)) {
|
||||
*p = L'\0'; // Avoid incomplete pair
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void TruncateStringMB(UINT Codepage, LPSTR Buffer, SIZE_T Length, unsigned short OverflowCh) {
|
||||
if (Length) {
|
||||
CHAR *p = &Buffer[Length - 1], buf[] = { *p, ' ', ' ', '\0' };
|
||||
|
||||
if (CharNextExA(Codepage, buf, 0) > buf + 1) { // Remove incomplete DBCS character?
|
||||
*p = '\0';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static BOOL IsWOW64() {
|
||||
#ifdef _WIN64
|
||||
return FALSE;
|
||||
#else
|
||||
typedef BOOL (WINAPI*ISWOW64PROCESS)(HANDLE, BOOL*);
|
||||
ISWOW64PROCESS pfIsWow64Process;
|
||||
typedef BOOL (WINAPI*ISWOW64PROCESS2)(HANDLE, USHORT*, USHORT*);
|
||||
ISWOW64PROCESS2 pfIsWow64Process2;
|
||||
HANDLE hProcess = GetCurrentProcess();
|
||||
HMODULE hK32 = GetModuleHandleA("KERNEL32");
|
||||
UINT_PTR retval;
|
||||
USHORT appmach, image_file_machine_unknown = 0;
|
||||
CHAR funcnam[16]
|
||||
#if defined(_MSC_VER) && (_MSC_VER-0 <= 1400)
|
||||
= "IsWow64Process2"; // MOVSD * 4
|
||||
#else
|
||||
; lstrcpyA(funcnam, "IsWow64Process2");
|
||||
#endif
|
||||
pfIsWow64Process2 = (ISWOW64PROCESS2) GetProcAddress(hK32, funcnam);
|
||||
if (pfIsWow64Process2 && pfIsWow64Process2(hProcess, &appmach, NULL)) {
|
||||
retval = image_file_machine_unknown != appmach;
|
||||
}
|
||||
else {
|
||||
BOOL wow64;
|
||||
pfIsWow64Process = (ISWOW64PROCESS) GetProcAddress(hK32, (funcnam[14] = '\0', funcnam));
|
||||
retval = (UINT_PTR) pfIsWow64Process;
|
||||
if (pfIsWow64Process && (retval = pfIsWow64Process(hProcess, &wow64))) {
|
||||
retval = wow64;
|
||||
}
|
||||
}
|
||||
return (BOOL) (UINT) retval;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Tim Kosse's LogMessage
|
||||
#ifdef UNICODE
|
||||
static void LogMessage(const TCHAR *pStr, BOOL bOEM) {
|
||||
#else
|
||||
static void LogMessage(TCHAR *pStr, BOOL bOEM) {
|
||||
#endif
|
||||
LVITEM item;
|
||||
int nItemCount;
|
||||
if (!g_hwndList) return;
|
||||
//if (!*pStr) return;
|
||||
#ifndef UNICODE
|
||||
if (bOEM == TRUE) OemToCharBuff(pStr, pStr, lstrlen(pStr));
|
||||
#endif
|
||||
nItemCount=(int) SendMessage(g_hwndList, LVM_GETITEMCOUNT, 0, 0);
|
||||
item.mask=LVIF_TEXT;
|
||||
item.pszText=(TCHAR *)pStr;
|
||||
item.cchTextMax=0;
|
||||
item.iItem=nItemCount, item.iSubItem=0;
|
||||
ListView_InsertItem(g_hwndList, &item);
|
||||
ListView_EnsureVisible(g_hwndList, item.iItem, 0);
|
||||
}
|
||||
|
||||
|
||||
void ExecScript(int mode) {
|
||||
TCHAR szRet[128];
|
||||
TCHAR meDLLPath[MAX_PATH];
|
||||
TCHAR *g_exec, *executor;
|
||||
TCHAR *pExec;
|
||||
int ignoreData = mode == MODE_IGNOREOUTPUT;
|
||||
int logMode = mode == MODE_LINES, stackMode = mode == MODE_STACK;
|
||||
unsigned int to, tabExpandLength = logMode ? TAB_REPLACE_CCH : 0, codepage;
|
||||
BOOL bOEM, forceNarrowInput = FALSE;
|
||||
|
||||
*szRet = _T('\0');
|
||||
|
||||
if (!IsWOW64()) {
|
||||
TCHAR* p;
|
||||
int nComSpecSize;
|
||||
|
||||
nComSpecSize = GetModuleFileName(g_hInstance, meDLLPath, MAX_PATH) + 2; // 2 chars for quotes
|
||||
g_exec = (TCHAR *)GlobalAlloc(GPTR, sizeof(TCHAR) * (g_stringsize+nComSpecSize+2)); // 1 for space, 1 for null
|
||||
p = meDLLPath + nComSpecSize - 2; // point p at null char of meDLLPath
|
||||
*g_exec = _T('"');
|
||||
executor = g_exec + 1;
|
||||
|
||||
// Look for the last '\' in path.
|
||||
do
|
||||
{
|
||||
if (*p == _T('\\'))
|
||||
break;
|
||||
p = CharPrev(meDLLPath, p);
|
||||
}
|
||||
while (p > meDLLPath);
|
||||
if (p == meDLLPath)
|
||||
{
|
||||
// bad path
|
||||
pushstring(_T("error"));
|
||||
GlobalFree(g_exec);
|
||||
return;
|
||||
}
|
||||
|
||||
*p = 0;
|
||||
GetTempFileName(meDLLPath, _T("ns"), 0, executor); // executor = new temp file name in module path.
|
||||
*p = _T('\\');
|
||||
if (CopyFile(meDLLPath, executor, FALSE)) // copy current DLL to temp file in module path.
|
||||
{
|
||||
HANDLE hFile, hMapping;
|
||||
LPBYTE pMapView;
|
||||
PIMAGE_NT_HEADERS pNTHeaders;
|
||||
hFile = CreateFile(executor, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING,0, 0);
|
||||
hMapping = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, 0, NULL);
|
||||
pMapView = MapViewOfFile(hMapping, FILE_MAP_WRITE, 0, 0, 0);
|
||||
if (pMapView)
|
||||
{
|
||||
pNTHeaders = (PIMAGE_NT_HEADERS)(pMapView + ((PIMAGE_DOS_HEADER)pMapView)->e_lfanew);
|
||||
// Turning the copied DLL into a stripped down executable.
|
||||
pNTHeaders->FileHeader.Characteristics = IMAGE_FILE_32BIT_MACHINE | IMAGE_FILE_LOCAL_SYMS_STRIPPED |
|
||||
IMAGE_FILE_LINE_NUMS_STRIPPED | IMAGE_FILE_EXECUTABLE_IMAGE;
|
||||
// Windows character-mode user interface (CUI) subsystem.
|
||||
pNTHeaders->OptionalHeader.Subsystem = IMAGE_SUBSYSTEM_WINDOWS_CUI;
|
||||
// g_hInst is assumed to be the very base of the DLL in memory.
|
||||
// WinMain will have the address of the WinMain function in memory.
|
||||
// Getting the difference gets you the relative location of the
|
||||
// WinMain function.
|
||||
pNTHeaders->OptionalHeader.AddressOfEntryPoint = (DWORD) ((DWORD_PTR)AsExeWinMain - (DWORD_PTR)g_hInstance);
|
||||
UnmapViewOfFile(pMapView);
|
||||
}
|
||||
CloseHandle(hMapping);
|
||||
CloseHandle(hFile);
|
||||
}
|
||||
|
||||
lstrcat(g_exec, _T("\""));
|
||||
|
||||
// add space
|
||||
pExec = g_exec + lstrlen(g_exec);
|
||||
*pExec = _T(' ');
|
||||
pExec++;
|
||||
} else {
|
||||
executor = NULL;
|
||||
g_exec = (TCHAR *)GlobalAlloc(GPTR, sizeof(TCHAR) * (g_stringsize+1)); // 1 for NULL
|
||||
pExec = g_exec;
|
||||
}
|
||||
|
||||
to = 0; // default is no timeout
|
||||
bOEM = FALSE; // default is no OEM->ANSI conversion
|
||||
|
||||
g_hwndList = NULL;
|
||||
|
||||
// g_hwndParent = the caller, usually NSIS installer.
|
||||
if (g_hwndParent) // The window class name for dialog boxes is "#32770"
|
||||
g_hwndList = FindWindowEx(FindWindowEx(g_hwndParent, NULL, _T("#32770"), NULL), NULL, _T("SysListView32"), NULL);
|
||||
|
||||
// g_exec is the complete command to run: It has the copy of this DLL turned
|
||||
// into an executable right now.
|
||||
|
||||
params:
|
||||
// Get the command I need to run from the NSIS stack.
|
||||
popstring(pExec);
|
||||
if (my_strstr(pExec, _T("/TIMEOUT=")) == pExec) {
|
||||
TCHAR *szTimeout = pExec + 9;
|
||||
to = my_atoi(szTimeout);
|
||||
*pExec = 0;
|
||||
goto params;
|
||||
}
|
||||
if (!lstrcmpi(pExec, _T("/OEM"))) {
|
||||
bOEM = forceNarrowInput = TRUE;
|
||||
*pExec = 0;
|
||||
goto params;
|
||||
}
|
||||
if (!lstrcmpi(pExec, _T("/MBCS"))) {
|
||||
forceNarrowInput = TRUE;
|
||||
*pExec = 0;
|
||||
goto params;
|
||||
}
|
||||
|
||||
if (!pExec[0])
|
||||
{
|
||||
pushstring(_T("error"));
|
||||
if (pExec-2 >= g_exec)
|
||||
*(pExec-2) = _T('\0'); // skip space and quote
|
||||
if (executor) DeleteFile(executor);
|
||||
GlobalFree(g_exec);
|
||||
return;
|
||||
}
|
||||
|
||||
// Got all the params off the stack.
|
||||
|
||||
{
|
||||
STARTUPINFO si = { sizeof(si), };
|
||||
SECURITY_ATTRIBUTES sa = { sizeof(sa), };
|
||||
SECURITY_DESCRIPTOR sd = { 0, };
|
||||
PROCESS_INFORMATION pi;
|
||||
const BOOL isNT = sizeof(void*) > 4 || (GetVersion() < 0x80000000);
|
||||
HANDLE newstdout = 0, read_stdout = 0;
|
||||
HANDLE newstdin = 0, read_stdin = 0;
|
||||
int utfSource = sizeof(TCHAR) > 1 && !forceNarrowInput ? -1 : FALSE, utfOutput = sizeof(TCHAR) > 1;
|
||||
DWORD cbRead, dwLastOutput;
|
||||
DWORD dwExit = 0, waitResult = WAIT_TIMEOUT;
|
||||
static BYTE bufSrc[1024];
|
||||
BYTE *pSrc;
|
||||
SIZE_T cbSrcTot = sizeof(bufSrc), cbSrc = 0, cbSrcFree;
|
||||
TCHAR *bufOutput = 0, *pNewAlloc, *pD;
|
||||
SIZE_T cchAlloc, cbAlloc, cchFree;
|
||||
#ifndef _MSC_VER // Avoid GCC "may be used uninitialized in this function" warnings
|
||||
pD = NULL;
|
||||
cchAlloc = 0;
|
||||
#endif
|
||||
|
||||
pi.hProcess = pi.hThread = NULL;
|
||||
codepage = bOEM ? CP_OEMCP : CP_ACP;
|
||||
|
||||
if (!ignoreData) {
|
||||
cbAlloc = stackMode ? (g_stringsize * sizeof(TCHAR)) : sizeof(bufSrc) * 4, cchAlloc = cbAlloc / sizeof(TCHAR);
|
||||
pD = bufOutput = GlobalAlloc(GPTR, cbAlloc + sizeof(TCHAR)); // Include "hidden" space for a \0
|
||||
if (!bufOutput) {
|
||||
lstrcpy(szRet, _T("error"));
|
||||
goto done;
|
||||
}
|
||||
*bufOutput = _T('\0');
|
||||
}
|
||||
|
||||
sa.bInheritHandle = TRUE;
|
||||
sa.lpSecurityDescriptor = NULL;
|
||||
if (isNT) {
|
||||
InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
|
||||
SetSecurityDescriptorDacl(&sd, TRUE, NULL, FALSE);
|
||||
sa.lpSecurityDescriptor = &sd;
|
||||
}
|
||||
|
||||
if (!CreatePipe(&read_stdout, &newstdout, &sa, 0)) {
|
||||
lstrcpy(szRet, _T("error"));
|
||||
goto done;
|
||||
}
|
||||
if (!CreatePipe(&read_stdin, &newstdin, &sa, 0)) {
|
||||
lstrcpy(szRet, _T("error"));
|
||||
goto done;
|
||||
}
|
||||
|
||||
GetStartupInfo(&si); // Why?
|
||||
si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
|
||||
si.wShowWindow = SW_HIDE;
|
||||
si.hStdInput = newstdin;
|
||||
si.hStdOutput = newstdout;
|
||||
si.hStdError = newstdout;
|
||||
if (!CreateProcess(NULL, g_exec, NULL, NULL, TRUE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) {
|
||||
lstrcpy(szRet, _T("error"));
|
||||
goto done;
|
||||
}
|
||||
|
||||
// Now I'm talking with an executable copy of myself.
|
||||
dwLastOutput = GetTickCount();
|
||||
for (;;) {
|
||||
TCHAR bufCh[2];
|
||||
waitForProcess:
|
||||
waitResult = WaitForSingleObject(pi.hProcess, 0);
|
||||
GetExitCodeProcess(pi.hProcess, &dwExit);
|
||||
readMore:
|
||||
PeekNamedPipe(read_stdout, 0, 0, 0, &cbRead, NULL);
|
||||
if (!cbRead) {
|
||||
if (waitResult == WAIT_OBJECT_0) {
|
||||
break; // No data in the pipe and process ended, we are done
|
||||
}
|
||||
if (to && GetTickCount() > dwLastOutput+to) {
|
||||
TerminateProcess(pi.hProcess, -1);
|
||||
lstrcpy(szRet, _T("timeout"));
|
||||
}
|
||||
else {
|
||||
Sleep(LOOPTIMEOUT);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
dwLastOutput = GetTickCount();
|
||||
ReadFile(read_stdout, bufSrc + cbSrc, (DWORD) (cbSrcFree = cbSrcTot - cbSrc), &cbRead, NULL);
|
||||
cbSrcFree -= cbRead, cbSrc = cbSrcTot - cbSrcFree;
|
||||
pSrc = bufSrc;
|
||||
|
||||
if (utfSource < 0 && cbSrc) { // Simple UTF-16LE detection
|
||||
#ifdef UNICODE
|
||||
utfSource = IsTextUnicode(pSrc, (UINT) (cbSrc & ~1), NULL) != FALSE;
|
||||
#else
|
||||
utfSource = (cbSrc >= 3 && pSrc[0] && !pSrc[1]) || (cbSrc > 4 && pSrc[2] && !pSrc[3]); // Lame latin-only test
|
||||
utfSource |= (cbSrc > 3 && pSrc[0] == 0xFF && pSrc[1] == 0xFE && (pSrc[2] | pSrc[3])); // Lame BOM test
|
||||
#endif
|
||||
}
|
||||
|
||||
if (ignoreData) {
|
||||
cbSrc = 0; // Overwrite the whole buffer every read
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!cbRead) {
|
||||
continue; // No new data, read more before trying to parse
|
||||
}
|
||||
|
||||
parseLines:
|
||||
cchFree = cchAlloc - (pD - bufOutput);
|
||||
for (;;) {
|
||||
DWORD cbSrcChar = 1, cchDstChar, i;
|
||||
*pD = _T('\0'); // Terminate output buffer because we can unexpectedly run out of data
|
||||
if (!cbSrc) {
|
||||
goto readMore;
|
||||
}
|
||||
|
||||
if (utfSource) { // UTF-16LE --> ?:
|
||||
if (cbSrc < 2) {
|
||||
goto readMore;
|
||||
}
|
||||
if (utfOutput) { // UTF-16LE --> UTF-16LE:
|
||||
bufCh[0] = ((TCHAR*)pSrc)[0], cbSrcChar = sizeof(WCHAR), cchDstChar = 1; // We only care about certain ASCII characters so we don't bother dealing with surrogate pairs.
|
||||
}
|
||||
else { // UTF-16LE --> DBCS
|
||||
// TODO: This is tricky because we need the complete base character (or surrogate pair) and all the trailing combining characters for a grapheme in the buffer before we can call WideCharToMultiByte.
|
||||
utfOutput = FALSE; // For now we just treat it as DBCS
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else { // DBCS --> ?:
|
||||
if (utfOutput) { // DBCS --> UTF-16LE:
|
||||
BOOL isMb = IsDBCSLeadByteEx(codepage, ((CHAR*)pSrc)[0]);
|
||||
if (isMb && cbSrc < ++cbSrcChar) {
|
||||
goto readMore;
|
||||
}
|
||||
cchDstChar = MultiByteToWideChar(codepage, 0, (CHAR*)pSrc, cbSrcChar, (WCHAR*) bufCh, 2);
|
||||
}
|
||||
else { // DBCS --> DBCS:
|
||||
bufCh[0] = ((CHAR*)pSrc)[0], cchDstChar = 1; // Note: OEM codepage will be converted by LogMessage
|
||||
}
|
||||
}
|
||||
|
||||
if (bufCh[0] == _T('\t') && tabExpandLength) { // Expand tab to spaces?
|
||||
if (cchFree < tabExpandLength) {
|
||||
goto resizeOutputBuffer;
|
||||
}
|
||||
lstrcpy(pD, TAB_REPLACE);
|
||||
pD += tabExpandLength, cchFree -= tabExpandLength;
|
||||
}
|
||||
else if (bufCh[0] == _T('\r') && logMode) {
|
||||
// Eating it
|
||||
}
|
||||
else if (bufCh[0] == _T('\n') && logMode) {
|
||||
LogMessage(bufOutput, bOEM); // Output has already been \0 terminated
|
||||
*(pD = bufOutput) = _T('\0'), cchFree = cchAlloc;
|
||||
}
|
||||
else {
|
||||
if (cchFree < cchDstChar) {
|
||||
SIZE_T cchOrgOffset;
|
||||
resizeOutputBuffer:
|
||||
if (stackMode) {
|
||||
ignoreData = TRUE; // Buffer was already maximum for the NSIS stack, we cannot handle more data
|
||||
if (utfOutput)
|
||||
TruncateStringUTF16LE((LPWSTR) bufOutput, pD - bufOutput, (LPCWSTR) bufCh, cchDstChar);
|
||||
else
|
||||
TruncateStringMB(codepage, (LPSTR) bufOutput, pD - bufOutput, bufCh[0]);
|
||||
goto waitForProcess;
|
||||
}
|
||||
cchAlloc += 1024, cbAlloc = cchAlloc / sizeof(TCHAR);
|
||||
pNewAlloc = GlobalReAlloc(bufOutput, cbAlloc + sizeof(TCHAR),GPTR|GMEM_MOVEABLE); // Include "hidden" space for a \0
|
||||
if (!pNewAlloc) {
|
||||
lstrcpy(szRet, _T("error"));
|
||||
ignoreData = TRUE;
|
||||
goto waitForProcess;
|
||||
}
|
||||
cchOrgOffset = pD - bufOutput;
|
||||
*(pD = (bufOutput = pNewAlloc) + cchOrgOffset) = _T('\0');
|
||||
goto parseLines;
|
||||
}
|
||||
for (i = 0; i < cchDstChar; ++i) {
|
||||
*pD++ = bufCh[i], --cchFree;
|
||||
}
|
||||
}
|
||||
pSrc += cbSrcChar, cbSrc -= cbSrcChar;
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
if (stackMode) pushstring(bufOutput);
|
||||
if (logMode && *bufOutput) LogMessage(bufOutput,bOEM); // Write remaining output
|
||||
if (dwExit == STATUS_ILLEGAL_INSTRUCTION)
|
||||
lstrcpy(szRet, _T("error"));
|
||||
if (!szRet[0]) wsprintf(szRet,_T("%d"),dwExit);
|
||||
pushstring(szRet);
|
||||
CloseHandle(pi.hThread);
|
||||
CloseHandle(pi.hProcess);
|
||||
CloseHandle(newstdout);
|
||||
CloseHandle(read_stdout);
|
||||
CloseHandle(newstdin);
|
||||
CloseHandle(read_stdin);
|
||||
if (pExec-2 >= g_exec)
|
||||
*(pExec-2) = _T('\0'); // skip space and quote
|
||||
if (executor)
|
||||
DeleteFile(executor);
|
||||
GlobalFree(g_exec);
|
||||
if (bufOutput)
|
||||
GlobalFree(bufOutput);
|
||||
}
|
||||
}
|
||||
|
||||
static TCHAR *my_strstr(TCHAR *a, TCHAR *b)
|
||||
{
|
||||
int l = lstrlen(b);
|
||||
while (lstrlen(a) >= l)
|
||||
{
|
||||
TCHAR c = a[l];
|
||||
a[l] = 0;
|
||||
if (!lstrcmpi(a, b))
|
||||
{
|
||||
a[l] = c;
|
||||
return a;
|
||||
}
|
||||
a[l] = c;
|
||||
a = CharNext(a);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static unsigned int my_atoi(TCHAR *s) {
|
||||
unsigned int v=0;
|
||||
if (*s == _T('0') && (s[1] == _T('x') || s[1] == _T('X'))) {
|
||||
s+=2;
|
||||
for (;;) {
|
||||
int c=*s++;
|
||||
if (c >= _T('0') && c <= _T('9')) c-=_T('0');
|
||||
else if (c >= _T('a') && c <= _T('f')) c-=_T('a')-10;
|
||||
else if (c >= _T('A') && c <= _T('F')) c-=_T('A')-10;
|
||||
else break;
|
||||
v<<=4;
|
||||
v+=c;
|
||||
}
|
||||
}
|
||||
else if (*s == _T('0') && s[1] <= _T('7') && s[1] >= _T('0')) {
|
||||
s++;
|
||||
for (;;) {
|
||||
int c=*s++;
|
||||
if (c >= _T('0') && c <= _T('7')) c-=_T('0');
|
||||
else break;
|
||||
v<<=3;
|
||||
v+=c;
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (;;) {
|
||||
int c=*s++ - _T('0');
|
||||
if (c < 0 || c > 9) break;
|
||||
v*=10;
|
||||
v+=c;
|
||||
}
|
||||
}
|
||||
return (int)v;
|
||||
}
|
||||
|
||||
int WINAPI AsExeWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
|
||||
{
|
||||
DWORD Ret;
|
||||
STARTUPINFO si = {0};
|
||||
PROCESS_INFORMATION pi = {0};
|
||||
TCHAR command_line[1024]; //BUGBUG
|
||||
TCHAR seekchar=_T(' ');
|
||||
TCHAR *cmdline;
|
||||
|
||||
si.cb = sizeof(si);
|
||||
// Make child process use this app's standard files. Not needed because the handles
|
||||
// we created when executing this process were inheritable.
|
||||
//si.dwFlags = STARTF_USESTDHANDLES;
|
||||
//si.hStdInput = GetStdHandle (STD_INPUT_HANDLE);
|
||||
//si.hStdOutput = GetStdHandle (STD_OUTPUT_HANDLE);
|
||||
//si.hStdError = GetStdHandle (STD_ERROR_HANDLE);
|
||||
lstrcpyn(command_line, GetCommandLine(), 1024);
|
||||
|
||||
cmdline = command_line;
|
||||
if (*cmdline == _T('\"')) seekchar = *cmdline++;
|
||||
|
||||
while (*cmdline && *cmdline != seekchar) cmdline=CharNext(cmdline);
|
||||
cmdline=CharNext(cmdline);
|
||||
// skip any spaces before the arguments
|
||||
while (*cmdline && *cmdline == _T(' ')) cmdline++;
|
||||
|
||||
Ret = CreateProcess (NULL, cmdline,
|
||||
NULL, NULL,
|
||||
TRUE, 0,
|
||||
NULL, NULL,
|
||||
&si, &pi
|
||||
);
|
||||
|
||||
if (Ret)
|
||||
{
|
||||
WaitForSingleObject(pi.hProcess, INFINITE);
|
||||
GetExitCodeProcess(pi.hProcess, &Ret);
|
||||
CloseHandle (pi.hProcess);
|
||||
CloseHandle (pi.hThread);
|
||||
ExitProcess(Ret);
|
||||
}
|
||||
else
|
||||
{
|
||||
ExitProcess(STATUS_ILLEGAL_INSTRUCTION);
|
||||
}
|
||||
|
||||
return 0; // dummy
|
||||
}
|
|
@ -0,0 +1,122 @@
|
|||
#include <windows.h>
|
||||
#include <nsis/pluginapi.h>
|
||||
#include "main.h"
|
||||
#include "WMI.h"
|
||||
#include "VersionInfo.h"
|
||||
#include "licdll.h"
|
||||
#include <slpublic.h>
|
||||
|
||||
typedef HRESULT (WINAPI *_SLOpen)(HSLC *);
|
||||
typedef HRESULT (WINAPI *_SLGetLicensingStatusInformation)(HSLC, const SLID *, DWORD, DWORD, UINT *, SL_LICENSING_STATUS **);
|
||||
typedef HRESULT (WINAPI *_SLClose)(HSLC);
|
||||
|
||||
static _SLOpen $SLOpen;
|
||||
static _SLClose $SLClose;
|
||||
static _SLGetLicensingStatusInformation $SLGetLicensingStatusInformation;
|
||||
|
||||
static BOOL g_loadedLicenseStatus = FALSE;
|
||||
static BOOL g_isActivated = TRUE;
|
||||
|
||||
PLUGIN_METHOD(IsActivated) {
|
||||
PLUGIN_INIT();
|
||||
|
||||
// Get the Operating System Version information as well as the CPU architecture.
|
||||
// We'll need this so that we activate the correct COM object on 64-bit versions
|
||||
// of Windows XP and Windows Server 2003.
|
||||
OSVERSIONINFOEX* versionInfo = GetVersionInfo();
|
||||
SYSTEM_INFO systemInfo;
|
||||
GetSystemInfo(&systemInfo);
|
||||
|
||||
// Activation is irrelevant prior to XP
|
||||
if (g_loadedLicenseStatus || !AtLeastWinXP2002()) {
|
||||
pushint(g_isActivated);
|
||||
return;
|
||||
}
|
||||
|
||||
g_loadedLicenseStatus = TRUE;
|
||||
|
||||
if (AtLeastWinVista()) {
|
||||
// Vista+: Ask the Software Licensing Service
|
||||
if (!$SLOpen) {
|
||||
HMODULE slc = LoadLibrary(L"slc.dll");
|
||||
$SLOpen = (_SLOpen)GetProcAddress(slc, "SLOpen");
|
||||
$SLClose = (_SLClose)GetProcAddress(slc, "SLClose");
|
||||
$SLGetLicensingStatusInformation = (_SLGetLicensingStatusInformation)GetProcAddress(slc, "SLGetLicensingStatusInformation");
|
||||
}
|
||||
|
||||
if (!$SLOpen || !$SLClose || !$SLGetLicensingStatusInformation) {
|
||||
TRACE(L"Failed to load slc.dll");
|
||||
pushint(1);
|
||||
return;
|
||||
}
|
||||
|
||||
HSLC slc;
|
||||
SL_LICENSING_STATUS *status;
|
||||
UINT count;
|
||||
HRESULT hr = $SLOpen(&slc);
|
||||
if (!SUCCEEDED(hr)) {
|
||||
goto end_slc;
|
||||
}
|
||||
|
||||
hr = $SLGetLicensingStatusInformation(slc, &WINDOWS_SLID, 0, 0, &count, &status);
|
||||
if (!SUCCEEDED(hr) || count == 0) {
|
||||
goto end_slc;
|
||||
}
|
||||
|
||||
// Iterate through all statuses until we find one in Licensed status.
|
||||
g_isActivated = FALSE;
|
||||
for (int i = 0; i < count; i++) {
|
||||
if (status[i].eStatus == SL_LICENSING_STATUS_LICENSED) {
|
||||
g_isActivated = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
end_slc:
|
||||
if (status) {
|
||||
LocalFree(status);
|
||||
}
|
||||
if (slc) {
|
||||
$SLClose(slc);
|
||||
}
|
||||
} else {
|
||||
// XP: Use private API
|
||||
ICOMLicenseAgent *agent;
|
||||
HRESULT hr;
|
||||
|
||||
// On XP and Server 2003 x64, we need to pass a different argument to CoCreateInstance.
|
||||
if (systemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) {
|
||||
hr = CoCreateInstance(&CLSID_COMLicenseAgent, NULL, CLSCTX_INPROC_SERVER | CLSCTX_ACTIVATE_64_BIT_SERVER, &IID_ICOMLicenseAgent, (void **)&agent);
|
||||
} else {
|
||||
hr = CoCreateInstance(&CLSID_COMLicenseAgent, NULL, CLSCTX_INPROC_SERVER, &IID_ICOMLicenseAgent, (void **)&agent);
|
||||
}
|
||||
|
||||
if (!SUCCEEDED(hr)) {
|
||||
TRACE(L"COMLicenseAgent load failed: %x", hr);
|
||||
goto end_xp;
|
||||
}
|
||||
|
||||
ULONG result;
|
||||
hr = ICOMLicenseAgent_Initialize(agent, 0xC475, 3, NULL, &result);
|
||||
if (!SUCCEEDED(hr) || result != 0) {
|
||||
TRACE(L"COMLicenseAgent init failed: %x", hr);
|
||||
goto end_xp;
|
||||
}
|
||||
|
||||
ULONG wpaLeft, evalLeft;
|
||||
hr = ICOMLicenseAgent_GetExpirationInfo(agent, &wpaLeft, &evalLeft);
|
||||
if (!SUCCEEDED(hr)) {
|
||||
TRACE(L"COMLicenseAgent GetExpirationInfo failed: %x", hr);
|
||||
goto end_xp;
|
||||
}
|
||||
|
||||
g_isActivated = wpaLeft == MAXLONG;
|
||||
|
||||
end_xp:
|
||||
if (agent) {
|
||||
ICOMLicenseAgent_Release(agent);
|
||||
}
|
||||
}
|
||||
|
||||
pushint(g_isActivated);
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
#include <windows.h>
|
||||
#include <nsis/pluginapi.h>
|
||||
#include "User.h"
|
||||
|
||||
PLUGIN_METHOD(IsAdmin) {
|
||||
PLUGIN_INIT();
|
||||
|
||||
pushint(IsUserAdmin());
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
#include <windows.h>
|
||||
#include <nsis/pluginapi.h>
|
||||
#include <wincrypt.h>
|
||||
#include "HResult.h"
|
||||
|
||||
PLUGIN_METHOD(UpdateRoots) {
|
||||
PLUGIN_INIT();
|
||||
|
||||
HRESULT hr = E_FAIL;
|
||||
WCHAR stateStr[1024], store[1024], path[1024];
|
||||
popstring(stateStr);
|
||||
popstring(store);
|
||||
popstring(path);
|
||||
|
||||
if (!stateStr || !store || !path) {
|
||||
pushint(E_INVALIDARG);
|
||||
return;
|
||||
}
|
||||
|
||||
BOOL add;
|
||||
if (lstrcmpi(stateStr, L"/update") == 0) {
|
||||
add = TRUE;
|
||||
} else if (lstrcmpi(stateStr, L"/delete") == 0) {
|
||||
add = FALSE;
|
||||
} else {
|
||||
pushint(E_INVALIDARG);
|
||||
return;
|
||||
}
|
||||
|
||||
HCERTSTORE srcStore = CertOpenStore(CERT_STORE_PROV_FILENAME_W, 0, 0, CERT_STORE_READONLY_FLAG, path);
|
||||
if (!srcStore) {
|
||||
TRACE(L"CertOpenStore for %ls failed: %08x", path, hr);
|
||||
hr = HRESULT_FROM_WIN32(GetLastError());
|
||||
goto end;
|
||||
}
|
||||
|
||||
HCERTSTORE dstStore = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W, 0, 0, CERT_SYSTEM_STORE_LOCAL_MACHINE, store);
|
||||
if (!dstStore) {
|
||||
hr = HRESULT_FROM_WIN32(GetLastError());
|
||||
TRACE(L"CertOpenStore for %ls failed: %08x", store, hr);
|
||||
goto end;
|
||||
}
|
||||
|
||||
PCCERT_CONTEXT cert = NULL;
|
||||
while ((cert = CertEnumCertificatesInStore(srcStore, cert)) != NULL) {
|
||||
BOOL result = add
|
||||
? CertAddCertificateContextToStore(dstStore, cert, CERT_STORE_ADD_REPLACE_EXISTING, NULL)
|
||||
: CertDeleteCertificateFromStore(CertDuplicateCertificateContext(cert));
|
||||
if (!result) {
|
||||
TRACE(L"cert %ls in %ls failed: %d\n", add ? L"add" : L"delete", store, GetLastError());
|
||||
hr = HRESULT_FROM_WIN32(GetLastError());
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
hr = S_OK;
|
||||
|
||||
end:
|
||||
if (srcStore) {
|
||||
CertCloseStore(srcStore, 0);
|
||||
}
|
||||
if (dstStore) {
|
||||
CertCloseStore(dstStore, 0);
|
||||
}
|
||||
|
||||
pushint(hr);
|
||||
}
|
|
@ -0,0 +1,99 @@
|
|||
Var Dialog
|
||||
Var Dialog.Y
|
||||
|
||||
Function ActiveXPage
|
||||
; Skip in runonce
|
||||
${If} ${IsRunOnce}
|
||||
${OrIf} ${IsPostInstall}
|
||||
Abort
|
||||
${EndIf}
|
||||
|
||||
; Skip if not required
|
||||
${If} ${AtLeastWin7}
|
||||
; TODO: Fix ordering of setup.nsi so we can do this
|
||||
; ${OrIfNot} ${SectionIsSelected} ${LEGACYUPDATE}
|
||||
Abort
|
||||
${EndIf}
|
||||
|
||||
!insertmacro MUI_HEADER_TEXT "How do you want to use Windows Update?" ""
|
||||
|
||||
nsDialogs::Create 1018
|
||||
Pop $Dialog
|
||||
|
||||
${AeroWizardDialogControl} $Dialog
|
||||
|
||||
StrCpy $Dialog.Y 0
|
||||
|
||||
${NSD_CreateLabel} 0 $Dialog.Y -1u 24u "Legacy Update configures Windows Update to use the Legacy Update proxy server, resolving connection issues to the official Microsoft Windows Update service. You can choose between two options to access Windows Update."
|
||||
Pop $0
|
||||
${AeroWizardDialogControl} $0
|
||||
|
||||
IntOp $Dialog.Y $Dialog.Y + 60
|
||||
|
||||
${NSD_CreateIcon} 3u $Dialog.Y 4u 4u ""
|
||||
Pop $0
|
||||
${AeroWizardDialogControl} $0
|
||||
${NSD_SetIconFromInstaller} $0 103
|
||||
|
||||
${NSD_CreateRadioButton} 30u $Dialog.Y -30u 10u "Use the Legacy Update website"
|
||||
Pop $0
|
||||
${AeroWizardDialogControl} $0
|
||||
${NSD_OnClick} $0 ActiveXPageSelectionChanged
|
||||
SendMessage $0 ${BM_SETCHECK} ${BST_CHECKED} 0
|
||||
|
||||
${NSD_SetFocus} $0
|
||||
|
||||
${If} ${AtLeastWinVista}
|
||||
StrCpy $0 "The Legacy Update website is a replacement for the original Windows Update website. If you select this, you can still use the Windows Update Control Panel."
|
||||
${Else}
|
||||
StrCpy $0 "The Legacy Update website is a replacement for the original Windows Update website, allowing you to download optional updates and drivers."
|
||||
${EndIf}
|
||||
|
||||
IntOp $Dialog.Y $Dialog.Y + 17
|
||||
|
||||
${NSD_CreateLabel} 41u $Dialog.Y -41u 24u "$0"
|
||||
Pop $0
|
||||
${AeroWizardDialogControl} $0
|
||||
|
||||
IntOp $Dialog.Y $Dialog.Y + 50
|
||||
|
||||
${NSD_CreateIcon} 3u $Dialog.Y 4u 4u ""
|
||||
Pop $0
|
||||
${AeroWizardDialogControl} $0
|
||||
|
||||
${If} ${AtLeastWinVista}
|
||||
${NSD_SetIcon} $0 "$WINDIR\System32\wucltux.dll" $1
|
||||
StrCpy $1 "Use the Windows Update Control Panel"
|
||||
StrCpy $2 "Legacy Update is compatible with the built-in Windows Update Control Panel. Make sure to check for updates $\"managed by your system administrator$\" to use the Legacy Update proxy server."
|
||||
${Else}
|
||||
${NSD_SetIcon} $0 "res://$WINDIR\System32\wupdmgr.exe/#Icon/APPICON" $1
|
||||
StrCpy $1 "Use Automatic Updates"
|
||||
StrCpy $2 "Use the built-in Automatic Updates feature to download and install updates. You will only be able to download critical updates."
|
||||
${EndIf}
|
||||
|
||||
${NSD_CreateRadioButton} 30u $Dialog.Y -30u 10u "$1"
|
||||
Pop $0
|
||||
${AeroWizardDialogControl} $0
|
||||
${NSD_OnClick} $0 ActiveXPageSelectionChanged
|
||||
|
||||
IntOp $Dialog.Y $Dialog.Y + 17
|
||||
|
||||
${NSD_CreateLabel} 41u $Dialog.Y -41u 24u "$2"
|
||||
Pop $0
|
||||
${AeroWizardDialogControl} $0
|
||||
|
||||
nsDialogs::Show
|
||||
Call AeroWizardOnShow
|
||||
FunctionEnd
|
||||
|
||||
Function ActiveXPageSelectionChanged
|
||||
Pop $0
|
||||
${NSD_GetState} $0 $0
|
||||
|
||||
; TODO: Fix ordering of setup.nsi so we can do this
|
||||
${If} $0 == ${BST_CHECKED}
|
||||
; !insertmacro UnselectSection ${ACTIVEX}
|
||||
${Else}
|
||||
; !insertmacro SelectSection ${ACTIVEX}
|
||||
${EndIf}
|
||||
FunctionEnd
|
|
@ -0,0 +1,170 @@
|
|||
Function NeedsPackage
|
||||
Pop $0
|
||||
ClearErrors
|
||||
FindFirst $R0 $R1 "$WINDIR\servicing\Packages\$0~31bf3856ad364e35~*"
|
||||
FindClose $R0
|
||||
${If} ${Errors}
|
||||
Push 1
|
||||
${Else}
|
||||
Push 0
|
||||
${EndIf}
|
||||
FunctionEnd
|
||||
|
||||
!macro SPHandler kbid pkg title
|
||||
Function Needs${kbid}
|
||||
Push ${pkg}
|
||||
Call NeedsPackage
|
||||
FunctionEnd
|
||||
|
||||
Function Download${kbid}
|
||||
Call Needs${kbid}
|
||||
Pop $0
|
||||
${If} $0 == 1
|
||||
Call GetArch
|
||||
Pop $0
|
||||
ReadINIStr $0 $PLUGINSDIR\Patches.ini "${kbid}" $0
|
||||
ReadINIStr $1 $PLUGINSDIR\Patches.ini "${kbid}" Prefix
|
||||
!insertmacro Download "${title}" "$1$0" "${kbid}.exe" 1
|
||||
${EndIf}
|
||||
FunctionEnd
|
||||
|
||||
Function Install${kbid}
|
||||
${If} ${NeedsPatch} ${kbid}
|
||||
Call Download${kbid}
|
||||
!insertmacro InstallSP "${title}" "${kbid}.exe"
|
||||
${EndIf}
|
||||
FunctionEnd
|
||||
!macroend
|
||||
|
||||
!macro MSUHandler kbid title
|
||||
Function Needs${kbid}
|
||||
Push Package_for_${kbid}
|
||||
Call NeedsPackage
|
||||
FunctionEnd
|
||||
|
||||
Function Download${kbid}
|
||||
${If} ${NeedsPatch} ${kbid}
|
||||
Call GetArch
|
||||
Pop $0
|
||||
ReadINIStr $1 $PLUGINSDIR\Patches.ini "${kbid}" $0
|
||||
ReadINIStr $2 $PLUGINSDIR\Patches.ini "${kbid}" Prefix
|
||||
!insertmacro DownloadMSU "${kbid}" "${title}" "$2$1"
|
||||
${EndIf}
|
||||
FunctionEnd
|
||||
|
||||
Function Install${kbid}
|
||||
${If} ${NeedsPatch} ${kbid}
|
||||
Call Download${kbid}
|
||||
!insertmacro InstallMSU "${kbid}" "${title}"
|
||||
${EndIf}
|
||||
FunctionEnd
|
||||
!macroend
|
||||
|
||||
; Service Packs
|
||||
!insertmacro SPHandler "VistaSP1" "VistaSP1-KB936330" "Windows Vista $(SP) 1"
|
||||
!insertmacro SPHandler "VistaSP2" "VistaSP2-KB948465" "Windows Vista $(SP) 2"
|
||||
!insertmacro SPHandler "Win7SP1" "Windows7SP1-KB976933" "Windows 7 $(SP) 1"
|
||||
|
||||
; Windows Vista post-SP2 update combination that fixes WU indefinitely checking for updates
|
||||
!insertmacro MSUHandler "KB3205638" "$(SecUpd) for Windows Vista"
|
||||
!insertmacro MSUHandler "KB4012583" "$(SecUpd) for Windows Vista"
|
||||
!insertmacro MSUHandler "KB4015195" "$(SecUpd) for Windows Vista"
|
||||
!insertmacro MSUHandler "KB4015380" "$(SecUpd) for Windows Vista"
|
||||
|
||||
; Internet Explorer 9 for Windows Vista
|
||||
!insertmacro MSUHandler "KB971512" "$(Update) for Windows Vista"
|
||||
!insertmacro MSUHandler "KB2117917" "$(PUS) for Windows Vista"
|
||||
|
||||
!insertmacro NeedsFileVersionHandler "IE9" "mshtml.dll" "9.0.8112.16421"
|
||||
!insertmacro PatchHandler "IE9" "$(IE) 9 for Windows Vista" ${PATCH_FLAGS_OTHER} "/passive /norestart /update-no /closeprograms"
|
||||
|
||||
; Windows Vista Servicing Stack Update
|
||||
!insertmacro MSUHandler "KB4493730" "2019-04 $(SSU) for Windows $(SRV) 2008"
|
||||
|
||||
; Windows 7 Servicing Stack Update
|
||||
!insertmacro MSUHandler "KB3138612" "2016-03 $(SSU) for Windows 7"
|
||||
!insertmacro MSUHandler "KB4474419" "$(SHA2) for Windows 7"
|
||||
!insertmacro MSUHandler "KB4490628" "2019-03 $(SSU) for Windows 7"
|
||||
|
||||
; Windows Home Server 2011 Update Rollup 4
|
||||
!insertmacro MSUHandler "KB2757011" "$(SectionWHS2011U4)"
|
||||
|
||||
; Windows 8 Servicing Stack
|
||||
!insertmacro MSUHandler "KB4598297" "2021-01 $(SSU) for Windows $(SRV) 2012"
|
||||
|
||||
; Windows 8.1 Servicing Stack
|
||||
!insertmacro MSUHandler "KB3021910" "2015-04 $(SSU) for Windows 8.1"
|
||||
|
||||
; Windows 8.1 Update 1
|
||||
!insertmacro MSUHandler "KB2919355" "Windows 8.1 $(Update) 1"
|
||||
!insertmacro MSUHandler "KB2932046" "Windows 8.1 $(Update) 1"
|
||||
!insertmacro MSUHandler "KB2959977" "Windows 8.1 $(Update) 1"
|
||||
!insertmacro MSUHandler "KB2937592" "Windows 8.1 $(Update) 1"
|
||||
!insertmacro MSUHandler "KB2934018" "Windows 8.1 $(Update) 1"
|
||||
|
||||
; Windows 8.1 Update 3
|
||||
; TODO
|
||||
; !insertmacro MSUHandler "KB2934018" "Windows 8.1 $(Update) 3"
|
||||
|
||||
Function NeedsVistaPostSP2
|
||||
${If} ${NeedsPatch} KB3205638
|
||||
${OrIf} ${NeedsPatch} KB4012583
|
||||
${OrIf} ${NeedsPatch} KB4015195
|
||||
${OrIf} ${NeedsPatch} KB4015380
|
||||
${OrIf} ${NeedsPatch} KB4493730
|
||||
Push 1
|
||||
${Else}
|
||||
Push 0
|
||||
${EndIf}
|
||||
FunctionEnd
|
||||
|
||||
Function NeedsWin7PostSP1
|
||||
${If} ${NeedsPatch} KB3138612
|
||||
${OrIf} ${NeedsPatch} KB4474419
|
||||
${OrIf} ${NeedsPatch} KB4490628
|
||||
Push 1
|
||||
${Else}
|
||||
Push 0
|
||||
${EndIf}
|
||||
FunctionEnd
|
||||
|
||||
Function NeedsWin81Update1
|
||||
${If} ${NeedsPatch} KB2919355
|
||||
${OrIf} ${NeedsPatch} KB2932046
|
||||
${OrIf} ${NeedsPatch} KB2937592
|
||||
${OrIf} ${NeedsPatch} KB2934018
|
||||
Push 1
|
||||
${Else}
|
||||
Push 0
|
||||
${EndIf}
|
||||
FunctionEnd
|
||||
|
||||
; TODO
|
||||
; Function NeedsWin81Update3
|
||||
; Call GetArch
|
||||
; Pop $0
|
||||
; ${If} $0 == "arm"
|
||||
; ${AndIf} ${NeedsPatch} KB2934018
|
||||
; Push 1
|
||||
; ${Else}
|
||||
; Push 0
|
||||
; ${EndIf}
|
||||
; FunctionEnd
|
||||
|
||||
; Weird prerequisite to Update 1 that fixes the main KB2919355 update failing to install
|
||||
Function DownloadClearCompressionFlag
|
||||
${If} ${NeedsPatch} KB2919355
|
||||
Call GetArch
|
||||
Pop $0
|
||||
ReadINIStr $0 $PLUGINSDIR\Patches.ini ClearCompressionFlag $0
|
||||
ReadINIStr $1 $PLUGINSDIR\Patches.ini ClearCompressionFlag Prefix
|
||||
!insertmacro Download "Windows 8.1 $(Update) 1 $(PrepTool)" "$1$0" "ClearCompressionFlag.exe" 1
|
||||
${EndIf}
|
||||
FunctionEnd
|
||||
|
||||
Function InstallClearCompressionFlag
|
||||
${If} ${NeedsPatch} KB2919355
|
||||
Call DownloadClearCompressionFlag
|
||||
!insertmacro Install "Windows 8.1 $(Update) 1 $(PrepTool)" "ClearCompressionFlag.exe" ""
|
||||
${EndIf}
|
||||
FunctionEnd
|
|
@ -0,0 +1,32 @@
|
|||
DEBUG ?= 1
|
||||
SIGN ?= 0
|
||||
CI ?= 0
|
||||
|
||||
MAKENSIS = makensis
|
||||
NSISFLAGS = -DDEBUG=$(DEBUG) -DSIGN=$(SIGN) -DCI=$(CI)
|
||||
|
||||
all:
|
||||
+$(MAKE) -C ../nsisplugin
|
||||
+$(MAKE) setup
|
||||
+$(MAKE) activex
|
||||
|
||||
setup:
|
||||
$(MAKENSIS) $(NSISFLAGS) setup.nsi
|
||||
|
||||
activex:
|
||||
ifeq ($(SIGN),1)
|
||||
cp LegacyUpdate-*.exe codebase/setup.exe
|
||||
cd codebase && makecab.exe /f lucontrl.ddf
|
||||
../build/sign.sh codebase/lucontrl.cab
|
||||
rm codebase/setup.exe codebase/setup.rpt
|
||||
endif
|
||||
|
||||
clean:
|
||||
+$(MAKE) -C ../nsisplugin clean
|
||||
rm -f LegacyUpdate-*.exe codebase/{lucontrl.cab,setup.exe,setup.rpt}
|
||||
|
||||
test:
|
||||
+$(MAKE)
|
||||
sudo.exe LegacyUpdate-*.exe
|
||||
|
||||
.PHONY: all nsisplugin setup activex clean
|
|
@ -0,0 +1,201 @@
|
|||
!insertmacro MUI_LANGUAGE "English"
|
||||
|
||||
; Dialog
|
||||
MiscButtonText "Back" "Next" "Cancel" "Close"
|
||||
|
||||
; Log
|
||||
LangString ^ExecShell ${LANG_ENGLISH} "Execute: "
|
||||
LangString ^Completed ${LANG_ENGLISH} "Done"
|
||||
LangString Downloading ${LANG_ENGLISH} "Downloading "
|
||||
LangString Extracting ${LANG_ENGLISH} "Extracting "
|
||||
LangString Installing ${LANG_ENGLISH} "Installing "
|
||||
LangString ExitCode ${LANG_ENGLISH} "Exit code: "
|
||||
|
||||
LangString RestartRequired ${LANG_ENGLISH} "Success - restart required"
|
||||
LangString AlreadyInstalled ${LANG_ENGLISH} "Installation skipped - already installed"
|
||||
LangString NotApplicable ${LANG_ENGLISH} "Installation skipped - not applicable"
|
||||
|
||||
; Download
|
||||
LangString DownloadStatusSingle ${LANG_ENGLISH} "{TIMEREMAINING} left - {RECVSIZE} of {FILESIZE} ({SPEED})"
|
||||
LangString DownloadStatusMulti ${LANG_ENGLISH} "{TIMEREMAINING} left - {TOTALRECVSIZE} of {TOTALFILESIZE} ({SPEED})"
|
||||
|
||||
; Startup errors
|
||||
LangString MsgBoxUsage ${LANG_ENGLISH} \
|
||||
"Usage: setup.exe [/S] [/v] [/passive] [/norestart]$\r$\n\
|
||||
$\r$\n\
|
||||
/S$\tExecute Legacy Update setup silently.$\r$\n\
|
||||
/v$\tDisplay verbose details during installation.$\r$\n\
|
||||
/passive$\tInstall without user interaction.$\r$\n\
|
||||
/norestart$\tDisable automatic restart during installation.$\r$\n\
|
||||
$\r$\n\
|
||||
If no flags are passed, Legacy Update will launch its full user interface.$\r$\n\
|
||||
For more information on these flags, visit legacyupdate.net."
|
||||
|
||||
LangString MsgBoxElevationRequired ${LANG_ENGLISH} \
|
||||
"Log on as an administrator to install Legacy Update."
|
||||
|
||||
LangString MsgBoxOldWinVersion ${LANG_ENGLISH} \
|
||||
"Legacy Update requires Windows 2000 or later.$\r$\n\
|
||||
$\r$\n\
|
||||
You might be interested in Windows Update Restored instead.$\r$\n\
|
||||
Would you like to go to ${WUR_WEBSITE} now?"
|
||||
|
||||
LangString MsgBoxBetaOS ${LANG_ENGLISH} \
|
||||
"The current version of Windows is a beta build. Legacy Update may not work correctly on this version of Windows.$\r$\n\
|
||||
$\r$\n\
|
||||
Continue anyway?"
|
||||
|
||||
LangString MsgBoxCompatMode ${LANG_ENGLISH} \
|
||||
"A compatibility mode has been set on this program. Legacy Update will not work correctly in compatibility mode.$\r$\n\
|
||||
$\r$\n\
|
||||
Disable it in the Properties dialog of this file and try again."
|
||||
|
||||
LangString MsgBoxPluginFailed ${LANG_ENGLISH} \
|
||||
"Setup failed to initialize.$\r$\n\
|
||||
$\r$\n\
|
||||
The file may be corrupt. Try downloading Legacy Update again."
|
||||
|
||||
; Install errors
|
||||
FileErrorText \
|
||||
'Unable to write to "$0".$\r$\n\
|
||||
$\r$\n\
|
||||
If Internet Explorer is open, close it and click Retry.' \
|
||||
'Unable to write to "$0".$\r$\n\
|
||||
$\r$\n\
|
||||
If Internet Explorer is open, close it and click Retry.'
|
||||
|
||||
LangString MsgBoxDownloadAbort ${LANG_ENGLISH} \
|
||||
"Cancelling will terminate Legacy Update setup."
|
||||
|
||||
LangString MsgBoxDownloadFailed ${LANG_ENGLISH} \
|
||||
"$2 failed to download.$\r$\n\
|
||||
$\r$\n\
|
||||
$0 ($1)"
|
||||
|
||||
LangString MsgBoxInstallFailed ${LANG_ENGLISH} \
|
||||
"$2 failed to install.$\r$\n\
|
||||
$\r$\n\
|
||||
$1 ($0)"
|
||||
|
||||
LangString MsgBoxPatchNotFound ${LANG_ENGLISH} \
|
||||
"$0 failed to install.$\r$\n\
|
||||
$\r$\n\
|
||||
The installed Windows language and/or architecture is not supported."
|
||||
|
||||
LangString MsgBoxMUFailed ${LANG_ENGLISH} \
|
||||
"Failed to enable Microsoft Update.$\r$\n\
|
||||
$\r$\n\
|
||||
$1 ($0)"
|
||||
|
||||
; Warnings
|
||||
LangString MsgBoxWES09NotSSE2 ${LANG_ENGLISH} \
|
||||
"Your processor does not support the Streaming SIMD Extensions 2 (SSE2) instruction set, which is required to install Windows Embedded 2009 updates released after May 2018.$\r$\n\
|
||||
Processors that initially implemented SSE2 instructions include the Intel Pentium 4, Pentium M, and AMD Athlon 64.$\r$\n\
|
||||
$\r$\n\
|
||||
To protect your Windows installation from becoming corrupted by incompatible updates, this option will be disabled."
|
||||
|
||||
LangString MsgBoxActivateXP2002NotSP3 ${LANG_ENGLISH} \
|
||||
"Windows XP must be updated to Service Pack 3 to activate over the internet. The Service Pack 3 update action will be enabled."
|
||||
|
||||
LangString MsgBoxActivateXP2003NotSP2 ${LANG_ENGLISH} \
|
||||
"Windows XP Professional x64 Edition or Windows Server 2003 must be updated to Service Pack 2 to activate over the internet. The Service Pack 2 update action will be enabled."
|
||||
|
||||
LangString MsgBoxVistaSPInstall ${LANG_ENGLISH} \
|
||||
"Your computer will restart several times to install Windows Vista Service Pack 2. Your screen may appear blank for an extended period of time. Do not turn off your computer during this process."
|
||||
|
||||
LangString MsgBoxWUA2000Datacenter ${LANG_ENGLISH} \
|
||||
"Windows Update Agent is not supported on Windows 2000 Datacenter Server. The Legacy Update action will be disabled."
|
||||
|
||||
; Statuses
|
||||
LangString StatusRestarting ${LANG_ENGLISH} "Restarting..."
|
||||
LangString StatusRestartingWUAU ${LANG_ENGLISH} "Restarting Windows Update service..."
|
||||
LangString StatusCheckingSSL ${LANG_ENGLISH} "Checking SSL connectivity..."
|
||||
LangString StatusCbsInstalling ${LANG_ENGLISH} "Configuring updates..."
|
||||
|
||||
; Sections
|
||||
LangString Setup ${LANG_ENGLISH} "Setup"
|
||||
LangString IE ${LANG_ENGLISH} "Internet Explorer"
|
||||
LangString PRO ${LANG_ENGLISH} "Professional"
|
||||
LangString P64 ${LANG_ENGLISH} "Professional x64 Edition"
|
||||
LangString EMB ${LANG_ENGLISH} "Embedded"
|
||||
LangString SRV ${LANG_ENGLISH} "Server"
|
||||
LangString SP ${LANG_ENGLISH} "Service Pack"
|
||||
LangString SSU ${LANG_ENGLISH} "Servicing Stack Update"
|
||||
LangString WUA ${LANG_ENGLISH} "Windows Update Agent"
|
||||
LangString SecUpd ${LANG_ENGLISH} "Security Update"
|
||||
LangString Update ${LANG_ENGLISH} "Update"
|
||||
LangString Rollup ${LANG_ENGLISH} "Update Rollup"
|
||||
LangString PrepTool ${LANG_ENGLISH} "Preparation Tool"
|
||||
LangString PUS ${LANG_ENGLISH} "Platform Update Supplement"
|
||||
LangString SHA2 ${LANG_ENGLISH} "SHA-2 Code Signing Support Update"
|
||||
LangString CTL ${LANG_ENGLISH} "Certificate Trust List"
|
||||
|
||||
LangString SectionWES09 ${LANG_ENGLISH} "Enable Windows Embedded 2009 updates"
|
||||
LangString SectionWHS2011U4 ${LANG_ENGLISH} "Windows Home Server 2011 $(Rollup) 4"
|
||||
LangString SectionW2KUR1 ${LANG_ENGLISH} "Update Rollup 1 for Windows 2000 $(SP) 4"
|
||||
LangString SectionSSU ${LANG_ENGLISH} "Windows Servicing Stack update"
|
||||
LangString SectionWUA ${LANG_ENGLISH} "Windows Update Agent update"
|
||||
LangString SectionRootCerts ${LANG_ENGLISH} "Root certificates store update"
|
||||
LangString SectionEnableMU ${LANG_ENGLISH} "Enable Microsoft Update"
|
||||
LangString SectionActivate ${LANG_ENGLISH} "Activate Windows"
|
||||
|
||||
LangString SectionReboots ${LANG_ENGLISH} \
|
||||
"Your computer will restart automatically to complete installation."
|
||||
LangString SectionSupEULA ${LANG_ENGLISH} \
|
||||
"By installing, you are agreeing to the Supplemental End User License Agreement for this update."
|
||||
LangString SectionMSLT ${LANG_ENGLISH} \
|
||||
"By installing, you are agreeing to the Microsoft Software License Terms for this update."
|
||||
|
||||
LangString SectionW2KSP4Desc ${LANG_ENGLISH} \
|
||||
"Updates Windows 2000 to Service Pack 4 with Update Rollup 1, as required to install the Windows Update Agent.$\r$\n$(SectionReboots) $(SectionSupEULA)"
|
||||
LangString SectionIE6SP1Desc ${LANG_ENGLISH} \
|
||||
"Updates Internet Explorer to 6.0 SP1, as required for Legacy Update.$\r$\n$(SectionReboots) $(SectionSupEULA)"
|
||||
LangString SectionXPSP3Desc ${LANG_ENGLISH} \
|
||||
"Updates Windows XP to Service Pack 3. Required if you would like to activate Windows online. $(SectionReboots) $(SectionSupEULA)"
|
||||
LangString SectionXPESP3Desc ${LANG_ENGLISH} \
|
||||
"Updates Windows XP Embedded to Service Pack 3. Required if you would like to activate Windows online. $(SectionReboots) $(SectionSupEULA)"
|
||||
LangString SectionWES09Desc ${LANG_ENGLISH} \
|
||||
"Configures Windows to appear as Windows Embedded POSReady 2009 to Windows Update, enabling access to Windows XP security updates released between 2014 and 2019. Please note that Microsoft officially advises against doing this."
|
||||
LangString Section2003SP2Desc ${LANG_ENGLISH} \
|
||||
"Updates Windows XP Professional x64 Edition or Windows Server 2003 to Service Pack 2. Required if you would like to activate Windows online. $(SectionReboots) $(SectionSupEULA)"
|
||||
LangString SectionVistaSP2Desc ${LANG_ENGLISH} \
|
||||
"Updates Windows Vista or Windows Server 2008 to Service Pack 2, as required to install the Windows Update Agent. $(SectionReboots) $(SectionMSLT)"
|
||||
LangString SectionVistaSSUDesc ${LANG_ENGLISH} \
|
||||
"Updates Windows Vista or Windows Server 2008 with additional updates required to resolve issues with the Windows Update Agent.$\r$\n$(SectionReboots)"
|
||||
LangString SectionVistaIE9Desc ${LANG_ENGLISH} \
|
||||
"Updates Internet Explorer to 9.0.$\r$\n$(SectionReboots) $(SectionMSLT)"
|
||||
LangString SectionWin7SP1Desc ${LANG_ENGLISH} \
|
||||
"Updates Windows 7 or Windows Server 2008 R2 to Service Pack 1, as required to install the Windows Update Agent. $(SectionReboots) $(SectionMSLT)"
|
||||
LangString SectionWin7SSUDesc ${LANG_ENGLISH} \
|
||||
"Updates Windows 7 or Windows Server 2008 R2 with additional updates required to resolve issues with the Windows Update Agent.$\r$\n$(SectionReboots)"
|
||||
LangString SectionWin8SSUDesc ${LANG_ENGLISH} \
|
||||
"Updates Windows 8 or Windows Server 2012 with additional updates required to resolve issues with the Windows Update Agent.$\r$\n$(SectionReboots)"
|
||||
LangString SectionWin81U1Desc ${LANG_ENGLISH} \
|
||||
"Updates Windows 8.1 to Update 1, as required to resolve issues with the Windows Update Agent. Also required to upgrade to Windows 10.$\r$\n$(SectionReboots)"
|
||||
LangString SectionWin81SSUDesc ${LANG_ENGLISH} \
|
||||
"Updates Windows 8.1 or Windows Server 2012 R2 with additional updates required to resolve issues with the Windows Update Agent.$\r$\n$(SectionReboots)"
|
||||
LangString SectionWHS2011U4Desc ${LANG_ENGLISH} \
|
||||
"Updates Windows Home Server 2011 to Update Rollup 4 to resolve issues with the Windows Update Agent. Also fixes data corruption problems.$\r$\n$(SectionReboots)"
|
||||
LangString SectionWUADesc ${LANG_ENGLISH} \
|
||||
"Updates the Windows Update Agent to the latest version, as required for Legacy Update."
|
||||
LangString SectionRootCertsDesc ${LANG_ENGLISH} \
|
||||
"Updates the root certificate store to the latest from Microsoft, and enables additional modern security features. Root certificates are used to verify the security of encrypted (https) connections. This fixes connection issues with some websites."
|
||||
LangString SectionWin7MUDesc ${LANG_ENGLISH} \
|
||||
"Configures Windows Update to receive updates for Microsoft Office and other Microsoft software."
|
||||
LangString SectionActivateDesc ${LANG_ENGLISH} \
|
||||
"Your copy of Windows is not activated. If you update the root certificates store, Windows Product Activation can be completed over the internet. Legacy Update can start the activation wizard after installation so you can activate your copy of Windows."
|
||||
LangString SectionActiveX2KXPDesc ${LANG_ENGLISH} \
|
||||
"Installs the Legacy Update ActiveX control, enabling access to the full Windows Update interface via the legacyupdate.net website."
|
||||
LangString SectionActiveXVista78Desc ${LANG_ENGLISH} \
|
||||
"Installs the Legacy Update ActiveX control, enabling access to the classic Windows Update interface via the legacyupdate.net website. Not required if you want to use the built-in Windows Update Control Panel."
|
||||
LangString SectionActiveXWin10Desc ${LANG_ENGLISH} \
|
||||
"Installs the Legacy Update ActiveX control, enabling access to the classic Windows Update interface via the legacyupdate.net website."
|
||||
|
||||
; LangString SectionLegacyUpdateDesc ${LANG_ENGLISH} \
|
||||
; "Installs Legacy Update, enabling access to Windows Update."
|
||||
; LangString SectionWUServerDesc ${LANG_ENGLISH} \
|
||||
; "Configures Windows Update to use the Legacy Update proxy server, resolving connection issues to the official Microsoft Windows Update service."
|
||||
|
||||
LangString SectionAllowOSUpgrade ${LANG_ENGLISH} "Allow OS Upgrade"
|
||||
LangString SectionAllowOSUpgradeDesc ${LANG_ENGLISH} \
|
||||
"Configures Windows Update to deliver the latest feature update. It can help upgrading from Windows 7 to 10 or from Windows 10 to Windows 11."
|
Binary file not shown.
After Width: | Height: | Size: 102 KiB |
Binary file not shown.
After Width: | Height: | Size: 6.9 KiB |
Binary file not shown.
After Width: | Height: | Size: 6.9 KiB |
Binary file not shown.
After Width: | Height: | Size: 6.0 KiB |
|
@ -115,8 +115,8 @@ Var /GLOBAL UninstallInstalled
|
|||
!include Strings.nsh
|
||||
|
||||
; Uncomment lines below to enable code signing when compiling under Windows
|
||||
; !uninstfinalize 'sign.cmd "certPath" certPassword "Legacy Update - Vichingo455 Mod" "%1"' = 0
|
||||
; !finalize 'sign.cmd "certPath" certPassword "Legacy Update - Vichingo455 Mod" "%1"' = 0
|
||||
; !uninstfinalize 'sign.cmd certFile certPassword "Legacy Update - Vichingo455 Mod" "%1"' = 0
|
||||
; !finalize 'sign.cmd certFile certPassword "Legacy Update - Vichingo455 Mod" "%1"' = 0
|
||||
|
||||
!macro RestartWUAUService
|
||||
${DetailPrint} "$(StatusRestartingWUAU)"
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
#include "stdafx.h"
|
||||
#include "Exec.h"
|
||||
|
||||
HRESULT Exec(LPWSTR verb, LPWSTR file, LPWSTR params, LPWSTR workingDir, WORD show, BOOL wait, LPDWORD exitCode) {
|
||||
SHELLEXECUTEINFO execInfo = {0};
|
||||
execInfo.cbSize = sizeof(execInfo);
|
||||
execInfo.lpVerb = verb;
|
||||
execInfo.lpFile = file;
|
||||
execInfo.lpParameters = params;
|
||||
execInfo.lpDirectory = workingDir;
|
||||
execInfo.nShow = show;
|
||||
return ExecEx(&execInfo, wait, exitCode);
|
||||
}
|
||||
|
||||
HRESULT ExecEx(LPSHELLEXECUTEINFO execInfo, BOOL wait, LPDWORD exitCode) {
|
||||
if (wait) {
|
||||
execInfo->fMask |= SEE_MASK_NOCLOSEPROCESS;
|
||||
}
|
||||
|
||||
if (!ShellExecuteEx(execInfo)) {
|
||||
return HRESULT_FROM_WIN32(GetLastError());
|
||||
}
|
||||
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
if (wait) {
|
||||
if (execInfo->hProcess == NULL) {
|
||||
TRACE(L"ShellExecuteEx() didn't return a handle: %u", GetLastError());
|
||||
hr = E_FAIL;
|
||||
}
|
||||
|
||||
WaitForSingleObject(execInfo->hProcess, INFINITE);
|
||||
|
||||
if (exitCode != NULL && GetExitCodeProcess(execInfo->hProcess, exitCode) == 0) {
|
||||
hr = HRESULT_FROM_WIN32(GetLastError());
|
||||
TRACE(L"GetExitCodeProcess() failed: %p\n", hr);
|
||||
}
|
||||
|
||||
CloseHandle(execInfo->hProcess);
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <windows.h>
|
||||
#include <shellapi.h>
|
||||
|
||||
EXTERN_C HRESULT Exec(LPWSTR verb, LPWSTR file, LPWSTR params, LPWSTR workingDir, WORD show, BOOL wait, LPDWORD exitCode);
|
||||
EXTERN_C HRESULT ExecEx(LPSHELLEXECUTEINFO execInfo, BOOL wait, LPDWORD exitCode);
|
|
@ -0,0 +1,36 @@
|
|||
#include "stdafx.h"
|
||||
#include <psapi.h>
|
||||
#include "GetPidForName.h"
|
||||
|
||||
#pragma comment(lib, "psapi.lib")
|
||||
|
||||
DWORD GetPidForName(const LPTSTR process) {
|
||||
// Yes, eat all of our SHRTs!
|
||||
DWORD pids[SHRT_MAX];
|
||||
DWORD bytesReturned;
|
||||
if (!EnumProcesses(pids, sizeof(pids), &bytesReturned)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
DWORD count = bytesReturned / sizeof(DWORD);
|
||||
for (DWORD i = 0; i < count; ++i) {
|
||||
HANDLE handle = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION | PROCESS_VM_READ, FALSE, pids[i]);
|
||||
if (handle) {
|
||||
WCHAR path[MAX_PATH];
|
||||
if (GetModuleBaseName(handle, NULL, path, ARRAYSIZE(path))) {
|
||||
LPWSTR basename = wcsrchr(path, L'\\');
|
||||
if (basename) {
|
||||
basename += 1;
|
||||
CharLowerBuffW(basename, (DWORD)wcslen(basename));
|
||||
if (_wcsicmp(process, basename) == 0) {
|
||||
CloseHandle(handle);
|
||||
return pids[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
CloseHandle(handle);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
#pragma once
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
EXTERN_C DWORD GetPidForName(LPTSTR process);
|
|
@ -0,0 +1,31 @@
|
|||
#include "stdafx.h"
|
||||
#include <windows.h>
|
||||
#include "Registry.h"
|
||||
|
||||
static LPWSTR _installPath;
|
||||
|
||||
EXTERN_C HRESULT GetInstallPath(LPWSTR *path) {
|
||||
*path = (LPWSTR)LocalAlloc(LPTR, MAX_PATH * sizeof(WCHAR));
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
if (!_installPath) {
|
||||
DWORD size = 0;
|
||||
hr = GetRegistryString(HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\LegacyUpdate", L"InstallLocation", KEY_WOW64_64KEY, &_installPath, &size);
|
||||
if (SUCCEEDED(hr)) {
|
||||
lstrcpy(*path, _installPath);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
// Do our best to guess where it should be
|
||||
LPWSTR programFiles;
|
||||
hr = GetRegistryString(HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows\\CurrentVersion", L"ProgramFilesDir", KEY_WOW64_64KEY, &programFiles, &size);
|
||||
if (SUCCEEDED(hr)) {
|
||||
_installPath = (LPWSTR)LocalAlloc(LPTR, MAX_PATH * sizeof(WCHAR));
|
||||
wsprintf(_installPath, L"%ls\\Legacy Update", programFiles);
|
||||
LocalFree(programFiles);
|
||||
}
|
||||
}
|
||||
|
||||
lstrcpy(*path, _installPath);
|
||||
return hr;
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
#pragma once
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
EXTERN_C HRESULT GetInstallPath(LPWSTR *path);
|
|
@ -0,0 +1,256 @@
|
|||
#include <windows.h>
|
||||
#include <wincodec.h>
|
||||
#include <gdiplus.h>
|
||||
|
||||
// Adapted from https://faithlife.codes/blog/2008/09/displaying_a_splash_screen_with_c_part_i/
|
||||
// 1. Get resource as an IStream
|
||||
// 2. Use Windows Imaging Component to load the PNG
|
||||
// 3. Convert the WIC bitmap to an HBITMAP
|
||||
// Why does loading a PNG need to be so difficult?
|
||||
|
||||
typedef HRESULT (WINAPI *_WICConvertBitmapSource)(REFWICPixelFormatGUID dstFormat, IWICBitmapSource *pISrc, IWICBitmapSource **ppIDst);
|
||||
|
||||
static _WICConvertBitmapSource $WICConvertBitmapSource;
|
||||
|
||||
static HGLOBAL GetRawResource(HINSTANCE hInstance, LPWSTR name, LPWSTR type) {
|
||||
HRSRC resource = FindResource(hInstance, name, type);
|
||||
if (!resource) {
|
||||
TRACE(L"FindResource failed: %d", GetLastError());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DWORD resourceSize = SizeofResource(hInstance, resource);
|
||||
HGLOBAL imageHandle = LoadResource(hInstance, resource);
|
||||
if (!imageHandle) {
|
||||
TRACE(L"LoadResource failed: %d", GetLastError());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
LPVOID sourceResourceData = LockResource(imageHandle);
|
||||
if (!sourceResourceData) {
|
||||
TRACE(L"LockResource failed: %d", GetLastError());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
HGLOBAL resourceDataHandle = GlobalAlloc(GMEM_MOVEABLE, resourceSize);
|
||||
if (!resourceDataHandle) {
|
||||
TRACE(L"GlobalAlloc failed: %d", GetLastError());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
LPVOID resourceData = GlobalLock(resourceDataHandle);
|
||||
if (!resourceData) {
|
||||
TRACE(L"GlobalLock failed: %d", GetLastError());
|
||||
GlobalFree(resourceDataHandle);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CopyMemory(resourceData, sourceResourceData, resourceSize);
|
||||
GlobalUnlock(resourceDataHandle);
|
||||
return resourceDataHandle;
|
||||
}
|
||||
|
||||
static IStream *GetResourceStream(HINSTANCE hInstance, LPWSTR name, LPWSTR type) {
|
||||
IStream *stream;
|
||||
HGLOBAL resource = GetRawResource(hInstance, name, type);
|
||||
if (!resource) {
|
||||
TRACE(L"GetResource failed: %d", GetLastError());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (SUCCEEDED(CreateStreamOnHGlobal(resource, TRUE, &stream))) {
|
||||
return stream;
|
||||
}
|
||||
|
||||
GlobalFree(resource);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static IWICBitmapSource *GetWICBitmap(IStream *imageStream) {
|
||||
IWICBitmapSource *bitmap;
|
||||
IWICBitmapDecoder *decoder;
|
||||
UINT frameCount;
|
||||
IWICBitmapFrameDecode *frame;
|
||||
|
||||
if (!SUCCEEDED(CoCreateInstance(&CLSID_WICPngDecoder, NULL, CLSCTX_INPROC_SERVER, &IID_IWICBitmapDecoder, (LPVOID *)&decoder))) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!SUCCEEDED(IWICBitmapDecoder_Initialize(decoder, imageStream, WICDecodeMetadataCacheOnLoad))) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (!SUCCEEDED(IWICBitmapDecoder_GetFrameCount(decoder, &frameCount)) || frameCount != 1) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (!SUCCEEDED(IWICBitmapDecoder_GetFrame(decoder, 0, &frame))) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
$WICConvertBitmapSource(&GUID_WICPixelFormat32bppPBGRA, (IWICBitmapSource *)frame, &bitmap);
|
||||
IWICBitmapFrameDecode_Release(frame);
|
||||
|
||||
end:
|
||||
IWICBitmapDecoder_Release(decoder);
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
static HBITMAP GetHBitmapForWICBitmap(IWICBitmapSource *bitmap) {
|
||||
HBITMAP hBitmap;
|
||||
UINT width, height;
|
||||
if (!SUCCEEDED(IWICBitmapSource_GetSize(bitmap, &width, &height)) || width == 0 || height == 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BITMAPINFO bminfo;
|
||||
ZeroMemory(&bminfo, sizeof(bminfo));
|
||||
bminfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
||||
bminfo.bmiHeader.biWidth = width;
|
||||
bminfo.bmiHeader.biHeight = -(LONG)height;
|
||||
bminfo.bmiHeader.biPlanes = 1;
|
||||
bminfo.bmiHeader.biBitCount = 32;
|
||||
bminfo.bmiHeader.biCompression = BI_RGB;
|
||||
|
||||
void *imageBits;
|
||||
HDC screenDC = GetDC(NULL);
|
||||
hBitmap = CreateDIBSection(screenDC, &bminfo, DIB_RGB_COLORS, &imageBits, NULL, 0);
|
||||
ReleaseDC(NULL, screenDC);
|
||||
if (!hBitmap) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
UINT stride = width * 4;
|
||||
UINT imageSize = stride * height;
|
||||
if (!SUCCEEDED(IWICBitmapSource_CopyPixels(bitmap, NULL, stride, imageSize, (BYTE*)imageBits))) {
|
||||
DeleteObject(hBitmap);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return hBitmap;
|
||||
}
|
||||
|
||||
HBITMAP LoadPNGResource(HINSTANCE hInstance, LPWSTR resourceName, LPWSTR resourceType) {
|
||||
if (!$WICConvertBitmapSource) {
|
||||
$WICConvertBitmapSource = (_WICConvertBitmapSource)GetProcAddress(LoadLibrary(L"windowscodecs.dll"), "WICConvertBitmapSource");
|
||||
if (!$WICConvertBitmapSource) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
IStream *imageStream = GetResourceStream(hInstance, resourceName, resourceType);
|
||||
if (!imageStream) {
|
||||
TRACE(L"GetResourceStream failed: %d", GetLastError());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
IWICBitmapSource *bitmap = GetWICBitmap(imageStream);
|
||||
if (!bitmap) {
|
||||
TRACE(L"GetWICBitmap failed: %d", GetLastError());
|
||||
IStream_Release(imageStream);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
HBITMAP result = GetHBitmapForWICBitmap(bitmap);
|
||||
IWICBitmapSource_Release(bitmap);
|
||||
IStream_Release(imageStream);
|
||||
return result;
|
||||
}
|
||||
|
||||
BOOL ScaleAndWriteToBMP(HBITMAP hBitmap, DWORD width, DWORD height, LPWSTR outputPath) {
|
||||
BOOL result = FALSE;
|
||||
if (!hBitmap) {
|
||||
TRACE(L"Null bitmap");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
HDC hdc = GetDC(NULL);
|
||||
HDC hdcMem = CreateCompatibleDC(hdc);
|
||||
HBITMAP scaledBitmap = CreateCompatibleBitmap(hdc, width, height);
|
||||
if (!scaledBitmap) {
|
||||
TRACE(L"CreateCompatibleBitmap failed: %d", GetLastError());
|
||||
goto end;
|
||||
}
|
||||
|
||||
BITMAP bmp;
|
||||
if (!GetObject(hBitmap, sizeof(BITMAP), &bmp)) {
|
||||
TRACE(L"GetObject failed: %d", GetLastError());
|
||||
goto end;
|
||||
}
|
||||
|
||||
HBITMAP hOld = (HBITMAP)SelectObject(hdcMem, hBitmap);
|
||||
HDC hdcMemScaled = CreateCompatibleDC(hdc);
|
||||
HBITMAP hOldScaled = (HBITMAP)SelectObject(hdcMemScaled, scaledBitmap);
|
||||
SetStretchBltMode(hdcMemScaled, HALFTONE);
|
||||
|
||||
if (!StretchBlt(hdcMemScaled,
|
||||
0, 0, width, height, hdcMem,
|
||||
0, 0, bmp.bmWidth, bmp.bmHeight, SRCCOPY)) {
|
||||
TRACE(L"StretchBlt failed: %d", GetLastError());
|
||||
goto end;
|
||||
}
|
||||
|
||||
BITMAPINFOHEADER bmih = {0};
|
||||
bmih.biSize = sizeof(BITMAPINFOHEADER);
|
||||
bmih.biWidth = width;
|
||||
bmih.biHeight = height;
|
||||
bmih.biPlanes = 1;
|
||||
bmih.biBitCount = bmp.bmBitsPixel;
|
||||
bmih.biCompression = BI_RGB;
|
||||
bmih.biSizeImage = ((width * bmp.bmBitsPixel + 31) / 32) * 4 * height;
|
||||
|
||||
BITMAPFILEHEADER bmfh = {0};
|
||||
bmfh.bfType = 0x4D42;
|
||||
bmfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
|
||||
bmfh.bfSize = bmfh.bfOffBits + bmih.biSizeImage;
|
||||
|
||||
HGLOBAL handle = GlobalAlloc(GMEM_MOVEABLE, bmih.biSizeImage);
|
||||
if (!handle) {
|
||||
TRACE(L"GlobalAlloc failed: %d", GetLastError());
|
||||
goto end;
|
||||
}
|
||||
|
||||
BYTE *bitmapData = (BYTE *)GlobalLock(handle);
|
||||
if (!bitmapData) {
|
||||
TRACE(L"GlobalLock failed: %d", GetLastError());
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (!GetDIBits(hdcMemScaled, scaledBitmap, 0, height, bitmapData, (BITMAPINFO *)&bmih, DIB_RGB_COLORS)) {
|
||||
TRACE(L"GetDIBits failed: %d", GetLastError());
|
||||
goto end;
|
||||
}
|
||||
|
||||
HANDLE file = CreateFile(outputPath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if (file == INVALID_HANDLE_VALUE) {
|
||||
TRACE(L"CreateFile failed: %d", GetLastError());
|
||||
goto end;
|
||||
}
|
||||
|
||||
DWORD written;
|
||||
if (!WriteFile(file, &bmfh, sizeof(BITMAPFILEHEADER), &written, NULL) ||
|
||||
!WriteFile(file, &bmih, sizeof(BITMAPINFOHEADER), &written, NULL) ||
|
||||
!WriteFile(file, bitmapData, bmih.biSizeImage, &written, NULL)) {
|
||||
TRACE(L"WriteFile failed: %d", GetLastError());
|
||||
goto end;
|
||||
}
|
||||
|
||||
result = TRUE;
|
||||
|
||||
end:
|
||||
if (file && file != INVALID_HANDLE_VALUE) {
|
||||
CloseHandle(file);
|
||||
}
|
||||
if (scaledBitmap) {
|
||||
DeleteObject(scaledBitmap);
|
||||
}
|
||||
if (handle) {
|
||||
GlobalUnlock(handle);
|
||||
GlobalFree(handle);
|
||||
}
|
||||
ReleaseDC(NULL, hdc);
|
||||
DeleteDC(hdcMem);
|
||||
DeleteDC(hdcMemScaled);
|
||||
|
||||
return result;
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
#include <windows.h>
|
||||
|
||||
HBITMAP LoadPNGResource(HINSTANCE hInstance, LPWSTR resourceName, LPWSTR resourceType);
|
||||
BOOL ScaleAndWriteToBMP(HBITMAP hBitmap, DWORD width, DWORD height, LPWSTR outputPath);
|
|
@ -0,0 +1,93 @@
|
|||
#include "stdafx.h"
|
||||
#include "Registry.h"
|
||||
#include "VersionInfo.h"
|
||||
#include <malloc.h>
|
||||
|
||||
static ALWAYS_INLINE REGSAM GetWow64Flag(REGSAM options) {
|
||||
#ifdef _WIN64
|
||||
return options;
|
||||
#else
|
||||
if (AtLeastWinXP2002()) {
|
||||
return options;
|
||||
}
|
||||
|
||||
// Filter out WOW64 keys, which are not supported on Windows 2000
|
||||
return options & ~(KEY_WOW64_64KEY | KEY_WOW64_32KEY);
|
||||
#endif
|
||||
}
|
||||
|
||||
HRESULT GetRegistryString(HKEY key, LPCWSTR subkeyPath, LPCWSTR valueName, REGSAM options, LPWSTR *data, LPDWORD size) {
|
||||
HKEY subkey;
|
||||
HRESULT hr = HRESULT_FROM_WIN32(RegOpenKeyEx(key, subkeyPath, 0, GetWow64Flag(KEY_READ | options), &subkey));
|
||||
if (!SUCCEEDED(hr)) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (data) {
|
||||
DWORD length = 512 * sizeof(WCHAR);
|
||||
LPWSTR buffer = (LPWSTR)LocalAlloc(LPTR, length);
|
||||
if (!buffer) {
|
||||
hr = E_OUTOFMEMORY;
|
||||
goto end;
|
||||
}
|
||||
|
||||
LSTATUS status;
|
||||
do {
|
||||
status = RegQueryValueEx(subkey, valueName, NULL, NULL, (BYTE *)buffer, &length);
|
||||
if (status == ERROR_MORE_DATA) {
|
||||
length += 256 * sizeof(WCHAR);
|
||||
LPWSTR newBuffer = (LPWSTR)LocalReAlloc(buffer, length, LMEM_MOVEABLE);
|
||||
if (!newBuffer) {
|
||||
LocalFree(buffer);
|
||||
hr = E_OUTOFMEMORY;
|
||||
goto end;
|
||||
}
|
||||
|
||||
buffer = newBuffer;
|
||||
} else if (status != ERROR_SUCCESS) {
|
||||
hr = HRESULT_FROM_WIN32(status);
|
||||
LocalFree(buffer);
|
||||
goto end;
|
||||
}
|
||||
} while (status == ERROR_MORE_DATA);
|
||||
|
||||
*data = buffer;
|
||||
|
||||
if (size) {
|
||||
*size = length / sizeof(WCHAR);
|
||||
}
|
||||
}
|
||||
|
||||
end:
|
||||
if (subkey) {
|
||||
RegCloseKey(subkey);
|
||||
}
|
||||
if (!SUCCEEDED(hr)) {
|
||||
if (data) {
|
||||
*data = NULL;
|
||||
}
|
||||
if (size) {
|
||||
*size = 0;
|
||||
}
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT GetRegistryDword(HKEY key, LPCWSTR subkeyPath, LPCWSTR valueName, REGSAM options, LPDWORD data) {
|
||||
HKEY subkey;
|
||||
HRESULT hr = HRESULT_FROM_WIN32(RegOpenKeyEx(key, subkeyPath, 0, GetWow64Flag(KEY_READ | options), &subkey));
|
||||
if (!SUCCEEDED(hr)) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (data) {
|
||||
DWORD length = sizeof(DWORD);
|
||||
hr = HRESULT_FROM_WIN32(RegQueryValueEx(subkey, valueName, NULL, NULL, (LPBYTE)data, &length));
|
||||
}
|
||||
|
||||
end:
|
||||
if (subkey) {
|
||||
RegCloseKey(subkey);
|
||||
}
|
||||
return hr;
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
EXTERN_C HRESULT GetRegistryString(HKEY key, LPCWSTR subkeyPath, LPCWSTR valueName, REGSAM options, LPWSTR *data, LPDWORD size);
|
||||
EXTERN_C HRESULT GetRegistryDword(HKEY key, LPCWSTR subkeyPath, LPCWSTR valueName, REGSAM options, LPDWORD data);
|
|
@ -0,0 +1,45 @@
|
|||
#pragma once
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
typedef void (WINAPI *_SetDefaultDllDirectories)(DWORD DirectoryFlags);
|
||||
typedef BOOL (WINAPI *_SetDllDirectoryW)(LPWSTR);
|
||||
|
||||
static inline void HardenDllSearchPaths() {
|
||||
// Try our best to secure DLL search paths to just system32
|
||||
WCHAR path[MAX_PATH];
|
||||
|
||||
// Reset %windir% and %SystemRoot%
|
||||
GetWindowsDirectory(path, ARRAYSIZE(path));
|
||||
SetEnvironmentVariable(L"WINDIR", path);
|
||||
SetEnvironmentVariable(L"SystemRoot", path);
|
||||
|
||||
// Reset %PATH% to just system32
|
||||
ZeroMemory(path, sizeof(path));
|
||||
GetSystemDirectory(path, ARRAYSIZE(path));
|
||||
SetEnvironmentVariable(L"PATH", path);
|
||||
|
||||
wcscat(path, L"\\kernel32.dll");
|
||||
HMODULE kernel32 = GetModuleHandle(path);
|
||||
if (!kernel32) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Windows Vista SP2+/7 SP1+ with KB2533623
|
||||
_SetDefaultDllDirectories $SetDefaultDllDirectories = (_SetDefaultDllDirectories)GetProcAddress(kernel32, "SetDefaultDllDirectories");
|
||||
if ($SetDefaultDllDirectories) {
|
||||
$SetDefaultDllDirectories(LOAD_LIBRARY_SEARCH_SYSTEM32);
|
||||
return;
|
||||
}
|
||||
|
||||
// Windows XP SP1+
|
||||
_SetDllDirectoryW $SetDllDirectoryW = (_SetDllDirectoryW)GetProcAddress(kernel32, "SetDllDirectoryW");
|
||||
if ($SetDllDirectoryW) {
|
||||
$SetDllDirectoryW(L"");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void Startup() {
|
||||
HardenDllSearchPaths();
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
#pragma once
|
||||
|
||||
#if defined(ATLTRACE)
|
||||
#define TRACE ATLTRACE
|
||||
#elif defined(_DEBUG)
|
||||
// Yeah, sue me lol
|
||||
#define TRACE(...) { \
|
||||
LPWSTR __traceMsg = (LPWSTR)LocalAlloc(LPTR, 4096 * sizeof(WCHAR)); \
|
||||
wsprintf(__traceMsg, L"%hs(%d): %hs: ", __FILE__, __LINE__, __FUNCTION__); \
|
||||
wsprintf(__traceMsg + wcslen(__traceMsg), __VA_ARGS__); \
|
||||
MessageBox(NULL, __traceMsg, L"Debug", MB_OK); \
|
||||
LocalFree(__traceMsg); \
|
||||
}
|
||||
#else
|
||||
#define TRACE(...)
|
||||
#endif
|
|
@ -0,0 +1,20 @@
|
|||
#pragma once
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
static inline BOOL IsUserAdmin() {
|
||||
SID_IDENTIFIER_AUTHORITY authority = SECURITY_NT_AUTHORITY;
|
||||
PSID adminsSid;
|
||||
BOOL result = FALSE;
|
||||
|
||||
if (!AllocateAndInitializeSid(&authority, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &adminsSid)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!CheckTokenMembership(NULL, adminsSid, &result)) {
|
||||
result = FALSE;
|
||||
}
|
||||
|
||||
FreeSid(adminsSid);
|
||||
return result;
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
#define VERSION_MAJOR 1
|
||||
#define VERSION_MINOR 11
|
||||
#define VERSION_PATCH 0
|
||||
#define VERSION_BUILD 0
|
||||
|
||||
#define VERSION_STRING "1.11"
|
|
@ -0,0 +1,44 @@
|
|||
#include "stdafx.h"
|
||||
#include "VersionInfo.h"
|
||||
|
||||
static BOOL _loadedOwnVersion = FALSE;
|
||||
static LPWSTR _version;
|
||||
|
||||
HRESULT GetOwnVersion(LPWSTR *version) {
|
||||
if (!_loadedOwnVersion) {
|
||||
_loadedOwnVersion = TRUE;
|
||||
|
||||
LPWSTR filename;
|
||||
GetOwnFileName(&filename);
|
||||
|
||||
DWORD verHandle;
|
||||
DWORD verInfoSize = GetFileVersionInfoSize(filename, &verHandle);
|
||||
if (verInfoSize == 0) {
|
||||
LocalFree(filename);
|
||||
return HRESULT_FROM_WIN32(GetLastError());
|
||||
}
|
||||
|
||||
LPVOID verInfo = LocalAlloc(LPTR, verInfoSize);
|
||||
if (!GetFileVersionInfo(filename, verHandle, verInfoSize, verInfo)) {
|
||||
LocalFree(filename);
|
||||
LocalFree(verInfo);
|
||||
return HRESULT_FROM_WIN32(GetLastError());
|
||||
}
|
||||
|
||||
LocalFree(filename);
|
||||
|
||||
LPWSTR value;
|
||||
UINT size;
|
||||
if (!VerQueryValue(verInfo, L"\\StringFileInfo\\040904B0\\ProductVersion", (LPVOID *)&value, &size)) {
|
||||
LocalFree(verInfo);
|
||||
return HRESULT_FROM_WIN32(GetLastError());
|
||||
}
|
||||
|
||||
_version = (LPWSTR)LocalAlloc(LPTR, (wcslen(value) + 1) * sizeof(WCHAR));
|
||||
wcscpy(_version, value);
|
||||
LocalFree(verInfo);
|
||||
}
|
||||
|
||||
*version = _version;
|
||||
return _version == NULL ? E_FAIL : S_OK;
|
||||
}
|
|
@ -0,0 +1,79 @@
|
|||
#include "stdafx.h"
|
||||
#include "WMI.h"
|
||||
#include <wbemcli.h>
|
||||
|
||||
#pragma comment(lib, "wbemuuid.lib")
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define our_CLSID_WbemLocator CLSID_WbemLocator
|
||||
#define our_IID_IWbemLocator IID_IWbemLocator
|
||||
#define IWbemLocator_ConnectServer(obj, ...) obj->ConnectServer(__VA_ARGS__)
|
||||
#define IWbemServices_ExecQuery(obj, ...) obj->ExecQuery(__VA_ARGS__)
|
||||
#define IEnumWbemClassObject_Next(obj, ...) obj->Next(__VA_ARGS__)
|
||||
#define IWbemClassObject_Get(obj, ...) obj->Get(__VA_ARGS__)
|
||||
#define IWbemClassObject_Release(obj) obj->Release()
|
||||
#define IEnumWbemClassObject_Release(obj) obj->Release()
|
||||
#define IWbemServices_Release(obj) obj->Release()
|
||||
#define IWbemLocator_Release(obj) obj->Release()
|
||||
#else
|
||||
#define our_CLSID_WbemLocator &CLSID_WbemLocator
|
||||
#define our_IID_IWbemLocator &IID_IWbemLocator
|
||||
#endif
|
||||
|
||||
HRESULT QueryWMIProperty(LPWSTR query, LPWSTR property, LPVARIANT value) {
|
||||
IWbemLocator *locator = NULL;
|
||||
IWbemServices *services = NULL;
|
||||
IEnumWbemClassObject *enumerator = NULL;
|
||||
IWbemClassObject *object = NULL;
|
||||
HRESULT hr = CoCreateInstance(our_CLSID_WbemLocator, NULL, CLSCTX_INPROC_SERVER, our_IID_IWbemLocator, (void **)&locator);
|
||||
if (!SUCCEEDED(hr)) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
BSTR server = SysAllocString(L"ROOT\\CIMV2");
|
||||
hr = IWbemLocator_ConnectServer(locator, server, NULL, NULL, NULL, 0, NULL, NULL, &services);
|
||||
SysFreeString(server);
|
||||
if (!SUCCEEDED(hr)) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
hr = CoSetProxyBlanket((IUnknown *)services, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL, RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE);
|
||||
if (!SUCCEEDED(hr)) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
BSTR wql = SysAllocString(L"WQL");
|
||||
BSTR queryBstr = SysAllocString(query);
|
||||
hr = IWbemServices_ExecQuery(services, wql, queryBstr, WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &enumerator);
|
||||
SysFreeString(wql);
|
||||
SysFreeString(queryBstr);
|
||||
if (!SUCCEEDED(hr)) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
ULONG uReturn = 0;
|
||||
hr = IEnumWbemClassObject_Next(enumerator, WBEM_INFINITE, 1, &object, &uReturn);
|
||||
if (!SUCCEEDED(hr)) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
BSTR propBstr = SysAllocString(property);
|
||||
hr = IWbemClassObject_Get(object, propBstr, 0, value, NULL, NULL);
|
||||
SysFreeString(propBstr);
|
||||
|
||||
end:
|
||||
if (object) {
|
||||
IWbemClassObject_Release(object);
|
||||
}
|
||||
if (enumerator) {
|
||||
IEnumWbemClassObject_Release(enumerator);
|
||||
}
|
||||
if (services) {
|
||||
IWbemServices_Release(services);
|
||||
}
|
||||
if (locator) {
|
||||
IWbemLocator_Release(locator);
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
#pragma once
|
||||
|
||||
#include "stdafx.h"
|
||||
#include <windows.h>
|
||||
#include <shlobj.h>
|
||||
#include "Exec.h"
|
||||
#include "HResult.h"
|
||||
#include "VersionInfo.h"
|
||||
|
||||
static inline HRESULT ViewWindowsUpdateLog(int nCmdShow) {
|
||||
WCHAR windir[MAX_PATH];
|
||||
HRESULT hr = SHGetFolderPath(0, CSIDL_WINDOWS, NULL, 0, windir);
|
||||
if (!SUCCEEDED(hr)) {
|
||||
TRACE(L"SHGetFolderPath() failed: %ls\n", GetMessageForHresult(hr));
|
||||
return hr;
|
||||
}
|
||||
|
||||
LPWSTR workDir = windir;
|
||||
|
||||
if (AtLeastWin10()) {
|
||||
// Windows 10 moves WU/USO logs to ETW. The ETW logs can be converted back to a plain-text .log
|
||||
// using a cmdlet.
|
||||
WCHAR powershell[MAX_PATH];
|
||||
ExpandEnvironmentStrings(L"%SystemRoot%\\System32\\WindowsPowerShell\\v1.0\\powershell.exe", powershell, ARRAYSIZE(powershell));
|
||||
|
||||
DWORD code;
|
||||
HRESULT hr = Exec(NULL, powershell, L"-Command Get-WindowsUpdateLog", windir, nCmdShow, TRUE, &code);
|
||||
if (!SUCCEEDED(hr) || code != 0) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
// On success, the log is written to Desktop\WindowsUpdate.log.
|
||||
WCHAR desktop[MAX_PATH];
|
||||
hr = SHGetFolderPath(0, CSIDL_DESKTOP, NULL, 0, desktop);
|
||||
if (!SUCCEEDED(hr)) {
|
||||
TRACE(L"SHGetFolderPath() failed: %ls\n", GetMessageForHresult(hr));
|
||||
return hr;
|
||||
}
|
||||
|
||||
workDir = desktop;
|
||||
}
|
||||
|
||||
return Exec(L"open", L"WindowsUpdate.log", NULL, workDir, nCmdShow, FALSE, NULL);
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
#include "stdafx.h"
|
||||
#include "Wow64.h"
|
||||
|
||||
typedef BOOL (WINAPI *_Wow64DisableWow64FsRedirection)(PVOID *OldValue);
|
||||
typedef BOOL (WINAPI *_Wow64RevertWow64FsRedirection)(PVOID OldValue);
|
||||
|
||||
static BOOL _loadedWow64;
|
||||
static _Wow64DisableWow64FsRedirection $Wow64DisableWow64FsRedirection;
|
||||
static _Wow64RevertWow64FsRedirection $Wow64RevertWow64FsRedirection;
|
||||
|
||||
#if _WIN64
|
||||
// Not needed
|
||||
#define DisableWow64FsRedirection(OldValue) TRUE
|
||||
#define RevertWow64FsRedirection(OldValue) TRUE
|
||||
#else
|
||||
static void LoadWow64Symbols() {
|
||||
if (!_loadedWow64) {
|
||||
_loadedWow64 = TRUE;
|
||||
|
||||
HMODULE kernel32 = GetModuleHandle(L"kernel32.dll");
|
||||
$Wow64DisableWow64FsRedirection = (_Wow64DisableWow64FsRedirection)GetProcAddress(kernel32, "Wow64DisableWow64FsRedirection");
|
||||
$Wow64RevertWow64FsRedirection = (_Wow64RevertWow64FsRedirection)GetProcAddress(kernel32, "Wow64RevertWow64FsRedirection");
|
||||
}
|
||||
}
|
||||
|
||||
BOOL DisableWow64FsRedirection(PVOID *OldValue) {
|
||||
LoadWow64Symbols();
|
||||
|
||||
if ($Wow64DisableWow64FsRedirection) {
|
||||
return $Wow64DisableWow64FsRedirection(OldValue);
|
||||
} else {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
BOOL RevertWow64FsRedirection(PVOID OldValue) {
|
||||
LoadWow64Symbols();
|
||||
|
||||
if ($Wow64RevertWow64FsRedirection) {
|
||||
return $Wow64RevertWow64FsRedirection(OldValue);
|
||||
} else {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
BOOL DisableWow64FsRedirection(PVOID *OldValue);
|
||||
BOOL RevertWow64FsRedirection(PVOID OldValue);
|
Loading…
Reference in New Issue