Windows HotFix Check Via C/C++ Update

2023-02-28 10:37:28 浏览数 (1)

Main File(hotfixtest.cpp)[Fix vista Filetime]:

代码语言:javascript复制
// hotfixtest.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "hotfix.h"
int _tmain(int argc, _TCHAR* argv[])
{
	std::cout < < "Hotfix Begin:" <>endno;
	return 0;
}

Header File(hotfixdetect.cpp):

代码语言:javascript复制
// hotfixdetect.cpp : 定义控制台应用程序的入口点。
//
#define  _AFXDLL
#include "stdafx.h"
#include "afxdisp.h"
#ifndef _WIN32_DCOM
#define _WIN32_DCOM
#endif
#include 
#include 
#include 
#include 
#include 
#include "Comdef.h"
#include 
#pragma comment(lib,"Wbemuuid.lib")

#define LENGTH 16

HRESULT test;

struct  Hotfix									//系统补丁结构
{
		_bstr_t csname;						//主机名称
		_bstr_t Description;				//描述符
		_bstr_t FixComments;			//字段可能为空
		_bstr_t HotFixID;					//补丁ID显示为补丁名称	
		_bstr_t FixCaption;					//
		_bstr_t InstallDate;					//
		_bstr_t InstalledBy;				//安装用户
		_bstr_t InstalledOn;				//补丁安装日期
		_bstr_t HotFixName;				//补丁名称多数情况下为空
		_bstr_t ServicePackInEffect;	//影响sp版本信息
		_bstr_t Fixstatus;					//补丁状态,字段通常为空
}  Myhotfix;
struct  NetShare 
{
	_bstr_t AccessMask;
	_bstr_t AllowMaximum;
	_bstr_t Caption;
	_bstr_t Description;
	_bstr_t InstallDate;
	_bstr_t MaximumAllowed;
	_bstr_t Name;
	_bstr_t Path;
	_bstr_t Status;
	_bstr_t Type;
} MyNetShare;
ULONG retcnt =1;
ULONG shareret =1;
COleDateTime LastPatchdate(1970,1,1,0,0,0);

//////////////////////////////////////////////////////////////////////////////////
//字符串转换函数,转换字符串为64位整形
//针对Vista 返回日期为16位的Filetime格式
//将16位字符串转换为Int64,返回日期目前未考虑大写字母
//////////////////////////////////////////////////////////////////////////////////
COleDateTime StringtoInt64(char *str)
{
	INT64 result = 0;
	while(*str)
	{
		result = result < < 4;
		if(*str <= '9')
		{
			result  = *str-'0';
		}
		else 
		{
			//*str =toupper(*str);
			result  = *str - ('a'-10); 
		}
		str  ;
	}
	return result;
}
//////////////////////////////////////////////////////////////////////////////////
//修改系统补丁日期格式
//通常情况下返回安装日志可能值为:0,2010/02/05,2010-02-05之类
//Vista返回安装日期为20100205或者是十六位的filetime格式
//////////////////////////////////////////////////////////////////////////////////
COleDateTime ChangeTimeType (Hotfix bBuffer)
{
	char* tmpSbuffer = bBuffer.InstalledOn;
	if (bBuffer.InstalledOn.length() ==0)  //返回日期长度为0
	{
		COleDateTime newTime(1970,1,1,0,0,0);
		return newTime;
	}
	if (bBuffer.InstalledOn.length() ==8 && !(NULL != strchr(tmpSbuffer,'/') || NULL !=strchr(tmpSbuffer,'-'))) //返回日期长度为8,并且在字符串中没有找到/或者-
	{
		int nTime = atoi(tmpSbuffer);
		int year = nTime/10000;
		int month = (nTime-year*10000)/100;
		int day = nTime-year*10000-month*100;

		COleDateTime newTime(year,month,day,0,0,0);
		return newTime;
	}
	if (bBuffer.InstalledOn.length() == 16) //返回日期长度为16
	{
		FILETIME FixFileTime;
		INT64 intBuffer = StringtoInt64(tmpSbuffer);
		DWORD high =( intBuffer>>32);
		DWORD low = intBuffer& 0x0FFFFFFFF;
		FixFileTime.dwHighDateTime=high;
		FixFileTime.dwLowDateTime =low;
			COleVariant ct1(FixFileTime);
		ct1.ChangeType(VT_DATE);
		COleDateTime otime1 = ct1;
		return otime1;
	}
	if (NULL != strchr(tmpSbuffer,'/') || NULL !=strchr(tmpSbuffer,'-') ) //默认日期格式
	{
		COleVariant vtime1(bBuffer.InstalledOn);
		vtime1.ChangeType(VT_DATE);
		COleDateTime otime1 = vtime1;
		return otime1;
	}

}

//////////////////////////////////////////////////////////////////////////////////
//Coletime2_bstr 时间转为字符串
//将Coletime转换为_bstr_t格式
//////////////////////////////////////////////////////////////////////////////////
_bstr_t ColeTime2Bstr (COleDateTime vtime)
{
	SYSTEMTIME   systime;			//时间类型转换
	VariantTimeToSystemTime(vtime,   &systime);   
	CTime   tm(systime); 
	CString szTime=tm.Format("%Y-%m-%d %H:%M:%S");
	BSTR bstrText = szTime.AllocSysString();	
	return bstrText;
	//SysFreeString(bstrText); // 用完释放
}

//////////////////////////////////////////////////////////////////////////////////
//获取当前系统补丁信息
//返回值:-1为错误,如果执行正确返回系统补丁数目
//////////////////////////////////////////////////////////////////////////////////
int Gethotfix(Hotfix hot[],COleDateTime &last)
{
	int i =0;
	HRESULT hr = CoInitializeEx( NULL, COINIT_MULTITHREADED );
	if ( FAILED( hr ) )
	{
		//std::cerr < < "COM initialization failed" << std::endl;
		return -1;
	}
	hr = CoInitializeSecurity( NULL, 
										-1, 
										NULL,
										NULL,
										RPC_C_AUTHN_LEVEL_DEFAULT, 
										RPC_C_IMP_LEVEL_IMPERSONATE,
										NULL,
										EOAC_NONE,
										NULL );
	if ( FAILED( hr ) )
	{
		//std::cerr << "Security initialization failed" << std::endl;
		return -1;
	}

	int result = 0;
	{
		CComPtr< IWbemLocator > locator;
		hr = CoCreateInstance( CLSID_WbemAdministrativeLocator,
											NULL,
											CLSCTX_INPROC_SERVER,
											IID_IWbemLocator, 
											reinterpret_cast< void** >( &locator ) );
		if ( FAILED( hr ) )
		{
			//std::cerr < < "Instantiation of IWbemLocator failed" << std::endl;
			return -1;
		}

		// 链接当前wmi服务
		CComPtr< IWbemServices > service;
		hr = locator->ConnectServer( L"root\cimv2",
														NULL,
														NULL, 
														NULL,
														WBEM_FLAG_CONNECT_USE_MAX_WAIT,
														NULL, 
														NULL,
														&service );
		if ( SUCCEEDED( hr ) )
		{
			CComPtr< IEnumWbemClassObject > enumerator;
			// 查询数据库获得补丁信息
			hr = service->ExecQuery( L"WQL", 
													L"Select * from Win32_QuickFixEngineering",
													WBEM_FLAG_RETURN_IMMEDIATELY,
													NULL,
													&enumerator );
			while ( SUCCEEDED( hr ) && retcnt >0)
			{
				CComPtr< IWbemClassObject > pHotfix;
				//枚举当前系统补丁信息
				hr = enumerator->Next( WBEM_INFINITE,
													1L,
													reinterpret_cast( &pHotfix), 
													&retcnt );
				if ( SUCCEEDED( hr ) && retcnt >0 )
				{
					_variant_t var_val;
					test = pHotfix->Get( L"CSName", 0, &var_val, NULL, NULL );
					if ( SUCCEEDED( test ) && var_val.vt !=VT_NULL )  
					{
						_bstr_t csname = var_val;
						hot[i].csname = csname;						
					}
					test = pHotfix->Get( L"HotFixID", 0, &var_val, NULL, NULL );
					if ( SUCCEEDED( test ) && var_val.vt !=VT_NULL ) 
					{
						_bstr_t HotFixID = var_val;
						hot[i].HotFixID = HotFixID;						
					}
					test = pHotfix->Get( L"InstalledOn", 0, &var_val, NULL, NULL );
					if ( SUCCEEDED( test ) && var_val.vt  != VT_NULL )  
					{
						_bstr_t InstalledOn = var_val;
						hot[i].InstalledOn =InstalledOn;		
						
					}
					test = pHotfix->Get( L"Name", 0, &var_val, NULL, NULL );
					if ( SUCCEEDED( test ) &&  var_val.vt ==VT_BSTR )  
					{
						_bstr_t Fixname = var_val;
						hot[i].HotFixName =Fixname;						
					}
					//更新最后的补丁时间
					COleDateTime ootime= ChangeTimeType(hot[i]);
					if (ootime > LastPatchdate)
					{
						LastPatchdate = ootime;
						last =LastPatchdate;

					}
				}
			i  ;
			}
		}
		else
		{
			//std::cerr < < "Couldn't connect to service" << std::endl;
			return -1;
		}
	}
	CoUninitialize();
	return i;
}
//////////////////////////////////////////////////////////////////////////////////
//获取当前系统共享信息
//返回值:-1为错误,如果执行正确返回共享数目
//////////////////////////////////////////////////////////////////////////////////
int GetNetShare( NetShare myshares[]) 
{
	int j =0;
	HRESULT hr = CoInitializeEx( NULL, COINIT_MULTITHREADED );
	if ( FAILED( hr ) )
	{
		std::cerr << "COM initialization failed" << std::endl;
		return -1;
	}
	hr = CoInitializeSecurity( NULL, 
											-1, 
											NULL,
											NULL,
											RPC_C_AUTHN_LEVEL_DEFAULT, 
											RPC_C_IMP_LEVEL_IMPERSONATE,
											NULL,
											EOAC_NONE,
											NULL );
	if ( FAILED( hr ) )
	{
		std::cerr << "Security initialization failed" << std::endl;
		return -1;
	}

	int result = 0;
	{
		CComPtr< IWbemLocator > locator;
		hr = CoCreateInstance( CLSID_WbemAdministrativeLocator, 
											NULL,
											CLSCTX_INPROC_SERVER,
											IID_IWbemLocator, 
											reinterpret_cast< void** >( &locator ) );
		if ( FAILED( hr ) )
		{
			std::cerr < < "Instantiation of IWbemLocator failed" << std::endl;
			return -1;
		}

		// 链接当前wmi服务
		CComPtr< IWbemServices > service;
		hr = locator->ConnectServer( L"root\cimv2", 
														NULL,
														NULL, 
														NULL,
														WBEM_FLAG_CONNECT_USE_MAX_WAIT,
														NULL, 
														NULL, 
														&service );
		if ( SUCCEEDED( hr ) )
		{
			CComPtr< IEnumWbemClassObject > enumerator;
			// 查询数据库获得共享
			hr = service->ExecQuery( L"WQL", 
													L"Select * from Win32_Share",
													WBEM_FLAG_RETURN_IMMEDIATELY, 
													NULL, 
													&enumerator );
			while ( SUCCEEDED( hr ) && shareret >0  )
			{
				CComPtr< IWbemClassObject > pNetShare;
				//枚举当前系统共享
				hr = enumerator->Next( WBEM_INFINITE, 
														1L,
														reinterpret_cast( &pNetShare), 
														&shareret );
				if ( SUCCEEDED( hr ) && shareret >0 )
				{
					_variant_t var_val;
					test = pNetShare->Get( L"Path", 0, &var_val, NULL, NULL );
					if ( SUCCEEDED( test ) && var_val.vt !=VT_NULL )  
					{
						_bstr_t SharePath = var_val;
						myshares[j].Path = SharePath;						
					}
					test = pNetShare->Get( L"Name", 0, &var_val, NULL, NULL );
					if ( SUCCEEDED( test ) && var_val.vt !=VT_NULL )  
					{
						_bstr_t ShareName = var_val;
						myshares[j].Name = ShareName;						
					}
					j  ;
				}			
				
			}
		}
		else
		{
			//std::cerr < < "Couldn't connect to service" << std::endl;
			return -1;
		}
	}
	CoUninitialize();
	return j;
}

0 人点赞