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
C++实现查询本机信息并且上报的更多相关文章
- 在Linux上查询物理机信息-不用去拆机器了
目录 一.查看系统信息(包含机器型号) 1.1 查看机型和品牌 二.查看CPU 信息 2.1 查看CPU 型号 2.2 查看CPU的物理数量 2.3 查看 CPU核心数量(非逻辑CPU) 2.4 查看 ...
- 在linux中查询硬件相关信息
1.查询cpu的相关 a.查询CPU的统计信息 使用命令:lscpu 得到的结果如下: Architecture: x86_64 CPU op-mode(s): -bit, -bit Byte Ord ...
- Atitit.Atiposter 发帖机 信息发布器 v7 q516
Atitit.Atiposter 发帖机 信息发布器 v7 q516 V7 jetty 版本 基本访问改为web版. 这样发布调试 V1 初步实现sina csdn cnblogs V2 实现qz ...
- 查询rman备份信息经常使用指令
查询rman备份信息经常使用指令 ----登陆到rman $rman target / ----以精简的格式查看备份信息 RMAN> list backup of database summar ...
- 使用mybatis开发Dao的原始方法,实现根据用户id查询一个用户信息 、根据用户名称模糊查询用户信息列表 、添加用户信息等功能
1.需求 将下边的功能实现Dao: 根据用户id查询一个用户信息 根据用户名称模糊查询用户信息列表 添加用户信息 2. 原始Dao开发方法需要程序员编写Dao接口和Dao实现类 3.User.xml映 ...
- 通过sql查询rman备份信息
通过sql查询rman备份信息 查看所有备份集 SELECT A.RECID "BACKUP SET", A.SET_STAMP, DECODE (B.INCREMENTAL_LE ...
- Linux下使用fstatfs/statfs查询系统相关信息
Linux下使用fstatfs/statfs查询系统相关信息 1. 功能 #include < sys/statfs.h > int statfs(const char *path, ...
- C# 有道API翻译 查询单词详细信息
原文:C# 有道API翻译 查询单词详细信息 有道云官方文档 有道云翻译API简介:http://ai.youdao.com/docs/doc-trans-api.s#p01 有道云C#Demo : ...
- Ubuntu:查询计算机软硬件信息
造冰箱的大熊猫,本文适用于Ubuntu 16.04@cnblogs 2019/1/1 1.查询Linux内核版本 在命令行中通过命令“uname -rv”获取内核版本信息,执行实例如下所示.其中,标 ...
- 使用ffprobe 查询wav文件信息
使用ffprobe 查询wav文件信息 安装 安装过程和ffmepg相同不在赘述 不带参数查询文件信息 ffprobe ZH_biaobei_标准合成_甜美女声_楠楠_5_5_5_6_1_4047db ...
随机推荐
- CSP2022-S游寄
游寄游寄,顾名思义,边游边寄 11.00AM 起床 复习了一下各种终端命令,然后又复习了一下对拍 虽然都没用到 然后接着睡. 有点小紧张,毕竟一年没搞OI 12.00AM 今天吃河虾 还行,只是有点扎 ...
- 【手搓模型】亲手实现 Vision Transformer
前言 博客主页:睡晚不猿序程 首发时间:2023.3.17,首发于博客园 最近更新时间:2023.3.17 本文由 睡晚不猿序程 原创 作者是蒻蒟本蒟,如果文章里有任何错误或者表述不清,请 tt 我, ...
- XAML 设计器已意外退出。(退出代码: e0434352)
一.前言 开门见山,这个问题我遇到过两次,第一次因为项目刚开始不长时间,我查了很长时间都没解决,然后就直接重写了,几乎一样的写法,但问题没复现了,但程序员思维告诉我,一定还是有比较关键的地方出现了问题 ...
- 机器学习基础05DAY
分类算法之k-近邻 k-近邻算法采用测量不同特征值之间的距离来进行分类 优点:精度高.对异常值不敏感.无数据输入假定 缺点:计算复杂度高.空间复杂度高 使用数据范围:数值型和标称型 一个例子弄懂k-近 ...
- Mysql 局域网远程连接设置——Windows
工作中,遇到mysql数据库存储于我的电脑上,而其他电脑需要共同进行读写数据(类似redis并发),所以我的电脑就必须开启mysql远程连接. 一. 授权 1. 连接数据库 mysql -uroot ...
- CentOS8删除boot目录恢复
系统安装完之后,boot分区最好做一个备份,因为这个分区 我们基本不会动它,所以备份一次一劳永逸,以防万一.如果我们不小心 误删除了这个目录,也不用慌,正因为这个分区,我们除了开机 其他时候基本用不到 ...
- 华为 A800-9000 服务器 离线安装MindX DL
MindX DL(昇腾深度学习组件)是支持 Atlas 800 训练服务器.Atlas 800 推理服务器的深度学习组件参考设计,提供昇腾 AI 处理器资源管理和监控.昇腾 AI 处理器优化调度.分布 ...
- [Java SE]Java SE异常合集
1 概述 2 问题集 Q1 : JAVA应用程序启动时报"A fatal error has been detected by the Java Runtime Environment: E ...
- [Java EE]辨析: POJO(PO / DTO / VO) | BO/DO | DAO
概念不清,会很影响开发中的逻辑性和条理性,进而影响接口设计,代码编写的质量. 网络上大家对这些个概念的探究很多,但终究没有一个统一的说法. 不论哪家解释,我觉得最重要的是: 1)词汇之间的解释统一: ...
- Redis key命名规范
Redis key命名规范 一.实现目标 简洁,高效,可维护 二.键值设计规约 1 Redis key 命名风格 [推荐]Redis key 命名需具有可读性以及可管理性,不该使用含义不清的 key ...