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)