having problem getting ProcessorID from C++ using DllExport by char array reference

 

Hello guys, 

i wrote the following codes in C++ and MQL5 to get the ProcessorID of the system, but it doesn't return the correct one. Please let me solve the problem.

my C++ code:

#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include "ole2.h"
#include <wbemidl.h>
#include <wbemcli.h>
#include <wbemprov.h>
#include <string>
#include <comdef.h>
#pragma comment(lib, "wbemuuid.lib")
#include <iostream>
using namespace std;
std::string utf8_encode(const std::wstring &wstr)
{
if (wstr.empty()) return std::string();
int size_needed = WideCharToMultiByte(CP_UTF8, 0, &wstr[0], (int)wstr.size(), NULL, 0, NULL, NULL);
std::string strTo(size_needed, 0);
WideCharToMultiByte(CP_UTF8, 0, &wstr[0], (int)wstr.size(), &strTo[0], size_needed, NULL, NULL);
return strTo;
}
BSTR ProNU;
#define _DLLAPI extern "C" __declspec(dllexport)
_DLLAPI void __stdcall GetProcessorLoad(char(&processorID)[16])
{
wchar_t *ProceID;
HRESULT hRes = CoInitializeEx(NULL, COINIT_MULTITHREADED);
if (hRes != S_OK) return;
hRes = CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_PKT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, 0);
if (hRes != S_OK) return;
CComPtr<IWbemLocator> pIWbemLocator;
CComPtr<IWbemServices> pIWbemServices;
CComPtr<IEnumWbemClassObject> pIEnumObject;
CComBSTR bstrNamespace(_T("root\\cimv2"));
hRes = CoCreateInstance(CLSID_WbemLocator, NULL, CLSCTX_ALL, IID_PPV_ARGS(&pIWbemLocator));
if (hRes != S_OK) return;
hRes = pIWbemLocator->ConnectServer(bstrNamespace, NULL, NULL, NULL, WBEM_FLAG_CONNECT_USE_MAX_WAIT, NULL, NULL, &pIWbemServices);
if (hRes != S_OK)
return;
hRes = pIWbemServices->ExecQuery
(L"WQL", L"SELECT * FROM Win32_Processor", WBEM_FLAG_FORWARD_ONLY, NULL, &pIEnumObject);
ULONG uCount = 1, uReturned;
CComPtr<IWbemClassObject> pIClassObject;
hRes = pIEnumObject->Reset();
hRes = pIEnumObject->Next
(WBEM_INFINITE, uCount, &pIClassObject, &uReturned);
if (hRes != S_OK) return;
CComVariant var;
BSTR bstrProp = SysAllocString(L"ProcessorId");
hRes = pIClassObject->Get(bstrProp, 0, &var, NULL, NULL);
if (hRes != S_OK) return;
SysFreeString(bstrProp);
BSTR NAME1 = V_BSTR(&var);
ProceID = _bstr_t(NAME1, false);
string procerID = utf8_encode(ProceID);
char tempchar[17];
strcpy_s(tempchar, procerID.c_str());
for (int j = 0; j < 17; j++)
processorID[j] = tempchar[j];
return;
}

and this is the corresponding  MQL5 code, but still get the -1 in all char array cells:

#import "ProN.dll"
   void GetProcessorLoad(ushort& wow[]);
#import
void OnStart()
  {
//---
   ushort wow[];
   ArrayResize(wow, 16);
   ArrayInitialize(wow, "1111111111111111");  
   ProN::GetProcessorLoad(wow);
   int result = ShortArrayToString(wow, 0);
   printf((string)wow[3]);
  }

Please help me solve the problem please. 

Thank you so much


Documentation on MQL5: Constants, Enumerations and Structures / Input/Output Constants / Use of a Codepage
Documentation on MQL5: Constants, Enumerations and Structures / Input/Output Constants / Use of a Codepage
  • www.mql5.com
Use of a Codepage - Input/Output Constants - Constants, Enumerations and Structures - MQL5 Reference - Reference on algorithmic/automated trading language for MetaTrader 5
 
Please insert the code correctly: when editing a message, press the button    Code and paste your code into the pop-up window. 
 
_DLLAPI void __stdcall GetProcessorLoad(char(&processorID)[16])
   ushort wow[];

I don't know the C++ version you are using, but you are passing in a 16-bit array and chars are 8-bit. I'd try it with short. And probably a static array on MQL side.

 
Why not use GetSystemInfo directly?


You do not need to do such complicated queries, as far as I am aware.

For whatever reason it is necessary to know the CPU ID within an EA.

 
Dominik Egert #:
Why not use GetSystemInfo directly?

https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getsysteminfo

You do not need to do such complicated queries, as far as I am aware.

For whatever reason it is necessary to know the CPU ID within an EA.

I want to bind my EA to the ProcessorID of a computer, so that it can't be run in another PC. Because i want to sell the EA and don't want to let it to be copied to other systems.

I bound it to Hard disk serial number, but i found that it can be changed by some software, so i decided to bind it to ProcessorID.

 
lippmaje #:

I don't know the C++ version you are using, but you are passing in a 16-bit array and chars are 8-bit. I'd try it with short. And probably a static array on MQL side.

Thanks. But it thought that 16 is the lenght of array. am i right or wrong?

please try to change the code and let us know how we can change it to get the right result.

Thank you so much.

 
I have already pointed out the issue with your code, just give it a go.
Reason: