VersionChecker类

//
// VersionChecker.h
//
// Copyright (c) Shareaza Development Team, 2002-2005.
// This file is part of SHAREAZA (
www.shareaza.com)
//
// Shareaza is free software; you can redistribute it
// and/or modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// Shareaza is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Shareaza; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//

#if !defined(AFX_VERSIONCHECKER_H__EB5F6233_9917_44C3_BE67_CACB43D929CA__INCLUDED_)
#define AFX_VERSIONCHECKER_H__EB5F6233_9917_44C3_BE67_CACB43D929CA__INCLUDED_

#pragma once

#include "HttpRequest.h"


class CVersionChecker 
{

// Construction

public:

 CVersionChecker();

 virtual ~CVersionChecker();
 
// Attributes

public:

 CString  m_sMessage;
 
 CString  m_sQuote;
 
 BOOL  m_bUpgrade;
 
 CString  m_sUpgradePrompt;
 
 CString  m_sUpgradeFile;
 
 CString  m_sUpgradeSHA1;
 
 CString  m_sUpgradeTiger;
 
 CString  m_sUpgradeSize;
 
 CString  m_sUpgradeSources;
 
 CString  m_sUpgradePath;
 
 CString  m_sUpgradeVersion;

protected:
 
 HANDLE    m_hThread;
 
 CHttpRequest  m_pRequest;
 
 CMapStringToString m_pResponse;
 
 HWND    m_hWndNotify;

// Operations

public:

 BOOL  NeedToCheck();

 BOOL  Start(HWND hWndNotify);

 void  Stop();

 void  SetNextCheck(int nDays);

 BOOL  CheckUpgradeHash(const SHA1* pHash, LPCTSTR pszPath);

protected:

 static UINT ThreadStart(LPVOID pParam);

 void  OnRun();

 void  BuildRequest(CString& strRequest);

 BOOL  UndertakeRequest(CString& strPost);

 void  ProcessResponse();

};

extern CVersionChecker VersionChecker;

#endif // !defined(AFX_VERSIONCHECKER_H__EB5F6233_9917_44C3_BE67_CACB43D929CA__INCLUDED_)

//
// VersionChecker.cpp
//
// Copyright (c) Shareaza Development Team, 2002-2005.
// This file is part of SHAREAZA (
www.shareaza.com)
//
// Shareaza is free software; you can redistribute it
// and/or modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// Shareaza is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Shareaza; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//

#include "StdAfx.h"
#include "Shareaza.h"
#include "Settings.h"
#include "VersionChecker.h"
#include "Transfer.h"
#include "Network.h"
#include "GProfile.h"
#include "DiscoveryServices.h"
#include "SHA.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

CVersionChecker VersionChecker;

//默认每隔七天升级一次

#define VERSIONCHECKER_FREQUENCY 7


//
// CVersionChecker construction

CVersionChecker::CVersionChecker()
{
 m_bUpgrade  = FALSE;

 m_hThread  = NULL;

 m_hWndNotify = NULL;
}

CVersionChecker::~CVersionChecker()
{
 Stop();
}

//
// CVersionChecker time check

/*

从注册表中读取出各个属性的值,填充到当前对象,

如果是用户手动升级,则将各个变量清空。

如果当前时间超过了下一次升级的时间,则需要升级,否则不需要升级

*/

BOOL CVersionChecker::NeedToCheck()
{
 m_sUpgradeVersion =
  theApp.GetProfileString( _T("VersionCheck"),
  _T("UpgradeVersion"), _T("") );

 DWORD nNextCheck = theApp.GetProfileInt( _T("VersionCheck"),
  _T("NextCheck"), 0 );

 if ( theApp.m_sVersion.Compare( m_sUpgradeVersion ) >= 0 ) // user manually upgraded
 {
  //用户手动升级,将各个变量清空,然后返回

  theApp.WriteProfileString( _T("VersionCheck"),
   _T("UpgradePrompt"), NULL );

  theApp.WriteProfileString( _T("VersionCheck"),
   _T("UpgradeFile"), NULL );

  theApp.WriteProfileString( _T("VersionCheck"),
   _T("UpgradeSHA1"), NULL );

  theApp.WriteProfileString( _T("VersionCheck"),
   _T("UpgradeTiger"), NULL);

  theApp.WriteProfileString( _T("VersionCheck"),
   _T("UpgradeSize"), NULL );

  theApp.WriteProfileString( _T("VersionCheck"),
   _T("UpgradeSources"), NULL );

  theApp.WriteProfileString( _T("VersionCheck"),
   _T("UpgradeVersion"), NULL );

  //如果当前时间超过了需要升级的时间,则需要升级,返回true

  return (DWORD)CTime::GetCurrentTime().GetTime() >= nNextCheck;
 }

 if ( !Settings.General.UpdateCheck )//没有设置,返回false
 {
  return FALSE;
 }

 //从注册表中读取出各个属性的值,填充到各个属性中
 
 m_sQuote = theApp.GetProfileString( _T("VersionCheck"),
  _T("Quote"), _T("") );
 
 m_sUpgradePrompt =
  theApp.GetProfileString( _T("VersionCheck"),
  _T("UpgradePrompt"), _T("") );

 m_sUpgradeFile  =
  theApp.GetProfileString( _T("VersionCheck"),
  _T("UpgradeFile"), _T("") );

 m_sUpgradeSHA1  =
  theApp.GetProfileString( _T("VersionCheck"),
  _T("UpgradeSHA1"), _T("") );

 m_sUpgradeTiger  =
  theApp.GetProfileString( _T("VersionCheck"),
  _T("UpgradeTiger"), _T("") );

 m_sUpgradeSize  =
  theApp.GetProfileString( _T("VersionCheck"),
  _T("UpgradeSize"), _T("") );

 m_sUpgradeSources =
  theApp.GetProfileString( _T("VersionCheck"),
  _T("UpgradeSources"), _T("") );

 m_bUpgrade   = ( m_sUpgradePrompt.GetLength() > 0 );
 
 //如果nNextCheck为0,则需要升级,如果为0XFFFFFFFF则不需要升级

 if ( ! nNextCheck )
 {
  return TRUE;
 }

 if ( nNextCheck == 0xFFFFFFFF )
 {
  return FALSE;
 }
 
 //如果当前时间超过了下一次升级的时间,则需要升级,否则不需要升级

 return (DWORD)CTime::GetCurrentTime().GetTime() >= nNextCheck;
}

//
// CVersionChecker start

BOOL CVersionChecker::Start(HWND hWndNotify)
{
 //首先停止原来的线程,取消http请求,然后开一个线程开始升级
 
 Stop();
 
 m_pRequest.Clear();

 //m_hWndNotify指向需要通知的窗口
 
 m_hWndNotify = hWndNotify;

 m_bUpgrade  = FALSE;

 //创建一个线程,启动之,开始升级过程
 
 CWinThread* pThread = AfxBeginThread( ThreadStart,
  this, THREAD_PRIORITY_IDLE );

 m_hThread = pThread->m_hThread;
 
 return TRUE;
}

//
// CVersionChecker stop

//首先取消httpRequest对象,然后关闭升级线程

void CVersionChecker::Stop()
{
 m_pRequest.Cancel();

 CHttpRequest::CloseThread( &m_hThread, _T("CVersionChecker") );
}

//
// CVersionChecker thread bootstrap

//执行OnRun函数完成升级过程

UINT CVersionChecker::ThreadStart(LPVOID pParam)
{
 CVersionChecker* pClass = (CVersionChecker*)pParam;

 pClass->OnRun();

 return 0;
}

//
// CVersionChecker thread run

void CVersionChecker::OnRun()
{
 CString strRequest;

 //加入version字符串
 
 BuildRequest( strRequest );

 //访问指定的URI,获得返回结果,并设置m_pResponse各项的内容
 
 BOOL bRequest = UndertakeRequest( strRequest );
 
 if ( bRequest ) // 成功了,调用PrcessResponse处理响应
 {
  //根据m_pResponse的内容写入注册表,同时向notify窗口发送VERSIONCHECK消息

  ProcessResponse();

  m_pResponse.RemoveAll(); // 检查结束了,释放m_pResponse占用的空间
 }
 else // 失败了,设置下一次升级的事件
 {
  SetNextCheck( VERSIONCHECKER_FREQUENCY );
 }
}

//
// CVersionChecker build request

//在参数strRequest的后面加入version=3.0字符串

void CVersionChecker::BuildRequest(CString& strRequest)
{
 strRequest += _T("Version=");

 strRequest += theApp.m_sVersion;
}

//
// CVersionChecker undertake request

/*

访问_T("http://update.trillinux.org/version/beta.php?") + strPost网址

然后根据返回的响应字符串设置m_pResponse的各项内容

*/

BOOL CVersionChecker::UndertakeRequest(CString& strPost)
{
 m_pRequest.SetURL( _T("
http://update.trillinux.org/version/beta.php?") + strPost );

 //Remember to set the update server for final releases.
 
 //连接到上面设置的uri地址

 if ( ! m_pRequest.Execute( FALSE ) )
 {
  return FALSE;
 }

 //检查返回状态
 
 int nStatusCode = m_pRequest.GetStatusCode();

 if ( nStatusCode < 200 || nStatusCode > 299 )//返回了错误码,则返回false
 {
  return FALSE;
 }

 //strResponse保存了返回的响应结果字符串
 
 CString strResponse = m_pRequest.GetResponseString();

 //如果VersionCheck下的TestResponse子键被设置了,则设置strResponse为strHack

 CString strHack = theApp.GetProfileString( _T("VersionCheck"),
  _T("TestResponse"), _T("") );

 if ( strHack.GetLength() )
 {
  strResponse = strHack;
 }
 
 //根据返回的响应字符串设置m_pResponse各个项的内容

 //reponse字符串的格式为“strkey=strItem&strkey1=strItem1”

 //为了保证最后一个也处理,首先给strResponse加上一个&结尾

 for ( strResponse += '&' ; strResponse.GetLength() ; )
 {
  //首先按照&切割字符串

  CString strItem = strResponse.SpanExcluding( _T("&") );

  strResponse  = strResponse.Mid( strItem.GetLength() + 1 );
  
  CString strKey = strItem.SpanExcluding( _T("=") );

  if ( strKey.GetLength() == strItem.GetLength() )
  {
   continue;
  }

  //strItem是&后面的部分,调用CTransfer的URLDecode完成解码

  strItem = CTransfer::URLDecode( strItem.Mid( strKey.GetLength() + 1 ) );

  strItem.TrimLeft();

  strItem.TrimRight();
  
  m_pResponse.SetAt( strKey, strItem );
 }
 
 return TRUE;
}

//
// CVersionChecker process response

//根据reponse各项的内容来设置各项属性的值,并更新注册表,最后向notify窗口发送

//versioncheck消息

void CVersionChecker::ProcessResponse()
{
 int nDays = VERSIONCHECKER_FREQUENCY;

 CString strValue;

 //如果m_pResponse中有Message或者MessageBox字符串,则设置m_sMessage

 //为Response中字符串对应的CString值
 
 if ( m_pResponse.Lookup( _T("Message"), strValue )
  || m_pResponse.Lookup( _T("MessageBox"), strValue ) )
 {
  m_sMessage = strValue;
 }

 //如果response中有quote,则设置m_sQuote为对应的值,同时写入

 //注册表VersionCheck下的Quote子键
 
 if ( m_pResponse.Lookup( _T("Quote"), strValue ) )
 {
  m_sQuote = strValue;

  theApp.WriteProfileString( _T("VersionCheck"),
   _T("Quote"), m_sQuote );
 }
 
 //Response中有SystemMsg,则执行之

 if ( m_pResponse.Lookup( _T("SystemMsg"), strValue ) )
 {
  //各个系统消息使用/r/n来分隔,依次调用app类的Message方法

  for ( strValue += '/n' ; strValue.GetLength() ; )
  {
   CString strLine = strValue.SpanExcluding( _T("/r/n") );

   strValue  = strValue.Mid( strLine.GetLength() + 1 );

   if ( strLine.GetLength() )
   {
    theApp.Message( MSG_SYSTEM, strLine );
   }
  }
 }

 //response中有upgradeprompt属性,则将各个相关项的value
 
 //保存到各个属性中,同时将新的属性值写入注册表
 
 if ( m_pResponse.Lookup( _T("UpgradePrompt"), strValue ) )
 {
  m_sUpgradePrompt = strValue;
  
  m_pResponse.Lookup( _T("UpgradeFile"), m_sUpgradeFile );

  m_pResponse.Lookup( _T("UpgradeSHA1"), m_sUpgradeSHA1 );

  m_pResponse.Lookup( _T("UpgradeTiger"), m_sUpgradeTiger );

  m_pResponse.Lookup( _T("UpgradeSize"), m_sUpgradeSize );

  m_pResponse.Lookup( _T("UpgradeSources"), m_sUpgradeSources );

  m_pResponse.Lookup( _T("UpgradeVersion"), m_sUpgradeVersion );

  // Old name

  if ( ! m_sUpgradeSHA1.GetLength() )
  {
   m_pResponse.Lookup( _T("UpgradeHash"), m_sUpgradeSHA1 );
  }
  
  theApp.WriteProfileString( _T("VersionCheck"),
   _T("UpgradePrompt"), m_sUpgradePrompt );

  theApp.WriteProfileString( _T("VersionCheck"),
   _T("UpgradeFile"), m_sUpgradeFile );

  theApp.WriteProfileString( _T("VersionCheck"),
   _T("UpgradeSHA1"), m_sUpgradeSHA1 );

  theApp.WriteProfileString( _T("VersionCheck"),
   _T("UpgradeTiger"), m_sUpgradeTiger);

  theApp.WriteProfileString( _T("VersionCheck"),
   _T("UpgradeSize"), m_sUpgradeSize );

  theApp.WriteProfileString( _T("VersionCheck"),
   _T("UpgradeSources"), m_sUpgradeSources );

  theApp.WriteProfileString( _T("VersionCheck"),
   _T("UpgradeVersion"), m_sUpgradeVersion );
  
  m_bUpgrade = TRUE; // 升级成功了
 }
 else // 没有,则写入空值,没有升级成功
 {
  theApp.WriteProfileString( _T("VersionCheck"),
   _T("UpgradePrompt"), _T("") );
  
  m_bUpgrade = FALSE;
 }

 //如果设置了adddiscovery,则在DiscoveryServices中
 
 //作为dsWebCache加入新的strValue
 
 if ( m_pResponse.Lookup( _T("AddDiscovery"), strValue ) )
 {
  strValue.TrimLeft();

  strValue.TrimRight();

  DiscoveryServices.Add( strValue, CDiscoveryService::dsWebCache );
 }

 //如果response连下一次升级所隔的天数也设置了,则写入天数nDays
 
 if ( m_pResponse.Lookup( _T("NextCheck"), strValue ) )
 {
  _stscanf( strValue, _T("%lu"), &nDays );
 }

 //根据天数算出下一次升级的时间,并写入注册表
 
 SetNextCheck( nDays );

 //向m_hWndNotify窗口发送WM_VERSIONCHECK消息,升级完毕了
 
 PostMessage( m_hWndNotify, WM_VERSIONCHECK, 0, 0 );
}

//
// CVersionChecker NextCheck update

//设定下一次升级时的时间,写入注册表VersionCheck 的NextCheck子键下。

void CVersionChecker::SetNextCheck(int nDays)
{
 //在nDays天后再次升级

 CTimeSpan tPeriod( nDays, 0, 0, 0 );

 //再次升级的时间,tNextCheck.GetTime()返回一个_time_64_t,转化为DWORD

 CTime tNextCheck = CTime::GetCurrentTime() + tPeriod;

 theApp.WriteProfileInt( _T("VersionCheck"),
  _T("NextCheck"), (DWORD)tNextCheck.GetTime() );
}

//
// CVersionChecker check if a download is an upgrade

BOOL CVersionChecker::CheckUpgradeHash(const SHA1* pHash, LPCTSTR pszPath)
{
 if ( ! m_bUpgrade ) // upgrade为false,直接返回
 {
  return FALSE;
 }

 //将参数pHash转化为字符串后和m_sUpgradeSHA1 不一样,返回false

 if ( CSHA::HashToString( pHash ) != m_sUpgradeSHA1 )
 {
  return FALSE;
 }

 //参数pszPath不是exe文件,返回false

 if ( _tcsstr( pszPath, _T(".exe") ) == NULL )
 {
  return FALSE;
 }

 //pszPath是exe文件,将m_sUpgradePath设置为参数pszPath

 m_sUpgradePath = pszPath;

 //向主窗口发送WM_VERSIONCHECK消息

 AfxGetMainWnd()->PostMessage( WM_VERSIONCHECK, 2 );

 return TRUE;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值