C++實(shí)現(xiàn)查詢本機(jī)信息的示例代碼
業(yè)務(wù)需求
共享文件夾、盤會(huì)導(dǎo)致系統(tǒng)安全性下降,故IT部門需要搜集公司中每臺(tái)電腦的共享情況,并且進(jìn)行上報(bào)
關(guān)鍵字
WMI查詢、Get請(qǐng)求、C++網(wǎng)絡(luò)庫(kù)mongoose
前置需要
1、簡(jiǎn)單C++語(yǔ)法知識(shí)
2、mongoose庫(kù)的導(dǎo)入
3、C++項(xiàng)目的啟動(dòng)
代碼
復(fù)制并不能直接使用,需導(dǎo)入mongoose庫(kù)
完整github項(xiàng)目代碼:https://github.com/Canwaiting/check_netshare
修改其中的變量url,app,white_list[],這個(gè)項(xiàng)目就是你的了
/********************************************************* * * 項(xiàng)目背景:共享文件夾、盤會(huì)導(dǎo)致系統(tǒng)安全性下降,故IT部門 * 需要搜集公司中每臺(tái)電腦的共享情況,并且進(jìn)行上報(bào) * *********************************************************/ #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") //靜默運(yùn)行 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); //退出標(biāo)志 用于控制關(guān)閉事件循環(huán) static int exit_flag = 0; //APP版本信息 static const string app = "XXX"; //白名單 static const string white_lists[] = { "IPC$", "ADMIN$", //"print$" 打印機(jī),暫時(shí)不需要 }; //上傳數(shù)據(jù)的地址前綴 static string url = "XXX"; int main(int argc, char** argv) { string data; data = GetData(); //拼接數(shù)據(jù),并轉(zhuǎn)成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",""); //這個(gè)特殊處理 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 暫時(shí)沒(méi)有什么要求 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點(diǎn)0分0秒到現(xiàn)在經(jīng)過(guò)的秒數(shù) tm tm_t; localtime_s(&tm_t, &nowtime); //將秒數(shù)轉(zhuǎn)換為本地時(shí)間,年從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; } //不上報(bào)默認(rèn)的、在白名單內(nèi)的共享盤 bool IsDefaultShare(string share_name, string share_path) { //1、系統(tǒng)默認(rèn)共享盤 if (!share_name.empty() && !share_path.empty() && // 非空 share_name[share_name.length() - 1] == '$' && // 共享名最后一個(gè)字符一定是$ share_path.length() == 3 && // 資源必須為 X:\ 的格式 share_name.substr(0,share_name.length() - 1) == share_path.substr(0,share_path.length() - 2)) // 盤符名一定要對(duì)得上 { 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; } } //重新實(shí)現(xiàn)_com_util的ConvertBSTRToString inline char* ConvertBSTRToString(BSTR pSrc) { //if (!pSrc) return NULL; 原本返回空會(huì)導(dǎo)致空指針異常 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; //獲取緩沖區(qū)大小,并申請(qǐng)空間,緩沖區(qū)大小按字符計(jì)算 int len = MultiByteToWideChar(CP_ACP, 0, str.c_str(), str.size(), NULL, 0); TCHAR* buffer = new TCHAR[len + 1]; //多字節(jié)編碼轉(zhuǎn)換成寬字節(jié)編碼 MultiByteToWideChar(CP_ACP, 0, str.c_str(), str.size(), buffer, len); buffer[len] = '\0'; //添加字符串結(jié)尾 //刪除緩沖區(qū)并返回值 result.append(buffer); delete[] buffer; return result; } string wstring2string(wstring wstr, UINT nCode) { string result; //獲取緩沖區(qū)大小,并申請(qǐng)空間,緩沖區(qū)大小事按字節(jié)計(jì)算的 int len = WideCharToMultiByte(nCode, 0, wstr.c_str(), wstr.size(), NULL, 0, NULL, NULL); char* buffer = new char[len + 1]; //寬字節(jié)編碼轉(zhuǎn)換成多字節(jié)編碼 WideCharToMultiByte(nCode, 0, wstr.c_str(), wstr.size(), buffer, len, NULL, NULL); buffer[len] = '\0'; //刪除緩沖區(qū)并返回值 result.append(buffer); delete[] buffer; return result; }
牢騷
本來(lái)是用C#寫的,但是打出來(lái)的包幾十M,不符合要求;還是得用回C++,各種輪子都要自己造,還得轉(zhuǎn)字符;差點(diǎn)就完不成了 : )
到此這篇關(guān)于C++實(shí)現(xiàn)查詢本機(jī)信息的示例代碼的文章就介紹到這了,更多相關(guān)C++查詢本機(jī)信息內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C 語(yǔ)言restrict 關(guān)鍵字的使用淺談
C 語(yǔ)言restrict 關(guān)鍵字的使用淺談,需要的朋友可以參考一下2013-04-04C++ Boost實(shí)現(xiàn)數(shù)字與字符串轉(zhuǎn)化詳解
Boost是為C++語(yǔ)言標(biāo)準(zhǔn)庫(kù)提供擴(kuò)展的一些C++程序庫(kù)的總稱。Boost庫(kù)是一個(gè)可移植、提供源代碼的C++庫(kù),作為標(biāo)準(zhǔn)庫(kù)的后備,是C++標(biāo)準(zhǔn)化進(jìn)程的開(kāi)發(fā)引擎之一,是為C++語(yǔ)言標(biāo)準(zhǔn)庫(kù)提供擴(kuò)展的一些C++程序庫(kù)的總稱2022-11-11C語(yǔ)言實(shí)例講解四大循環(huán)語(yǔ)句的使用
C語(yǔ)言有四大循環(huán)語(yǔ)句,他們之間可以進(jìn)行任意轉(zhuǎn)換。本文將首先對(duì)其語(yǔ)法進(jìn)行講解,然后通過(guò)一個(gè)實(shí)例用四種循環(huán)來(lái)實(shí)現(xiàn)。相信通過(guò)本文的學(xué)習(xí),大家都能夠?qū)語(yǔ)言循環(huán)語(yǔ)句有著熟練的掌握2022-05-05C++中based for循環(huán)的實(shí)現(xiàn)
C++中的范圍for循環(huán)是一種簡(jiǎn)潔的遍歷容器的方法,本文主要介紹了C++中based for循環(huán)的實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的可以了解一下2025-02-02C++中使用哈希表(unordered_map)的一些常用操作方法
C++標(biāo)準(zhǔn)庫(kù)中使用的unordered_map底層實(shí)現(xiàn)是哈希表,下面這篇文章主要給大家介紹了關(guān)于C++中使用哈希表(unordered_map)的一些常用操作方法,需要的朋友可以參考下2022-03-03基于c中使用ftruncate()前需要fflush(),使用后需要rewind()的深入探討
本篇文章是對(duì)在c中使用ftruncate()前需要fflush(),使用后需要rewind()進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05