Compare commits

...

10 Commits

Author SHA1 Message Date
TheTank20 9afa6404fc o2003's still broken, but less 2024-01-05 19:35:13 -05:00
TheTank20 79bd667054
Update README.md 2023-12-21 17:55:32 +00:00
TheTank20 5da134e7f0 fixed broken error codes 2023-12-21 12:49:43 -05:00
TheTank20 b64e3d0cb2 Merge remote-tracking branch 'origin/master' 2023-12-21 12:46:34 -05:00
TheTank20 823e44ec56 more fixes 2023-12-21 12:46:26 -05:00
TheTank20 d3e9089700 Fixed errors not showing up 2023-12-21 12:39:22 -05:00
TheTank20 7ca11132b8
fixed again 2023-12-21 16:51:39 +00:00
TheTank20 650f94babf
fix build instructions 2023-12-21 16:41:51 +00:00
TheTank20 0dce831512
Remove misplaced test file 2023-12-21 02:04:55 +00:00
TheTank20 a829a21a17
Remove unneeded file 2023-12-21 02:04:41 +00:00
5 changed files with 359 additions and 141 deletions

102
.idea/editor.xml Normal file
View File

@ -0,0 +1,102 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="BackendCodeEditorSettings">
<option name="/Default/CodeStyle/CodeFormatting/CppClangFormat/EnableClangFormatSupport/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/EditorConfig/EnableClangFormatSupport/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_BINARY_EXPRESSIONS_CHAIN/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_CALLS_CHAIN/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_EXPRESSION/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_FOR_STMT/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTIPLE_DECLARATION/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_TERNARY/@EntryValue" value="ALIGN_ALL" type="string" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/BLANK_LINES_AROUND_CLASS_DEFINITION/@EntryValue" value="1" type="int" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/KEEP_BLANK_LINES_IN_DECLARATIONS/@EntryValue" value="2" type="int" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/KEEP_BLANK_LINES_IN_CODE/@EntryValue" value="2" type="int" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/KEEP_USER_LINEBREAKS/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INDENT_CASE_FROM_SWITCH/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INDENT_COMMENT/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INT_ALIGN_EQ/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SIMPLE_BLOCK_STYLE/@EntryValue" value="DO_NOT_CHANGE" type="string" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_COMMA_IN_TEMPLATE_ARGS/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_COMMA_IN_TEMPLATE_PARAMS/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_FOR_SEMICOLON/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_FOR_SEMICOLON/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_UNARY_OPERATOR/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_ARRAY_ACCESS_BRACKETS/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_CAST_EXPRESSION_PARENTHESES/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_EMPTY_INITIALIZER_BRACES/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_EMPTY_METHOD_PARENTHESES/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_INITIALIZER_BRACES/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPECIAL_ELSE_IF_TREATMENT/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_CAST_EXPRESSION_PARENTHESES/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_AFTER_BINARY_OPSIGN/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_BEFORE_TERNARY_OPSIGNS/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/TYPE_DECLARATION_BRACES/@EntryValue" value="END_OF_LINE" type="string" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/OTHER_BRACES/@EntryValue" value="END_OF_LINE" type="string" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/CASE_BLOCK_BRACES/@EntryValue" value="END_OF_LINE" type="string" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/BLANK_LINES_AROUND_FUNCTION_DECLARATION/@EntryValue" value="1" type="int" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/BLANK_LINES_AROUND_FUNCTION_DEFINITION/@EntryValue" value="1" type="int" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/PLACE_WHILE_ON_NEW_LINE/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/PLACE_ELSE_ON_NEW_LINE/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/PLACE_CATCH_ON_NEW_LINE/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/NAMESPACE_INDENTATION/@EntryValue" value="All" type="string" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_ARGUMENT/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_EXTENDS_LIST/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_PARAMETER/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_TYPE_ARGUMENT/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_TYPE_PARAMETER/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/BLANK_LINES_AROUND_DECLARATIONS/@EntryValue" value="0" type="int" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INDENT_ACCESS_SPECIFIERS_FROM_CLASS/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INDENT_CLASS_MEMBERS_FROM_ACCESS_SPECIFIERS/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/LINE_BREAK_AFTER_COLON_IN_MEMBER_INITIALIZER_LISTS/@EntryValue" value="ON_SINGLE_LINE" type="string" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/MEMBER_INITIALIZER_LIST_STYLE/@EntryValue" value="DO_NOT_CHANGE" type="string" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/PLACE_NAMESPACE_DEFINITIONS_ON_SAME_LINE/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_COLON_IN_BITFIELD_DECLARATOR/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_COLON_IN_BITFIELD_DECLARATOR/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_EXTENDS_COLON/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_EXTENDS_COLON/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_FOR_COLON/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_FOR_COLON/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_PTR_IN_DATA_MEMBER/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_PTR_IN_DATA_MEMBERS/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_PTR_IN_METHOD/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_PTR_IN_NESTED_DECLARATOR/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_REF_IN_DATA_MEMBER/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_REF_IN_DATA_MEMBERS/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_REF_IN_METHOD/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_PTR_IN_ABSTRACT_DECL/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_PTR_IN_DATA_MEMBER/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_PTR_IN_DATA_MEMBERS/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_PTR_IN_METHOD/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_REF_IN_ABSTRACT_DECL/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_REF_IN_DATA_MEMBER/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_REF_IN_DATA_MEMBERS/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_REF_IN_METHOD/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_TEMPLATE_ARGS/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_TEMPLATE_PARAMS/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BETWEEN_CLOSING_ANGLE_BRACKETS_IN_TEMPLATE_ARGS/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_EMPTY_TEMPLATE_PARAMS/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_TEMPLATE_ARGS/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_TEMPLATE_PARAMS/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_DECLARATION_PARENTHESES/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_EMPTY_BLOCKS/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_BEFORE_INVOCATION_LPAR/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_AFTER_INVOCATION_LPAR/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_BEFORE_INVOCATION_RPAR/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_BEFORE_DECLARATION_LPAR/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_AFTER_DECLARATION_LPAR/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_BEFORE_DECLARATION_RPAR/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_ARGUMENTS_STYLE/@EntryValue" value="WRAP_IF_LONG" type="string" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_PARAMETERS_STYLE/@EntryValue" value="WRAP_IF_LONG" type="string" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/BREAK_TEMPLATE_DECLARATION/@EntryValue" value="LINE_BREAK" type="string" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/NAMESPACE_DECLARATION_BRACES/@EntryValue" value="END_OF_LINE" type="string" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/FREE_BLOCK_BRACES/@EntryValue" value="END_OF_LINE" type="string" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INVOCABLE_DECLARATION_BRACES/@EntryValue" value="END_OF_LINE" type="string" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ANONYMOUS_METHOD_DECLARATION_BRACES/@EntryValue" value="END_OF_LINE" type="string" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INITIALIZER_BRACES/@EntryValue" value="END_OF_LINE_NO_SPACE" type="string" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INDENT_STYLE/@EntryValue" value="Space" type="string" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INDENT_SIZE/@EntryValue" value="4" type="int" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/CONTINUOUS_LINE_INDENT/@EntryValue" value="Double" type="string" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/TAB_WIDTH/@EntryValue" value="4" type="int" />
</component>
</project>

View File

@ -6,7 +6,7 @@ Command line interface for Windows XP license management, inspired by Microsoft'
In most cases, you'll need `xpmgr_x86.exe`. In most cases, you'll need `xpmgr_x86.exe`.
If you have Windows XP Professional x64 Edition or an x64 version of Windows Server 2003, you need `xpmgr_x64.exe`. If you have Windows XP Professional x64 Edition or a x64 version of Windows Server 2003, you need `xpmgr_x64.exe`.
If you have an Itanium version of Windows XP or Server 2003, Windows Product Activation is not on those editions, so there is no need for this tool. If you have an Itanium version of Windows XP or Server 2003, Windows Product Activation is not on those editions, so there is no need for this tool.
@ -26,6 +26,8 @@ If you're trying to manage products other than Windows, you need `xpmgr_x86.exe`
`--Office2003`: This provides **EXPERIMENTAL** support for Office 2003. When this parameter is used, all other parameters except `--GetInstallationID` and `--SetConfirmationID` are disabled, and those two (attempt) to go what they do on Office 2003, rather than Windows. `--Office2003`: This provides **EXPERIMENTAL** support for Office 2003. When this parameter is used, all other parameters except `--GetInstallationID` and `--SetConfirmationID` are disabled, and those two (attempt) to go what they do on Office 2003, rather than Windows.
`--BypassInstallCheck`: Disables the check to see if Office 2003 is installed. Intended for debugging purposes only. If it doesn't work without this enabled, it probably won't work with it either.
`--GetUsage`: Outputs all the commands you can use. `--GetUsage`: Outputs all the commands you can use.
## Releases ## Releases
@ -37,8 +39,13 @@ Make sure Visual Studio 2017 or later is installed. Then, install [TDM-GCC](http
mkdir build mkdir build
mkdir build\x86 mkdir build\x86
mkdir build\x64 mkdir build\x64
windres icon.rc -O coff -F pe-i386 -o build\x64\icon_x64.res windres icon.rc -F pe-i386 -O coff -o build\x86\icon_x86.res
g++ -m32 -o build\x86\xpmgr_x86 xpmgr.cpp build\x64\icon_x64.res -lole32 -luuid -loleaut32 g++ -m32 -o build\x86\xpmgr_x86 xpmgr.cpp build\x86\icon_x86.res -lole32 -luuid -loleaut32
windres icon.rc -O coff -o build\x86\icon_x86.res windres icon.rc -O coff -o build\x64\icon_x64.res
g++ -o build\x64\xpmgr_x64 xpmgr.cpp build\x86\icon_x86.res -lole32 -luuid -loleaut32 g++ -o build\x64\xpmgr_x64 xpmgr.cpp build\x64\icon_x64.res -lole32 -luuid -loleaut32
```
Or, if you like one-liners:
```
mkdir build & mkdir build\x86 & mkdir build\x64 & windres icon.rc -F pe-i386 -O coff -o build\x86\icon_x86.res & g++ -m32 -o build\x86\xpmgr_x86 xpmgr.cpp build\x86\icon_x86.res -lole32 -luuid -loleaut32 & windres icon.rc -O coff -o build\x64\icon_x64.res & g++ -o build\x64\xpmgr_x64 xpmgr.cpp build\x64\icon_x64.res -lole32 -luuid -loleaut32
``` ```

View File

@ -1,16 +0,0 @@
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by xpmgr.rc
//
#define IDI_ICON1 101
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 102
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1001
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

View File

@ -1,3 +0,0 @@
14037188531115461057117122732036502128316172554233
115654-870803-633253-538651-586936-689612-768696

362
xpmgr.cpp
View File

@ -1,3 +1,4 @@
// ReSharper disable CppEnforceOverridingFunctionStyle
typedef struct IUnknown IUnknown; typedef struct IUnknown IUnknown;
#include <windows.h> #include <windows.h>
@ -15,23 +16,28 @@ typedef struct IUnknown IUnknown;
#endif #endif
#endif #endif
const char* specifiedProduct = NULL; const char* specifiedProduct = nullptr;
// This is a really weird way of making a GUID. In short, this becomes ACADF079-CBCD-4032-83F2-FA47C4DB096F. Ignore the 0x and it makes sense. // This is a really weird way of making a GUID. In short, this becomes ACADF079-CBCD-4032-83F2-FA47C4DB096F. Ignore the 0x and it makes sense.
static CLSID XP_CLSID = { 0xACADF079, 0xCBCD, 0x4032, {0x83, 0xF2, 0xFA, 0x47, 0xC4, 0xDB, 0x09, 0x6F} }; static CLSID XP_CLSID = { 0xACADF079, 0xCBCD, 0x4032, {0x83, 0xF2, 0xFA, 0x47, 0xC4, 0xDB, 0x09, 0x6F} };
static IID XP_IID = { 0xB8CBAD79, 0x3F1F, 0x481A, {0xBB, 0x0C, 0xE7, 0xBB, 0xD7, 0x7B, 0xDD, 0xD1} }; static IID XP_IID = { 0xB8CBAD79, 0x3F1F, 0x481A, { 0xBB, 0x0C, 0xE7, 0xBB, 0xD7, 0x7B, 0xDD, 0xD1 } };
static CLSID O2003_CLSID = { 0x2DF8D04C, 0x5BFA, 0x101B, { 0xBD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0xDE, 0x52 } }; static CLSID O2003_CLSID = { 0x812034D2, 0x760F, 0x11CF, { 0x93, 0x70, 0x00, 0xAA, 0x00, 0xB8, 0xBF, 0x00 } };
static IID O2003_IID = { 0x00194002, 0xD9C3, 0x11D3, { 0x8D, 0x59, 0x00, 0x50, 0x04, 0x83, 0x84, 0xE3 } }; static IID O2003_IID = { 0x00194002, 0xD9C3, 0x11D3, { 0x8D, 0x59, 0x00, 0x50, 0x04, 0x83, 0x84, 0xE3 } };
#undef XP_INTERFACE #undef XP_INTERFACE
#define XP_INTERFACE ICOMLicenseAgent #define XP_INTERFACE ICOMLicenseAgent
DECLARE_INTERFACE_(ICOMLicenseAgent, IDispatch) DECLARE_INTERFACE_(ICOMLicenseAgent, IDispatch)
{ {
protected:
~ICOMLicenseAgent() = default;
public:
/*** IUnknown methods ***/ /*** IUnknown methods ***/
STDMETHOD(QueryInterface)(THIS_ REFIID riid, LPVOID * ppvObj) PURE; STDMETHOD(QueryInterface)(THIS_ REFIID riid, LPVOID * ppvObj) PURE;
STDMETHOD_(ULONG, AddRef)(THIS) PURE; STDMETHOD_(ULONG, AddRef)() PURE;
STDMETHOD_(ULONG, Release)(THIS) PURE; STDMETHOD_(ULONG, Release)() PURE;
/*** IDispatch methods ***/ /*** IDispatch methods ***/
STDMETHOD(GetTypeInfoCount)(THIS_ UINT FAR * pctinfo) PURE; STDMETHOD(GetTypeInfoCount)(THIS_ UINT FAR * pctinfo) PURE;
@ -74,21 +80,21 @@ DECLARE_INTERFACE_(ICOMLicenseAgent, IDispatch)
STDMETHOD(GetAddress2)(THIS_ BSTR * pbstrVal) PURE; STDMETHOD(GetAddress2)(THIS_ BSTR * pbstrVal) PURE;
STDMETHOD(SetAddress2)(THIS_ BSTR bstrNewVal) PURE; STDMETHOD(SetAddress2)(THIS_ BSTR bstrNewVal) PURE;
STDMETHOD(AsyncProcessHandshakeRequest)(THIS_ LONG bReviseCustInfo) PURE; STDMETHOD(AsyncProcessHandshakeRequest)(THIS_ LONG bReviseCustInfo) PURE;
STDMETHOD(AsyncProcessNewLicenseRequest)(THIS) PURE; STDMETHOD(AsyncProcessNewLicenseRequest)() PURE;
STDMETHOD(AsyncProcessReissueLicenseRequest)(THIS) PURE; STDMETHOD(AsyncProcessReissueLicenseRequest)() PURE;
STDMETHOD(AsyncProcessReviseCustInfoRequest)(THIS) PURE; STDMETHOD(AsyncProcessReviseCustInfoRequest)() PURE;
STDMETHOD(GetAsyncProcessReturnCode)(THIS_ ULONG * pdwRetCode) PURE; STDMETHOD(GetAsyncProcessReturnCode)(THIS_ ULONG * pdwRetCode) PURE;
STDMETHOD(AsyncProcessDroppedLicenseRequest)(THIS) PURE; STDMETHOD(AsyncProcessDroppedLicenseRequest)() PURE;
STDMETHOD(GenerateInstallationId)(THIS_ BSTR * pbstrVal) PURE; STDMETHOD(GenerateInstallationId)(THIS_ BSTR * pbstrVal) PURE;
STDMETHOD(DepositConfirmationId)(THIS_ BSTR bstrVal, ULONG * pdwRetCode) PURE; STDMETHOD(DepositConfirmationId)(THIS_ BSTR bstrVal, ULONG * pdwRetCode) PURE;
STDMETHOD(GetExpirationInfo)(THIS_ ULONG * pdwWPALeft, ULONG * pdwEvalLeft) PURE; STDMETHOD(GetExpirationInfo)(THIS_ ULONG * pdwWPALeft, ULONG * pdwEvalLeft) PURE;
STDMETHOD(AsyncProcessRegistrationRequest)(THIS) PURE; STDMETHOD(AsyncProcessRegistrationRequest)() PURE;
STDMETHOD(ProcessHandshakeRequest)(THIS_ LONG bReviseCustInfo) PURE; STDMETHOD(ProcessHandshakeRequest)(THIS_ LONG bReviseCustInfo) PURE;
STDMETHOD(ProcessNewLicenseRequest)(THIS) PURE; STDMETHOD(ProcessNewLicenseRequest)() PURE;
STDMETHOD(ProcessDroppedLicenseRequest)(THIS) PURE; STDMETHOD(ProcessDroppedLicenseRequest)() PURE;
STDMETHOD(ProcessReissueLicenseRequest)(THIS) PURE; STDMETHOD(ProcessReissueLicenseRequest)() PURE;
STDMETHOD(ProcessReviseCustInfoRequest)(THIS) PURE; STDMETHOD(ProcessReviseCustInfoRequest)() PURE;
STDMETHOD(EnsureInternetConnection)(THIS) PURE; STDMETHOD(EnsureInternetConnection)() PURE;
STDMETHOD(SetProductKey)(THIS_ LPWSTR pszNewProductKey) PURE; STDMETHOD(SetProductKey)(THIS_ LPWSTR pszNewProductKey) PURE;
STDMETHOD(GetProductID)(THIS_ BSTR * pbstrVal) PURE; STDMETHOD(GetProductID)(THIS_ BSTR * pbstrVal) PURE;
STDMETHOD(VerifyCheckDigits)(THIS_ BSTR bstrCIDIID, LONG * pbValue) PURE; STDMETHOD(VerifyCheckDigits)(THIS_ BSTR bstrCIDIID, LONG * pbValue) PURE;
@ -98,10 +104,14 @@ DECLARE_INTERFACE_(ICOMLicenseAgent, IDispatch)
#define O2003_INTERFACE ILicAgent #define O2003_INTERFACE ILicAgent
DECLARE_INTERFACE_(ILicAgent, IDispatch) DECLARE_INTERFACE_(ILicAgent, IDispatch)
{ {
protected:
~ILicAgent() = default;
public:
/*** IUnknown methods ***/ /*** IUnknown methods ***/
STDMETHOD(QueryInterface)(THIS_ REFIID riid, LPVOID * ppvObj) PURE; STDMETHOD(QueryInterface)(THIS_ REFIID riid, LPVOID * ppvObj) PURE;
STDMETHOD_(ULONG, AddRef)(THIS) PURE; STDMETHOD_(ULONG, AddRef)() PURE;
STDMETHOD_(ULONG, Release)(THIS) PURE; STDMETHOD_(ULONG, Release)() PURE;
/*** IDispatch methods ***/ /*** IDispatch methods ***/
STDMETHOD(GetTypeInfoCount)(THIS_ UINT FAR * pctinfo) PURE; STDMETHOD(GetTypeInfoCount)(THIS_ UINT FAR * pctinfo) PURE;
@ -185,16 +195,16 @@ DECLARE_INTERFACE_(ILicAgent, IDispatch)
STDMETHOD(GetDisconnectOption)(THIS_ int* pbRetVal) PURE; STDMETHOD(GetDisconnectOption)(THIS_ int* pbRetVal) PURE;
STDMETHOD(SetDisconnectOption)(THIS_ int bNewVal) PURE; STDMETHOD(SetDisconnectOption)(THIS_ int bNewVal) PURE;
STDMETHOD(AsyncProcessHandshakeRequest)(THIS_ int bReviseCustInfo) PURE; STDMETHOD(AsyncProcessHandshakeRequest)(THIS_ int bReviseCustInfo) PURE;
STDMETHOD(AsyncProcessNewLicenseRequest)(THIS) PURE; STDMETHOD(AsyncProcessNewLicenseRequest)() PURE;
STDMETHOD(AsyncProcessReissueLicenseRequest)(THIS) PURE; STDMETHOD(AsyncProcessReissueLicenseRequest)() PURE;
STDMETHOD(AsyncProcessRetailRenewalLicenseRequest)(THIS) PURE; STDMETHOD(AsyncProcessRetailRenewalLicenseRequest)() PURE;
STDMETHOD(AsyncProcessReviseCustInfoRequest)(THIS) PURE; STDMETHOD(AsyncProcessReviseCustInfoRequest)() PURE;
STDMETHOD(AsyncProcessCCRenewalPriceRequest)(THIS) PURE; STDMETHOD(AsyncProcessCCRenewalPriceRequest)() PURE;
STDMETHOD(AsyncProcessCCRenewalLicenseRequest)(THIS) PURE; STDMETHOD(AsyncProcessCCRenewalLicenseRequest)() PURE;
STDMETHOD(GetAsyncProcessReturnCode)(THIS_ unsigned long* pdwRetCode) PURE; STDMETHOD(GetAsyncProcessReturnCode)(THIS_ unsigned long* pdwRetCode) PURE;
STDMETHOD(IsUpgradeAvailable)(THIS_ int* pbUpgradeAvailable) PURE; STDMETHOD(IsUpgradeAvailable)(THIS_ int* pbUpgradeAvailable) PURE;
STDMETHOD(WantUpgrade)(THIS_ int bWantUpgrade) PURE; STDMETHOD(WantUpgrade)(THIS_ int bWantUpgrade) PURE;
STDMETHOD(AsyncProcessDroppedLicenseRequest)(THIS) PURE; STDMETHOD(AsyncProcessDroppedLicenseRequest)() PURE;
STDMETHOD(GenerateInstallationId)(THIS_ BSTR * pbstrVal) PURE; STDMETHOD(GenerateInstallationId)(THIS_ BSTR * pbstrVal) PURE;
STDMETHOD(DepositConfirmationId)(THIS_ BSTR bstrVal, unsigned long* pdwRetCode) PURE; STDMETHOD(DepositConfirmationId)(THIS_ BSTR bstrVal, unsigned long* pdwRetCode) PURE;
STDMETHOD(VerifyCheckDigits)(THIS_ BSTR bstrCIDIID, int* pbValue) PURE; STDMETHOD(VerifyCheckDigits)(THIS_ BSTR bstrCIDIID, int* pbValue) PURE;
@ -213,37 +223,45 @@ DECLARE_INTERFACE_(ILicAgent, IDispatch)
}; };
static BOOL XP_ComInitialized = FALSE; static BOOL XP_ComInitialized = FALSE;
static ICOMLicenseAgent* XP_LicenseAgent = NULL; static ICOMLicenseAgent* XP_LicenseAgent = nullptr;
static BOOL O2003_ComInitialized = FALSE; static BOOL O2003_ComInitialized = FALSE;
static ILicAgent* O2003_LicenseAgent = NULL; static ILicAgent* O2003_LicenseAgent = nullptr;
static BOOL XP_LoadLicenseManager() static BOOL XP_LoadLicenseManager()
{ {
if (!XP_ComInitialized) { if (!XP_ComInitialized) {
HRESULT status = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); const HRESULT status = CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);
if (FAILED(status)) { if (FAILED(status)) {
std::cout << "An error occurred at CoInitializeEx: ", status; const char* errorString = "An error occurred at CoInitializeEx:";
const int bufferSize = snprintf(nullptr, 0, "%s 0x%08X\n", errorString, static_cast<unsigned int>(status));
char* result = new char[bufferSize + 1];
snprintf(result, bufferSize + 1, "%s 0x%08X\n", errorString, static_cast<unsigned int>(status));
std::cout << result;
return FALSE; return FALSE;
} }
XP_ComInitialized = TRUE; XP_ComInitialized = TRUE;
} }
if (!XP_LicenseAgent) { if (!XP_LicenseAgent) {
HRESULT status = CoCreateInstance(XP_CLSID, NULL, CLSCTX_INPROC_SERVER, XP_IID, (void**)&XP_LicenseAgent); HRESULT status = CoCreateInstance(XP_CLSID, nullptr, CLSCTX_INPROC_SERVER, XP_IID, reinterpret_cast<void **>(&XP_LicenseAgent));
int good = 0; int good = 0;
if (SUCCEEDED(status)) { if (SUCCEEDED(status)) {
ULONG dwRetCode; ULONG dwRetCode;
status = XP_LicenseAgent->Initialize(0xC475 /* This needs to be changed, I believe it's causing the crashing.*/ , 3, 0, &dwRetCode); status = XP_LicenseAgent->Initialize(0xC475 /* This needs to be changed, I believe it's causing the crashing.*/ , 3, nullptr, &dwRetCode);
if (SUCCEEDED(status) && dwRetCode == 0) { if (SUCCEEDED(status) && dwRetCode == 0) {
good = 1; good = 1;
} }
else { else {
XP_LicenseAgent->Release(); XP_LicenseAgent->Release();
XP_LicenseAgent = NULL; XP_LicenseAgent = nullptr;
} }
} }
if (!good) { if (!good) {
std::cout << "An error occurred at CoCreateInstance: " + status; const char* errorString = "An error occurred at CoCreateInstance:";
const int bufferSize = snprintf(nullptr, 0, "%s 0x%08X\n", errorString, static_cast<unsigned int>(status));
char* result = new char[bufferSize + 1];
snprintf(result, bufferSize + 1, "%s 0x%08X\n", errorString, static_cast<unsigned int>(status));
std::cout << result;
return FALSE; return FALSE;
} }
} }
@ -253,29 +271,42 @@ static BOOL XP_LoadLicenseManager()
static BOOL O2003_LoadLicenseManager() static BOOL O2003_LoadLicenseManager()
{ {
if (!O2003_ComInitialized) { if (!O2003_ComInitialized) {
HRESULT status = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); const HRESULT status = CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);
if (FAILED(status)) { if (FAILED(status)) {
std::cout << "An error occurred at CoInitializeEx: ", status; const char* errorString = "An error occurred at CoInitializeEx:";
const int bufferSize = snprintf(nullptr, 0, "%s 0x%08X\n", errorString, static_cast<unsigned int>(status));
char* result = new char[bufferSize + 1];
snprintf(result, bufferSize + 1, "%s 0x%08X\n", errorString, static_cast<unsigned int>(status));
std::cout << result;
return FALSE; return FALSE;
} }
O2003_ComInitialized = TRUE; O2003_ComInitialized = TRUE;
} }
if (!O2003_LicenseAgent) { if (!O2003_LicenseAgent) {
HRESULT status = CoCreateInstance(O2003_CLSID, NULL, CLSCTX_INPROC_SERVER, O2003_IID, (void**)&O2003_LicenseAgent); HRESULT status = CoCreateInstance(O2003_CLSID, nullptr, CLSCTX_INPROC_SERVER, O2003_IID, reinterpret_cast<void **>(&O2003_LicenseAgent));
int good = 0; int good = 0;
if (SUCCEEDED(status)) { if (SUCCEEDED(status)) {
ULONG dwRetCode; ULONG dwRetCode;
status = O2003_LicenseAgent->Initialize(0xC475, 3, 0, &dwRetCode); status = O2003_LicenseAgent->Initialize(0xC475, 3, nullptr, &dwRetCode);
if (SUCCEEDED(status) && dwRetCode == 0) { if (SUCCEEDED(status) && dwRetCode == 0) {
good = 1; good = 1;
} }
else { else {
O2003_LicenseAgent->Release(); O2003_LicenseAgent->Release();
O2003_LicenseAgent = NULL; O2003_LicenseAgent = nullptr;
const auto errorString = "An error occurred at Initialize:";
const int bufferSize = snprintf(nullptr, 0, "%s 0x%08X, %z\n", errorString, static_cast<unsigned int>(status), dwRetCode);
const auto result = new char[bufferSize + 1];
snprintf(result, bufferSize + 1, "%s 0x%08X, %z\n", errorString, static_cast<unsigned int>(status), dwRetCode);
std::cout << result;
} }
} }
if (!good) { if (!good) {
std::cout << "An error occurred at CoCreateInstance: " + status; const auto errorString = "An error occurred at CoCreateInstance:";
const int bufferSize = snprintf(nullptr, 0, "%s 0x%08X\n", errorString, static_cast<unsigned int>(status));
const auto result = new char[bufferSize + 1];
snprintf(result, bufferSize + 1, "%s 0x%08X\n", errorString, static_cast<unsigned int>(status));
std::cout << result;
return FALSE; return FALSE;
} }
} }
@ -285,7 +316,7 @@ static BOOL O2003_LoadLicenseManager()
#pragma region Internals #pragma region Internals
bool RegistryKeyExists(HKEY rootKey, const char* keyPath) { bool RegistryKeyExists(HKEY rootKey, const char* keyPath) {
HKEY hKey; HKEY hKey;
LSTATUS result = RegOpenKeyEx(rootKey, keyPath, 0, KEY_READ, &hKey); const LSTATUS result = RegOpenKeyEx(rootKey, keyPath, 0, KEY_READ, &hKey);
if (result == ERROR_SUCCESS) { if (result == ERROR_SUCCESS) {
RegCloseKey(hKey); RegCloseKey(hKey);
@ -302,7 +333,7 @@ bool RegistryKeyExists(HKEY rootKey, const char* keyPath) {
wchar_t* convertCharArrayToLPCWSTR(const char* charArray) wchar_t* convertCharArrayToLPCWSTR(const char* charArray)
{ {
wchar_t* wString = new wchar_t[4096]; auto* wString = new wchar_t[4096];
MultiByteToWideChar(CP_ACP, 0, charArray, -1, wString, 4096); MultiByteToWideChar(CP_ACP, 0, charArray, -1, wString, 4096);
return wString; return wString;
} }
@ -314,7 +345,7 @@ char* getCmdOption(char** begin, char** end, const std::string& option)
{ {
return *itr; return *itr;
} }
return 0; return nullptr;
} }
bool cmdOptionExists(char** begin, char** end, const std::string& option) bool cmdOptionExists(char** begin, char** end, const std::string& option)
@ -324,10 +355,10 @@ bool cmdOptionExists(char** begin, char** end, const std::string& option)
char* BstrToChar(BSTR bstr) char* BstrToChar(BSTR bstr)
{ {
int len = ::SysStringLen(bstr); const int len = static_cast<int>(::SysStringLen(bstr));
int bufSize = ::WideCharToMultiByte(CP_UTF8, 0, bstr, len, NULL, 0, NULL, NULL); const int bufSize = ::WideCharToMultiByte(CP_UTF8, 0, bstr, len, nullptr, 0, nullptr, nullptr);
char* buffer = new char[bufSize + 1]; const auto buffer = new char[bufSize + 1];
::WideCharToMultiByte(CP_UTF8, 0, bstr, len, buffer, bufSize, NULL, NULL); ::WideCharToMultiByte(CP_UTF8, 0, bstr, len, buffer, bufSize, nullptr, nullptr);
buffer[bufSize] = '\0'; buffer[bufSize] = '\0';
return buffer; return buffer;
} }
@ -335,32 +366,33 @@ char* BstrToChar(BSTR bstr)
ULONG ConvertToULONG(const char* str) ULONG ConvertToULONG(const char* str)
{ {
char* end; char* end;
ULONG value = std::strtoul(str, &end, 10); const ULONG value = std::strtoul(str, &end, 10);
return value; return value;
} }
OLECHAR SizeToOLECHAR(size_t value) OLECHAR SizeToOLECHAR(size_t value)
{ {
// Convert size_t to wstring // Convert size_t to wstring
std::wstring wideString = std::to_wstring(value); const std::wstring wideString = std::to_wstring(value);
// Retrieve the first character from the wide string // Retrieve the first character from the wide string
OLECHAR oChar = wideString[0]; const OLECHAR oChar = wideString[0];
return oChar; return oChar;
} }
BSTR ConvertToBSTR(const std::string& str) { BSTR ConvertToBSTR(const std::string& str) {
int size = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, NULL, 0); const int size = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, nullptr, 0);
BSTR bstr = SysAllocStringLen(NULL, size - 1); // ReSharper disable once CppLocalVariableMayBeConst
BSTR bstr = SysAllocStringLen(nullptr, size - 1);
MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, bstr, size); MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, bstr, size);
return bstr; return bstr;
} }
std::string ConvertToStdString(BSTR bstr) { std::string ConvertToStdString(BSTR bstr) {
int size = WideCharToMultiByte(CP_UTF8, 0, bstr, -1, NULL, 0, NULL, NULL); const int size = WideCharToMultiByte(CP_UTF8, 0, bstr, -1, nullptr, 0, nullptr, nullptr);
char* buffer = new char[size]; const auto buffer = new char[size];
WideCharToMultiByte(CP_UTF8, 0, bstr, -1, buffer, size, NULL, NULL); WideCharToMultiByte(CP_UTF8, 0, bstr, -1, buffer, size, nullptr, nullptr);
std::string result(buffer); std::string result(buffer);
delete[] buffer; delete[] buffer;
@ -369,18 +401,36 @@ std::string ConvertToStdString(BSTR bstr) {
} }
BSTR ConvertCharToBSTR(const char* charString) { BSTR ConvertCharToBSTR(const char* charString) {
int size = MultiByteToWideChar(CP_UTF8, 0, charString, -1, NULL, 0); const int size = MultiByteToWideChar(CP_UTF8, 0, charString, -1, nullptr, 0);
BSTR bstr = SysAllocStringLen(NULL, size - 1); // ReSharper disable once CppLocalVariableMayBeConst
BSTR bstr = SysAllocStringLen(nullptr, size - 1);
MultiByteToWideChar(CP_UTF8, 0, charString, -1, bstr, size); MultiByteToWideChar(CP_UTF8, 0, charString, -1, bstr, size);
return bstr; return bstr;
} }
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
void safeStrncat(char* destination, const char* source, size_t size) {
const size_t destLen = strlen(destination);
const size_t srcLen = strlen(source);
if (destLen + srcLen < size) {
// fuck off Microsoft
strncat(destination, source, size - destLen - 1); // -1 for the null terminator
} else {
// Handle buffer overflow error
std::cout << "An error occurred at safeStrncat: Buffer overflow during strncat operation." << std::endl;
}
}
#pragma clang diagnostic pop
bool IsProcessRunning(const wchar_t* processName) bool IsProcessRunning(const wchar_t* processName)
{ {
// ReSharper disable once CppLocalVariableMayBeConst
HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (snapshot == INVALID_HANDLE_VALUE) if (snapshot == INVALID_HANDLE_VALUE)
{ {
std::cerr << "Failed to create process snapshot." << std::endl; std::cout << "An error occurred at IsProcessRunning: Failed to create process snapshot." << std::endl;
return false; return false;
} }
@ -389,7 +439,7 @@ bool IsProcessRunning(const wchar_t* processName)
if (!Process32FirstW(snapshot, &processEntry)) if (!Process32FirstW(snapshot, &processEntry))
{ {
CloseHandle(snapshot); CloseHandle(snapshot);
std::cerr << "Failed to retrieve process information." << std::endl; std::cout << "An error occurred at IsProcessRunning: Failed to retrieve process information." << std::endl;
return false; return false;
} }
@ -408,6 +458,7 @@ bool IsProcessRunning(const wchar_t* processName)
bool TerminateProcessByName(const wchar_t* processName) bool TerminateProcessByName(const wchar_t* processName)
{ {
// ReSharper disable once CppLocalVariableMayBeConst
HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (snapshot == INVALID_HANDLE_VALUE) if (snapshot == INVALID_HANDLE_VALUE)
{ {
@ -426,8 +477,9 @@ bool TerminateProcessByName(const wchar_t* processName)
{ {
if (wcscmp(processEntry.szExeFile, processName) == 0) if (wcscmp(processEntry.szExeFile, processName) == 0)
{ {
// ReSharper disable once CppLocalVariableMayBeConst
HANDLE processHandle = OpenProcess(PROCESS_TERMINATE, FALSE, processEntry.th32ProcessID); HANDLE processHandle = OpenProcess(PROCESS_TERMINATE, FALSE, processEntry.th32ProcessID);
if (processHandle != NULL) if (processHandle != nullptr)
{ {
if (TerminateProcess(processHandle, 0)) if (TerminateProcess(processHandle, 0))
{ {
@ -463,11 +515,18 @@ static BSTR XP_GetWPALeft() {
} }
ULONG dwWPALeft = 0, dwEvalLeft = 0; ULONG dwWPALeft = 0, dwEvalLeft = 0;
HRESULT status = XP_LicenseAgent->GetExpirationInfo(&dwWPALeft, &dwEvalLeft); const HRESULT status = XP_LicenseAgent->GetExpirationInfo(&dwWPALeft, &dwEvalLeft);
if (FAILED(status)) { if (FAILED(status)) {
XP_LicenseAgent->Release(); XP_LicenseAgent->Release();
XP_LicenseAgent = NULL; XP_LicenseAgent = nullptr;
return SysAllocString(L"An error occurred at GetExpirationInfo: " + status); const char* errorString = "An error occurred at CoInitializeEx:";
const int bufferSize = snprintf(nullptr, 0, "%s 0x%08X", errorString, static_cast<unsigned int>(status));
char* result = new char[bufferSize + 1];
snprintf(result, bufferSize + 1, "%s 0x%08X", errorString, static_cast<unsigned int>(status));
const int wideCharSize = MultiByteToWideChar(CP_UTF8, 0, result, -1, nullptr, 0);
auto* wideResult = new OLECHAR[wideCharSize];
MultiByteToWideChar(CP_UTF8, 0, result, -1, wideResult, wideCharSize);
return SysAllocString(wideResult);
} }
if (dwWPALeft == 0x7FFFFFFF) { if (dwWPALeft == 0x7FFFFFFF) {
return SysAllocString(L"An error occurred at GetWPALeft: Windows is activated"); return SysAllocString(L"An error occurred at GetWPALeft: Windows is activated");
@ -481,11 +540,18 @@ static BSTR XP_GetEvalLeft() {
} }
ULONG dwWPALeft = 0, dwEvalLeft = 0; ULONG dwWPALeft = 0, dwEvalLeft = 0;
HRESULT status = XP_LicenseAgent->GetExpirationInfo(&dwWPALeft, &dwEvalLeft); const HRESULT status = XP_LicenseAgent->GetExpirationInfo(&dwWPALeft, &dwEvalLeft);
if (FAILED(status)) { if (FAILED(status)) {
XP_LicenseAgent->Release(); XP_LicenseAgent->Release();
XP_LicenseAgent = NULL; XP_LicenseAgent = nullptr;
return SysAllocString(L"An error occurred at GetExpirationInfo: " + status); const char* errorString = "An error occurred at GetExpirationInfo:";
const int bufferSize = snprintf(nullptr, 0, "%s 0x%08X", errorString, static_cast<unsigned int>(status));
char* result = new char[bufferSize + 1];
snprintf(result, bufferSize + 1, "%s 0x%08X", errorString, static_cast<unsigned int>(status));
const int wideCharSize = MultiByteToWideChar(CP_UTF8, 0, result, -1, nullptr, 0);
auto* wideResult = new OLECHAR[wideCharSize];
MultiByteToWideChar(CP_UTF8, 0, result, -1, wideResult, wideCharSize);
return SysAllocString(wideResult);
} }
if (dwEvalLeft == 0x7FFFFFFF) { if (dwEvalLeft == 0x7FFFFFFF) {
return SysAllocString(L"An error occurred at GetEvalLeft: Not an evaluation copy"); return SysAllocString(L"An error occurred at GetEvalLeft: Not an evaluation copy");
@ -503,9 +569,16 @@ static BSTR XP_VerifyCheckDigits(BSTR cidChunk) {
} }
LONG pbValue; LONG pbValue;
HRESULT status = XP_LicenseAgent->VerifyCheckDigits(cidChunk, &pbValue); const HRESULT status = XP_LicenseAgent->VerifyCheckDigits(cidChunk, &pbValue);
if (FAILED(status) || !pbValue) { if (FAILED(status) || !pbValue) {
return SysAllocString(L"An error occurred at XP_VerifyCheckDigits: " + pbValue); char errorMessage[70] = "An error occurred at XP_VerifyCheckDigits:";
char pbValueChar[20];
snprintf(errorMessage, sizeof(errorMessage), "%ld", pbValue);
safeStrncat(errorMessage, pbValueChar, sizeof(errorMessage));
const int len = MultiByteToWideChar(CP_UTF8, 0, errorMessage, -1, nullptr, 0);
auto* oleCharString = new OLECHAR[len];
MultiByteToWideChar(CP_UTF8, 0, errorMessage, -1, oleCharString, len);
return SysAllocString(oleCharString);
} }
return SysAllocString(L"Successfully verified CID chunk"); return SysAllocString(L"Successfully verified CID chunk");
} }
@ -519,10 +592,9 @@ static BSTR XP_SetConfirmationID(BSTR confirmationID) {
return SysAllocString(L"An error occurred at GetWPALeft: Windows is activated"); return SysAllocString(L"An error occurred at GetWPALeft: Windows is activated");
} }
// const int length = static_cast<int>(SysStringLen(confirmationID));
int length = SysStringLen(confirmationID);
char* str = new char[length + 1]; char* str = new char[length + 1];
WideCharToMultiByte(CP_UTF8, 0, confirmationID, length, str, length, NULL, NULL); WideCharToMultiByte(CP_UTF8, 0, confirmationID, length, str, length, nullptr, nullptr);
str[length] = '\0'; str[length] = '\0';
std::string inputString(str); std::string inputString(str);
@ -536,9 +608,17 @@ static BSTR XP_SetConfirmationID(BSTR confirmationID) {
} }
ULONG dwRetCode; ULONG dwRetCode;
HRESULT status = XP_LicenseAgent->DepositConfirmationId(confirmationID, &dwRetCode); const HRESULT status = XP_LicenseAgent->DepositConfirmationId(confirmationID, &dwRetCode);
if (FAILED(status) || dwRetCode) { if (FAILED(status) || dwRetCode) {
return SysAllocString(L"An error occurred at DepositConfirmationId: " + status + dwRetCode); const char* errorString = "An error occurred at DepositConfirmationId:";
const int bufferSize = snprintf(nullptr, 0, "%s 0x%08X %lu", errorString, static_cast<unsigned int>(status), dwRetCode);
char* result = new char[bufferSize + 1];
snprintf(result, bufferSize + 1, "%s 0x%08X %lu", errorString, static_cast<unsigned int>(status), dwRetCode);
const int wideCharSize = MultiByteToWideChar(CP_UTF8, 0, result, -1, nullptr, 0);
auto* wideResult = new OLECHAR[wideCharSize];
MultiByteToWideChar(CP_UTF8, 0, result, -1, wideResult, wideCharSize);
return SysAllocString(wideResult);
} }
system("rundll32 setupapi,InstallHinfSection DEL_OOBE_ACTIVATE 132 syssetup.inf"); // remove activation shortcuts system("rundll32 setupapi,InstallHinfSection DEL_OOBE_ACTIVATE 132 syssetup.inf"); // remove activation shortcuts
@ -554,15 +634,21 @@ static BSTR XP_GetInstallationID() {
if (!XP_LoadLicenseManager()) { if (!XP_LoadLicenseManager()) {
return SysAllocString(L"An error occurred at XP_LoadLicenseManager: Failed to load"); return SysAllocString(L"An error occurred at XP_LoadLicenseManager: Failed to load");
} }
if (0 == wcscmp(XP_GetWPALeft(), L"An error occurred at GetWPALeft: Windows is activated")) { if (0 == wcscmp(XP_GetWPALeft(), L"An error occurred at GetWPALeft: Windows is activated")) {
return SysAllocString(L"An error occurred at GetWPALeft: Windows is activated"); return SysAllocString(L"An error occurred at GetWPALeft: Windows is activated");
} }
BSTR installationID = NULL; BSTR installationID = nullptr;
HRESULT status = XP_LicenseAgent->GenerateInstallationId(&installationID); const HRESULT status = XP_LicenseAgent->GenerateInstallationId(&installationID);
if (FAILED(status) || !installationID) { if (FAILED(status) || !installationID) {
return SysAllocString(L"An error occurred at GenerateInstallationId: " + status); const char* errorString = "An error occurred at GenerateInstallationId:";
const int bufferSize = snprintf(nullptr, 0, "%s 0x%08X", errorString, static_cast<unsigned int>(status));
char* result = new char[bufferSize + 1];
snprintf(result, bufferSize + 1, "%s 0x%08X", errorString, static_cast<unsigned int>(status));
const int wideCharSize = MultiByteToWideChar(CP_UTF8, 0, result, -1, nullptr, 0);
auto* wideResult = new OLECHAR[wideCharSize];
MultiByteToWideChar(CP_UTF8, 0, result, -1, wideResult, wideCharSize);
return SysAllocString(wideResult);
} }
else { else {
return installationID; return installationID;
@ -575,8 +661,8 @@ static BSTR XP_SetProductKey(LPWSTR productKey) {
} }
std::wstring ws(productKey); std::wstring ws(productKey);
std::string productKeyToRegex = std::string(ws.begin(), ws.end()); const std::string productKeyToRegex = std::string(ws.begin(), ws.end());
std::regex pattern("[2346789BCDFGHJKMPQRTVWXY]{5}-[2346789BCDFGHJKMPQRTVWXY]{5}-[2346789BCDFGHJKMPQRTVWXY]{5}-[2346789BCDFGHJKMPQRTVWXY]{5}-[2346789BCDFGHJKMPQRTVWXY]{5}"); const std::regex pattern("[2346789BCDFGHJKMPQRTVWXY]{5}-[2346789BCDFGHJKMPQRTVWXY]{5}-[2346789BCDFGHJKMPQRTVWXY]{5}-[2346789BCDFGHJKMPQRTVWXY]{5}-[2346789BCDFGHJKMPQRTVWXY]{5}");
if (!std::regex_match(productKeyToRegex, pattern)) { if (!std::regex_match(productKeyToRegex, pattern)) {
return SysAllocString(L"An error occurred at regex_match: Product key is invalid"); return SysAllocString(L"An error occurred at regex_match: Product key is invalid");
@ -586,9 +672,16 @@ static BSTR XP_SetProductKey(LPWSTR productKey) {
return SysAllocString(L"An error occurred at GetWPALeft: Windows is activated"); return SysAllocString(L"An error occurred at GetWPALeft: Windows is activated");
} }
HRESULT status = XP_LicenseAgent->SetProductKey(productKey); const HRESULT status = XP_LicenseAgent->SetProductKey(productKey);
if (FAILED(status)) { if (FAILED(status)) {
return SysAllocString(L"An error occurred at SetProductKey: " + status); const char* errorString = "An error occurred at SetProductKey:";
const int bufferSize = snprintf(nullptr, 0, "%s 0x%08X", errorString, static_cast<unsigned int>(status));
char* result = new char[bufferSize + 1];
snprintf(result, bufferSize + 1, "%s 0x%08X", errorString, static_cast<unsigned int>(status));
const int wideCharSize = MultiByteToWideChar(CP_UTF8, 0, result, -1, nullptr, 0);
auto* wideResult = new OLECHAR[wideCharSize];
MultiByteToWideChar(CP_UTF8, 0, result, -1, wideResult, wideCharSize);
return SysAllocString(wideResult);
} }
else { else {
return SysAllocString(L"Successfully set product key"); return SysAllocString(L"Successfully set product key");
@ -600,11 +693,18 @@ static BSTR XP_GetProductID() {
return SysAllocString(L"An error occurred at XP_LoadLicenseManager: Failed to load"); return SysAllocString(L"An error occurred at XP_LoadLicenseManager: Failed to load");
} }
BSTR productID = NULL; BSTR productID = nullptr;
HRESULT status = XP_LicenseAgent->GetProductID(&productID); const HRESULT status = XP_LicenseAgent->GetProductID(&productID);
if (FAILED(status)) { if (FAILED(status)) {
return SysAllocString(L"An error occurred at GetProductID: " + status); const char* errorString = "An error occurred at GetProductID:";
const int bufferSize = snprintf(nullptr, 0, "%s 0x%08X", errorString, static_cast<unsigned int>(status));
char* result = new char[bufferSize + 1];
snprintf(result, bufferSize + 1, "%s 0x%08X", errorString, static_cast<unsigned int>(status));
const int wideCharSize = MultiByteToWideChar(CP_UTF8, 0, result, -1, nullptr, 0);
auto* wideResult = new OLECHAR[wideCharSize];
MultiByteToWideChar(CP_UTF8, 0, result, -1, wideResult, wideCharSize);
return SysAllocString(wideResult);
} }
else { else {
return productID; return productID;
@ -613,6 +713,7 @@ static BSTR XP_GetProductID() {
#pragma endregion #pragma endregion
#pragma region Office 2003 #pragma region Office 2003
// ReSharper disable once CppDeclaratorNeverUsed
static BSTR O2003_VerifyCheckDigits(BSTR cidChunk) { static BSTR O2003_VerifyCheckDigits(BSTR cidChunk) {
if (!O2003_LoadLicenseManager()) { if (!O2003_LoadLicenseManager()) {
return SysAllocString(L"An error occurred at O2003_LoadLicenseManager: Failed to load"); return SysAllocString(L"An error occurred at O2003_LoadLicenseManager: Failed to load");
@ -621,9 +722,17 @@ static BSTR O2003_VerifyCheckDigits(BSTR cidChunk) {
// TODO: find a way to check office 2003 activation status // TODO: find a way to check office 2003 activation status
int pbValue; int pbValue;
HRESULT status = O2003_LicenseAgent->VerifyCheckDigits(cidChunk, &pbValue); const HRESULT status = O2003_LicenseAgent->VerifyCheckDigits(cidChunk, &pbValue);
if (FAILED(status) || !pbValue) { if (FAILED(status) || !pbValue) {
return SysAllocString(L"An error occurred at XP_VerifyCheckDigits: " + pbValue);
wchar_t error[] = L"An error occurred at XP_VerifyCheckDigits:";
const std::wstring numberStr = std::to_wstring(pbValue);
std::wstring result = error + numberStr;
wchar_t buffer[100];
swprintf(buffer, sizeof(buffer) / sizeof(buffer[0]), L"%s 0x%X %d", error, status, pbValue);
return SysAllocString(buffer);
} }
return SysAllocString(L"Successfully verified CID chunk"); return SysAllocString(L"Successfully verified CID chunk");
} }
@ -635,9 +744,9 @@ static BSTR O2003_SetConfirmationID(BSTR confirmationID) {
// TODO: find a way to check office 2003 activation status // TODO: find a way to check office 2003 activation status
int length = SysStringLen(confirmationID); const int length = static_cast<int>(SysStringLen(confirmationID));
char* str = new char[length + 1]; char* str = new char[length + 1];
WideCharToMultiByte(CP_UTF8, 0, confirmationID, length, str, length, NULL, NULL); WideCharToMultiByte(CP_UTF8, 0, confirmationID, length, str, length, nullptr, nullptr);
str[length] = '\0'; str[length] = '\0';
std::string inputString(str); std::string inputString(str);
@ -651,9 +760,16 @@ static BSTR O2003_SetConfirmationID(BSTR confirmationID) {
} }
ULONG dwRetCode; ULONG dwRetCode;
HRESULT status = O2003_LicenseAgent->DepositConfirmationId(confirmationID, &dwRetCode); const HRESULT status = O2003_LicenseAgent->DepositConfirmationId(confirmationID, &dwRetCode);
if (FAILED(status) || dwRetCode) { if (FAILED(status) || dwRetCode) {
return SysAllocString(L"An error occurred at DepositConfirmationId: " + status + dwRetCode); const char* errorString = "An error occurred at DepositConfirmationId:";
const int bufferSize = snprintf(nullptr, 0, "%s 0x%08X %lu", errorString, static_cast<unsigned int>(status), dwRetCode);
char* result = new char[bufferSize + 1];
snprintf(result, bufferSize + 1, "%s 0x%08X %lu", errorString, static_cast<unsigned int>(status), dwRetCode);
const int wideCharSize = MultiByteToWideChar(CP_UTF8, 0, result, -1, nullptr, 0);
auto* wideResult = new OLECHAR[wideCharSize];
MultiByteToWideChar(CP_UTF8, 0, result, -1, wideResult, wideCharSize);
return SysAllocString(wideResult);
} }
return SysAllocString(L"Successfully set confirmation ID"); return SysAllocString(L"Successfully set confirmation ID");
@ -669,12 +785,19 @@ static BSTR O2003_GetInstallationID() {
// TODO: find a way to check office 2003 activation status // TODO: find a way to check office 2003 activation status
BSTR installationID = NULL; BSTR installationID = nullptr;
std::cout << "DEBUG: installationID = NULL"; std::cout << "DEBUG: installationID = NULL";
HRESULT status = O2003_LicenseAgent->GenerateInstallationId(&installationID); const HRESULT status = O2003_LicenseAgent->GenerateInstallationId(&installationID);
std::cout << "DEBUG: GenerateInstallationID executed"; std::cout << "DEBUG: GenerateInstallationID executed";
if (FAILED(status) || !installationID) { if (FAILED(status) || !installationID) {
return SysAllocString(L"An error occurred at GenerateInstallationId: " + status); const char* errorString = "An error occurred at GenerateInstallationId:";
const int bufferSize = snprintf(nullptr, 0, "%s 0x%08X", errorString, static_cast<unsigned int>(status));
char* result = new char[bufferSize + 1];
snprintf(result, bufferSize + 1, "%s 0x%08X", errorString, static_cast<unsigned int>(status));
const int wideCharSize = MultiByteToWideChar(CP_UTF8, 0, result, -1, nullptr, 0);
auto* wideResult = new OLECHAR[wideCharSize];
MultiByteToWideChar(CP_UTF8, 0, result, -1, wideResult, wideCharSize);
return SysAllocString(wideResult);
} }
else { else {
return installationID; return installationID;
@ -683,6 +806,8 @@ static BSTR O2003_GetInstallationID() {
#pragma endregion #pragma endregion
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
const char* text = const char* text =
@ -705,7 +830,11 @@ int main(int argc, char* argv[])
if (cmdOptionExists(argv, argv + argc, "--Office2003")) { if (cmdOptionExists(argv, argv + argc, "--Office2003")) {
#ifdef ENVIRONMENT32 #ifdef ENVIRONMENT32
if (RegistryKeyExists(HKEY_CLASSES_ROOT, "CLSID\\{000C0114-0000-0000-C000-000000000046}")) {
if (cmdOptionExists(argv, argv + argc, "--BypassInstallCheck")) {
specifiedProduct = "Office2003";
}
else if (RegistryKeyExists(HKEY_CLASSES_ROOT, "CLSID\\{000C0114-0000-0000-C000-000000000046}")) {
specifiedProduct = "Office2003"; specifiedProduct = "Office2003";
} }
else { else {
@ -727,7 +856,7 @@ int main(int argc, char* argv[])
specifiedProduct = "WindowsNT5x"; specifiedProduct = "WindowsNT5x";
#endif #endif
if (specifiedProduct == "WindowsNT5x") { if (std::strcmp(specifiedProduct, "WindowsNT5x") == 0) {
SYSTEM_INFO systemInfo; SYSTEM_INFO systemInfo;
GetNativeSystemInfo(&systemInfo); GetNativeSystemInfo(&systemInfo);
#ifdef ENVIRONMENT32 #ifdef ENVIRONMENT32
@ -741,36 +870,35 @@ int main(int argc, char* argv[])
else { // is PPC, megafart 386, whatever else else { // is PPC, megafart 386, whatever else
std::cout << "An error occurred at systemInfo: Incorrect version of xpmgr. Go to https://umskt.zulipchat.com if you want to help us make a version for your platform!"; std::cout << "An error occurred at systemInfo: Incorrect version of xpmgr. Go to https://umskt.zulipchat.com if you want to help us make a version for your platform!";
} }
return 0; return 1;
} }
#endif #endif
OSVERSIONINFOEX info; OSVERSIONINFOEX info = {};
memset(&info, 0, sizeof(OSVERSIONINFOEX));
info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
GetVersionEx((LPOSVERSIONINFO)&info); GetVersionEx(reinterpret_cast<LPOSVERSIONINFO>(&info));
if (info.dwMajorVersion != 5) { if (info.dwMajorVersion != 5) {
std::cout << "An error occurred at OSVERSIONINFOEX: Windows management only works on Windows NT 5.1 and 5.2."; std::cout << "An error occurred at OSVERSIONINFOEX: Windows management only works on Windows NT 5.1 and 5.2.";
if (info.dwMajorVersion > 5) { if (info.dwMajorVersion > 5) {
std::cout << " Use slmgr instead."; std::cout << " Use slmgr instead: https://learn.microsoft.com/en-us/windows-server/get-started/activation-slmgr-vbs-options";
return 0; return 3;
} }
return 0; return 2;
} }
else { else {
if (info.dwMinorVersion != 1 && info.dwMinorVersion != 2) { if (info.dwMinorVersion != 1 && info.dwMinorVersion != 2) {
std::cout << "An error occurred at OSVERSIONINFOEX: Windows management only works on Windows NT 5.1 and 5.2.";
if (info.dwMinorVersion == 0) { if (info.dwMinorVersion == 0) {
std::cout << " You should be fine anyways, since Windows 2000 doesn't use Product Activation."; std::cout << " You should be fine anyways, since Windows 2000 doesn't use Product Activation.";
return 0; return 4;
} }
std::cout << "An error occurred OSVERSIONINFOEX: Windows management only works on Windows NT 5.1 and 5.2."; return 5;
return 0;
} }
} }
} }
if (cmdOptionExists(argv, argv + argc, "--GetInstallationID")) { if (cmdOptionExists(argv, argv + argc, "--GetInstallationID")) {
if (specifiedProduct == "Office2003") { if (std::strcmp(specifiedProduct, "Office2003") == 0) {
std::cout << ConvertToStdString(O2003_GetInstallationID()); std::cout << ConvertToStdString(O2003_GetInstallationID());
return 0; return 0;
} }
@ -778,43 +906,42 @@ int main(int argc, char* argv[])
return 0; return 0;
} }
else if (cmdOptionExists(argv, argv + argc, "--SetConfirmationID")) { else if (cmdOptionExists(argv, argv + argc, "--SetConfirmationID")) {
if (specifiedProduct == "Office2003") { if (std::strcmp(specifiedProduct, "Office2003") == 0) {
std::cout << ConvertToStdString(O2003_SetConfirmationID(ConvertCharToBSTR(getCmdOption(argv, argv + argc, "--SetConfirmationID")))); std::cout << ConvertToStdString(O2003_SetConfirmationID(ConvertCharToBSTR(getCmdOption(argv, argv + argc, "--SetConfirmationID"))));
return 0; return 0;
} }
std::cout << ConvertToStdString(XP_SetConfirmationID(ConvertCharToBSTR(getCmdOption(argv, argv + argc, "--SetConfirmationID")))); std::cout << ConvertToStdString(XP_SetConfirmationID(ConvertCharToBSTR(getCmdOption(argv, argv + argc, "--SetConfirmationID"))));
return 0; return 0;
} }
else if (cmdOptionExists(argv, argv + argc, "--GetWPALeft")) { else if (cmdOptionExists(argv, argv + argc, "--GetWPALeft")) {
if (specifiedProduct != "WindowsNT5x") { if (std::strcmp(specifiedProduct, "WindowsNT5x") != 0) {
std::cout << "An error occurred at specifiedProduct: This command is for Windows management only."; std::cout << "An error occurred at specifiedProduct: This command is for Windows management only.";
return 0; return 6;
} }
std::cout << ConvertToStdString(XP_GetWPALeft()); std::cout << ConvertToStdString(XP_GetWPALeft());
return 0; return 0;
} }
else if (cmdOptionExists(argv, argv + argc, "--GetEvalLeft")) { else if (cmdOptionExists(argv, argv + argc, "--GetEvalLeft")) {
if (specifiedProduct != "WindowsNT5x") { if (std::strcmp(specifiedProduct, "WindowsNT5x") != 0) {
std::cout << "An error occurred at specifiedProduct: This command is for Windows management only."; std::cout << "An error occurred at specifiedProduct: This command is for Windows management only.";
return 0; return 6;
} }
std::cout << ConvertToStdString(XP_GetEvalLeft()); std::cout << ConvertToStdString(XP_GetEvalLeft());
return 0; return 0;
} }
else if (cmdOptionExists(argv, argv + argc, "--SetProductKey")) { else if (cmdOptionExists(argv, argv + argc, "--SetProductKey")) {
if (specifiedProduct != "WindowsNT5x") { if (std::strcmp(specifiedProduct, "WindowsNT5x") != 0) {
std::cout << "An error occurred at specifiedProduct: This command is for Windows management only."; std::cout << "An error occurred at specifiedProduct: This command is for Windows management only.";
return 0; return 6;
} }
std::cout << ConvertToStdString(XP_SetProductKey(convertCharArrayToLPCWSTR(getCmdOption(argv, argv + argc, "--SetProductKey")))); std::cout << ConvertToStdString(XP_SetProductKey(convertCharArrayToLPCWSTR(getCmdOption(argv, argv + argc, "--SetProductKey"))));
return 0; return 0;
} }
else if (cmdOptionExists(argv, argv + argc, "--GetProductID")) { else if (cmdOptionExists(argv, argv + argc, "--GetProductID")) {
if (specifiedProduct != "WindowsNT5x") { if (std::strcmp(specifiedProduct, "WindowsNT5x") != 0) {
std::cout << "An error occurred at specifiedProduct: This command is for Windows management only."; std::cout << "An error occurred at specifiedProduct: This command is for Windows management only.";
return 0; return 6;
} }
std::cout << ConvertToStdString(XP_GetProductID()); std::cout << ConvertToStdString(XP_GetProductID());
return 0; return 0;
@ -822,6 +949,7 @@ int main(int argc, char* argv[])
else { else {
std::cout << "An error occurred at main: No arguments listed\n\n"; std::cout << "An error occurred at main: No arguments listed\n\n";
std::cout << text; std::cout << text;
return 0; return 7;
} }
} }
#pragma clang diagnostic pop