mirror of
https://github.com/LegacyUpdate/LegacyUpdate.git
synced 2025-01-22 06:01:50 -05:00
Use slc.dll for activation status on Vista+
The WMI approach is incredibly slow, taking around ~3000ms in my unactivated Vista and 7 VMs, and activated 7 Core 2 Duo laptop. Using slc.dll directly takes 1300-1500ms on Vista, and interestingly, exactly 31ms on both 7 installs. (Why is Vista still so slow here?)
This commit is contained in:
parent
94cf287758
commit
7a35bf7b16
2 changed files with 88 additions and 25 deletions
33
include/slpublic.h
Normal file
33
include/slpublic.h
Normal file
|
@ -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
|
|
@ -4,67 +4,97 @@
|
|||
#include "WMI.h"
|
||||
#include "VersionInfo.h"
|
||||
#include "licdll.h"
|
||||
#include <slpublic.h>
|
||||
|
||||
#define WindowsLicensingAppId L"55c92734-d682-4d71-983e-d6ec3f16059f"
|
||||
typedef HRESULT (WINAPI *_SLOpen)(HSLC *);
|
||||
typedef HRESULT (WINAPI *_SLGetLicensingStatusInformation)(HSLC, const SLID *, DWORD, DWORD, UINT *, SL_LICENSING_STATUS **);
|
||||
typedef HRESULT (WINAPI *_SLClose)(HSLC);
|
||||
|
||||
enum {
|
||||
LicenseStatusUnlicensed,
|
||||
LicenseStatusLicensed,
|
||||
LicenseStatusOOBGrace,
|
||||
LicenseStatusOOTGrace,
|
||||
LicenseStatusNonGenuineGrace,
|
||||
LicenseStatusNotification,
|
||||
LicenseStatusExtendedGrace
|
||||
};
|
||||
static _SLOpen $SLOpen;
|
||||
static _SLClose $SLClose;
|
||||
static _SLGetLicensingStatusInformation $SLGetLicensingStatusInformation;
|
||||
|
||||
static BOOL g_loadedLicenseStatus = FALSE;
|
||||
static BOOL g_isActivated = TRUE;
|
||||
|
||||
PLUGIN_METHOD(IsActivated) {
|
||||
PLUGIN_INIT();
|
||||
|
||||
// Activation is irrelevant prior to XP
|
||||
if (!IsOSVersionOrLater(5, 1)) {
|
||||
pushint(1);
|
||||
if (g_loadedLicenseStatus || !IsOSVersionOrLater(5, 1)) {
|
||||
pushint(g_isActivated);
|
||||
return;
|
||||
}
|
||||
|
||||
g_loadedLicenseStatus = TRUE;
|
||||
|
||||
if (IsOSVersionOrLater(6, 0)) {
|
||||
// Vista+: Ask the Software Licensing Service
|
||||
VARIANT value;
|
||||
HRESULT hr = QueryWMIProperty(L"SELECT LicenseStatus FROM SoftwareLicensingProduct WHERE ApplicationID = '" WindowsLicensingAppId L"'", L"LicenseStatus", &value);
|
||||
if (!SUCCEEDED(hr)) {
|
||||
// Treat as success because we can't determine the status
|
||||
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;
|
||||
}
|
||||
|
||||
pushint(value.intVal == LicenseStatusLicensed);
|
||||
VariantClear(&value);
|
||||
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;
|
||||
}
|
||||
|
||||
g_isActivated = status->eStatus == SL_LICENSING_STATUS_LICENSED;
|
||||
|
||||
end_slc:
|
||||
if (status) {
|
||||
LocalFree(status);
|
||||
}
|
||||
if (slc) {
|
||||
$SLClose(slc);
|
||||
}
|
||||
} else {
|
||||
// XP: Use private API
|
||||
ICOMLicenseAgent *agent;
|
||||
HRESULT hr = CoCreateInstance(&CLSID_COMLicenseAgent, NULL, CLSCTX_INPROC_SERVER, &IID_ICOMLicenseAgent, (void **)&agent);
|
||||
if (!SUCCEEDED(hr)) {
|
||||
goto end;
|
||||
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) {
|
||||
pushint(1);
|
||||
goto end;
|
||||
TRACE(L"COMLicenseAgent init failed: %x", hr);
|
||||
goto end_xp;
|
||||
}
|
||||
|
||||
ULONG wpaLeft, evalLeft;
|
||||
hr = ICOMLicenseAgent_GetExpirationInfo(agent, &wpaLeft, &evalLeft);
|
||||
if (!SUCCEEDED(hr)) {
|
||||
pushint(1);
|
||||
goto end;
|
||||
TRACE(L"COMLicenseAgent GetExpirationInfo failed: %x", hr);
|
||||
goto end_xp;
|
||||
}
|
||||
|
||||
pushint(wpaLeft == MAXLONG);
|
||||
g_isActivated = wpaLeft == MAXLONG;
|
||||
|
||||
end:
|
||||
end_xp:
|
||||
if (agent) {
|
||||
ICOMLicenseAgent_Release(agent);
|
||||
}
|
||||
}
|
||||
|
||||
pushint(g_isActivated);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue