From 66dc549f2bb4a1e31961dedc514dea4ff7e7520b Mon Sep 17 00:00:00 2001 From: A1ive <10670106+a1ive@users.noreply.github.com> Date: Wed, 19 Jun 2024 23:19:50 +0900 Subject: [PATCH] print ProductPolicy (#39) --- README.md | 2 + libnw/libnw.c | 2 + libnw/libnw.h | 2 + libnw/libnw.vcxproj | 1 + libnw/libnw.vcxproj.filters | 3 ++ libnw/productpolicy.c | 96 +++++++++++++++++++++++++++++++++++++ nwinfo.c | 3 ++ 7 files changed, 109 insertions(+) create mode 100644 libnw/productpolicy.c diff --git a/README.md b/README.md index d079bf89..9751a588 100644 --- a/README.md +++ b/README.md @@ -49,6 +49,8 @@ OPTIONS: --uefi Print UEFI boot information. --shares List network mapped drives. --audio List audio devices. + --public-ip Print public IP address. + --product-policy Print ProductPolicy values. ``` ## Credits diff --git a/libnw/libnw.c b/libnw/libnw.c index 35c6e6fa..c824e209 100644 --- a/libnw/libnw.c +++ b/libnw/libnw.c @@ -86,6 +86,8 @@ VOID NW_Print(LPCSTR lpFileName) NW_Audio(); if (NWLC->PublicIpInfo) NW_PublicIp(); + if (NWLC->ProductPolicyInfo) + NW_ProductPolicy(); NW_Libinfo(); NW_Export(NWLC->NwRoot, NWLC->NwFile); } diff --git a/libnw/libnw.h b/libnw/libnw.h index ae3dd330..6517e090 100644 --- a/libnw/libnw.h +++ b/libnw/libnw.h @@ -42,6 +42,7 @@ typedef struct _NWLIB_CONTEXT BOOL ShareInfo; BOOL AudioInfo; BOOL PublicIpInfo; + BOOL ProductPolicyInfo; BOOL Debug; BOOL HideSensitive; @@ -117,6 +118,7 @@ PNODE NW_Uefi(VOID); PNODE NW_NetShare(VOID); PNODE NW_Audio(VOID); PNODE NW_PublicIp(VOID); +PNODE NW_ProductPolicy(VOID); VOID NWL_GetUptime(CHAR* szUptime, DWORD dwSize); VOID NWL_GetHostname(CHAR* szHostname); diff --git a/libnw/libnw.vcxproj b/libnw/libnw.vcxproj index 28739e7d..e426eb6f 100644 --- a/libnw/libnw.vcxproj +++ b/libnw/libnw.vcxproj @@ -166,6 +166,7 @@ copy "$(SolutionDir)winring0\HwRwDrvx64.sys" "$(SolutionDir)$(Platform)\$(Config + diff --git a/libnw/libnw.vcxproj.filters b/libnw/libnw.vcxproj.filters index 210ad610..546fc29e 100644 --- a/libnw/libnw.vcxproj.filters +++ b/libnw/libnw.vcxproj.filters @@ -128,6 +128,9 @@ 源文件 + + 源文件 + diff --git a/libnw/productpolicy.c b/libnw/productpolicy.c new file mode 100644 index 00000000..23b47e34 --- /dev/null +++ b/libnw/productpolicy.c @@ -0,0 +1,96 @@ +// SPDX-License-Identifier: Unlicense + +#include +#include +#include + +#include "libnw.h" +#include "utils.h" + + +#pragma pack(1) +typedef struct _PRODUCT_POLICY_HEADER +{ + DWORD dwSize; // total size, including this header + DWORD dwArraySize; // size of values array that follows this header + DWORD dwEndSize; // size of end marker that follows the values array + DWORD unused; + DWORD dwVersion; // must be 1 +} PRODUCT_POLICY_HEADER, * PPRODUCT_POLICY_HEADER; + +typedef struct _PRODUCT_POLICY_VALUE +{ + UINT16 wSize; // total size, including this header + UINT16 wNameSize; // size of name + // type of data + // 1 - REG_SZ, 2- REG_EXPAND_SZ, 3 - REG_BINARY, 4 - REG_BINARY + UINT16 wType; + UINT16 wDataSize; // size of data + DWORD dwFlags; + DWORD unused; +} PRODUCT_POLICY_VALUE, * PPRODUCT_POLICY_VALUE; + +#define PRODUCT_POLICY_END_MARK 0x45ul // dword +#pragma pack() + +PNODE NW_ProductPolicy(VOID) +{ + CHAR hex[] = "0123456789ABCDEF"; + PNODE pp = NWL_NodeAlloc("Product Policy", 0); + if (NWLC->ProductPolicyInfo) + NWL_NodeAppendChild(NWLC->NwRoot, pp); + DWORD dwType; + DWORD ppSize; + PPRODUCT_POLICY_HEADER ppHeader = NULL; + PPRODUCT_POLICY_VALUE ppValue; + PUINT8 ppData = NWL_NtGetRegValue(HKEY_LOCAL_MACHINE, + L"SYSTEM\\CurrentControlSet\\Control\\ProductOptions", + L"ProductPolicy", &ppSize, &dwType); + if (ppData == NULL || dwType != REG_BINARY || ppSize <= sizeof(PRODUCT_POLICY_HEADER)) + goto end; + ppHeader = (PPRODUCT_POLICY_HEADER)ppData; + if (ppSize != ppHeader->dwSize || ppHeader->dwVersion != 1) + goto end; + if (ppHeader->dwArraySize + ppHeader->dwEndSize + sizeof(PRODUCT_POLICY_HEADER) > ppSize) + goto end; + for (ppValue = (PPRODUCT_POLICY_VALUE)(ppData + sizeof(PRODUCT_POLICY_HEADER)); + (PUINT8)ppValue < ppData + sizeof(PRODUCT_POLICY_HEADER) + ppHeader->dwArraySize; + ppValue = (PPRODUCT_POLICY_VALUE)((PUINT8)ppValue + ppValue->wSize)) + { + CHAR* pName = _strdup(NWL_Ucs2ToUtf8((WCHAR*)((PUINT8)ppValue + sizeof(PRODUCT_POLICY_VALUE)))); + PUINT8 pValueData = (PUINT8)ppValue + sizeof(PRODUCT_POLICY_VALUE) + ppValue->wNameSize; + pName[ppValue->wNameSize / sizeof(WCHAR)] = '\0'; + switch (ppValue->wType) + { + case REG_SZ: + case REG_EXPAND_SZ: + case REG_MULTI_SZ: //FIXME + NWL_NodeAttrSet(pp, pName, NWL_Ucs2ToUtf8((LPCWSTR)pValueData), 0); + break; + case REG_DWORD: + NWL_NodeAttrSetf(pp, pName, NAFLG_FMT_NUMERIC, "%lu", *(PDWORD)pValueData); + break; + case REG_QWORD: + NWL_NodeAttrSetf(pp, pName, NAFLG_FMT_NUMERIC, "%llu", *(PUINT64)pValueData); + break; + default: + { + CHAR* tmp = calloc(ppValue->wDataSize, 3); + for (UINT i = 0; i < ppValue->wDataSize; i++) + { + tmp[i * 3] = hex[(pValueData[i] & 0xF0) >> 4]; + tmp[i * 3 + 1] = hex[pValueData[i] & 0x0F]; + if (i < ppValue->wDataSize - 1U) + tmp[i * 3 + 2] = ' '; + } + NWL_NodeAttrSet(pp, pName, tmp, 0); + free(tmp); + } + break; + } + free(pName); + } +end: + free(ppData); + return pp; +} diff --git a/nwinfo.c b/nwinfo.c index f5cb5376..fc9baf6d 100644 --- a/nwinfo.c +++ b/nwinfo.c @@ -45,6 +45,7 @@ static void nwinfo_help(void) " --shares Print network mapped drives.\n" " --audio Print audio devices.\n" " --public-ip Print public IP address.\n" + " --product-policy Print ProductPolicy.\n"); } int main(int argc, char* argv[]) @@ -142,6 +143,8 @@ int main(int argc, char* argv[]) nwContext.AudioInfo = TRUE; else if (_stricmp(argv[i], "--public-ip") == 0) nwContext.PublicIpInfo = TRUE; + else if (_stricmp(argv[i], "--product-policy") == 0) + nwContext.ProductPolicyInfo = TRUE; else if (_stricmp(argv[i], "--debug") == 0) nwContext.Debug = TRUE; else if (_stricmp(argv[i], "--hide-sensitive") == 0)