C++实现查询本机信息并且上报

业务需求

共享文件夹、盘会导致系统安全性下降,故IT部门需要搜集公司中每台电脑的共享情况,并且进行上报

关键字

WMI查询、Get请求、C++网络库mongoose

前置需要

1、简单C++语法知识
2、mongoose库的导入
3、C++项目的启动

代码

复制并不能直接使用,需导入mongoose库
完整github项目代码:https://github.com/Canwaiting/check_netshare
修改其中的变量url,app,white_list[],这个项目就是你的了

/*********************************************************
*
* 项目背景:共享文件夹、盘会导致系统安全性下降,故IT部门
* 需要搜集公司中每台电脑的共享情况,并且进行上报
*
*********************************************************/

#include 
#include 
#include "mongoose.h"
#define _WIN32_DCOM
#include 
#include 
#include 
#include 
#include 
#include 
#include  
#pragma comment(lib, "wbemuuid.lib")
#pragma comment( linker, "/subsystem:windows /entry:mainCRTStartup") //静默运行
using namespace std;

string wstring2string(wstring wstr, UINT nCode);
wstring string2wstring(string str);
LPCWSTR string2LPCWSTR(string str);
string WMIQuery(string table, string key);
string GetData();
string UploadData(string data);
string GetDateTime();
static void fn(struct mg_connection* c, int ev, void* ev_data, void* fn_data);
bool IsDefaultShare(string share_name, string share_path);
inline char* ConvertBSTRToString(BSTR pSrc);

//退出标志 用于控制关闭事件循环
static int exit_flag = 0; 
//APP版本信息 
static const string app = "XXX";
//白名单
static const string white_lists[] =
{
"IPC$",
"ADMIN$",
//"print$" 打印机,暂时不需要
};
//上传数据的地址前缀
static string url = "XXX";

int main(int argc, char** argv)
{
    string data; 
    data = GetData(); 

    //拼接数据,并转成UTF-8
    url += data; 
    wstring wstr = string2wstring(url);
    url = wstring2string(wstr, CP_UTF8); 

    UploadData(url); 
    //getchar();

    return 0; 
}

string GetData() 
{
    stringstream ss;
    string date_time = "";
    string host_name = "";
    string machine_code= "";
    string share_lists = "";
    string data = "";

    date_time = GetDateTime();
    host_name = WMIQuery("Win32_ComputerSystem", "Name"); 
    machine_code= WMIQuery("Win32_BIOS","SerialNumber"); 
    share_lists = WMIQuery("win32_share",""); //这个特殊处理

    ss ConnectServer(
_bstr_t(L"ROOT\CIMV2"), // Object path of WMI namespace
NULL,                    // User name. NULL = current user
NULL,                    // User password. NULL = current
0,                       // Locale. NULL indicates current
NULL,                    // Security flags.
0,                       // Authority (for example, Kerberos)
0,                       // Context object 
&pSvc                    // pointer to IWbemServices proxy
);

if (FAILED(hres))
{
cout Release();
CoUninitialize();
return empty_result;                  // Program has failed.
}

//cout Release();
pLoc->Release();
CoUninitialize();
return empty_result;                  // Program has failed.
}

// Step 6: --------------------------------------------------
// Use the IWbemServices pointer to make requests of WMI ----

// For example, get the name of the operating system
IEnumWbemClassObject* pEnumerator = NULL;
string sql = "SELECT * FROM " + table;
hres = pSvc->ExecQuery(
bstr_t("WQL"),
bstr_t((wchar_t*) (_bstr_t(sql.c_str()))),
WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
NULL,
&pEnumerator);

if (FAILED(hres))
{
pSvc->Release();
pLoc->Release();
CoUninitialize();
return empty_result;                  // Program has failed.
}

// Step 7: -------------------------------------------------
// Get the data from the query in step 6 -------------------

IWbemClassObject* pclsObj = NULL;
ULONG uReturn = 0;

while (pEnumerator)
{
HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1,
&pclsObj, &uReturn);

if (0 == uReturn)
{
break;
}

VARIANT vtProp;

VariantInit(&vtProp);

// Get the value of the Name property 
if (key == "") {
hr =  pclsObj->Get(L"Name", 0, &vtProp, 0, 0);
string share_name = _com_util::ConvertBSTRToString(vtProp.bstrVal);
hr =  pclsObj->Get(L"Path", 0, &vtProp, 0, 0); 
string share_path = _com_util::ConvertBSTRToString(vtProp.bstrVal);
if (!IsDefaultShare(share_name, share_path))
{
ss Get(string2LPCWSTR(key), 0, &vtProp, 0, 0);
ss Release();
}

// Cleanup
// ========

pSvc->Release();
pLoc->Release();
pEnumerator->Release();
CoUninitialize();

result = ss.str();
if (key == "") {
result = result.substr(0, result.length() - 1);
}
return result; 
}

LPCWSTR string2LPCWSTR(string str)
{
size_t size = str.length();
int wLen = ::MultiByteToWideChar(CP_UTF8,
0,
str.c_str(),
-1,
NULL,
0);
wchar_t* buffer = new wchar_t[wLen + 1];
memset(buffer, 0, (wLen + 1) * sizeof(wchar_t));
MultiByteToWideChar(CP_ACP, 0, str.c_str(), size, (LPWSTR)buffer, wLen);
return buffer;
}

string GetDateTime()
{

string date_time = "";
time_t nowtime;
time(&nowtime); //获取1970年1月1日0点0分0秒到现在经过的秒数
tm tm_t;
localtime_s(&tm_t, &nowtime); //将秒数转换为本地时间,年从1900算起,需要+1900,月为0-11,所以要+1
stringstream ss;
ss 

牢骚

本来是用C#写的,但是打出来的包几十M,不符合要求;还是得用回C++,各种轮子都要自己造,还得转字符;差点就完不成了 : )

部分参考

https://www.jb51.net/softjc/2124_2.html
https://mongoose.ws/documentation/tutorials/http-client/
https://blog.csdn.net/hanxiaoyong_/article/details/123494927
https://github.com/tashaxing/cpphttpdemo

文章来源于互联网:C++实现查询本机信息并且上报

THE END
分享
二维码