在软件中控制 Windows 防火墙

在安装程序中,往往需要安装一个本地的网络服务,但是在开了 Windows 防火墙的机器上,安装了服务后即使启动了该服务,别的机器仍然无法连接,这是因为服务是在 system 账号中启动的,不会提示用户是否让该服务通过 Windows 防火墙,因此服务启动了,但是网络端口却被 Windows 防火墙屏蔽了,因此安装程序应该能够自己检测到 Windows 防火墙是否开启,如果开启应该自动将安装的服务增加到 Windows 防火墙的例外程序列表中,控制 Windows 防火墙其实很简单使用微软提供的 COM 接口就可以了,下面就是封装的类:

ContractedBlock.gif ExpandedBlockStart.gif WindowsFirewall.h
//==================================================================================================
//                MSI 安装函数封装类( Microsoft Installer Wrapper Template Class )
//
//    作者:王志科                                        版权没有,随意转载(请保留该文件头部信息)
//==================================================================================================

#pragma once

#include 
"msi.h"
#include 
"MsiDefs.h"
#include 
"MsiQuery.h"

#pragma comment(lib,"msi")

#ifndef CHK_EXP_RET
#define CHK_EXP_RET(exp,ret) if(exp){ return ret; }
#define CHK_EXP_RUN(exp,run) if(exp){ run; }
#endif

namespace MSI
{
    
//==============================================================================================
    
//
    template<bool tManage = true> class HandlerT
    {
    
public:
        HandlerT(MSIHANDLE hMsi 
= NULL) : m_hMsi(hMsi) { }
        
~HandlerT() { if(tManage){ Close(); } }

    
public:
        
void Close(){ if(m_hMsi){ MsiCloseHandle(m_hMsi); m_hMsi = NULL; } }

    
public:
        
void Attach(MSIHANDLE hMsi){ ATLASSERT(m_hMsi != NULL); m_hMsi = hMsi; }
        MSIHANDLE Detach(){ MSIHANDLE hMsi 
= m_hMsi; m_hMsi = NULL; return hMsi; }

    
public:
        
void operator =(MSIHANDLE hMsi){ Close(); m_hMsi = hMsi; }
        MSIHANDLE
* operator &() { Close(); return &m_hMsi; }
        
operator MSIHANDLE() { return m_hMsi; }

    
protected:
        MSIHANDLE m_hMsi;
    };

    
//==============================================================================================
    
//
    template<bool tManage = true> class DatabaseT : public HandlerT<tManage>
    {
    
public:
        DatabaseT(MSIHANDLE hDatabase 
= NULL)
        {
            m_hMsi 
= hDatabase;
        }

        DatabaseT(LPCTSTR lpszDatabase, LPCTSTR szPersist)
        {
            Open(lpszDatabase, szPersist);
        }

    
public:
        UINT Open(LPCTSTR lpszDatabase, LPCTSTR szPersist)
        {
            
return MsiOpenDatabase(lpszDatabase, szPersist, &m_hMsi);
        }

        VOID Close(BOOL bCommit 
= FALSE)
        {
            
if(bCommit) Commit();
            HandlerT::Close();
        }

        UINT Commit()
        {
            
return MsiDatabaseCommit(m_hMsi);
        }

        UINT Import(LPCTSTR szFolderPath,LPCTSTR szFileName)
        {
            
return MsiDatabaseImport(m_hMsi,szFolderPath,szFileName);
        }

        UINT Export(LPCTSTR szTableName,LPCTSTR szFolderPath,LPCTSTR szFileName)
        {
            
return MsiDatabaseExport(m_hMsi,szTableName,szFolderPath,szFileName);
        }

        UINT Merge(MSIHANDLE hDatabase, LPCTSTR szTableName)
        {
            
return MsiDatabaseMerge(m_hMsi,hDatabase,szTableName);
        }

        UINT GenerateTransform(MSIHANDLE hDatabase, LPCTSTR szTransformFile)
        {
            
return MsiDatabaseGenerateTransform(m_hMsi,hDatabase,szTransformFile,0,0);
        }

        UINT ApplyTransform(LPCTSTR szTransformFile, INT iErrorConditions)
        {
            
return MsiDatabaseApplyTransform(m_hMsi,szTransformFile,iErrorConditions);
        }

        MSIDBSTATE GetState()
        {
            
return MsiGetDatabaseState(m_hMsi);
        }

        MSICONDITION TableExists(LPCTSTR szTableName)
        {
            
return MsiDatabaseIsTablePersistent(m_hMsi,szTableName);
        }

        MSICONDITION IsTablePersistent(LPCTSTR szTableName)
        {
            
return MsiDatabaseIsTablePersistent(m_hMsi,szTableName);
        }

        
// RecordT
        UINT PrimaryKeys(LPCTSTR szTableName, MSIHANDLE& hRecord)
        {
            
return MsiDatabaseGetPrimaryKeys(m_hMsi,szTableName,&hRecord);
        }

        
// View
        UINT OpenView(LPCTSTR szQuery, MSIHANDLE* pView)
        {
            
return MsiDatabaseOpenView(m_hMsi,szQuery, pView);
        }

        
// View
        UINT OpenExecuteView(LPCTSTR szQuery, MSIHANDLE* pView)
        {
            UINT nCaller 
= OpenView(szQuery, pView);
            CHK_EXP_RET(nCaller 
!= ERROR_SUCCESS , nCaller);
            
return MsiViewExecute(*pView, NULL);
        }
    };

    
//==============================================================================================
    
//
    template<bool tManage = true> class RecordT : public HandlerT<tManage>
    {
    
public:
        RecordT(UINT cParams 
= 3)
        {
            m_hMsi 
= MsiCreateRecord(cParams);
        }

    
public:
        UINT GetFieldCount()
        {
            
return MsiRecordGetFieldCount(m_hMsi);
        }

        BOOL IsNull(UINT iField)
        {
            
return MsiRecordIsNull(m_hMsi,iField);
        }

        UINT SetNumber(UINT iField, INT iValue)
        {
            
return MsiRecordSetInteger(m_hMsi,iField,iValue);
        }

        INT GetNumber(UINT iField)
        {
            
return MsiRecordGetInteger(m_hMsi,iField);
        }

        BOOL GetString(UINT iField, CString
& strValue)
        {
            DWORD dwValue 
= 4096;
            LPTSTR szValue 
= strValue.GetBuffer(dwValue);
            UINT nCaller 
= MsiRecordGetString(m_hMsi,iField,szValue,&dwValue);
            
if(nCaller == ERROR_MORE_DATA)
            {
                dwValue 
+= 2;
                strValue.ReleaseBuffer();
                szValue 
= strValue.GetBuffer(dwValue);
                nCaller 
= MsiRecordGetString(m_hMsi,iField,szValue,&dwValue);
            }

            strValue.ReleaseBuffer();
            
return nCaller == ERROR_SUCCESS;
        }

        UINT GetString(UINT iField, LPTSTR szValue, LPDWORD dwValue)
        {
            
return MsiRecordGetString(m_hMsi,iField,szValue,dwValue);
        }

        UINT SetString(UINT iField, LPCTSTR szValue)
        {
            
return MsiRecordSetString(m_hMsi,iField,szValue);
        }

        UINT GetStream(UINT iField, LPSTR szBuffer,LPDWORD dwBuffer)
        {
            
return MsiRecordReadStream(m_hMsi,iField,szBuffer,dwBuffer);
        }

        UINT SetStream(UINT iField, LPCTSTR szFilePath)
        {
            
return MsiRecordSetStream(m_hMsi,iField,szFilePath);
        }
    };

    
//==============================================================================================
    
//
    template<bool tManage = true> class ViewT : public HandlerT<tManage>
    {
    
public:
        ViewT(MSIHANDLE hView 
= NULL)
        {
            m_hMsi 
= hView;
        }

        ViewT(MSIHANDLE hDatabase, LPCTSTR szQuery)
        {
            Open(hDatabase, szQuery);
        }

    
public:
        UINT Open(MSIHANDLE hDatabase, LPCTSTR szQuery)
        {
            
return MsiDatabaseOpenView(hDatabase,szQuery,&m_hMsi);
        }

        BOOL Execute(MSIHANDLE hRecord 
= NULL)
        {
            
return MsiViewExecute(m_hMsi, hRecord);
        }

        UINT Fetch(MSIHANDLE
& hRecord)
        {
            
return MsiViewFetch(m_hMsi, &hRecord);
        }

        UINT Modify(MSIMODIFY eModify, MSIHANDLE hRecord)
        {
            
return MsiViewModify(m_hMsi,eModify,hRecord);
        }

        UINT GetColumnInfo(MSICOLINFO eColumnInfo,MSIHANDLE
& hRecord)
        {
            
return MsiViewGetColumnInfo(m_hMsi,eColumnInfo,&hRecord);
        }

        
// 执行了 Execute 之后,那么在下一次执行 Execute 之前必须调用该函数
        UINT Release()
        {
            
return MsiViewClose(m_hMsi);
        }
    };

    template
<bool tManage = true> class SummaryInformationT : public HandlerT<tManage>
    {
    
public:
        SummaryInformationT(MSIHANDLE hDatabase, LPCTSTR szDatabase 
= NULL, UINT uiUpdateCount = 20)
        {
            Open(hDatabase,szDatabase, uiUpdateCount);
        }

    
public:
        UINT GetPropertyCount(PUINT puiPropertyCount)
        {
            
return MsiSummaryInfoGetPropertyCount(m_hMsi, puiPropertyCount);
        }

        UINT GetProperty(UINT uProperty,PUINT puiDataType,PINT piValue,PFILETIME pFileTime,LPTSTR szValue,LPDWORD dwValue)
        {
            
return MsiSummaryInfoGetProperty(m_hMsi,uProperty,puiDataType,piValue,pFileTime,szValue,dwValue);
        }

        UINT SetProperty(UINT uProperty,UINT uDataType,INT iValue,PFILETIME pFileTime,LPTSTR szValue)
        {
            
return MsiSummaryInfoSetProperty(m_hMsi,uProperty,uDataType,iValue,pFileTime,szValue);
        }

        UINT Open(MSIHANDLE hDatabase, LPCTSTR szDatabase 
= NULL, UINT uiUpdateCount = 20)
        {
            
return MsiGetSummaryInformation(hDatabase,szDatabase, uiUpdateCount, &m_hMsi);
        }

        UINT Commit()
        {
            
return MsiSummaryInfoPersist(m_hMsi);
        }

    
public:
        UINT GetPropertyInteger(UINT uProperty,PINT piValue)
        {
            UINT uiDataType 
= VT_I4;
            
return GetProperty(uProperty,&uiDataType,piValue,NULL,NULL,0);
        }

        UINT GetPropertyFiletime(UINT uProperty,PFILETIME pFileTime)
        {
            UINT uiDataType 
= VT_FILETIME;
            
return GetProperty(uProperty,&uiDataType,NULL,pFileTime,NULL,0);
        }

        UINT GetPropertyString(UINT uProperty,LPTSTR szValue,LPDWORD dwValue)
        {
            UINT uiDataType 
= VT_LPSTR;
            
return GetProperty(uProperty,&uiDataType,NULL,NULL,szValue,dwValue);
        }

        UINT SetPropertyInteger(UINT uProperty,INT iValue)
        {
            
return SetProperty(uProperty,VT_I4,iValue,NULL,NULL);
        }

        UINT SetPropertyString(UINT uProperty,LPWSTR szValue)
        {
            
return SetProperty(uProperty, VT_LPSTR, 0, NULL, szValue);
        }

        UINT SetPropertyFiletime(UINT uProperty,PFILETIME pFileTime)
        {
            
return SetProperty(uProperty,VT_FILETIME,0,pFileTime,NULL);
        }

    
public:
        VOID Close(BOOL bCommit 
= FALSE)
        {
            
if(bCommit) Commit();
            HandlerT::Close();
        }
    };

    
//==============================================================================================
    
//    安装控制函数
    template<typename T = CWindow > struct InstallerT
    {
    
public:
        InstallerT()
        {
            MemberInitialize();
            m_nProgressBar 
= 0;
            m_nProcessInfo 
= 0;
        }

        
~InstallerT()
        {
            CancelInstaller();
        }
        
    
public:
        VOID CancelInstaller()
        {
            m_bCancelInstall 
= FALSE;
        }

        VOID SetExternalUI(DWORD dwMsgFilter)
        {
            MsiSetExternalUI(InstallerCallback, dwMsgFilter, (LPVOID)
this);
        }

        UINT SetInternalUI(INSTALLUILEVEL nInstallerLevel, HWND
* pWindow = NULL)
        {
            
return MsiSetInternalUI(nInstallerLevel, pWindow);
        }

        
//    在命令行中可以设置动作和属性,例如下面将产品安装到 D:\LiveSystem
        
//    TEXT("ACTION=INSTALL TARGETDIR=\"D:\\LiveSystem\"")
        UINT StartInstaller(LPCTSTR lpszPackage, LPCTSTR szCommandLine = NULL)
        {
            
return MsiInstallProduct(lpszPackage, szCommandLine);
        }

        UINT SetControlID(UINT nProgressBar, UINT nProcessInfo 
= 0)
        {
            m_nProgressBar 
= nProgressBar;
            m_nProcessInfo 
= nProcessInfo;
            
return ERROR_SUCCESS;
        }

        UINT SetScriptStringID(UINT nScriptStrID 
= 0)
        {
            m_nScriptStrID 
= nScriptStrID;
            
return ERROR_SUCCESS;
        }

    
public:
        
// 采用默认参数安装指定的包
        UINT InstallPackage(LPCTSTR lpszPackage, LPCTSTR pszCommand = NULL)
        {
            
// 准备参数变量
            DWORD dwUILevel = INSTALLUILEVEL_NONE|INSTALLUILEVEL_SOURCERESONLY;
            DWORD dwMessageFilter 
= INSTALLLOGMODE_USER | INSTALLLOGMODE_INFO
                
| INSTALLLOGMODE_ACTIONDATA | INSTALLLOGMODE_OUTOFDISKSPACE
                
| INSTALLLOGMODE_COMMONDATA | INSTALLLOGMODE_RESOLVESOURCE
                
| INSTALLLOGMODE_INITIALIZE | INSTALLLOGMODE_ACTIONSTART
                
| INSTALLLOGMODE_SHOWDIALOG | INSTALLLOGMODE_TERMINATE
                
| INSTALLLOGMODE_FILESINUSE | INSTALLLOGMODE_PROGRESS
                
| INSTALLLOGMODE_EXTRADEBUG | INSTALLLOGMODE_WARNING
                
| INSTALLLOGMODE_FATALEXIT  | INSTALLLOGMODE_ERROR;

            MemberInitialize();
            SetExternalUI(dwMessageFilter);
            SetInternalUI((INSTALLUILEVEL)dwUILevel);
            
return StartInstaller(lpszPackage, pszCommand);
        }

    
public:
        
// 下面的函数是消息回调
        enum InstallerProgress
        {
            PROGRESS_RESET        
= 0,
            PROGRESS_ACTIONINFO    
= 1,
            PROGRESS_REPORT        
= 2,
            PROGRESS_ADDITION    
= 3,
        };

        
enum InstallerCommonData
        {
            COMMON_DATA_LANGUAGE    
= 0,
            COMMON_DATA_CAPTION        
= 1,
            COMMON_DATA_CANCELSHOW    
= 2,
        };

        
// premature termination, possibly fatal OOM
        INT OnInstallerFatalExit(UINT uFlags, LPCTSTR lpszMessage)
        {
            T
* pT = static_cast<T*>(this);
            
return pT->MessageBox(lpszMessage,m_strTitle, uFlags);
        }

        
// formatted error message
        INT OnInstallerError(UINT uFlags, LPCTSTR lpszMessage)
        {
            T
* pT = static_cast<T*>(this);
            
return pT->MessageBox(lpszMessage, m_strTitle, uFlags);
        }

        
// formatted warning message
        INT OnInstallerWarning(UINT uFlags, LPCTSTR lpszMessage)
        {
            T
* pT = static_cast<T*>(this);
            
return pT->MessageBox(lpszMessage, m_strTitle ,uFlags);
        }

        
// user request message
        INT OnInstallerUser(UINT uFlags, LPCTSTR lpszMessage)
        {
            
// 需要分析 uFlags 来确定返回 IDOK 或者 IDYES 或者其他值
            return (uFlags & 0x0F== MB_YESNO ? IDYES : IDOK;
        }

        
// informative message for log
        INT OnInstallerInfo(UINT uFlags, LPCTSTR lpszMessage)
        {
            
return IDOK;
        }

        
// list of files in use that need to be replaced
        INT OnInstallerFilesInuse(UINT uFlags, LPCTSTR lpszMessage)
        {
            
// 显示文件被使用的对话框
            return ERROR_SUCCESS;
        }

        
// request to determine a valid source location
        INT OnInstallerResolveSource(UINT uFlags, LPCTSTR lpszMessage)
        {
            
return ERROR_SUCCESS;
        }

        
// insufficient disk space message
        INT OnInstallerOutOfDiskSpace(UINT uFlags, LPCTSTR lpszMessage)
        {
            
return IDOK;
        }

        
// start of action: action name & description
        INT OnInstallerActionStart(UINT uFlags, LPCTSTR lpszMessage)
        {
            
return IDOK;
        }

        
// formatted data associated with individual action item
        INT OnInstallerActionData(UINT uFlags, LPCTSTR lpszMessage)
        {
            
// 如果没有初始化进度条,直接返回
            CHK_EXP_RET( m_nProgressTotal == 0 , IDOK );

            T
* pT = static_cast<T*>(this);
            pT
->SetDlgItemText(m_nProcessInfo, lpszMessage);
            
            
if( m_bEnableActionData && m_nProgressBar ) 
            {
                HWND hProgressBar 
= pT->GetDlgItem(m_nProgressBar);
                SendMessage(hProgressBar, PBM_STEPIT, 
00);
            }
            
return IDOK;
        }

        
// progress gauge info: units so far, total
        INT OnInstallerProgress(UINT uFlags, LPCTSTR lpszMessage)
        {
            T
* pT = static_cast<T*>(this);
            HWND hProgressBar 
= pT->GetDlgItem(m_nProgressBar);

            LONG nData[
4= { 0 , 0 , 0 , 0 };
            
if( ParseProgressString(lpszMessage, nData) )
            {
                
if(nData[0== PROGRESS_RESET)
                {
                    m_nProgressTotal 
= nData[1];
                    m_bProgressForward 
= (nData[2== 0);
                    m_nProgress 
= m_bProgressForward ? 0 : m_nProgressTotal ;
                    
// 设置进度条的工作长度
                    SendMessage(hProgressBar, PBM_SETRANGE32, 0, m_nProgressTotal);
                    
// 如果在处理脚本结束进度条,否则重置
                    WPARAM nCurrentPos = m_bProgressScript ? m_nProgressTotal : m_nProgress;
                    SendMessage(hProgressBar, PBM_SETPOS, nCurrentPos , 
0);
                    m_nPosition 
= 0;
                    
// 检测新的状态
                    m_bProgressScript = (nData[3== 1);
                    
                    
if( m_bProgressScript && m_nProcessInfo && m_nScriptStrID )
                    {
                        TCHAR szScriptString[MAX_PATH] 
= { TEXT("") };
                        AtlLoadString(m_nScriptStrID, szScriptString, MAX_PATH);
                        pT
->SetDlgItemText(m_nProcessInfo, szScriptString);
                    }
                }
                
else if(nData[0== PROGRESS_ACTIONINFO )
                {
                    
if( nData[2&& m_nProgressBar )
                    {
                        WPARAM nStep 
=  m_bProgressForward ? nData[1] : -1 * nData[1] ;
                        SendMessage(hProgressBar, PBM_SETSTEP, nStep, 
0);
                    }
                    m_bEnableActionData 
= nData[2? TRUE : FALSE ;
                }
                
else if(nData[0== PROGRESS_REPORT)
                {
                    
if( m_nProgressTotal != 0 )
                    {
                        m_nPosition 
+= nData[1];
                        WPARAM nCurrentPos 
= m_bProgressForward ? m_nPosition : -1 * m_nPosition;
                        SendMessage(hProgressBar, PBM_SETPOS, nCurrentPos, 
0);
                    }
                }
                
else if(nData[0== PROGRESS_ADDITION)
                {

                }
            }

            
return m_bCancelInstall ? IDCANCEL : IDOK ;
        }

        
// product info for dialog: language Id, dialog caption
        INT OnInstallerCommonData(UINT uFlags, LPCTSTR lpszMessage)
        {
            ParseCommonDataString(lpszMessage);
            
return IDOK;
        }

        
// sent prior to UI initialization, no string data
        INT OnInstallerInitialize(UINT uFlags, LPCTSTR lpszMessage /* = NULL */)
        {
            
return IDOK;
        }

        
// sent after UI termination, no string data
        INT OnInstallerTerminate(UINT uFlags, LPCTSTR lpszMessage /* = NULL */)
        {
            
return IDOK;
        }

        
// sent prior to display or authored dialog or wizard
        INT OnInstallerShowDialog(UINT uFlags, LPCTSTR lpszMessage)
        {
            
return IDOK;
        }

    
public:
        INT OnInstallerPrepare(UINT uiMessageType, LPCTSTR lpszMessage)
        {
            
if( m_bFirstTimeCall )
            {
                MsiSetInternalUI(INSTALLUILEVEL_BASIC, NULL);
                m_bFirstTimeCall 
= FALSE;
            }
        
            
return ERROR_SUCCESS ;
        }

    
public:
        
// 消息回调的处理函数
        INT InstallerHandler(UINT uiMessageType, LPCTSTR lpszMessage)
        {
            T
* pT = static_cast<T*>(this);

            
// 首先允许进行特殊的消息处理
            INT nPrepare = pT->OnInstallerPrepare(uiMessageType, lpszMessage);
            CHK_EXP_RET( FAILED( nPrepare ) , nPrepare );

            
// 根据消息类型进行分类处理
            UINT uFlags = (uiMessageType & 0x00FFFFFF);
            
switch( (INSTALLMESSAGE)(0xFF000000 & uiMessageType) )
            {
                
case INSTALLMESSAGE_FATALEXIT      : return pT->OnInstallerFatalExit     (uFlags, lpszMessage);
                
case INSTALLMESSAGE_ERROR          : return pT->OnInstallerError         (uFlags, lpszMessage);
                
case INSTALLMESSAGE_WARNING        : return pT->OnInstallerWarning       (uFlags, lpszMessage);
                
case INSTALLMESSAGE_USER           : return pT->OnInstallerUser          (uFlags, lpszMessage);
                
case INSTALLMESSAGE_INFO           : return pT->OnInstallerInfo          (uFlags, lpszMessage);
                
case INSTALLMESSAGE_FILESINUSE     : return pT->OnInstallerFilesInuse    (uFlags, lpszMessage);
                
case INSTALLMESSAGE_RESOLVESOURCE  : return pT->OnInstallerResolveSource (uFlags, lpszMessage);
                
case INSTALLMESSAGE_OUTOFDISKSPACE : return pT->OnInstallerOutOfDiskSpace(uFlags, lpszMessage);
                
case INSTALLMESSAGE_ACTIONSTART    : return pT->OnInstallerActionStart   (uFlags, lpszMessage);
                
case INSTALLMESSAGE_ACTIONDATA     : return pT->OnInstallerActionData    (uFlags, lpszMessage);
                
case INSTALLMESSAGE_PROGRESS       : return pT->OnInstallerProgress      (uFlags, lpszMessage);
                
case INSTALLMESSAGE_COMMONDATA     : return pT->OnInstallerCommonData    (uFlags, lpszMessage);
                
case INSTALLMESSAGE_INITIALIZE     : return pT->OnInstallerInitialize    (uFlags, lpszMessage);
                
case INSTALLMESSAGE_TERMINATE      : return pT->OnInstallerTerminate     (uFlags, lpszMessage);
                
case INSTALLMESSAGE_SHOWDIALOG     : return pT->OnInstallerShowDialog    (uFlags, lpszMessage);
            }

            
return ERROR_SUCCESS;
        }

    
protected:
        
static INT CALLBACK InstallerCallback(LPVOID lpContext, UINT uiMessageType, LPCTSTR lpszMessage)
        {
            InstallerT
< T >* lpInstaller = reinterpret_cast< InstallerT< T >* >(lpContext);
            
return static_cast<T*>(lpInstaller)->InstallerHandler(uiMessageType,lpszMessage);
        }
    
    
protected:
        
void MemberInitialize()
        {
            m_bShowCancel 
= TRUE;
            m_wLanguage 
= LANG_NEUTRAL;
            m_wCodePage 
= GetACP();

            m_bProgressForward 
= TRUE;
            m_bProgressScript 
= FALSE;
            m_nProgressTotal 
= 0;
            m_nProgress 
= 0;
            m_nPosition 
= 0;

            m_bEnableActionData 
= FALSE;
            m_bCancelInstall 
= FALSE;
            m_bFirstTimeCall 
= TRUE;
        }

    
protected:
        BOOL ParseCommonDataString(LPCTSTR lpString)
        {
            CHK_EXP_RET(lpString 
== NULL , FALSE );
            CHK_EXP_RET(lpString[
0== 0 , FALSE );
            
            
// 分析字符串类型
            lpString = StrStr(lpString, TEXT("1:"));
            CHK_EXP_RET(lpString 
== NULL , FALSE);
            LONG nCommon 
= lpString[3- TEXT('0');
            
            LPCTSTR lpStr2 
= StrStr(lpString, TEXT("2:"));
            LPCTSTR lpStr3 
= StrStr(lpString, TEXT("3:"));
    
            CHK_EXP_RET(lpStr2 
== NULL , FALSE);

            
if( nCommon == COMMON_DATA_CAPTION )
            {
                LPTSTR lpTail 
= (LPTSTR)lpStr3;
                
if(lpTail != NULL){ *lpTail = 0; }
                m_strTitle 
= lpString + 2//Skip "2:"
            }
            
else if( nCommon == COMMON_DATA_LANGUAGE )
            {
                m_wLanguage 
= StrToLong(lpStr2 + 3);

                CHK_EXP_RET(lpStr3 
== NULL , FALSE);
                m_wCodePage 
= StrToLong(lpStr3 + 3);
            }
            
else if( nCommon == COMMON_DATA_CANCELSHOW )
            {
                LONG nShow 
= StrToLong(lpStr2 + 3);
                m_bShowCancel 
= nShow ? TRUE : FALSE;
            }

            
return TRUE;
        }

        BOOL ParseProgressString(LPCTSTR lpString, LONG nData[
4])
        {
            ZeroMemory( nData, 
sizeof(LONG) * 4 );

            CHK_EXP_RET(lpString 
== NULL , FALSE );
            CHK_EXP_RET(lpString[
0== 0 , FALSE );
            
            
// 分析字符串类型
            lpString = StrStr(lpString, TEXT("1:"));
            CHK_EXP_RET(lpString 
== NULL , FALSE);
            nData[
0= lpString[3- TEXT('0');

            
// 第一个参数
            lpString = StrStr(lpString, TEXT("2:"));
            CHK_EXP_RET(lpString 
== NULL , TRUE);
            nData[
1= StrToLong(lpString + 3);

            
// 第二个参数
            lpString = StrStr(lpString, TEXT("3:"));
            CHK_EXP_RET(lpString 
== NULL , TRUE);
            nData[
2= StrToLong(lpString + 3);

            
// 第三个参数
            lpString = StrStr(lpString, TEXT("4:"));
            CHK_EXP_RET(lpString 
== NULL , TRUE);
            nData[
3= StrToLong(lpString + 3);

            
return TRUE;
        }
        
    
protected:
        
// 下面是 CommonData 分析出的数据
        CString m_strTitle;            // 一般是安装的产品标题
        BOOL m_bShowCancel;            //    是否要显示“取消”按钮
        WORD m_wLanguage;            //    当前的语言 
        WORD m_wCodePage;            //    当前的代码页

        
// 下面是 ProgressInfo 分析出的数据
        BOOL m_bProgressForward;    //    TRUE 表示当前处理进度条是增加的方式
        BOOL m_bProgressScript;        //    TRUE 表示在处理脚本,可以显示“请稍后dot.gif
        LONG m_nProgressTotal;        //    进度条总数
        LONG m_nProgress;            //    进度数
        LONG m_nPosition;            //    当前位置

        
// 其他控制数据
        BOOL m_bEnableActionData;    //    TRUE 表示 INSTALLOGMODE_ACTIONDATA 消息发送进度信息
        BOOL m_bCancelInstall;        //    如果要取消安装将该值设置为 TRUE 
        BOOL m_bFirstTimeCall;        //    是否第一次调用外部界面接口

        
// 窗口显示信息控件的ID
        UINT m_nProgressBar;        //    进度条控件
        UINT m_nProcessInfo;        //    显示处理信息的控件
        UINT m_nScriptStrID;        //    处理脚本,请稍后dot.gif
    };

    
//==============================================================================================
    
//    全局的静态函数
    inline UINT GetFileHash(LPCTSTR lpszFileName, DWORD dwOptions, MSIFILEHASHINFO& rMsiFileHashInfo)
    {
        rMsiFileHashInfo.dwFileHashInfoSize 
= sizeof(MSIFILEHASHINFO);
        
return MsiGetFileHash(lpszFileName, dwOptions, &rMsiFileHashInfo);
    }

    inline UINT GetLastError(CString
& strErrorDescription)
    {
        strErrorDescription 
= TEXT("");
        MSIHANDLE hLastErrorRecord 
= MsiGetLastErrorRecord();
        CHK_EXP_RET(hLastErrorRecord 
== NULL , NO_ERROR);
        
        DWORD dwErrorLength 
= 4096;
        HandlerT
<> hRecord(hLastErrorRecord);
        UINT nCaller 
= MsiFormatRecord(NULL,hRecord,NULL,&dwErrorLength);
        
if(nCaller == ERROR_MORE_DATA)
        {
            dwErrorLength 
++;
            LPTSTR lpszError 
= new TCHAR[dwErrorLength];
            nCaller 
= MsiFormatRecord(NULL,hRecord,lpszError,&dwErrorLength);
            
if(nCaller == ERROR_SUCCESS) strErrorDescription = lpszError;
            delete [] lpszError;
        }
        
return nCaller;
    }

    inline UINT GetFileVersion(LPCTSTR szFilePath, CString
& strVersion, CString& strLanguage)
    {
        DWORD dwVersion 
= 32, dwLang = 32;
        LPTSTR lpszLang 
= strLanguage.GetBuffer(dwLang);
        LPTSTR lpszVersion 
= strVersion.GetBuffer(dwVersion);
        UINT nCaller 
= MsiGetFileVersion(szFilePath,lpszVersion, &dwVersion, lpszLang, &dwLang);
        
if(nCaller == ERROR_MORE_DATA)
        {
            
// 增加内存空间
            dwLang += 2; dwVersion += 2;
            strVersion.ReleaseBuffer(); lpszVersion 
= strVersion.GetBuffer(dwVersion);
            strLanguage.ReleaseBuffer(); lpszLang 
= strLanguage.GetBuffer(dwLang);
            nCaller 
= MsiGetFileVersion(szFilePath,lpszVersion, &dwVersion, lpszLang, &dwLang);
        }
        
else if(nCaller == ERROR_FILE_INVALID)
        {
            
// 文件没有版本信息
            nCaller = NO_ERROR;
        }

        strLanguage.ReleaseBuffer();
        strVersion.ReleaseBuffer();
        
return nCaller;
    }
}

转载于:https://www.cnblogs.com/WonKerr/archive/2009/03/20/WinFirewall.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值