windows-nt/Source/XPSP1/NT/windows/appcompat/checkacversion/main.cpp
2020-09-26 16:20:57 +08:00

195 lines
5.4 KiB
C++

/*++
Copyright (c) 2001 Microsoft Corporation
Module Name:
main.cpp
Abstract:
This is the customization DLL for update.exe. When the AppCompat package
is installed, the first thing that happens is update.exe calls BeginInstallation().
That function checks the registry for the version of the already-installed package.
The user may continue to install THIS package under the following conditions:
- There is no package already installed
- There is any corruption in these registry values
- The package that's already installed is an older version than this one.
The user will not be able to install this package under only the condition that he/she
has a package already installed that's a newer version.
Notes:
* This is written in ANSI because Update.exe is ANSI and a Unicode implementation would add
no value.
* Any messages in the string table of AcVersion.rc will override messages in Update.exe.
For instance, if BeginInstallation() returns STATUS_SP_VERSION_GREATER_1, normally the
message in Update.exe's resources that corresponds to this would be displayed to the user.
If there is, however, a STATUS_SP_VERSION_GREATER_1 string in AcVersion.rc, it will be used
instead. This way we can use either Update.exe's strings OR our own custom strings.
This works for all areas of the installer, by the way, not just BeginInstallation() return value.
For instance, adding a STR_WELCOME_LINE string in AcVersion.rc would replace the corresponding
string in Update.exe.
Author:
carlco created 07/30/2001
--*/
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include "buildno.h"
#include "resource.h"
#define THIS_MAJOR 5
#define THIS_MINOR 1
#define THIS_BUILD 0
#define THIS_REVISION AC_BUILD
// This is from %WIN2k_SE_ROOT%\private\windows\setup\srvpack5\update4\resource.h
//#define STATUS_SP_VERSION_GREATER_1 0xf06a
#define STR_WELCOME_LINE 0xf039
#define STATUS_BUILD_VERSION_MISMATCH 0xf020
/*
This is the code that will be passed back to update.exe to notify the mechanism that
a package has already been installed that is a greater version than this one.
*/
#define QFE_FAIL_CODE STATUS_SP_VERSION_GREATER_1
//#define QFE_FAIL_CODE IDS_TEST
/*
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Active Setup\\Installed Components\\{2eac6a2d-57a8-44d4-96f7-e32bab40ca5f}]
@="Windows Update"
"ComponentID"="Windows XP Application Compatibility Update"
"IsInstalled"=dword:00000001
"Locale"="*"
"Version"="1,0,2205,0"
*/
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, PVOID lpvReserved)
{
return TRUE;
}
#define GRABNEXTTOKEN(a) \
sz = strchr(szTok, ','); \
if(sz == NULL) \
{ \
return S_OK; \
} \
*sz = 0; \
(a) = atoi(szTok); \
szTok = sz + 1;
DWORD BeginInstallation(PVOID pCustomInfo)
{
HKEY hKey = NULL;
CHAR szVersion[25];
DWORD dwSize = 25;
//CHAR szBuf[500];
DWORD dwMajor = 0;
DWORD dwMinor = 0;
DWORD dwBuild = 0;
DWORD dwRevision = 0;
PSTR sz = NULL;
PSTR szTok = NULL;
//sprintf(szBuf, "BeginInstallation\n");
//OutputDebugString(szBuf);
if(ERROR_SUCCESS != RegOpenKeyEx(
HKEY_LOCAL_MACHINE,
"SOFTWARE\\Microsoft\\Active Setup\\Installed Components\\" AC_GUID,
NULL,
KEY_QUERY_VALUE,
&hKey))
{
// Error opening the key - the package may not be installed, so it's OK to install it.
return S_OK;
}
// Get the version
if(ERROR_SUCCESS != RegQueryValueEx(
hKey, "Version", NULL, NULL, (PBYTE)szVersion, &dwSize
))
{
// Error getting this value; let's install the package.
RegCloseKey(hKey);
return S_OK;
}
RegCloseKey(hKey);
// Examine the version. Find the major version number.
// Find the first comma and replace it with a NULL
szTok = szVersion;
GRABNEXTTOKEN(dwMajor)
GRABNEXTTOKEN(dwMinor)
GRABNEXTTOKEN(dwBuild)
// Now there shouldn't be any more commas left.
// szTok is the last token.
dwRevision = atoi(szTok);
//sprintf(szBuf, "%d,%d,%d,%d\n", dwMajor, dwMinor, dwBuild, dwRevision);
//OutputDebugString(szBuf);
/*
If we've made it this far, we can now compare the version.
*/
if(dwMajor > THIS_MAJOR)
{
return QFE_FAIL_CODE;
}
if(dwMajor == THIS_MAJOR)
{
if(dwMinor > THIS_MINOR)
{
return QFE_FAIL_CODE;
}
if(dwMinor == THIS_MINOR)
{
if(dwBuild > THIS_BUILD)
{
return QFE_FAIL_CODE;
}
if(dwBuild == THIS_BUILD)
{
if(dwRevision > THIS_REVISION) return QFE_FAIL_CODE;
}
}
}
return S_OK;
}
DWORD EndInstallation(PVOID pCustomInfo)
{
return S_OK;
}