bool CGameUpdate::StartUpdate(DWORD gid, LPCWSTR tid, LPCWSTR src, LPCWSTR dst, DWORD flag, LPCSTR svrip, LPCSTR cliip, DWORD maxspeed, DWORD type)
{
	StopUpdate();
    ZeroMemory(&m_UpdateStuats, sizeof(m_UpdateStuats));
    m_UpdateStuats.cbSize = sizeof(m_UpdateStuats);

	m_dwGid = gid;
	m_dwUptType = type;
	if(tid!= NULL && wcslen(tid) < MAX_GUID_LEN)
	{
		_tcscpy_s(m_szTid, CW2T(tid));
	}
	
	if (maxspeed)
		//m_dwMaxSpeed = (maxspeed < 1000) ? 640 : ((maxspeed - 200) * 1000);
    {
        if (maxspeed * .2 < 200)
        {
            m_dwMaxSpeed = max(DWORD(maxspeed * .8)  * 1024, 640);
        }
        else
        {
            m_dwMaxSpeed = (maxspeed - 200)  * 1024;
        }
    }

	//check parameter
	if (src == NULL || dst == NULL || wcslen(src) < 2 || wcslen(dst) < 2 ||
		src[1] != L':' || src[2] != L'\\' || 
		dst[1] != L':' || dst[2] != L'\\')
	{
		SetErrorInfo(UPT_ERR_DIRNOTOK, src, dst);
		return false;
	}

	//save parameter.
	m_strSvrPath = src;	m_strCliPath = dst;	
	if (svrip != NULL)	m_strSvrIp = svrip; 
	if (cliip != NULL)	m_strCliIp = cliip; 
	m_dwUptFlag  = flag;
	if (*m_strSvrPath.rbegin() != L'\\')
		m_strSvrPath += L"\\";
	if (*m_strCliPath.rbegin() != L'\\')
		m_strCliPath += L"\\";

	//convert and create directory.
	if (!hy_LoadVirtualDevice(m_strCliPath[0]))
	{
		SetErrorInfo(UPT_ERR_LOADDEVICE);
		return false;
	}
	m_strDevPath = hy_ConvertPath(m_strCliPath);
	if (!hy_CreateDirectory(m_strCliPath) || !hy_CreateDirectory(m_strDevPath))
	{
		SetErrorInfo(UPT_ERR_CREATEDIR, m_strCliPath.c_str());
		return false;
	}

	//create update work thread.
	m_hExited = CreateEvent(NULL, TRUE, FALSE, NULL);
	if (m_hExited == NULL)
	{
		SetErrorInfo(UPT_ERR_INNERERR, GetLastError());
		return false;
	}

	// 暂停事件
	if( !m_eventRun.Create(0, TRUE, TRUE) )
	{
		SetErrorInfo(UPT_ERR_INNERERR, GetLastError());
		return false;
	}

	m_pipe  = new PCMomule<tagIdxBlock*>(m_hExited);
	m_pipe2 = new PCMomule<tagIdxBlock*>(m_hExited);
	m_hThread = (HANDLE)_beginthreadex(NULL, 0, WorkThread, this, 0, NULL);
	if (m_hThread == NULL)
	{
		SetErrorInfo(UPT_ERR_INNERERR, GetLastError());
		StopUpdate();
		return false;
	}

	return true;
}
std::wstring TrimEnd(std::wstring s)
{
	s.erase(std::find_if(s.rbegin(), s.rend(),
		std::not1(std::ptr_fun<int, int>(std::isspace))).base(), s.end());
	return s;
}