检查 Windows 激活状态返回错误值

Posted

技术标签:

【中文标题】检查 Windows 激活状态返回错误值【英文标题】:Checking windows activation state returns wrong value 【发布时间】:2019-09-28 13:46:56 【问题描述】:

我正在为 Windows 10 构建一个桌面应用程序,用于检查 Windows 是否已激活。我正在使用在另一个线程上找到的方法来检查激活状态,该方法有效,但仅在创建窗口的几秒钟内调用它时才有效。很奇怪,我知道。有谁知道这可能是什么原因,如果有什么我可以做的来解决它?任何帮助表示赞赏。

bool isGenuineWindows()

    //WindowsAppId
    unsigned char uuid_bytes[] = 0x35, 0x35, 0x63, 0x39, 0x32, 0x37, 0x33, 0x34, 0x2d, 0x64, 0x36,
                                0x38, 0x32, 0x2d, 0x34, 0x64, 0x37, 0x31, 0x2d, 0x39, 0x38, 0x33,
                                0x65, 0x2d, 0x64, 0x36, 0x65, 0x63, 0x33, 0x66, 0x31, 0x36, 0x30,
                                0x35, 0x39, 0x66;

    GUID uuid;
    SL_GENUINE_STATE state;

    UuidFromStringA(uuid_bytes, &uuid);
    SLIsGenuineLocal(&uuid, &state, nullptr);
    return state == SL_GEN_STATE_IS_GENUINE;


int main(void)

      /*creates GUI and all that boring stuff*/
      MessageBox(NULL, "Some random message", "message", MB_ICONERROR);
      printf("%d", isGenuineWindows()); //works
      Sleep(5000); //wait a bit for the magic to wear off
      printf("%d", isGenuineWindows()); //always returns true regardless of activation state
      MessageBox(NULL, "Some random message", "message", MB_ICONERROR);
      printf("%d", isGenuineWindows()); //works again


【问题讨论】:

您不检查返回值。这就是你判断函数是否成功的方式。您的字符串不是以空值结尾的。你为什么不使用一个字符串,更容易看到它实际上是什么。但是第 1 步,添加缺少的错误检查。 @DavidHeffernan 返回值正在检查中。它们只是用 printf 打印为 0 或 1。这不是理想的方法,但它们已经过检查。 return state == SL_GEN_STATE_IS_GENUINE; @Zachary `//works` 是什么意思然后//always returns true printf 是否为您打印两个单独的值?由于您的窗口已激活,它总是返回 true 吗? printf 是否返回 false 而第二个 true?你的问题有点不清楚。 @Nina 不,不检查api调用的返回值 @Nina 第一个 printf 返回真正的激活状态。无论窗口是否被激活,第二个总是正确的。再次打开消息框后,它会打印正确的输出。例如,如果 windows 未激活,它将打印 010,如果它被激活,它将打印 111。我知道 printf 不是这样做的好方法,它只是一个概念证明。 @DavidHeffernan 你是对的,我应该检查 SLIsGenuineLocal 的返回是否有错误,但我只是没有在这里实现。我之前检查过退货,没有错误。 【参考方案1】:

UuidFromStringA第一个参数的类型是RPC_CSTR,在rpcdce.h中定义:

typedef _Null_terminated_ unsigned char __RPC_FAR * RPC_CSTR;

它是一个以 NULL 结尾的字符串,尽管它没有被记录。 如果参数不是 NULL-Terminated,则函数将失败。您传递的字符串不是以 NULL 结尾的,这将导致未定义的行为(取决于 uuid_bytes[36] 的原始值)。

使用明文字符串而不是ASCII,这是默认的以NULL结尾的字符串:

unsigned char uuid_bytes[] = "55c92734-d682-4d71-983e-d6ec3f16059f";

【讨论】:

以上是关于检查 Windows 激活状态返回错误值的主要内容,如果未能解决你的问题,请参考以下文章

检查是不是有新的 Windows 版本可用并以编程方式安装

Shell命令的退出状态及错误检查

如何在 C# 中检查 Windows 许可证状态?

存储过程返回错误值?

Zabbix监控Windows客户端设置

怎样激活Win10企业版