#include "StdAfx.h" #include "DeviceQuery.h" #include #include #include "..\cJson\cJSON.h" #include "..\Base64\Base64.h" #include "..\des\des.h" #include #include #ifdef _WRITE_LOG_ /************************************************************************/ /* 函数:WriteTextLog[7/28/2016 IT]; /* 描述:写文本日志; /* 参数:; /* [IN] :; /* 返回:void; /* 注意:; /* 示例:; /* /* 修改:; /* 日期:; /* 内容:; /************************************************************************/ void WriteTextLog(const TCHAR *format, ...) { try { //static ThreadSection _critSection; //AutoThreadSection aSection(&_critSection); // 解析出日志路径; TCHAR szlogpath[MAX_PATH] = {0}; static TCHAR szModulePath[MAX_PATH] = {0}; static TCHAR szFna[_MAX_DIR] = { 0 }; if ( szModulePath[0] == _T('\0') ) { TCHAR szDrive[_MAX_DRIVE] = { 0 }; TCHAR szDir[_MAX_DIR] = { 0 }; TCHAR szExt[_MAX_DIR] = { 0 }; ::GetModuleFileName(NULL, szModulePath, sizeof(szModulePath) / sizeof(TCHAR)); _tsplitpath_s(szModulePath, szDrive, szDir, szFna, szExt); _tcscpy_s(szModulePath, szDrive); _tcscat_s(szModulePath, szDir); } _stprintf_s(szlogpath, _T("%s%s%s.txt"), szModulePath, szFna, CTime::GetCurrentTime().Format("[%Y-%m-%d]").GetString()); // 打开或创建文件; CStdioFile fp; if (PathFileExists(szlogpath)) { if (fp.Open(szlogpath, CFile::modeWrite) == FALSE) { return; } fp.SeekToEnd(); } else { if ( !fp.Open(szlogpath, CFile::modeCreate | CFile::modeWrite) ) return; } // 格式化前设置语言区域; TCHAR* old_locale = _tcsdup(_tsetlocale(LC_CTYPE, NULL)); _tsetlocale(LC_CTYPE, _T("chs"));//设定中文; // 格式化日志内容; va_list args = NULL; int len = 0; TCHAR *buffer = NULL; va_start( args, format ); // _vscprintf doesn't count. terminating '\0' len = _vsctprintf_p( format, args ); if ( len == -1 ) { goto clear; } len++; buffer = (TCHAR*)malloc( len * sizeof(TCHAR) ); _vstprintf_s( buffer, len, format, args ); // C4996 // Note: vsprintf is deprecated; consider using vsprintf_s instead // 将日志内容输入到文件中; fp.WriteString( CTime::GetCurrentTime().Format(_T("%Y-%m-%d %H:%M:%S ")) ); fp.WriteString(buffer); fp.WriteString(_T("\n")); // 关闭文件,释放资源并设置回原语言区域; free( buffer ); clear: _tsetlocale(LC_CTYPE, old_locale); free(old_locale);//还原区域设定; fp.Close(); } catch (CException *e) { e->ReportError(); e->Delete(); } } #endif // usb; static GUID UsbClassGuid = { 0xA5DCBF10L, 0x6530, 0x11D2,{ 0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED } }; // mac; static GUID MacClassGuid = { 0xAD498944, 0x762F, 0x11D0, { 0x8D, 0xCB, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C } }; // hdd; static GUID HDDClassGuid = { 0x53F56307, 0xB6BF, 0x11D0, { 0x94, 0xF2, 0x00, 0xA0, 0xC9, 0x1E, 0xFB, 0x8B } }; CDeviceQuery::CDeviceQuery(void) { } CDeviceQuery::~CDeviceQuery(void) { } ////////////////////////////////////////////////////////////////////////// // 获得设备注册表中的内容; ////////////////////////////////////////////////////////////////////////// BOOL CDeviceQuery::GetRegistryProperty( IN HDEVINFO DeviceInfoSet, OUT PSP_DEVINFO_DATA DeviceInfoData, IN ULONG Property, OUT PVOID Buffer, OUT PULONG Length ) { while ( !SetupDiGetDeviceRegistryProperty( DeviceInfoSet, DeviceInfoData, Property, NULL, (BYTE *)*(TCHAR **)Buffer, *Length, Length)) { // 长度不够则重新分配缓冲区; if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) { if (*(LPTSTR *)Buffer) LocalFree(*(LPTSTR *)Buffer); *(LPTSTR *)Buffer = (PTCHAR)LocalAlloc(LPTR,*Length); } else { return false; } } return (BOOL)(*(LPTSTR *)Buffer)[0]; } void CDeviceQuery::EnumNetCards() { DWORD Status, Problem; LPTSTR Buffer = NULL; DWORD BufSize = 0; // 返回所有设备信息; HDEVINFO hDevInfo = SetupDiGetClassDevs(NULL,NULL,0,DIGCF_PRESENT|DIGCF_ALLCLASSES) ; if (INVALID_HANDLE_VALUE == hDevInfo ) return; SP_DEVINFO_DATA DeviceInfoData = {sizeof(SP_DEVINFO_DATA)}; // 枚举设备 ; for ( DWORD DeviceId=0; SetupDiEnumDeviceInfo( hDevInfo,DeviceId,&DeviceInfoData); DeviceId++) { // 获得设备的状态 ; if (CM_Get_DevNode_Status(&Status, &Problem, DeviceInfoData.DevInst ,0) != CR_SUCCESS) continue; // 获取设备类名; TCHAR szDevName [MAX_PATH] = _T("") ; if (GetRegistryProperty(hDevInfo, &DeviceInfoData, SPDRP_CLASS , &Buffer, (PULONG)&BufSize)) { lstrcpyn( szDevName, Buffer, MAX_PATH ) ; } if ( lstrcmp( szDevName, _T("Net") ) == 0 ) { TCHAR szName [MAX_PATH] = _T("") ; if (GetRegistryProperty(hDevInfo, &DeviceInfoData, SPDRP_ENUMERATOR_NAME , &Buffer, (PULONG)&BufSize)) { lstrcpyn( szName, Buffer, MAX_PATH ) ; } if ( lstrcmp( szName, _T("ROOT") ) != 0 && lstrcmp( szName, _T("SWD") ) != 0) { if (GetRegistryProperty(hDevInfo, &DeviceInfoData, SPDRP_DRIVER , &Buffer, (PULONG)&BufSize)) { lstrcpyn( szName, Buffer, MAX_PATH ) ; GetRegistryProperty(hDevInfo, &DeviceInfoData, SPDRP_DEVICEDESC , &Buffer, (PULONG)&BufSize); GetRegistryProperty(hDevInfo, &DeviceInfoData, SPDRP_CLASSGUID , &Buffer, (PULONG)&BufSize); GetRegistryProperty(hDevInfo, &DeviceInfoData, SPDRP_ADDRESS , &Buffer, (PULONG)&BufSize); GetRegistryProperty(hDevInfo, &DeviceInfoData, SPDRP_ENUMERATOR_NAME , &Buffer, (PULONG)&BufSize); GetRegistryProperty(hDevInfo, &DeviceInfoData, SPDRP_ADDRESS/*SPDRP_DEVICEDESC*/ , &Buffer, (PULONG)&BufSize); // 获取设备描述 if (GetRegistryProperty(hDevInfo, &DeviceInfoData, SPDRP_ADDRESS/*SPDRP_DEVICEDESC*/ , &Buffer, (PULONG)&BufSize)) { lstrcpyn( szName, Buffer, MAX_PATH ) ; // if(ControlDevice(DeviceId,hDevInfo)) // { // printf("Successful\n"); // } // else // { // printf("FAILED\n"); // } } } } } } SetupDiDestroyDeviceInfoList(hDevInfo); } INT CDeviceQuery::GetMacAddress() { HDEVINFO hDevInfo; DWORD MemberIndex, RequiredSize; SP_DEVICE_INTERFACE_DATA DeviceInterfaceData; PSP_DEVICE_INTERFACE_DETAIL_DATA DeviceInterfaceDetailData; INT nTotal = 0; INT nNICKind = 0; // 获取设备信息集; hDevInfo = SetupDiGetClassDevs(&MacClassGuid, NULL, NULL, DIGCF_PRESENT | DIGCF_INTERFACEDEVICE); if (hDevInfo == INVALID_HANDLE_VALUE) { return -1; } m_vtMacAddress.clear(); // 枚举设备信息集中所有设备; DeviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); for (MemberIndex = 0; SetupDiEnumDeviceInterfaces(hDevInfo, NULL, &MacClassGuid, MemberIndex, &DeviceInterfaceData); MemberIndex++) { // 获取接收缓冲区大小,函数返回值为FALSE,GetLastError()=ERROR_INSUFFICIENT_BUFFER; SetupDiGetDeviceInterfaceDetail(hDevInfo, &DeviceInterfaceData, NULL, 0, &RequiredSize, NULL); // 申请接收缓冲区; DeviceInterfaceDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(RequiredSize); DeviceInterfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); // 获取设备细节信息; if (SetupDiGetDeviceInterfaceDetail(hDevInfo, &DeviceInterfaceData, DeviceInterfaceDetailData, RequiredSize, NULL, NULL)) { HANDLE hDeviceFile; BOOL isOK = FALSE; if( _tcsnicmp( DeviceInterfaceDetailData->DevicePath + 4, TEXT("root"), 4 ) == 0 ) {// 剔除虚拟网卡; nNICKind = NIC_ROOT; } else if ( _tcsnicmp(DeviceInterfaceDetailData->DevicePath + 4, TEXT("swd"), 3 ) == 0 ) {// 剔除仿真网卡; nNICKind = NIC_SWD; } else if( _tcsnicmp( DeviceInterfaceDetailData->DevicePath + 4, TEXT("usb"), 3 ) == 0 ) {// 保留USB网卡(无线网卡); nNICKind = NIC_USB; } else if (_tcsnicmp( DeviceInterfaceDetailData->DevicePath + 4, TEXT("pci"), 3 ) == 0 ) {// pci网卡; nNICKind = NIC_PCI; } // 获取设备句柄; hDeviceFile = CreateFile( DeviceInterfaceDetailData->DevicePath, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if( hDeviceFile != INVALID_HANDLE_VALUE ) { ULONG dwID; BYTE ucData[8]; DWORD dwByteRet; // 获取原生MAC地址; dwID = OID_802_3_PERMANENT_ADDRESS; isOK = DeviceIoControl( hDeviceFile, IOCTL_NDIS_QUERY_GLOBAL_STATS, &dwID, sizeof(dwID), ucData, sizeof(ucData), &dwByteRet, NULL ); if( isOK ) { ++nTotal; MacAddress tagMacAddress; _stprintf_s(tagMacAddress.szDevicePath, _T("%s"), DeviceInterfaceDetailData->DevicePath); memset(tagMacAddress.szMacAddress, 0, sizeof(TCHAR)*MAX_PATH); // 将字节数组转换成16进制字符串; for ( DWORD i = 0; i < dwByteRet; i++ ) { _stprintf_s( &tagMacAddress.szMacAddress[i << 1], MAX_PATH - (i << 1), _T("%02X"), ucData[i] ); } switch(nNICKind) { case NIC_PCI: _stprintf_s(tagMacAddress.szNICKind, _T("%s"), _T("NIC_PCI")); break; case NIC_USB: _stprintf_s(tagMacAddress.szNICKind, _T("%s"), _T("NIC_USB")); break; case NIC_ROOT: _stprintf_s(tagMacAddress.szNICKind, _T("%s"), _T("NIC_ROOT")); break; case NIC_SWD: _stprintf_s(tagMacAddress.szNICKind, _T("%s"), _T("NIC_SWD")); break; default: _stprintf_s(tagMacAddress.szNICKind, _T("%s"), _T("NIC_UNK")); break; } tagMacAddress.nNICKind = nNICKind; m_vtMacAddress.push_back(tagMacAddress); #ifdef _DEBUG WriteTextLog(_T("网卡MAC地址:%s"),tagMacAddress.szMacAddress); WriteTextLog(DeviceInterfaceDetailData->DevicePath); #endif } CloseHandle( hDeviceFile ); } } free(DeviceInterfaceDetailData); } SetupDiDestroyDeviceInfoList(hDevInfo); return nTotal; } INT CDeviceQuery::GetHardDiskInfo() { HDEVINFO hDevInfo; DWORD MemberIndex, RequiredSize; SP_DEVICE_INTERFACE_DATA DeviceInterfaceData; PSP_DEVICE_INTERFACE_DETAIL_DATA DeviceInterfaceDetailData; INT nTotal = 0; // 获取设备信息集; hDevInfo = SetupDiGetClassDevs(&HDDClassGuid, NULL, NULL, DIGCF_PRESENT | DIGCF_INTERFACEDEVICE); if (hDevInfo == INVALID_HANDLE_VALUE) { return -1; } m_vtHardDiskID.clear(); // 枚举设备信息集中所有设备; DeviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); for (MemberIndex = 0; SetupDiEnumDeviceInterfaces(hDevInfo, NULL, &HDDClassGuid, MemberIndex, &DeviceInterfaceData); MemberIndex++) { // 获取接收缓冲区大小,函数返回值为FALSE,GetLastError()=ERROR_INSUFFICIENT_BUFFER; SetupDiGetDeviceInterfaceDetail(hDevInfo, &DeviceInterfaceData, NULL, 0, &RequiredSize, NULL); // 申请接收缓冲区; DeviceInterfaceDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(RequiredSize); DeviceInterfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); // 获取设备细节信息; if (SetupDiGetDeviceInterfaceDetail(hDevInfo, &DeviceInterfaceData, DeviceInterfaceDetailData, RequiredSize, NULL, NULL)) { HANDLE hDeviceFile; BOOL isOK = FALSE; // 获取设备句柄; hDeviceFile = CreateFile( DeviceInterfaceDetailData->DevicePath, GENERIC_READ | GENERIC_WRITE, // 注意:需要系统管理员权限才能执行读写操作; FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if( hDeviceFile != INVALID_HANDLE_VALUE ) { GETVERSIONINPARAMS VersionInParams; DWORD dwByteRet; // 获取硬盘属性; isOK = DeviceIoControl( hDeviceFile, SMART_GET_VERSION, NULL, 0, &VersionInParams, sizeof(GETVERSIONINPARAMS), &dwByteRet, NULL ); if( isOK ) { isOK = FALSE; if( VersionInParams.fCapabilities & CAP_ATA_ID_CMD ) { BYTE abSCIP[sizeof(SENDCMDINPARAMS) - 1] = {0}; BYTE abSCOP[sizeof(SENDCMDOUTPARAMS) - 1 + 512] = {0}; SENDCMDINPARAMS *scip = reinterpret_cast(abSCIP); SENDCMDOUTPARAMS *scop = reinterpret_cast(abSCOP); // 设置输入参数; scip->irDriveRegs.bCommandReg = ID_CMD; // 设置输出参数; scop->cBufferSize = 512; // 获取硬盘详细信息; isOK = DeviceIoControl( hDeviceFile, SMART_RCV_DRIVE_DATA, scip, sizeof(abSCIP), scop, sizeof(abSCOP), &dwByteRet, NULL ); if( isOK ) { ++nTotal; std::string strHDSerialNumber; strHDSerialNumber.resize(32,'\0'); // 提取硬盘序列号; for( UINT i = 0, j = 0; i < 20; i += 2 ) { // 颠倒高低位字节; if ( scop->bBuffer[i+20] != 32) { if (scop->bBuffer[i+21] != 32) strHDSerialNumber[j++] = scop->bBuffer[i+21]; strHDSerialNumber[j++] = scop->bBuffer[i+20]; } } m_vtHardDiskID.push_back(strHDSerialNumber); #ifdef _DEBUG WriteTextLog(_T("硬盘序列号:%s"), strHDSerialNumber.c_str()); #endif } } } CloseHandle( hDeviceFile ); } } free(DeviceInterfaceDetailData); } SetupDiDestroyDeviceInfoList(hDevInfo); return nTotal; } void CDeviceQuery::OutHDString() { for ( std::vector::iterator it = m_vtMacAddress.begin(); it != m_vtMacAddress.end(); it++ ) { std::string strNICKind; switch(it->nNICKind) { case NIC_PCI: strNICKind = "PCI网卡"; break; case NIC_USB: strNICKind = "USB无线网卡"; break; case NIC_SWD: strNICKind = "仿真网卡"; break; case NIC_ROOT: strNICKind = "虚拟网卡"; break; default: break; } WriteTextLog(_T("类型:%s, 物理地址:%s"), strNICKind.c_str(), it->szMacAddress); } for ( std::vector::iterator it = m_vtHardDiskID.begin(); it != m_vtHardDiskID.end(); it++ ) { WriteTextLog(_T("硬盘序列号:%s"), it->c_str()); } } BYTE* CDeviceQuery::GetHardWareSerialNumber(IN DWORD &dwBytelen) { char *out = NULL; cJSON *pJson = NULL; pJson = cJSON_CreateObject(); // 存在网卡时; if ( m_vtMacAddress.size() ) { INT nNIC_PCI = 0; INT nNIC_USB = 0; std::vector vtMacAddress; for ( std::vector::iterator it = m_vtMacAddress.begin(); it != m_vtMacAddress.end(); it++ ) { if ( it->nNICKind == NIC_ROOT || it->nNICKind == NIC_SWD) continue; if ( it->nNICKind == NIC_PCI ) ++nNIC_PCI; else if (it->nNICKind == NIC_USB) ++nNIC_USB; vtMacAddress.push_back(*it); } // 只获取pic和usb网卡; if ( vtMacAddress.size() ) { cJSON *pMacArry = cJSON_CreateArray(); cJSON_AddItemToObject(pJson, "MAC", pMacArry); std::vector::iterator it; for ( it = vtMacAddress.begin(); it != vtMacAddress.end(); it++) { cJSON *pMacItem = cJSON_CreateObject(); cJSON_AddStringToObject(pMacItem, "Address", it->szMacAddress); cJSON_AddStringToObject(pMacItem, "kind", it->szNICKind); cJSON_AddItemToArray(pMacArry, pMacItem); } } } // 存在硬盘时; if ( m_vtHardDiskID.size() ) { cJSON *pHDArry = cJSON_CreateArray(); cJSON_AddItemToObject(pJson, "HD", pHDArry); for ( std::vector::iterator it = m_vtHardDiskID.begin(); it != m_vtHardDiskID.end(); it++) { cJSON *pHDItem = cJSON_CreateObject(); cJSON_AddStringToObject(pHDItem, "SerialNum", it->c_str()); cJSON_AddItemToArray(pHDArry, pHDItem); } } out = cJSON_Print(pJson); #ifdef _DEBUG WriteTextLog(_T("JSON:%s"), out); #endif cJSON_Delete(pJson); #if 0 // 以下是加密; INT nSrclen = strlen(out); INT nEncryptlen = des_enc_len(nSrclen); INT nBase64len = CBase64::CalcBase64Len(nEncryptlen); dwBytelen = nBase64len; BYTE *pEncryptStr = new BYTE[nBase64len+1]; memset(pEncryptStr, 0, nBase64len+1); des_crypt_cbc(DES_ENCRYPT,nSrclen, (LPBYTE)out, pEncryptStr, nBase64len); if(0) // 还原测试-ok; { nSrclen = strlen((char*)pEncryptStr); nEncryptlen = des_dec_len(pEncryptStr, nSrclen); nBase64len = CBase64::CalcBinLen(nEncryptlen); BYTE *pDecryptStr = new BYTE[nBase64len+1]; memset(pDecryptStr, 0, nBase64len + 1); des_crypt_cbc(DES_DECRYPT, nSrclen, pEncryptStr, pDecryptStr, nBase64len); if (pDecryptStr) { delete pDecryptStr; } if ( pEncryptStr ) { delete pEncryptStr; } } if ( out ) { delete out; } return pEncryptStr; #else return (BYTE*)out; #endif }