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

这篇具有很好参考价值的文章主要介绍了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 <fstream>
#include <iostream>
#include "mongoose.h"
#define _WIN32_DCOM
#include <iostream>
#include <comdef.h>
#include <Wbemidl.h>
#include <string>
#include <time.h>
#include <sstream>
#include <iomanip> 
#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 << "&APP=" << app
        << "&DateTime=" << date_time
        << "&HostName=" << host_name
        << "&MachineCode=" << machine_code
        << "&ShareLists=" << share_lists;
    data = ss.str();


    /*
cout << "**********" << endl;
cout << "APP: " << app << endl;
cout << "DateTime: " << date_time << endl;
cout << "HostName: " << host_name << endl;
cout << "MachineCode: " << machine_code<< endl;
cout << "ShareLists: " << share_lists<< endl;
cout << "**********" << endl;
cout << "data: " << data << endl;;
*/

    return data;
}

string UploadData(string data)
{
    char* s_url = new char[strlen(url.c_str()) + 1];
    strcpy(s_url,url.c_str());

    struct mg_mgr mgr;
    mg_mgr_init(&mgr);                        // Init manager
    mg_http_connect(&mgr, s_url, fn, NULL);   // Create client connection 
    while (exit_flag == 0) {
        mg_mgr_poll(&mgr, 1000); 
    }
    mg_mgr_free(&mgr);                        // Cleanup

    string response = ""; //TODO 暂时没有什么要求
    return response; 
}

string WMIQuery(string table, string key) {
HRESULT hres;
string result = "";
string empty_result = "";
stringstream ss;

// Step 1: --------------------------------------------------
// Initialize COM. ------------------------------------------

hres = CoInitializeEx(0, COINIT_MULTITHREADED);
if (FAILED(hres))
{
cout << "Failed to initialize COM library. Error code = 0x"
<< hex << hres << endl;
return empty_result;                  // Program has failed.
}

// Step 2: --------------------------------------------------
// Set general COM security levels --------------------------

hres = CoInitializeSecurity(
NULL,
-1,                          // COM authentication
NULL,                        // Authentication services
NULL,                        // Reserved
RPC_C_AUTHN_LEVEL_DEFAULT,   // Default authentication 
RPC_C_IMP_LEVEL_IMPERSONATE, // Default Impersonation  
NULL,                        // Authentication info
EOAC_NONE,                   // Additional capabilities 
NULL                         // Reserved
);


if (FAILED(hres))
{

CoUninitialize();
return empty_result;                  // Program has failed.
}

// Step 3: ---------------------------------------------------
// Obtain the initial locator to WMI -------------------------

IWbemLocator* pLoc = NULL;

hres = CoCreateInstance(
CLSID_WbemLocator,
0,
CLSCTX_INPROC_SERVER,
IID_IWbemLocator, (LPVOID*)&pLoc);

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

// Step 4: -----------------------------------------------------
// Connect to WMI through the IWbemLocator::ConnectServer method

IWbemServices* pSvc = NULL;

// Connect to the root\cimv2 namespace with
// the current user and obtain pointer pSvc
// to make IWbemServices calls.
hres = pLoc->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 << "Could not connect. Error code = 0x"
<< hex << hres << endl;
pLoc->Release();
CoUninitialize();
return empty_result;                  // Program has failed.
}

//cout << "Connected to ROOT\\CIMV2 WMI namespace" << endl;


// Step 5: --------------------------------------------------
// Set security levels on the proxy -------------------------

hres = CoSetProxyBlanket(
pSvc,                        // Indicates the proxy to set
RPC_C_AUTHN_WINNT,           // RPC_C_AUTHN_xxx
RPC_C_AUTHZ_NONE,            // RPC_C_AUTHZ_xxx
NULL,                        // Server principal name 
RPC_C_AUTHN_LEVEL_CALL,      // RPC_C_AUTHN_LEVEL_xxx 
RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxx
NULL,                        // client identity
EOAC_NONE                    // proxy capabilities 
);

if (FAILED(hres))
{
cout << "Could not set proxy blanket. Error code = 0x"
<< hex << hres << endl;
pSvc->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 << "\"" << share_name << "\"";
ss << ":";
ss << "\"" << share_path << "\"";
ss << ","; 
}
}
else {
hr = pclsObj->Get(string2LPCWSTR(key), 0, &vtProp, 0, 0);
ss << ConvertBSTRToString(vtProp.bstrVal); 
//ss << _com_util::ConvertBSTRToString(vtProp.bstrVal); 
}
VariantClear(&vtProp);

pclsObj->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 << tm_t.tm_year + 1900
<< setw(2) << setfill('0') << tm_t.tm_mon + 1
<< setw(2) << setfill('0') << tm_t.tm_mday
<< " "
<< setw(2) << setfill('0') << tm_t.tm_hour 
<< ":" 
<< setw(2) << setfill('0') << tm_t.tm_min 
<< ":" 
<< setw(2) << setfill('0') << tm_t.tm_sec;
date_time = ss.str();
return date_time; 
}

//不上报默认的、在白名单内的共享盘
bool IsDefaultShare(string share_name, string share_path)
{
//1、系统默认共享盘
if (!share_name.empty() && !share_path.empty() &&  // 非空
share_name[share_name.length() - 1] == '$' &&  // 共享名最后一个字符一定是$
share_path.length() == 3 &&  // 资源必须为 X:\ 的格式
share_name.substr(0,share_name.length() - 1) == share_path.substr(0,share_path.length() - 2))  // 盘符名一定要对得上 
{
return true;
}
//2、白名单
for (string white_list_item : white_lists)
{
if (share_name == white_list_item)
{
return true;
} 
} 
return false; 
}

static void fn(struct mg_connection* c, int ev, void* ev_data, void* fn_data)
{
char* s_url = new char[strlen(url.c_str()) + 1];
strcpy(s_url,url.c_str());
if (ev == MG_EV_CONNECT) { 
struct mg_str host = mg_url_host(s_url);
// Send request
mg_printf(c,
"GET %s HTTP/1.0\r\n"
"Host: %.*s\r\n"
"\r\n",
mg_url_uri(s_url), (int)host.len, host.ptr);
} if (ev == MG_EV_HTTP_MSG) {
struct mg_http_message* hm = (struct mg_http_message*)ev_data;
exit_flag = 1;
}
}

//重新实现_com_util的ConvertBSTRToString
inline char* ConvertBSTRToString(BSTR pSrc)
{
//if (!pSrc) return NULL;  原本返回空会导致空指针异常
if (!pSrc)
{
char* szOut = new char[1];
szOut[0] = '\0';
return szOut;
}

DWORD cb, cwch = ::SysStringLen(pSrc);

char* szOut = NULL;

if (cb = ::WideCharToMultiByte(CP_ACP, 0,
pSrc, cwch + 1, NULL, 0, 0, 0))
{
szOut = new char[cb];
if (szOut)
{
szOut[cb - 1] = '\0';

if (!::WideCharToMultiByte(CP_ACP, 0,
pSrc, cwch + 1, szOut, cb, 0, 0))
{
delete[]szOut;//clean up if failed;
szOut = NULL;
}
}
} 
return szOut;
};

wstring string2wstring(string str)
{
wstring result;
//获取缓冲区大小,并申请空间,缓冲区大小按字符计算  
int len = MultiByteToWideChar(CP_ACP, 0, str.c_str(), str.size(), NULL, 0);
TCHAR* buffer = new TCHAR[len + 1];
//多字节编码转换成宽字节编码  
MultiByteToWideChar(CP_ACP, 0, str.c_str(), str.size(), buffer, len);
buffer[len] = '\0';             //添加字符串结尾  
//删除缓冲区并返回值  
result.append(buffer);
delete[] buffer;
return result;
}

string wstring2string(wstring wstr, UINT nCode)
{
string result;
//获取缓冲区大小,并申请空间,缓冲区大小事按字节计算的  
int len = WideCharToMultiByte(nCode, 0, wstr.c_str(), wstr.size(), NULL, 0, NULL, NULL);
char* buffer = new char[len + 1];
//宽字节编码转换成多字节编码  
WideCharToMultiByte(nCode, 0, wstr.c_str(), wstr.size(), buffer, len, NULL, NULL);
buffer[len] = '\0';
//删除缓冲区并返回值  
result.append(buffer);
delete[] buffer;
return result;
}

牢骚

本来是用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文章来源地址https://www.toymoban.com/news/detail-450202.html

到了这里,关于C++实现查询本机信息并且上报的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 软件机器人财务报表信息的采集和录入、抵押贷款信息查询助力银行贷款业务管理

    随着科技的飞速发展,自动化的应用场景也越来越广泛。博为小帮软件机器人的出现,无疑为众多行业带来了巨大的转变,其中就包括银行贷款业务。 软件机器人是一种可以模拟人类行为,自动化执行高重复性任务。银行业务中,许多重复性高、规则明确的工作,如企业客户

    2024年02月07日
    浏览(55)
  • 微信小程序开发---购物商城系统。【详细业务需求描述+实现效果】

    视频演示 以下演示为手机真机录屏 微信小程序商品系统功能演示       该微信商城系统实现的主要如下图所示 3.1 首页        首页基本构成:1、顶部搜索页;2、轮播图(点击轮播图可跳转);3、导航栏分类(点击可跳转)。4、商品分类图集(点击页面可跳转);

    2024年02月11日
    浏览(44)
  • 【业务功能篇20】Springboot java逻辑实现动态行转列需求

    在此前,我也写过一个行转列的文章,是用存储过程sql处理的一个动态的逻辑 Mysql 存储过程Mybatis框架call调用 实现动态行转列 那么后面我们同样又接收了业务的一个新需求,针对的是不同的业务数据,做的同样的一个展示数据报表,同样还是产品归属信息表头,拼接查询年

    2024年02月09日
    浏览(45)
  • Java 多输入框查询需求实现

    💗wei_shuo的个人主页 💫wei_shuo的学习社区 🌐Hello World ! 需求分析 任意一个输入框,输入内容点击搜索都可以精准搜索到对应的内容 代码实现 Controller接口编写 ResultPageResultDisputeMerchantManageResponse: 返回给前端的字段:VO @RequestBody DisputeMerchantManageRequest request: 接收前端传递的

    2024年02月08日
    浏览(32)
  • 使用springboot实现查询更改数据库需求

    使用springboot实现简单的数据库数据交互请求 实现:通过springboot框架,实现接口 /user/view; 查询数据库user表中的user数据, /user/insert; 新增user数据到user表 /user/update 修改user的对应user信息 集成规范数据响应: 功能实现: 定义简单的user类并添加对应的user表,用于数据交互 创建数据访问

    2024年02月16日
    浏览(40)
  • 从零开始,我的第一个物联网平台搭建好了,ESP8266+DHT11+阿里云平台+IOT StudioWEB应用开发,实现网页实时查看设备上报的信息,控制开关

        记录下自己做的第一个物联网项目,真正从零开始,断断续续花了2个月时间看各种视频,网站学习有关物联网的知识,期间碰到过好多问题,没有人指导,都得靠自己慢慢研究,有时会很迷茫,没有方向,但还得坚持下去,当经过自己的努力解决一个个问题时,会很兴奋

    2024年01月19日
    浏览(93)
  • 安卓开发后台应用周期循环获取位置信息上报服务器

    最近有需求,在APP启动后,退到后台,还要能实现周期获取位置信息上报服务器,研究了一下实现方案。 一、APP退到后台后网络请求实现 APP退到后台后,实现周期循环发送网络请求。目前尝试了两种方案是OK,如下: (1)AlarmManager + 前台服务 +广播的方案,可以正常实现,

    2024年02月16日
    浏览(40)
  • STM32的电动自行车信息采集上报系统(学习)

    针对电动自行车实时监管不便的问题,设计了一种基于STM32的电动自行车信息采集系统,通过获取电池、位置和行驶状态信息并上报到服务器中,实现实时监管。 通过多路串口请求电池、行驶状态和位置信息,以并发方式进行数据接收、解析、模块控制和数据上报等操作;

    2024年02月14日
    浏览(47)
  • thinkphp 5 实现UNION ALL 3个联表查询,并且带上搜索条件,名称,时间,手机号

    在ThinkPHP 5中实现带有搜索条件、名称、时间和手机号的3个联表查询(UNION ALL),您可以按照以下步骤进行操作: 确保已经配置好数据库连接信息和相关的模型。 使用 union() 方法来构建3个联表查询,同时在每个查询中添加所需的搜索条件、名称、时间和手机号。 在上述代码

    2024年02月12日
    浏览(51)
  • Mac查询本机ip地址

    Mac系统版本和网络配置不同,可能会有一些细微差别。         并回车,在输出的信息中,查找“inet”或“inet6”字样,后面跟着的数字就是你的IP地址,然后在输出中查找以 “inet “ 或 “inet6 “ 开头的行,这些行后面跟着的就是对应的IP地址。 (1)、查看特定网络接

    2024年01月23日
    浏览(47)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包