Index: /branches/rel_ag_9_4_5/windows/ArrClean/Manager.cpp
===================================================================
--- /branches/rel_ag_9_4_5/windows/ArrClean/Manager.cpp	(revision 20638)
+++ /branches/rel_ag_9_4_5/windows/ArrClean/Manager.cpp	(working copy)
@@ -1,1891 +1,1900 @@
-#include "stdafx.h"
-#include "Manager.h"
-#include <strsafe.h>
-#include <cfgmgr32.h>
-#include <SetupAPI.h>
-#include "..\utilitylib\System.h"
-#include "..\utilitylib\AdapterUtils.h"
-
-CString g_cStrInf = L""; 
-
-void CManager::run()
-{
-	Log(LOG_INFO, ("Uninstall: start uninstall vpn client components...\n"));
-	m_bNeedReboot = false;
-	BOOL bResult = TRUE;
-
-	for(int i=0;i<MAX_NULBER_LIST;i++)
-	{
-		m_pProgressCtrl->SetPos((i*100)/MAX_NULBER_LIST);
-		if(m_pUIList[i].pctrlCheckbox->GetCheck() == BST_CHECKED)
-		{
-			ShowCheckImage(i);
-			bResult = m_pUIList[i].pCleanFunc->run();
-			if(!bResult)
-			{
-				ShowResultImage(i);
-			}
-			::SendMessage(m_hwMainWindow, WM_UPDATE_MSG, i, (int)bResult);
-		}
-
-		if (m_pUIList[0].pctrlCheckbox->GetCheck() == BST_CHECKED || m_pUIList[1].pctrlCheckbox->GetCheck() == BST_CHECKED)
-		{
-			m_bNeedReboot = true;
-		}
-	}
-	
-	m_pProgressCtrl->SetPos(100);
-	::SendMessage(m_hwMainWindow, WM_UPDATE_MSG, 100, 100);
-}
-
-bool CTDIFunc::run()
-{
-	Log(LOG_INFO, (L"CTDIFunc: Start to Uninstall TDI component\n"));
-	SetInstallStatus(SSLVPN_COMPONENT_CLSID, aisUninstallingTDI);
-	if(!UninstallTDIDriver())
-	{
-		Log(LOG_WARNING, (L"UninstallTDIDriver: failed\n"));
-		return false;
-	}
-	Log(LOG_INFO, (L"CTDIFunc: Uninstall TDI component success\n"));
-	return true;
-}
-
-bool CTDIFunc::UninstallTDIDriver()
-{
-	bool bRet = false;
-	do
-	{
-		SC_HANDLE sch, service;
-		DWORD tags[100], n, type, i, service_tag;
-		char buf[2048];
-		HKEY reg_key;
-		QUERY_SERVICE_CONFIG *cfg = (QUERY_SERVICE_CONFIG *)buf;
-		int status;
-
-		bRet = true;
-
-		sch = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
-		if (sch == NULL) 
-		{
-			Log(LOG_ERROR, (L"UninstallTDIDriver: OpenSCManager: %d\n", GetLastError()));
-			bRet = false;
-			break;
-		}
-
-		// get tag for driver
-
-		service = OpenService(sch, TDI_DRIVER_NAME, SERVICE_ALL_ACCESS);
-		if (service == NULL) 
-		{
-			Log(LOG_ERROR, (L"UninstallTDIDriver: OpenService: %d\n", GetLastError()));
-			break;
-		}
-
-		if (QueryServiceConfig(service, cfg, sizeof(buf), &n)) 
-		{
-			service_tag = cfg->dwTagId;
-
-			// remove tag from registry
-			status = RegOpenKey(HKEY_LOCAL_MACHINE,
-				L"SYSTEM\\CurrentControlSet\\Control\\GroupOrderList", &reg_key);
-			if (status != ERROR_SUCCESS) 
-			{
-				Log(LOG_ERROR, (L"UninstallTDIDriver: RegOpenKey: %d\n", status));
-				break;
-			}
-
-			n = sizeof(tags);
-			status = RegQueryValueEx(reg_key, TDI_DRIVER_GROUP, NULL, &type, (LPBYTE)tags, &n);
-			if (status != ERROR_SUCCESS) 
-			{
-				Log(LOG_ERROR, (L"UninstallTDIDriver: RegQueryValueEx: %d\n", status));
-				break;
-			}
-
-			n /= sizeof(DWORD);
-
-			for (i = 1; i < n; i++)
-				if (tags[i] == service_tag) 
-				{
-					memmove(&tags[i], &tags[i + 1], (n - i - 1) * sizeof(DWORD));
-					n--;
-					break;
-				}
-
-				tags[0] = n - 1;
-
-				status = RegSetValueEx(reg_key, TDI_DRIVER_GROUP, 0, type, (LPBYTE)tags, n * sizeof(DWORD));
-				if (status != ERROR_SUCCESS) 
-				{
-					Log(LOG_ERROR, (L"UninstallTDIDriver: RegSetValueEx: %d\n", status));
-					break;
-				}
-
-				RegCloseKey(reg_key);
-		}
-		else
-		{
-			Log(LOG_ERROR, (L"UninstallTDIDriver: QueryServiceConfig(tcpip): %d\n", GetLastError()));
-		}
-
-		//delete the sys file
-		wchar_t SystemDir[MAX_PATH] = {'\0'};
-		GetSystemDirectory(SystemDir, MAX_PATH);
-		if(Is64bitOS())
-		{
-			StringCchCat(SystemDir, sizeof(SystemDir)/sizeof(char), TDI_DRIVER_BINARY_X64);
-		}
-		else
-		{
-			StringCchCat(SystemDir, sizeof(SystemDir)/sizeof(char), TDI_DRIVER_BINARY);
-		}
-
-		if( !DeleteFile( SystemDir ) )
-		{
-			//we should never go here
-			Log(LOG_ERROR, (L"UninstallTDIDriver: Delete tdi driver files from system32\\drivers failed, check this and delete it if need\n"));
-		}
-
-
-		if (!DeleteService(service)) 
-		{
-			if (GetLastError() != ERROR_SERVICE_MARKED_FOR_DELETE) 
-			{
-				Log(LOG_ERROR, (L"UninstallTDIDriver: DeleteService: %d\n", GetLastError()));
-				bRet = false;
-				break;
-			}
-			Log(LOG_ERROR, (L"UninstallTDIDriver: Restart Windows to changes has effect\n"));
-		}
-
-		CloseServiceHandle(service);
-		CloseServiceHandle(sch);
-
-		Log(LOG_INFO, (L"UninstallTDIDriver: uninstall tdi successfully\n"));
-	}while(0);
-	return bRet;
-}
-
-bool CVNICFunc::run()
-{
-	SetInstallStatus(SSLVPN_COMPONENT_CLSID, aisUninstallingVNIC);
-	int iRet = CFG_FAILURE;
-
-	iRet =  fnRemove_ByInf();
-
-
-	Log(LOG_INFO, (L"UninstallAdapter: finished, iRet is %d\n", iRet));
-	if(iRet == CFG_EXIT_OK)
-	{
-		return true;
-	}
-	else if(iRet == CFG_EXIT_REBOOT)
-	{
-		Log(LOG_INFO, (L"Need to reboot windows\n"));
-	}
-	else if(iRet == CFG_FAILURE)
-	{
-		Log(LOG_WARNING, (L"L3VPN adapter failed remove, please remove it from System Device Management\n"));
-		return false;
-	}
-	return true;
-}
-
-unsigned int WINAPI ThreadUninstallDevice(void *pValue)
-{
-	wchar_t szRegPath[MAX_PATH] = {'\0'};
-	_stprintf_s(szRegPath, MAX_PATH, L"%s\\%s", AIM_REG_PATH, SSLVPN_COMPONENT_CLSID);
-
-	DWORD dwValue = VNIC_RUNNING;
-	SHSetValue(HKEY_LOCAL_MACHINE, szRegPath, VNIC_UNINSTALL_STATUS, REG_DWORD, &dwValue, sizeof(dwValue));
-
-	LPCTSTR INFFile = g_cStrInf;
-	Log(LOG_INFO, (L"VPN Installer : enter UninstallDevice in another thread, inf is %s\n", INFFile));
-	TCHAR devID[MAX_DEVICE_ID_LEN] = {'\0'};
-	if(EnumInstalledDevice(devID, MAX_DEVICE_ID_LEN))
-	{
-		fnDisable(devID);
-	}
-
-	HDEVINFO			DeviceInfoSet;
-	SP_DEVINFO_DATA		DeviceInfoData;
-	GUID				ClassGUID;
-	TCHAR				ClassName[MAX_CLASS_NAME_LEN] = {0};
-	wchar_t				HardwareID[MAX_PATH] = {0};
-	DWORD				i;
-	BOOLEAN				ReturnValue = TRUE;
-
-	//Get Device ID from the inf file.
-	if(GetDeviceandClassID((LPTSTR)INFFile, HardwareID, NULL) == FALSE)
-	{
-		Log(LOG_ERROR, (L"VPN Installer: GetDeviceandClassID failed. INFFile: %s\n", INFFile));
-	}
-	// Use the INF File to extract the Class GUID. 
-	if (!SetupDiGetINFClass(INFFile,&ClassGUID,ClassName,sizeof(ClassName),0))
-	{
-		Log(LOG_ERROR, (L"in UninstallDevice,can not get device class from the INF file,check INF file.\n"));
-	}    
-	// Create a Device Information Set with all present devices.
-	DeviceInfoSet = SetupDiGetClassDevs(&ClassGUID, 0,0,0);
-	if (DeviceInfoSet == INVALID_HANDLE_VALUE)
-	{
-		Log(LOG_ERROR, (L"in UninstallDevice,Can not create Device List.\n"));
-		return FALSE;
-	}
-	// Enumerate device with DeviceID through the  Devices List.
-	DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
-	for (i=0;SetupDiEnumDeviceInfo(DeviceInfoSet,i,&DeviceInfoData);i++)
-	{
-		DWORD DataT;
-		wchar_t*	p;
-		wchar_t    buffer[MAX_PATH*2] = { 0 };
-		DWORD	buffersize = MAX_PATH*2;
-
-		// We won't know the size of the HardwareID buffer until we call
-		// this function. So call it with a null to begin with, and then 
-		// use the required buffer size to Alloc the nessicary space.
-		// Keep calling we have success or an unknown failure.
-		if (!SetupDiGetDeviceRegistryProperty(DeviceInfoSet,
-			&DeviceInfoData,
-			SPDRP_HARDWAREID,
-			&DataT,
-			(PBYTE)buffer,
-			buffersize,
-			&buffersize))
-		{
-			Log(LOG_INFO, (L"VPN Installer : in UninstallDevice, Get device description register property fail.\n"));
-			continue;       
-		}
-
-		// Compare each entry in the buffer multi-sz list with our HardwareID.
-		for (p=buffer;*p&&(p<&buffer[buffersize]);p+=lstrlen((LPCWSTR)p)+sizeof(TCHAR))
-		{
-			Log(LOG_INFO,(L"Compare device ID:[%s] -- [%s]\n", HardwareID, p));
-			if (!_tcscmp(HardwareID,(const wchar_t*)p))
-			{
-				// Worker function to remove device.
-				Log(LOG_INFO,("uninstall adapter: Worker function to remove device."));
-				ReturnValue=SetupDiCallClassInstaller(DIF_REMOVE,
-					DeviceInfoSet,
-					&DeviceInfoData);
-				if(!ReturnValue)
-				{
-					Log(LOG_WARNING, (L"VPN Installer: in UninstallDevice,Can not remove the Device List..\n"));
-				}
-				break;
-			}
-		}
-	}
-
-	//  Cleanup.
-	DeleteEnumDevice();
-	ClearVNICRegister_NetworkConnection();
-	ClearVNICRegister_EnumDevice();
-	SetupDiDestroyDeviceInfoList(DeviceInfoSet);
-	//DeleteDriverServices();
-	ClearATPRegistry();
-
-	dwValue = (DWORD)ReturnValue;
-	SHSetValue(HKEY_LOCAL_MACHINE, szRegPath, VNIC_UNINSTALL_RETURNVALUE, REG_DWORD, &dwValue, sizeof(dwValue));
-
-	dwValue = VNIC_FINISHED;
-	SHSetValue(HKEY_LOCAL_MACHINE, szRegPath, VNIC_UNINSTALL_STATUS, REG_DWORD, &dwValue, sizeof(dwValue));
-	return TRUE;
-}
-
-int CVNICFunc::fnRemove_ByInf()
-{
-	Log(LOG_INFO, (L"VPN Installer: begin to un-install.\n"));
-	DWORD dwSize = 0;
-	wchar_t  INFFile[MAX_PATH]={ '\0' },TempPath[MAX_PATH]={ '\0' }, TargetInf[MAX_PATH]={ '\0' }, SrcPath[MAX_PATH] = { '\0' };
-
-	GetApplicationDirectory(SrcPath);
-	_tcscat(SrcPath, L"\\");
-
-	GetTempPath(MAX_PATH,TempPath);	
-	_tcscat_s(TempPath, VPN_DEFAULT_FOLDER_NAME);
-	_tcscat_s(TempPath, L"\\");
-	SHPathPrepareForWrite(NULL, NULL, TempPath, SHPPFW_DIRCREATE);
-
-	RepairRegInstaller();
-
-	int iVersion = GetWindowVersion();
-	DWORD dwProcessType = GetProcessorArchitectureFlag();
-
-	if(iVersion == WINDOWS_VERSION_VISTA)
-	{
-		if(dwProcessType == PROCESSOR_TYPE_AMD64)
-		{
-			_stprintf_s(INFFile,L"%s%s", SrcPath, ARR_INF_VISTA_X64_NAME);
-			_stprintf_s(TargetInf,L"%s%s", TempPath, ARR_INF_VISTA_X64_NAME);
-		}
-		else
-		{
-			_stprintf_s(INFFile,L"%s%s", SrcPath, ARR_INF_VISTA_NAME);
-			_stprintf_s(TargetInf,L"%s%s", TempPath, ARR_INF_VISTA_NAME);
-		}
-	}
-	else if(iVersion == WINDOWS_VERSION_2003)
-	{
-		if(dwProcessType == PROCESSOR_TYPE_AMD64)
-		{
-			_stprintf_s(INFFile,L"%s%s", SrcPath, ARR_INF_WIN2003_X64_NAME);
-			_stprintf_s(TargetInf,L"%s%s", TempPath, ARR_INF_WIN2003_X64_NAME);
-		}
-		else
-		{
-			_stprintf_s(INFFile,L"%s%s", SrcPath, ARR_INF_WIN2003_NAME);
-			_stprintf_s(TargetInf,L"%s%s", TempPath, ARR_INF_WIN2003_NAME);
-		}
-	}
-	else if(iVersion == WINDOWS_VERSION_2008)
-	{
-		if(dwProcessType == PROCESSOR_TYPE_AMD64)
-		{
-			_stprintf_s(INFFile,L"%s%s", SrcPath, ARR_INF_WIN2008_X64_NAME);
-			_stprintf_s(TargetInf,L"%s%s", TempPath, ARR_INF_WIN2008_X64_NAME);
-		}
-		else
-		{
-			_stprintf_s(INFFile,L"%s%s", SrcPath, ARR_INF_WIN2008_NAME);
-			_stprintf_s(TargetInf,L"%s%s", TempPath, ARR_INF_WIN2008_NAME);
-		}
-	}
-	else if(iVersion >= WINDOWS_VERSION_7)
-	{
-		if(dwProcessType == PROCESSOR_TYPE_AMD64)
-		{
-			_stprintf_s(INFFile,L"%s%s", SrcPath, ARR_INF_WIN7_X64_NAME);
-			_stprintf_s(TargetInf,L"%s%s", TempPath, ARR_INF_WIN7_X64_NAME);
-		}
-		else
-		{
-			_stprintf_s(INFFile,L"%s%s", SrcPath, ARR_INF_WIN7_NAME);
-			_stprintf_s(TargetInf,L"%s%s", TempPath, ARR_INF_WIN7_NAME);
-		}
-	}
-	else
-	{
-		_stprintf_s(INFFile,L"%s%s", SrcPath, ARR_INF_NAME);
-		_stprintf_s(TargetInf,L"%s%s", TempPath,  ARR_INF_NAME);
-	}
-
-	if(CopyFile(INFFile,TargetInf,FALSE) == 0)//copy this inf file file,no matter it has exist.
-	{
-		Log(LOG_INFO, (L"fnRemove_ByInf: Copy file from %s to %s failed, error is %d\n", INFFile, TargetInf, GetLastError()));
-	}
-	else
-	{
-		Log(LOG_INFO, (L"fnRemove_ByInf: Copy file success.\n"));
-	}
-
-	Log(LOG_INFO, (L"fnRemove_ByInf : get INF path: %s\n", TargetInf));
-
-	if(!PathFileExists(TargetInf))
-	{
-		Log(LOG_WARNING, (L"File %s is not exist\n", TargetInf));
-		memset(TargetInf, 0, MAX_PATH);
-		_stprintf_s(TargetInf, L"%s", SrcPath);
-	}
-
-	if(!PathFileExists(TargetInf))
-	{
-		Log(LOG_ERROR, (L"Can not find inf path, we don't remove L3VPN Adapter\n"));
-		return  fnRemove_ByDevID(VNIC_DEV_ID);;
-	}
-
-	if(UninstallDevice(TargetInf))
-	{
-		return CFG_EXIT_OK;
-	}
-	else
-	{
-		return CFG_FAILURE;
-	}
-}
-
-void CVNICFunc::RepairRegInstaller()
-{
+﻿#include "stdafx.h"
+#include "Manager.h"
+#include <strsafe.h>
+#include <cfgmgr32.h>
+#include <SetupAPI.h>
+#include "..\utilitylib\System.h"
+#include "..\utilitylib\AdapterUtils.h"
+
+CString g_cStrInf = L""; 
+
+void CManager::run()
+{
+	Log(LOG_INFO, ("Uninstall: start uninstall vpn client components...\n"));
+	m_bNeedReboot = false;
+	BOOL bResult = TRUE;
+
+	for(int i=0;i<MAX_NULBER_LIST;i++)
+	{
+		m_pProgressCtrl->SetPos((i*100)/MAX_NULBER_LIST);
+		if(m_pUIList[i].pctrlCheckbox->GetCheck() == BST_CHECKED)
+		{
+			ShowCheckImage(i);
+			bResult = m_pUIList[i].pCleanFunc->run();
+			if(!bResult)
+			{
+				ShowResultImage(i);
+			}
+			::SendMessage(m_hwMainWindow, WM_UPDATE_MSG, i, (int)bResult);
+		}
+
+		if (m_pUIList[0].pctrlCheckbox->GetCheck() == BST_CHECKED || m_pUIList[1].pctrlCheckbox->GetCheck() == BST_CHECKED)
+		{
+			m_bNeedReboot = true;
+		}
+	}
+	
+	m_pProgressCtrl->SetPos(100);
+	::SendMessage(m_hwMainWindow, WM_UPDATE_MSG, 100, 100);
+}
+
+bool CTDIFunc::run()
+{
+	Log(LOG_INFO, (L"CTDIFunc: Start to Uninstall TDI component\n"));
+	SetInstallStatus(SSLVPN_COMPONENT_CLSID, aisUninstallingTDI);
+	if(!UninstallTDIDriver())
+	{
+		Log(LOG_WARNING, (L"UninstallTDIDriver: failed\n"));
+		return false;
+	}
+	Log(LOG_INFO, (L"CTDIFunc: Uninstall TDI component success\n"));
+	return true;
+}
+
+bool CTDIFunc::UninstallTDIDriver()
+{
+	bool bRet = false;
+	do
+	{
+		SC_HANDLE sch, service;
+		DWORD tags[100], n, type, i, service_tag;
+		char buf[2048];
+		HKEY reg_key;
+		QUERY_SERVICE_CONFIG *cfg = (QUERY_SERVICE_CONFIG *)buf;
+		int status;
+
+		bRet = true;
+
+		sch = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
+		if (sch == NULL) 
+		{
+			Log(LOG_ERROR, (L"UninstallTDIDriver: OpenSCManager: %d\n", GetLastError()));
+			bRet = false;
+			break;
+		}
+
+		// get tag for driver
+
+		service = OpenService(sch, TDI_DRIVER_NAME, SERVICE_ALL_ACCESS);
+		if (service == NULL) 
+		{
+			Log(LOG_ERROR, (L"UninstallTDIDriver: OpenService: %d\n", GetLastError()));
+			break;
+		}
+
+		if (QueryServiceConfig(service, cfg, sizeof(buf), &n)) 
+		{
+			service_tag = cfg->dwTagId;
+
+			// remove tag from registry
+			status = RegOpenKey(HKEY_LOCAL_MACHINE,
+				L"SYSTEM\\CurrentControlSet\\Control\\GroupOrderList", &reg_key);
+			if (status != ERROR_SUCCESS) 
+			{
+				Log(LOG_ERROR, (L"UninstallTDIDriver: RegOpenKey: %d\n", status));
+				break;
+			}
+
+			n = sizeof(tags);
+			status = RegQueryValueEx(reg_key, TDI_DRIVER_GROUP, NULL, &type, (LPBYTE)tags, &n);
+			if (status != ERROR_SUCCESS) 
+			{
+				Log(LOG_ERROR, (L"UninstallTDIDriver: RegQueryValueEx: %d\n", status));
+				break;
+			}
+
+			n /= sizeof(DWORD);
+
+			for (i = 1; i < n; i++)
+				if (tags[i] == service_tag) 
+				{
+					memmove(&tags[i], &tags[i + 1], (n - i - 1) * sizeof(DWORD));
+					n--;
+					break;
+				}
+
+				tags[0] = n - 1;
+
+				status = RegSetValueEx(reg_key, TDI_DRIVER_GROUP, 0, type, (LPBYTE)tags, n * sizeof(DWORD));
+				if (status != ERROR_SUCCESS) 
+				{
+					Log(LOG_ERROR, (L"UninstallTDIDriver: RegSetValueEx: %d\n", status));
+					break;
+				}
+
+				RegCloseKey(reg_key);
+		}
+		else
+		{
+			Log(LOG_ERROR, (L"UninstallTDIDriver: QueryServiceConfig(tcpip): %d\n", GetLastError()));
+		}
+
+		//delete the sys file
+		wchar_t SystemDir[MAX_PATH] = {'\0'};
+		GetSystemDirectory(SystemDir, MAX_PATH);
+		if(Is64bitOS())
+		{
+			StringCchCat(SystemDir, sizeof(SystemDir)/sizeof(char), TDI_DRIVER_BINARY_X64);
+		}
+		else
+		{
+			StringCchCat(SystemDir, sizeof(SystemDir)/sizeof(char), TDI_DRIVER_BINARY);
+		}
+
+		if( !DeleteFile( SystemDir ) )
+		{
+			//we should never go here
+			Log(LOG_ERROR, (L"UninstallTDIDriver: Delete tdi driver files from system32\\drivers failed, check this and delete it if need\n"));
+		}
+
+
+		if (!DeleteService(service)) 
+		{
+			if (GetLastError() != ERROR_SERVICE_MARKED_FOR_DELETE) 
+			{
+				Log(LOG_ERROR, (L"UninstallTDIDriver: DeleteService: %d\n", GetLastError()));
+				bRet = false;
+				break;
+			}
+			Log(LOG_ERROR, (L"UninstallTDIDriver: Restart Windows to changes has effect\n"));
+		}
+
+		CloseServiceHandle(service);
+		CloseServiceHandle(sch);
+
+		Log(LOG_INFO, (L"UninstallTDIDriver: uninstall tdi successfully\n"));
+	}while(0);
+	return bRet;
+}
+
+bool CVNICFunc::run()
+{
+	SetInstallStatus(SSLVPN_COMPONENT_CLSID, aisUninstallingVNIC);
+	int iRet = CFG_FAILURE;
+
+	iRet =  fnRemove_ByInf();
+
+
+	Log(LOG_INFO, (L"UninstallAdapter: finished, iRet is %d\n", iRet));
+	if(iRet == CFG_EXIT_OK)
+	{
+		return true;
+	}
+	else if(iRet == CFG_EXIT_REBOOT)
+	{
+		Log(LOG_INFO, (L"Need to reboot windows\n"));
+	}
+	else if(iRet == CFG_FAILURE)
+	{
+		Log(LOG_WARNING, (L"L3VPN adapter failed remove, please remove it from System Device Management\n"));
+		return false;
+	}
+	return true;
+}
+
+unsigned int WINAPI ThreadUninstallDevice(void *pValue)
+{
+	wchar_t szRegPath[MAX_PATH] = {'\0'};
+	_stprintf_s(szRegPath, MAX_PATH, L"%s\\%s", AIM_REG_PATH, SSLVPN_COMPONENT_CLSID);
+
+	DWORD dwValue = VNIC_RUNNING;
+	SHSetValue(HKEY_LOCAL_MACHINE, szRegPath, VNIC_UNINSTALL_STATUS, REG_DWORD, &dwValue, sizeof(dwValue));
+
+	LPCTSTR INFFile = g_cStrInf;
+	Log(LOG_INFO, (L"VPN Installer : enter UninstallDevice in another thread, inf is %s\n", INFFile));
+	TCHAR devID[MAX_DEVICE_ID_LEN] = {'\0'};
+	if(EnumInstalledDevice(devID, MAX_DEVICE_ID_LEN))
+	{
+		fnDisable(devID);
+	}
+
+	HDEVINFO			DeviceInfoSet;
+	SP_DEVINFO_DATA		DeviceInfoData;
+	GUID				ClassGUID;
+	TCHAR				ClassName[MAX_CLASS_NAME_LEN] = {0};
+	wchar_t				HardwareID[MAX_PATH] = {0};
+	DWORD				i;
+	BOOLEAN				ReturnValue = TRUE;
+
+	//Get Device ID from the inf file.
+	if(GetDeviceandClassID((LPTSTR)INFFile, HardwareID, NULL) == FALSE)
+	{
+		Log(LOG_ERROR, (L"VPN Installer: GetDeviceandClassID failed. INFFile: %s\n", INFFile));
+	}
+	// Use the INF File to extract the Class GUID. 
+	if (!SetupDiGetINFClass(INFFile,&ClassGUID,ClassName,sizeof(ClassName),0))
+	{
+		Log(LOG_ERROR, (L"in UninstallDevice,can not get device class from the INF file,check INF file.\n"));
+	}    
+	// Create a Device Information Set with all present devices.
+	DeviceInfoSet = SetupDiGetClassDevs(&ClassGUID, 0,0,0);
+	if (DeviceInfoSet == INVALID_HANDLE_VALUE)
+	{
+		Log(LOG_ERROR, (L"in UninstallDevice,Can not create Device List.\n"));
+		return FALSE;
+	}
+	// Enumerate device with DeviceID through the  Devices List.
+	DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
+	for (i=0;SetupDiEnumDeviceInfo(DeviceInfoSet,i,&DeviceInfoData);i++)
+	{
+		DWORD DataT;
+		wchar_t*	p;
+		wchar_t    buffer[MAX_PATH*2] = { 0 };
+		DWORD	buffersize = MAX_PATH*2;
+
+		// We won't know the size of the HardwareID buffer until we call
+		// this function. So call it with a null to begin with, and then 
+		// use the required buffer size to Alloc the nessicary space.
+		// Keep calling we have success or an unknown failure.
+		if (!SetupDiGetDeviceRegistryProperty(DeviceInfoSet,
+			&DeviceInfoData,
+			SPDRP_HARDWAREID,
+			&DataT,
+			(PBYTE)buffer,
+			buffersize,
+			&buffersize))
+		{
+			Log(LOG_INFO, (L"VPN Installer : in UninstallDevice, Get device description register property fail.\n"));
+			continue;       
+		}
+
+		// Compare each entry in the buffer multi-sz list with our HardwareID.
+		for (p=buffer;*p&&(p<&buffer[buffersize]);p+=lstrlen((LPCWSTR)p)+sizeof(TCHAR))
+		{
+			Log(LOG_INFO,(L"Compare device ID:[%s] -- [%s]\n", HardwareID, p));
+			if (!_tcscmp(HardwareID,(const wchar_t*)p))
+			{
+				// Worker function to remove device.
+				Log(LOG_INFO,("uninstall adapter: Worker function to remove device."));
+				ReturnValue=SetupDiCallClassInstaller(DIF_REMOVE,
+					DeviceInfoSet,
+					&DeviceInfoData);
+				if(!ReturnValue)
+				{
+					Log(LOG_WARNING, (L"VPN Installer: in UninstallDevice,Can not remove the Device List..\n"));
+				}
+				break;
+			}
+		}
+	}
+
+	//  Cleanup.
+	DeleteEnumDevice();
+	ClearVNICRegister_NetworkConnection();
+	ClearVNICRegister_EnumDevice();
+	SetupDiDestroyDeviceInfoList(DeviceInfoSet);
+	//DeleteDriverServices();
+	ClearATPRegistry();
+
+	dwValue = (DWORD)ReturnValue;
+	SHSetValue(HKEY_LOCAL_MACHINE, szRegPath, VNIC_UNINSTALL_RETURNVALUE, REG_DWORD, &dwValue, sizeof(dwValue));
+
+	dwValue = VNIC_FINISHED;
+	SHSetValue(HKEY_LOCAL_MACHINE, szRegPath, VNIC_UNINSTALL_STATUS, REG_DWORD, &dwValue, sizeof(dwValue));
+	return TRUE;
+}
+
+int CVNICFunc::fnRemove_ByInf()
+{
+	Log(LOG_INFO, (L"VPN Installer: begin to un-install.\n"));
+	DWORD dwSize = 0;
+	wchar_t  INFFile[MAX_PATH]={ '\0' },TempPath[MAX_PATH]={ '\0' }, TargetInf[MAX_PATH]={ '\0' }, SrcPath[MAX_PATH] = { '\0' };
+
+	GetApplicationDirectory(SrcPath);
+	_tcscat(SrcPath, L"\\");
+
+	GetTempPath(MAX_PATH,TempPath);	
+	_tcscat_s(TempPath, VPN_DEFAULT_FOLDER_NAME);
+	_tcscat_s(TempPath, L"\\");
+	SHPathPrepareForWrite(NULL, NULL, TempPath, SHPPFW_DIRCREATE);
+
+	RepairRegInstaller();
+
+	int iVersion = GetWindowVersion();
+	DWORD dwProcessType = GetProcessorArchitectureFlag();
+
+	if(iVersion == WINDOWS_VERSION_VISTA)
+	{
+		if(dwProcessType == PROCESSOR_TYPE_AMD64)
+		{
+			_stprintf_s(INFFile,L"%s%s", SrcPath, ARR_INF_VISTA_X64_NAME);
+			_stprintf_s(TargetInf,L"%s%s", TempPath, ARR_INF_VISTA_X64_NAME);
+		}
+		else
+		{
+			_stprintf_s(INFFile,L"%s%s", SrcPath, ARR_INF_VISTA_NAME);
+			_stprintf_s(TargetInf,L"%s%s", TempPath, ARR_INF_VISTA_NAME);
+		}
+	}
+	else if(iVersion == WINDOWS_VERSION_2003)
+	{
+		if(dwProcessType == PROCESSOR_TYPE_AMD64)
+		{
+			_stprintf_s(INFFile,L"%s%s", SrcPath, ARR_INF_WIN2003_X64_NAME);
+			_stprintf_s(TargetInf,L"%s%s", TempPath, ARR_INF_WIN2003_X64_NAME);
+		}
+		else
+		{
+			_stprintf_s(INFFile,L"%s%s", SrcPath, ARR_INF_WIN2003_NAME);
+			_stprintf_s(TargetInf,L"%s%s", TempPath, ARR_INF_WIN2003_NAME);
+		}
+	}
+	else if(iVersion == WINDOWS_VERSION_2008)
+	{
+		if(dwProcessType == PROCESSOR_TYPE_AMD64)
+		{
+			_stprintf_s(INFFile,L"%s%s", SrcPath, ARR_INF_WIN2008_X64_NAME);
+			_stprintf_s(TargetInf,L"%s%s", TempPath, ARR_INF_WIN2008_X64_NAME);
+		}
+		else
+		{
+			_stprintf_s(INFFile,L"%s%s", SrcPath, ARR_INF_WIN2008_NAME);
+			_stprintf_s(TargetInf,L"%s%s", TempPath, ARR_INF_WIN2008_NAME);
+		}
+	}
+	else if(iVersion >= WINDOWS_VERSION_7)
+	{
+		if(dwProcessType == PROCESSOR_TYPE_AMD64)
+		{
+			_stprintf_s(INFFile,L"%s%s", SrcPath, ARR_INF_WIN7_X64_NAME);
+			_stprintf_s(TargetInf,L"%s%s", TempPath, ARR_INF_WIN7_X64_NAME);
+		}
+		else
+		{
+			_stprintf_s(INFFile,L"%s%s", SrcPath, ARR_INF_WIN7_NAME);
+			_stprintf_s(TargetInf,L"%s%s", TempPath, ARR_INF_WIN7_NAME);
+		}
+	}
+	else
+	{
+		_stprintf_s(INFFile,L"%s%s", SrcPath, ARR_INF_NAME);
+		_stprintf_s(TargetInf,L"%s%s", TempPath,  ARR_INF_NAME);
+	}
+
+	if(CopyFile(INFFile,TargetInf,FALSE) == 0)//copy this inf file file,no matter it has exist.
+	{
+		Log(LOG_INFO, (L"fnRemove_ByInf: Copy file from %s to %s failed, error is %d\n", INFFile, TargetInf, GetLastError()));
+	}
+	else
+	{
+		Log(LOG_INFO, (L"fnRemove_ByInf: Copy file success.\n"));
+	}
+
+	Log(LOG_INFO, (L"fnRemove_ByInf : get INF path: %s\n", TargetInf));
+
+	if(!PathFileExists(TargetInf))
+	{
+		Log(LOG_WARNING, (L"File %s is not exist\n", TargetInf));
+		memset(TargetInf, 0, MAX_PATH);
+		_stprintf_s(TargetInf, L"%s", SrcPath);
+	}
+
+	if(!PathFileExists(TargetInf))
+	{
+		Log(LOG_ERROR, (L"Can not find inf path, we don't remove L3VPN Adapter\n"));
+		return  fnRemove_ByDevID(VNIC_DEV_ID);;
+	}
+
+	if(UninstallDevice(TargetInf))
+	{
+		return CFG_EXIT_OK;
+	}
+	else
+	{
+		return CFG_FAILURE;
+	}
+}
+
+void CVNICFunc::RepairRegInstaller()
+{
 	int iWindowsVer = GetWindowVersion();
 	if(iWindowsVer >= WINDOWS_VERSION_8)
 	{
 		Log(LOG_INFO, (L"RepairRegInstaller: this is win8 or higher version, do nothing.\n"));
 		return ;
-	}
-
-	Log(LOG_INFO, (L"RepairRegInstaller: start\n"));
-	wchar_t wchValue[MAX_PATH] = {'\0'};
-	DWORD dwType = REG_SZ;
-	DWORD dwSize = sizeof(wchValue);
-	DWORD dwRet = SHGetValue(HKEY_LOCAL_MACHINE, VPN_ADAPTER_INSTALLER_REG_PATH, VPN_ADAPTER_INSTALLER_REG_NAME, &dwType, wchValue, &dwSize);
-	if(dwRet != ERROR_SUCCESS || _tcsicmp(wchValue, VPN_ADAPTER_INSTALLER_REG_VALUE) != 0)
-	{
-		Log(LOG_INFO, (L"RepairRegInstaller: the value was changed, we should repair it:%s\n", wchValue));
-		dwRet = SHSetValue(HKEY_LOCAL_MACHINE, VPN_ADAPTER_INSTALLER_REG_PATH, VPN_ADAPTER_INSTALLER_REG_NAME, REG_SZ, VPN_ADAPTER_INSTALLER_REG_VALUE, (_tcslen(VPN_ADAPTER_INSTALLER_REG_VALUE)+1)*2);
-		if(dwRet != ERROR_SUCCESS)
-		{
-			Log(LOG_WARNING, (L"RepairRegInstaller: SHSetValue failed, err is %d\n", dwRet));
-		}
-		else
-		{
-			Log(LOG_INFO, (L"RepairRegInstaller: SHSetValue success.\n"));
-		}
-	}
-	else
-	{
-		Log(LOG_INFO, (L"RepairRegInstaller: the value correct, no need repair\n"));
-	}
-}
-
-int CVNICFunc::fnRemove_ByDevID(LPCTSTR hwID)
-{
-	RepairRegInstaller();
-
-	wchar_t szPath[MAX_PATH] = {'\0'};
-	GetModuleFileNameW(GetModuleHandle(NULL), szPath, MAX_PATH);
-	PathRemoveFileSpec(szPath);
-	PathAppend(szPath, DEVCON_EXE_NAME);
-	if(!PathFileExists(szPath))
-	{
-		Log(LOG_WARNING, (L"fnRemove_ByDevID: file%s not found\n", szPath));
-		return CFG_FAILURE;
-	}
-
-	Log(LOG_INFO, (L"fnRemove_ByDevID: file %s found\n", szPath));
-
-	HANDLE   hRead,   hWrite; 
-	SECURITY_ATTRIBUTES   sec; 
-	sec.nLength   =   sizeof(SECURITY_ATTRIBUTES); 
-	sec.bInheritHandle   =   TRUE; 
-	sec.lpSecurityDescriptor   =   NULL; 
-	BOOL   fResult   =   CreatePipe(&hRead,   &hWrite,   &sec,   0); 
-
-	STARTUPINFO si; 
-	PROCESS_INFORMATION pi; 
-	ZeroMemory(&si, sizeof(STARTUPINFO));
-	si.cb = sizeof(STARTUPINFO);
-	si.wShowWindow = SW_HIDE; 
-	si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; 
-	si.hStdOutput   =   hWrite; 
-	si.hStdInput   =   hRead; 
-	si.hStdError   =   hWrite;
-
-	CString csCommand;
-	csCommand.Format(L"\"%s\" remove  \"%s\"", szPath, VNIC_DEV_ID);
-	Log(LOG_INFO, (L"csCommand:%s\n", csCommand));
-
-	if(!::CreateProcess(NULL, csCommand.GetBuffer(0), NULL, NULL, TRUE, NULL, NULL, NULL, &si, &pi))
-	{ 
-		Log(LOG_WARNING, (L"CreateProcess failed, error:%d, command is %s", GetLastError(), csCommand.GetBuffer(0)));
-		return CFG_FAILURE;
-	}
-
-	if(pi.hProcess == NULL)
-	{
-		Log(LOG_WARNING,(L"CreateProcess: hProcess is null\n"));
-		return CFG_FAILURE;
-	}
-	// show info to user when cache cleaner triggered and exit.
-	DWORD dwRe = ::WaitForSingleObject(pi.hProcess, 60*1000);
-	if(WAIT_OBJECT_0 == dwRe)
-	{
-		Log(LOG_INFO, ("Process devcon.exe has exit\n"));
-	}
-	else
-	{
-		Log(LOG_INFO, ("WaitForSingleObject timeout!\n"));
-	}
-	char szBuffer[MAX_PATH]  =  {0};
-	if(fResult) 
-	{
-		DWORD  dwReadLen   =   0;
-
-		fResult = ReadFile(hRead, szBuffer, MAX_PATH, &dwReadLen, NULL);
-		Log(LOG_ERROR, ("Adapter removed: return: %s\n", szBuffer));
-	}
-
-	if(pi.hProcess)
-	{
-		CloseHandle(pi.hProcess);
-	}
-	if(pi.hThread)
-	{
-		CloseHandle(pi.hThread);
-	}
-
-	if(StrStrIA(szBuffer, "device(s) were removed") != NULL)
-	{
-		return CFG_EXIT_OK;
-	}
-
-	return CFG_EXIT_OK;
-}
-
-BOOL CVNICFunc::UninstallDevice(LPCTSTR INFFile)
-{
-	Log(LOG_INFO, (L"VPN L3 Installer : enter UninstallDevice.\n"));
-
-	BOOL ReturnValue = FALSE;
-	g_cStrInf = INFFile;
-	CComVariant varParam;
-	V_VT(&varParam) = VT_UI4;
-	VARIANT_BOOL vbCancel = VARIANT_FALSE;
-	HANDLE hThread = NULL;
-	hThread = (HANDLE) _beginthreadex(NULL, 0, ThreadUninstallDevice, NULL, 0, NULL);
-	int iNum = 0;
-	DWORD dwValue = 0;
-
-	Sleep(1000);
-	V_UI4(&varParam) = 2403;
-	while(iNum < 2*60) //sleep 60 seconds
-	{
-		dwValue = 0;
-		wchar_t szRegPath[MAX_PATH] = {'\0'};
-		DWORD dwType = REG_DWORD;
-		DWORD dwSize = sizeof(dwValue);
-		_stprintf_s(szRegPath, MAX_PATH, L"%s\\%s", AIM_REG_PATH, SSLVPN_COMPONENT_CLSID);
-		SHGetValue(HKEY_LOCAL_MACHINE, szRegPath, VNIC_UNINSTALL_STATUS, &dwType, &dwValue, &dwSize);
-		if(dwValue != VNIC_FINISHED)
-		{
-			Sleep(500);
-			continue;
-		}
-		break;
-	}
-	V_UI4(&varParam) = 2403;
-
-	wchar_t szRegPath[MAX_PATH] = {'\0'};
-	_stprintf_s(szRegPath, MAX_PATH, L"%s\\%s", AIM_REG_PATH, SSLVPN_COMPONENT_CLSID);
-
-	dwValue = VNIC_NONE;
-	SHSetValue(HKEY_LOCAL_MACHINE, szRegPath, VNIC_UNINSTALL_STATUS, REG_DWORD, &dwValue, sizeof(dwValue));
-
-
-	DWORD dwType = REG_DWORD;
-	DWORD dwSize = sizeof(dwValue);
-	DWORD dwRet = SHGetValue(HKEY_LOCAL_MACHINE, szRegPath, VNIC_UNINSTALL_RETURNVALUE, &dwType, &dwValue, &dwSize);
-	if(dwRet != ERROR_SUCCESS)
-	{
-		Log(LOG_WARNING, (L"Query cmdUpdate value: can not get the value, error is %d\n", dwRet));
-	}
-	else
-	{
-		ReturnValue  = (BOOL)dwValue;
-	}
-
-	if(hThread != NULL)
-	{
-		CloseHandle(hThread);
-	}
-
-	return ReturnValue;
-}
-
-BOOL GetDeviceandClassID(LPTSTR INFFile, LPTSTR  DeviceID OPTIONAL, LPTSTR  DeviceDesc OPTIONAL)
-{
-	HINF  hInfFile;
-	INFCONTEXT InfLine;
-	wchar_t   LineText[MAX_PATH] = { 0 }, DeviceWarring[MAX_PATH] = { 0 };
-	wchar_t*   HardwareID;
-	UINT err;
-
-	//Get Device ID from the inf file.
-	hInfFile = SetupOpenInfFile(INFFile, NULL, INF_STYLE_WIN4, &err);
-	if(hInfFile == INVALID_HANDLE_VALUE)
-	{
-		Log(LOG_ERROR, (L"VPN Installer : in GetDeviceandClassID Can not open the INF file:%s\n", INFFile));
-		return FALSE;
-	}
-	if(SetupFindFirstLine(hInfFile, L"Manufacturer", NULL, &InfLine) == FALSE)
-	{
-		Log(LOG_ERROR, (L"VPN Installer : in GetDeviceandClassID Can not get the INF Manufacturer sections\n"));
-		SetupCloseInfFile(hInfFile);
-		return FALSE;
-	}
-	if(SetupGetLineText(&InfLine, NULL, NULL, NULL, LineText, MAX_PATH, NULL) == FALSE)
-	{
-		Log(LOG_ERROR, (L"VPN Installer : in GetDeviceandClassID can not get the keyword provider from the maunfacturer section.\n"));
-		SetupCloseInfFile(hInfFile);
-		return FALSE;
-	}
-	//the inf file is 
-	//[Manufacturer]
-	//%l_Provider% = ArrayNetworks,NTx86
-	//the old is
-	//[Manufacturer]
-	//%l_Provider% = ArrayNetworks
-	for(unsigned int i=0;i<_tcslen(LineText);i++)
-	{
-		if(LineText[i]==',')
-		{
-			LineText[i]='\0';
-			break;
-		}
-	}
-	if(SetupFindFirstLine(hInfFile, LineText, NULL, &InfLine) == FALSE)
-	{
-		Log(LOG_ERROR, (L"VPN Installer : in GetDeviceandClassID Can not get the INF Device sections.\n"));
-		SetupCloseInfFile(hInfFile);
-		return FALSE;
-	}
-	if(SetupGetLineText(&InfLine, NULL, NULL, NULL, LineText, MAX_PATH, NULL) == FALSE)
-	{
-		Log(LOG_ERROR, (L"VPN Installer : in GetDeviceandClassID can not get the keyword provider from the device section.\n"));
-		SetupCloseInfFile(hInfFile);
-		return FALSE;
-	}
-	//i must clear the string.
-	LineText[_tcslen(LineText)]=LineText[_tcslen(LineText)+1] = '\0';
-	//the inf file can not be changed anyway!!!!!!!!!!!!!!!,it must be as follows:
-	//%DeviceDescription%  =   ATP.ndi,     VPNATP
-	HardwareID = wcschr(LineText, L',');
-	if(HardwareID == NULL)
-	{
-		Log(LOG_ERROR, (L"VPN Installer : in GetDeviceandClassID can not get the HardwareID from the device section.\n"));
-		SetupCloseInfFile(hInfFile);
-		return FALSE;		
-	}
-	HardwareID++;
-
-	//get the device description.
-	if(DeviceDesc)
-	{
-		if(SetupFindFirstLine(hInfFile, L"Strings", L"DeviceDescription", &InfLine) == FALSE)
-		{	
-			if(SetupFindFirstLine(hInfFile, L"Strings", L"l_DeviceDescription", &InfLine) == FALSE)
-			{
-				Log(LOG_ERROR, (L"VPN Installer : in GetDeviceandClassID Can not get the INF String sections.\n"));
-				SetupCloseInfFile(hInfFile);
-				return FALSE;
-			}
-		}
-		if(SetupGetLineText(&InfLine, NULL, NULL, NULL, DeviceWarring, MAX_PATH, NULL) == FALSE)
-		{
-			Log(LOG_ERROR, (L"VPN Installer : in GetDeviceandClassID can not get the keyword string from the string section.\n"));
-			SetupCloseInfFile(hInfFile);
-			return FALSE;
-		}
-	}
-	SetupCloseInfFile(hInfFile);
-	if(DeviceID)
-	{
-		lstrcpy(DeviceID, HardwareID);
-	}
-	if(DeviceDesc)
-	{
-		lstrcpy(DeviceDesc, DeviceWarring);
-	}
-	return TRUE;
-}
-
-bool DeleteEnumDevice()
-{
-	HDEVINFO        devs = INVALID_HANDLE_VALUE;
-	SP_DEVINFO_DATA devInfo;
-	HKEY            hDeviceKey = NULL;
-	HKEY            hEnumKey = NULL;
-	TCHAR            EnumPath[MAX_PATH] = {'\0'};
-	TCHAR RegPath[MAX_PATH] = {'\0'};
-	TCHAR            szHardwareId[MAX_PATH]= {'\0'};
-	TCHAR TempKey[MAX_PATH]= {'\0'};
-	TCHAR			DeviceEnumPath[20][MAX_PATH] = {0};
-	int             Length, iEnumNum;
-	bool            bReturn = false;
-
-#define MAX_ENUM_DEVICE_NUMBER     20
-
-	Log(LOG_INFO, (L" enter DeleteEnumDevice........\n"));
-	devs = SetupDiGetClassDevsEx(NULL,
-		NULL,
-		NULL,
-		(DIGCF_ALLCLASSES) | DIGCF_PRESENT,
-		NULL,
-		L"",
-		NULL);
-
-	if(devs == INVALID_HANDLE_VALUE) 
-	{
-		Log(LOG_ERROR, (L" in DeleteEnumDevice,SetupDiGetClassDevsEx failed.\n"));
-		goto final;
-	}
-
-	//open the device key
-	_stprintf_s(RegPath, MAX_PATH, _T("%s\\%s"), DEVICE_REGISTER_PATH, DEVICE_ENUM_PATH);
-	if(RegOpenKey(HKEY_LOCAL_MACHINE, RegPath, &hDeviceKey) == ERROR_SUCCESS)
-	{
-		Log(LOG_INFO, (L" in DeleteEnumDevice,RegOpenKeyA success:%s.\n", RegPath));
-	}
-	else
-	{
-		Log(LOG_INFO, (L" in DeleteEnumDevice,RegOpenKeyA failed:%s.\n", RegPath));
-		goto final;
-	}
-	Length = sizeof(TempKey);
-	iEnumNum = 0;
-	//enum the device enum key
-	while(RegEnumKeyEx(hDeviceKey, iEnumNum++, TempKey, (ULONG*)&Length, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
-	{
-		_stprintf_s(EnumPath, MAX_PATH, _T("%s\\%s"), DEVICE_ENUM_PATH, TempKey);
-		_stprintf_s(RegPath, MAX_PATH, _T("%s\\%s"), DEVICE_REGISTER_PATH, EnumPath);
-		if(RegOpenKey(HKEY_LOCAL_MACHINE, RegPath, &hEnumKey) == ERROR_SUCCESS)
-		{
-			Log(LOG_INFO, (L" in DeleteEnumDevice,RegOpenKeyA success:%s.\n", RegPath));
-		}
-		else
-		{
-			Log(LOG_INFO, (L" in DeleteEnumDevice,RegOpenKeyA failed:%s.\n", RegPath));
-			continue;
-		}
-		Length = MAX_PATH;
-		memset(szHardwareId, MAX_PATH, 0);
-		if(RegQueryValueEx(hEnumKey, L"HardwareID", NULL, NULL, (UCHAR*)szHardwareId, (ULONG*)&Length) == ERROR_SUCCESS)
-		{
-			Log(LOG_INFO, (L" in DeleteEnumDevice, Reg query success.\n"));
-			RegCloseKey(hEnumKey);
-
-			if(_tcsicmp(szHardwareId, VNIC_DEV_ID) == 0)
-			{
-				//this is our device;
-				Log(LOG_INFO, (L" in DeleteEnumDevice,this is our device.\n"));
-			}
-			else
-			{
-				Log(LOG_INFO, (L" in DeleteEnumDevice,this is not our device.\n"));
-				continue;
-			}
-		}
-		else
-		{
-			Log(LOG_INFO, (L" in DeleteEnumDevice,Regquery failed.\n"));
-			RegCloseKey(hEnumKey);
-			Length = MAX_PATH;
-			continue;
-		}
-		//restore the device enum path.
-		if(iEnumNum < MAX_ENUM_DEVICE_NUMBER)
-		{
-			_tcscpy(DeviceEnumPath[iEnumNum], EnumPath);
-		}
-		else
-		{
-			Log(LOG_INFO, (L"in DeleteEnumDevice,too many enum path......\n"));
-		}
-		Length = MAX_PATH;
-	}
-	//delete the matched device
-	for(iEnumNum = 0; iEnumNum < MAX_ENUM_DEVICE_NUMBER; iEnumNum++)
-	{
-		if(_tcslen(DeviceEnumPath[iEnumNum]) == 0)
-		{
-			continue;
-		}
-		memset(&devInfo, 0, sizeof(devInfo));
-		devInfo.cbSize = sizeof(devInfo);
-		//clear the device enum path.
-		memset(EnumPath, 0, sizeof(EnumPath));
-		_tcscpy(EnumPath, DeviceEnumPath[iEnumNum]);
-		if(!SetupDiOpenDeviceInfo(devs, EnumPath, NULL, 0, &devInfo))
-		{
-			Log(LOG_INFO, (L"in DeleteEnumDevice,SetupDiOpenDeviceInfo failed.:%s\n", EnumPath));
-			//delete the device register path,//root\net\000x
-			_tcscpy(TempKey, &EnumPath[9]);
-			if(SHDeleteKey (hDeviceKey, TempKey) == ERROR_SUCCESS)
-			{
-				Log(LOG_INFO, (L"in DeleteEnumDevice,delete Key success:%s.\n", TempKey));
-			}
-			else
-			{
-				Log(LOG_INFO, (L"in DeleteEnumDevice,delete Key failed:%s.\n", TempKey));
-			}
-			continue;
-		}
-
-		if(!SetupDiCallClassInstaller(DIF_REMOVE, devs, &devInfo))
-		{
-			Log(LOG_INFO, (L"in DeleteEnumDevice,SetupDiCallClassInstaller failed.error:%0x\n", GetLastError()));
-		}
-		else
-		{
-			Log(LOG_INFO, (L"in DeleteEnumDevice,SetupDiCallClassInstaller succeed.\n"));
-			bReturn = true;
-		}
-	}
-	RegCloseKey(hDeviceKey);
-	RegCloseKey(hDeviceKey);
-
-
-final:   
-	if(devs != INVALID_HANDLE_VALUE) 
-	{
-		SetupDiDestroyDeviceInfoList(devs);
-	}
-	Log(LOG_INFO, (L" leave DeleteEnumDevice........\n"));
-	return bReturn;
-}
-
-void ClearVNICRegister_NetworkConnection()
-{
-	HKEY            hDeviceKey = NULL, hEnumKey = NULL, hDevicePathKey = NULL;
-	wchar_t         wchName[MAX_PATH] = {'\0'}, RegPath[MAX_PATH] = {'\0'}, TempPath[MAX_PATH] = {'\0'} ,HardWareIdInfo[MAX_PATH] = {'\0'}, DeviceInstanceID[MAX_PATH] = {'\0'}, DeviceNameInfo[MAX_PATH] = {'\0'};
-	int             iSubkeyNumber = 0, Length = 0;
-	DWORD           dwRet = 0;
-
-	_stprintf_s(RegPath, L"%s\\Descriptions", NETWORK_CONNECTION);
-	_stprintf_s(wchName, L"%s%s", VPN_PROVIDEER_NAME, VPN_ADAPTER_POSTFIX);
-	dwRet = SHDeleteValue(HKEY_LOCAL_MACHINE, RegPath, wchName); 
-	Log(LOG_INFO, (L"VNIC adapter number remove finished, ret is %d\n", dwRet));
-
-	//open the device key
-	_stprintf_s(RegPath, L"%s", NETWORK_CONNECTION);
-	dwRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, RegPath, 0, KEY_READ, &hDeviceKey);
-	if(dwRet != ERROR_SUCCESS)
-	{
-		Log(LOG_ERROR, (L"In Clear VNIC Register,RegOpenKey failed:%d.\n", dwRet));
-		return;
-	}
-
-	Length = sizeof(TempPath);
-	iSubkeyNumber = 0;
-	//enum the device enum key
-	while(RegEnumKeyEx(hDeviceKey, iSubkeyNumber++, TempPath, (ULONG*)&Length, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
-	{
-		_stprintf_s(RegPath, L"%s\\%s\\%s", NETWORK_CONNECTION, TempPath, L"Connection");
-		dwRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, RegPath, 0, KEY_READ, &hEnumKey);
-		if(dwRet != ERROR_SUCCESS)
-		{
-			memset(TempPath,0,sizeof(TempPath));
-			Length = MAX_PATH;
-			continue;
-		}
-		bool bShouldDeleteTempKey = false;
-		Length = MAX_PATH;
-		memset(DeviceNameInfo, MAX_PATH, 0);
-		dwRet = RegQueryValueEx(hEnumKey, L"Name", NULL, NULL, (LPBYTE)DeviceNameInfo, (LPDWORD)&Length);
-		if(dwRet == ERROR_SUCCESS)
-		{
-			wchar_t szCompanyName[MAX_PATH] = {'\0'};
-			GetCompanyName(szCompanyName);
-			_tcscat(szCompanyName, VPN_ADAPTER_POSTFIX);
-			if(StrStrIW(DeviceNameInfo, szCompanyName) != NULL)
-			{
-				bShouldDeleteTempKey = true;
-			}
-		}
-		else
-		{
-			Log(LOG_INFO, (L"In Clear VNIC Register: Name query failed, ret is %d\n", dwRet));
-		}
-
-		Length = MAX_PATH;
-		memset(DeviceInstanceID, MAX_PATH, 0);
-		dwRet = RegQueryValueEx(hEnumKey, L"PnpInstanceID", NULL, NULL, (LPBYTE)DeviceInstanceID, (LPDWORD)&Length);
-		if(dwRet == ERROR_SUCCESS)
-		{
-			if(StrStrIW(DeviceInstanceID, DEVICE_ENUM_PATH) != NULL)
-			{
-				//this is root device;
-				_stprintf_s(RegPath, L"%s\\%s", DEVICE_REGISTER_PATH, DeviceInstanceID);
-				dwRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, RegPath, 0, KEY_READ, &hDevicePathKey);
-				if(dwRet == ERROR_SUCCESS)
-				{
-					Length = MAX_PATH;
-					memset(HardWareIdInfo, MAX_PATH, 0);
-					dwRet = RegQueryValueEx(hDevicePathKey, L"HardwareID", NULL, NULL, (LPBYTE)HardWareIdInfo, (LPDWORD)&Length);
-					if(dwRet == ERROR_SUCCESS)
-					{
-						if(_tcsicmp(HardWareIdInfo, VNIC_DEV_ID) == 0)
-						{
-							//this is our device;
-							bShouldDeleteTempKey = true;
-							dwRet = SHDeleteKey(HKEY_LOCAL_MACHINE, RegPath);
-							Log(LOG_INFO, (L"In Clear VNIC Register,reg %s was deleted, return value is %d\n", RegPath, dwRet));
-						}
-
-					}
-					else
-					{
-						Log(LOG_INFO, (L"In Clear VNIC Register: DeviceDesc query failed, ret is %d\n", dwRet));
-					}
-				}
-				else
-				{
-					Log(LOG_INFO, (L"In Clear VNIC Register: reg open failed, ret is %d\n", dwRet));
-				}
-
-			}
-		}
-		if(bShouldDeleteTempKey)
-		{
-			dwRet = SHDeleteKey(hDeviceKey, TempPath);
-			Log(LOG_INFO, (L"In Clear VNIC Register,reg %s was deleted, return value is %d\n", TempPath, dwRet));
-		}
-
-
-		memset(TempPath,0,sizeof(TempPath));
-		RegCloseKey(hDevicePathKey);
-		hDevicePathKey = NULL;
-		RegCloseKey(hEnumKey);
-		hEnumKey = NULL;
-		Length = MAX_PATH;
-
-	}
-	if(hDeviceKey)
-	{
-		RegCloseKey(hDeviceKey);
-	}
-	if(hEnumKey)
-	{
-		RegCloseKey(hEnumKey);
-	}
-	if(hDevicePathKey)
-	{
-		RegCloseKey(hDevicePathKey);
-	}
-}
-
-void ClearVNICRegister_EnumDevice()
-{
-	HKEY            hDeviceKey = NULL, hEnumKey = NULL;
-	wchar_t         RegPath[MAX_PATH] = {'\0'}, TempPath[MAX_PATH] = {'\0'} ,HardWareIdInfo[MAX_PATH] = {'\0'};
-	int             iSubkeyNumber = 0, Length = 0;
-	DWORD           dwRet = 0;
-
-
-	//open the device key
-	_stprintf_s(RegPath, L"%s\\Root\\NET", DEVICE_REGISTER_PATH);
-	dwRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, RegPath, 0, KEY_READ, &hDeviceKey);
-	if(dwRet != ERROR_SUCCESS)
-	{
-		Log(LOG_INFO, (L"In Clear VNIC Register, RegOpenKey root\\net failed: %d.\n", dwRet));
-		return;
-	}
-
-	Length = sizeof(TempPath);
-	iSubkeyNumber = 0;
-	//enum the device enum key
-	while(RegEnumKeyEx(hDeviceKey, iSubkeyNumber++, TempPath, (ULONG*)&Length, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
-	{
-		_stprintf_s(RegPath, L"%s\\Root\\NET\\%s", DEVICE_REGISTER_PATH, TempPath);
-		dwRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, RegPath, 0, KEY_READ, &hEnumKey);
-		if(dwRet != ERROR_SUCCESS)
-		{
-			memset(TempPath,0,sizeof(TempPath));
-			Length = MAX_PATH;
-			continue;
-		}
-
-		Length = MAX_PATH;
-		memset(HardWareIdInfo, MAX_PATH, 0);
-		dwRet = RegQueryValueEx(hEnumKey, L"HardwareID", NULL, NULL, (LPBYTE)HardWareIdInfo, (LPDWORD)&Length);
-		if(dwRet == ERROR_SUCCESS)
-		{
-			if(_tcsicmp(HardWareIdInfo, VNIC_DEV_ID) == 0)
-			{
-				//this is our device;
-				dwRet = SHDeleteKey(HKEY_LOCAL_MACHINE, RegPath);
-				Log(LOG_INFO, (L"In Clear VNIC Register,reg %s was deleted, return value is %d\n", RegPath, dwRet));
-			}
-		}
-
-		memset(TempPath,0,sizeof(TempPath));
-		RegCloseKey(hEnumKey);
-		hEnumKey = NULL;
-		Length = MAX_PATH;
-	}
-
-	if(hDeviceKey)
-	{
-		RegCloseKey(hDeviceKey);
-	}
-	if(hEnumKey)
-	{
-		RegCloseKey(hEnumKey);
-	}
-}
-
-void ClearATPRegistry()
-{
-	HKEY            hDeviceKey;
-	wchar_t         TempPath[MAX_PATH]={0};
-	int iSubkeyNumber = 0, iLength;
-	DWORD dwRet = 0;
-	dwRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"SYSTEM\\", 0, KEY_READ, &hDeviceKey);
-	if(dwRet != ERROR_SUCCESS)
-	{
-		Log(LOG_ERROR,(L"RegOpenKey fail! Please check!\n"));
-		return;
-	}
-
-	iLength = sizeof(TempPath);
-	while( RegEnumKeyEx(hDeviceKey, iSubkeyNumber++, TempPath, (ULONG*)&iLength, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
-	{
-		wchar_t regpath[MAX_PATH];
-		if (StrStrIW(TempPath,L"ControlSet") != NULL )
-		{
-			memset(regpath,0,sizeof(regpath));
-			_stprintf_s(regpath,L"SYSTEM\\%s\\Services\\",TempPath);
-			DetectATPRegAndRemove(regpath, true);
-		}
-
-		memset(TempPath,0,sizeof(TempPath));
-		iLength = sizeof(TempPath);
-	}
-	RegCloseKey(hDeviceKey);
-}
-
-bool DetectATPRegAndRemove(wchar_t *regpath, bool bRemoveATPReg)
-{
-	HKEY            hDeviceKey = NULL;
-	wchar_t         TempPath[MAX_PATH];
-	int iSubkeyNumber = 0,iLength;
-	DWORD dwRet = 0;
-	bool bRet = false;
-
-	dwRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, regpath, 0, KEY_READ, &hDeviceKey);
-	if(dwRet != ERROR_SUCCESS)
-	{
-		Log(LOG_INFO,(L"Remove ATP Reg: reg open %s failed, error is %d\n", regpath, dwRet));
-		return bRet;
-	}
-
-	iLength = sizeof(TempPath);
-	while(RegEnumKeyEx(hDeviceKey, iSubkeyNumber++, TempPath, (ULONG*)&iLength, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
-	{
-		if(_tcsicmp(TempPath, L"ATP") == 0)
-		{
-			if(bRemoveATPReg)
-			{
-				SHDeleteKey(hDeviceKey, TempPath);
-			}
-			bRet = true;
-		}
-
-		memset(TempPath,0,sizeof(TempPath));
-		iLength = sizeof(TempPath);
-	}
-	RegCloseKey(hDeviceKey);
-	return bRet;
-}
-
-bool CServiceFunc::run()
-{
-	Log(LOG_INFO, (L"CServiceFunc: Start to Uninstall service\n"));
-	SetInstallStatus(SSLVPN_COMPONENT_CLSID, aisRemovingService);
-	if (!RemoveVPNService())
-	{
-		Log(LOG_WARNING, (L"CServiceFunc: Uninstall service failed\n"));
-		return false;
-	}
-	Log(LOG_INFO, (L"CServiceFunc: Start to Uninstall service success\n"));
-	return true;
-}
-
-bool CServiceFunc::RemoveVPNService()
-{
-	bool bServiceFileExist = false;
-	bool bRet = true;
-	int iErrorCode = 0;
-	wchar_t szVPNServiceFilePath[MAX_PATH] = {'\0'}, szRegPath[MAX_PATH] = {'\0'}, szWebVPNServiceFilePath[MAX_PATH] = {'\0'}, szVPNInstallManagerFilePath[MAX_PATH] = {'\0'};
-
-	DWORD dwType = REG_EXPAND_SZ;
-	DWORD dwSize = sizeof(szVPNServiceFilePath);
-	_stprintf_s(szRegPath, MAX_PATH, L"SYSTEM\\CurrentControlSet\\Services\\%s", ARR_VPNSERVICE_NAME);
-	DWORD dwRet = SHGetValue(HKEY_LOCAL_MACHINE, szRegPath, IMAGEPATH_NAME, &dwType, szVPNServiceFilePath, &dwSize);
-	if(dwRet != ERROR_SUCCESS)
-	{
-		Log(LOG_INFO, (L"RemoveVPNService: can not get the com file path from reg, dwRet is %d\n", dwRet));
-	}
-	else
-	{
-		//
-		int iLength = _tcslen(szVPNServiceFilePath); //
-		Log(LOG_INFO, (L"RemoveVPNService: old path string: %s \n", szVPNServiceFilePath));
-		for(int i = 0; i < iLength-2 ; i++) //
-		{
-			szVPNServiceFilePath[i] = szVPNServiceFilePath[i+1];
-		}
-		szVPNServiceFilePath[iLength-2] = '\0';  //
-		Log(LOG_INFO, (L"RemoveVPNService: new path string is %s\n", szVPNServiceFilePath));
-		if(PathFileExists(szVPNServiceFilePath))
-		{
-			Log(LOG_INFO, (L"RemoveVPNService: file %s exist\n", szVPNServiceFilePath));
-			bServiceFileExist = true;
-		}
-	}
-
-	if(!bServiceFileExist)
-	{
-		wchar_t szAppDir[MAX_PATH] = {'\0'};
-		GetApplicationDirectory(szAppDir);
-		_stprintf_s(szVPNServiceFilePath, MAX_PATH, L"%s\\%s", szAppDir, ARR_VPNSERVICE_FILE_NAME);
-		if(!PathFileExists(szVPNServiceFilePath))
-		{
-			Log(LOG_INFO, (L"RemoveVPNService: file %s is not exist\n", szVPNServiceFilePath));
-		}
-	}
-
-	if (IsCOMServiceExist(ARR_VPNSERVICE_NAME))
-	{
-		if(bRet && !RemoveCOMService(szVPNServiceFilePath, true))
-		{
-			Log(LOG_INFO, (L"RemoveVPNService: remove VPN service failed\n"));
-			bRet = false;
-		}
-	}
-	
-	Sleep(1000);//
-
-	CString csFilePath = szVPNServiceFilePath; //c:\program files\...\..\VPNService.exe
-	csFilePath = csFilePath.Left(csFilePath.GetLength() - _tcslen(ARR_VPNSERVICE_FILE_NAME));
-	_stprintf_s(szWebVPNServiceFilePath, MAX_PATH, L"%s%s", csFilePath, ARR_WEBVPN_SERVICE_FILE_NAME);
-	if(!PathFileExists(szWebVPNServiceFilePath))
-	{
-		Log(LOG_INFO, (L"RemoveVPNService: file %s is not exist\n", szWebVPNServiceFilePath));
-	}
-	if(!StopProcessByProcessName(ARR_WEBVPN_SERVICE_FILE_NAME))
-	{
-		Log(LOG_INFO, (L"RemoveVPNService: peocess %s is also running\n", ARR_WEBVPN_SERVICE_FILE_NAME));
-	}
-	
-	if (IsCOMServiceExist(ARR_WEBVPN_SERVICE_NAME))
-	{
-		if(!RemoveCOMService(szWebVPNServiceFilePath, false))
-		{
-			Log(LOG_INFO, (L"RemoveVPNService: remove Web vpn service failed\n"));
-			bRet = false;
-		}
-	}
-
-	csFilePath = szVPNServiceFilePath;
-	csFilePath = csFilePath.Left(csFilePath.GetLength() - _tcslen(ARR_VPNSERVICE_INSTALL_PATH));
-	_stprintf_s(szVPNInstallManagerFilePath, MAX_PATH, L"%s%s\\%s", csFilePath, INSTALL_MANAGER_NAME, ARR_AIM_FILE_NAME);
-	if(!PathFileExists(szVPNInstallManagerFilePath))
-	{
-		Log(LOG_INFO, (L"RemoveVPNService: file %s is not exist\n", szVPNInstallManagerFilePath));
-	}
-	if(!StopProcessByProcessName(ARR_AIM_FILE_NAME))
-	{
-		Log(LOG_INFO, (L"RemoveVPNService: peocess %s is also running\n", ARR_AIM_FILE_NAME));
-	}
-
-	if (IsCOMServiceExist(ARR_AIM_SERVICE_NAME))
-	{
-		if(!RemoveCOMService(szVPNInstallManagerFilePath, false))
-		{
-			Log(LOG_INFO, (L"RemoveVPNService: remove VPNInstallManager service failed\n"));
-			bRet = false;
-		}
-	}
-
-	Log(LOG_INFO, (L"RemoveVPNService: finished and ret is %d\n", bRet));
-	return bRet;
-}
-
-bool CActiveXCFunc::run()
-{
-	bool bRet = true;
-	Log(LOG_INFO, (L"CActiveXCFunc: Start to Uninstall ActiveX\n"));
-	if(!DeleteActiveXComponent(ARR_ACTIVEX_INF_NAME_X64))
-	{
-		bRet = false;
-	}
-	if(!DeleteActiveXComponent(ARR_ACTIVEX_INF_NAME))
-	{
-		bRet = false;
-	}
-	if(!DeleteActiveXComponent(VPNINIT_FILE_NAME))
-	{
-		bRet = false;
-	}
-	if(!DeleteActiveXComponent(ARR_ACTIVEX_FILE_NAME))
-	{
-		bRet = false;
-	}
-	if (Is64bitOS())
-	{
-		SHDeleteKey(HKEY_CLASSES_ROOT, L"Wow6432Node\\CLSID\\{47C6ECF4-2DDE-4001-836B-5BF6ED9BC2DC}");
-	}
-	SHDeleteKey(HKEY_CLASSES_ROOT, L"CLSID\\{47C6ECF4-2DDE-4001-836B-5BF6ED9BC2DC}");
-	Log(LOG_INFO, (L"CActiveXCFunc: Uninstall ActiveX finish\n"));
-	return bRet;
-}
-
-bool CActiveXCFunc::DeleteActiveXComponent(LPCTSTR lpActiveXName)
-{
-	wchar_t szPath[MAX_PATH] = {'\0'}, szSystemPath[MAX_PATH] = {'\0'};
-	GetSystemDirectory(szSystemPath, MAX_PATH);
-	
-	_stprintf_s(szPath, MAX_PATH, L"%s\\%s", szSystemPath, lpActiveXName);
-	Log(LOG_INFO, (L"Delete ActiveX: szPath:%s\n", szPath));
-	if (PathFileExists(szPath))
-	{
-		Log(LOG_INFO, (L"Delete ActiveX: szPath:%s exist\n", szPath));
-		if (!DeleteFile(szPath))
-		{
-			Log(LOG_ERROR, (L"Delete ActiveX:%d failed\n", GetLastError()));
-			return false;
-		}
-	} 
-	else
-	{
-		Log(LOG_INFO, (L"Delete ActiveX: szPath:%s is not exist\n", szPath));
-	}
-
-	if (Is64bitOS())
-	{
-		memset(szSystemPath, 0, sizeof(szSystemPath));
-		GetSystemWow64Directory(szSystemPath, MAX_PATH);
-
-		_stprintf_s(szPath, MAX_PATH, L"%s\\%s", szSystemPath, lpActiveXName);
-		Log(LOG_INFO, (L"Delete ActiveX: szPath:%s\n", szPath));
-		if (PathFileExists(szPath))
-		{
-			Log(LOG_INFO, (L"Delete ActiveX: szPath:%s exist\n", szPath));
-			if (!DeleteFile(szPath))
-			{
-				Log(LOG_ERROR, (L"Delete ActiveX:%d failed\n", GetLastError()));
-				return false;
-			}
-		} 
-		else
-		{
-			Log(LOG_INFO, (L"Delete ActiveX: szPath:%s is not exist\n", szPath));
-		}
-	}
-	return true;
-}
-
-bool CRegFunc::run()
-{
-	Log(LOG_INFO, (L"CRegFunc: Start to delete Reg\n"));
-	SetInstallStatus(SSLVPN_COMPONENT_CLSID, aisDeletingReg);
-	if(!DeleteComponentIDRegs())
-	{
-		Log(LOG_WARNING, (L"CRegFunc: DeleteComponentIDRegs failed\n"));
-	}
-	if(!DeleteUninstallRegs())
-	{
-		Log(LOG_WARNING, (L"CRegFunc: DeleteUninstallRegs failed\n"));
-	}
-	if(!DeleteMSIRegs())
-	{
-		Log(LOG_WARNING, (L"CRegFunc: DeleteUninstallRegs failed\n"));
-	}
-	Log(LOG_INFO, (L"CRegFunc: delete Reg finish\n"));
-	return true;
-}
-
-bool CRegFunc::DeleteComponentIDRegs()
-{
-	DWORD dwRet = 0;
-	wchar_t szRegPath[MAX_PATH] = {'\0'};
-	_stprintf_s(szRegPath, MAX_PATH, L"%s\\%s",AIM_REG_PATH, SSLVPN_COMPONENT_CLSID);
-
-	dwRet = SHDeleteKey(HKEY_LOCAL_MACHINE, szRegPath);
-	if(dwRet != ERROR_SUCCESS)
-	{
-		Log(LOG_WARNING, (L"DeleteComponentIDRegs: reg delete key failed, error is %d\n", dwRet));
-	}
-
-	//delete auto run reg, so that can resume outside proxy
-	dwRet = SHDeleteValue(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", L"WebVPN");
-	if(dwRet != ERROR_SUCCESS)
-	{
-		Log(LOG_WARNING, (L"DeleteComponentIDRegs: reg delete auto run key failed, error is %d\n", dwRet));
-	}
-
-	//delete IE particular setting reg
-	dwRet = SHDeleteKey(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Internet Explorer\\Low Rights\\ElevationPolicy\\{82680856-28A3-4099-AD55-7C5201D3194D}");
-	if(dwRet != ERROR_SUCCESS)
-	{
-		Log(LOG_WARNING, (L"DeleteComponentIDRegs: reg delete IE key failed, error is %d\n", dwRet));
-	}
-
-	if(Is64bitOS())
-	{
-		dwRet = SHDeleteKey(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Wow6432Node\\Microsoft\\Internet Explorer\\Low Rights\\ElevationPolicy\\{82680856-28A3-4099-AD55-7C5201D3194D}");
-		if(dwRet != ERROR_SUCCESS)
-		{
-			Log(LOG_WARNING, (L"DeleteComponentIDRegs: reg delete 32bitIE key failed, error is %d\n", dwRet));
-		}
-
-		if (SHDeleteValue(HKEY_LOCAL_MACHINE, AUTORUN_REG_PATH, STANDALONE_AUTORUN) != ERROR_SUCCESS)
-		{
-			Log(LOG_WARNING, (L"Reg delete key VPN failed.\n"));
-		}
-	}
-
-	if (SHDeleteKey(HKEY_LOCAL_MACHINE, VPN_REG_PATH) != ERROR_SUCCESS)
-	{
-		Log(LOG_WARNING, (L"Reg delete key VPN failed.\n"));
-	}
-
-	wchar_t wchOldValue[512] = {0};
-	DWORD dwType = REG_SZ;
-	DWORD dwSize = sizeof(wchOldValue);
-	dwRet = SHGetValue(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon"), _T("Shell"), &dwType, wchOldValue, &dwSize);
-	Log(LOG_INFO, (L"DeleteComponentIDRegs: before set shell value, old value:%s, ret:%d\n", wchOldValue, dwRet));
-
-	if(StrStrIW(wchOldValue, L"StandaloneVPN.exe") != NULL)
-	{
-		dwRet = SHSetValue(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon"), _T("Shell"), REG_SZ, L"explorer.exe", (_tcslen(L"explorer.exe") + 1)*2);
-		Log(LOG_INFO, ("DeleteComponentIDRegs: set value for shell finished, ret:%u\n", dwRet));
-	}
-
-	return true;
-}
-
-bool CRegFunc::DeleteUninstallRegs()
-{
-	wchar_t szRegPath[MAX_PATH] = {'\0'}, szRegWow64Path[MAX_PATH] = {'\0'};
-
-	DWORD hRet = 0;
-	hRet = SHDeleteKey(HKEY_LOCAL_MACHINE, MSI_REGEDIT_DELETE);
-	if(hRet != ERROR_SUCCESS)
-	{
-		Log(LOG_INFO, (L"SHDeleteKey failed, error is %d\n", hRet));
-	}
-
-	_stprintf_s(szRegPath, MAX_PATH-1, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\%s", SSLVPN_DEFAULT_APPNAME);
-	_stprintf_s(szRegWow64Path, MAX_PATH-1, L"SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\%s", SSLVPN_DEFAULT_APPNAME);
-
-
-	DWORD dwRet = SHDeleteKey(HKEY_LOCAL_MACHINE, szRegPath);
-	if(dwRet != ERROR_SUCCESS)
-	{
-		Log(LOG_WARNING, (L"DeleteUninstallRegs: failed , the ret is %d\n", dwRet));
-		return false;
-	}
-
-	if(Is64bitOS())
-	{
-		dwRet = SHDeleteKey(HKEY_LOCAL_MACHINE, szRegWow64Path);
-		if(dwRet != ERROR_SUCCESS)
-		{
-			Log(LOG_WARNING, (L"DeleteUninstallRegs: failed in Wow64 , the ret is %d\n", dwRet));
-		}
-	}
-	return true;
-}
-
-bool CRegFunc::DeleteMSIRegs()
-{
-	DWORD dwRet = 0;
-
-	dwRet = SHDeleteKey(HKEY_CURRENT_USER, MSI_REGEDIT_MEMORY);
-	if (dwRet != ERROR_SUCCESS)
-	{
-		Log(LOG_INFO, (L"SHDeleteKey msi failed, error is %d\n", dwRet));
-	}
-	else
-	{
-		Log(LOG_INFO, (L"SHDeleteKey msi success\n"));
-	}
-
-	DeleteSubKeysbyName(HKEY_CLASSES_ROOT, L"Installer\\Products", L"ProductName", VPN_CLIENT_NAME);
-	SHDeleteKey(HKEY_CLASSES_ROOT, L"Installer\\Products\\F131988C510D00A488582C3E983569A0");
-
-	DeleteSubKeysbyName(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Classes\\Installer\\Products", L"ProductName", VPN_CLIENT_NAME);
-	DeleteSubKeysbyName(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Group Policy\\AppMgmt", L"Deployment Name", VPN_CLIENT_NAME);
-	DeleteSubKeysbyName(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Products", L"DisplayName", VPN_CLIENT_NAME);
-
-	SHDeleteKey(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Classes\\Installer\\Products\\F131988C510D00A488582C3E983569A0");
-	SHDeleteKey(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Products\\F131988C510D00A488582C3E983569A0");
-	
-
-	wstring strRegPath = L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\";
-	if(Is64bitOS())
-	{
-		strRegPath = L"SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\";
-		SHDeleteKey(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Wow6432Node\\Classes\\Installer\\Products\\F131988C510D00A488582C3E983569A0");
-		SHDeleteKey(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Products\\F131988C510D00A488582C3E983569A0");
-		DeleteSubKeysbyName(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Wow6432Node\\Classes\\Installer\\Products", L"ProductName", VPN_CLIENT_NAME);
-		DeleteSubKeysbyName(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Group Policy\\AppMgmt", L"Deployment Name", VPN_CLIENT_NAME);
-		DeleteSubKeysbyName(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Products", L"DisplayName", VPN_CLIENT_NAME);
-	}
-	strRegPath += MSI_REGEDIT_CLSID;
-	dwRet = SHDeleteKey(HKEY_LOCAL_MACHINE, strRegPath.c_str());
-	Log(LOG_INFO, (L"SHDeleteKey %s finished, ret is %d\n", strRegPath.c_str(), dwRet));
-
-	//DeleteSubKeysbyName(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall", L"DisplayName", VPN_CLIENT_NAME);
-	//DeleteSubKeysbyName(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall", L"DisplayName", VPN_CLIENT_NAME);
-
-	return true;
-}
-
-BOOL CRegFunc::DeleteSubKeysbyName(HKEY hRootKey, LPCTSTR lpRegPath, LPCTSTR lpKeyName, LPCTSTR lpKeyValue)
-{
-	Log(LOG_INFO, (L"DeleteSubKeysbyName: keyPath:%s, keyName:%s, keyValue:%s\n", lpRegPath, lpKeyName, lpKeyValue));
-	HKEY hKey = NULL, hEnumKey = NULL;
-	DWORD dwRet = RegOpenKeyEx(hRootKey, lpRegPath, 0, KEY_ALL_ACCESS, &hKey);
-	if(dwRet != ERROR_SUCCESS)
-	{
-		Log(LOG_INFO, (L"DeleteSubKeysbyName: RegOpenKeyEx failed, dwRet:%d\n", dwRet));
-		return FALSE;
-	}
-
-	DWORD dwIndex = 0, dwBufferSize = MAX_PATH;
-	DWORD dwType = REG_SZ, dwSize = 0;
-	wchar_t wchValue[MAX_PATH] = {0}, szProductName[MAX_PATH] = {'\0'};
-	wstring wstrPath = L"";
-
-	//enum the device enum key
-	while(RegEnumKeyEx(hKey, dwIndex++, wchValue, &dwBufferSize, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
-	{
-		memset(szProductName, 0, sizeof(szProductName));
-		dwType = REG_SZ;
-		dwSize = sizeof(szProductName);
-		wstrPath = lpRegPath;
-		wstrPath += L"\\";
-		wstrPath += wchValue;
-		dwRet = SHGetValue(hRootKey, wstrPath.c_str(), lpKeyName, &dwType, szProductName, &dwSize);
-		if(dwRet == ERROR_SUCCESS && StrCmpIW(szProductName, lpKeyValue) == 0)
-		{
-			Log(LOG_INFO, (L"DeleteSubKeysbyName: delete reg key: %s\n", wstrPath.c_str()));
-			SHDeleteKey(hRootKey, wstrPath.c_str());
-		}
-
-		memset(wchValue, 0, sizeof(wchValue));
-		dwBufferSize = MAX_PATH;		
-	}
-
-	if(hKey != NULL)
-	{
-		RegCloseKey(hKey);
-	}
-	Log(LOG_INFO, (L"DeleteSubKeysbyName: finished\n"));
-	return TRUE;
-}
-
-bool CFileFunc::run()
-{
-	Log(LOG_INFO, (L"CFileFunc: Start to delete Local files\n"));
-	bool bRet = true;
-	if(!DeleteComponentFiles())
-	{
-		Log(LOG_WARNING, (L"CFileFunc:DeleteComponentFiles failed\n"));
-		bRet = false;
-	}
-	if(!DeleteTempFiles())
-	{
-		Log(LOG_WARNING, (L"CFileFunc:DeleteTempFiles failed\n"));
-		bRet = false;
-	}
-	if (!DeleteConfigureFile())
-	{
-		Log(LOG_WARNING, (L"CFileFunc:DeleteConfigureFile failed\n"));
-		bRet = false;
-	}
-	DeleteCompanyShortcuts();
-	DeleteMSIFiles();
-	Log(LOG_INFO, (L"CFileFunc: delete Local files finish\n"));
-	return bRet;
-}
-
-bool CFileFunc::DeleteComponentFiles()
-{
-	bool bRet = true;
-	wchar_t szPath[MAX_PATH] = {'\0'};
-	GetApplicationDirectory(szPath);
-	Log(LOG_INFO, (L"DeteleCompanyVPNFolder: start delete folder %s\n", szPath));
-	if (PathFileExists(szPath))
-	{
-		if(EmptyDirectory(szPath))
-		{
-			Log(LOG_INFO, (L"DeleteComponentFiles: %s success\n", szPath));
-		}
-		else
-		{
-			Log(LOG_INFO, (L"DeleteComponentFiles: %s failed\n", szPath));
-			bRet = false;
-		}
-	}
-	memset(szPath, 0, sizeof(szPath));
-	GetInstallManagerDirectory(szPath);
-	Log(LOG_INFO, (L"DeteleCompanyVPNFolder: start delete folder %s\n", szPath));
-	if (PathFileExists(szPath))
-	{
-		if(EmptyDirectory(szPath))
-		{
-			Log(LOG_INFO, (L"DeleteComponentFiles: %s success\n", szPath));
-		}
-		else
-		{
-			Log(LOG_INFO, (L"DeleteComponentFiles: %s failed\n", szPath));
-			bRet = false;
-		}
-	}
-	return bRet;
-}
-
-bool CFileFunc::DeleteTempFiles()
-{
-	wchar_t szTempPath[MAX_PATH] = {'\0'}, szTargetFile[MAX_PATH] = {'\0'};
-	GetTempPath(MAX_PATH,szTempPath);
-	_stprintf_s(szTargetFile,L"%s%s", szTempPath, VPN_DEFAULT_FOLDER_NAME);
-	EmptyDirectory(szTargetFile);
-
-	memset(szTargetFile, 0, MAX_PATH);
-	_stprintf_s(szTargetFile,L"%s\\Low\\%s", szTempPath, VPN_DEFAULT_FOLDER_NAME);
-	EmptyDirectory(szTargetFile);
-
-	return true;
-}
-
-bool CFileFunc::DeleteCompanyShortcuts()
-{
-	HRESULT hRet;
-	TCHAR   szPath[MAX_PATH] = {0};
-	CString strShortcutPath = L"";
-
-	BOOL bSPXClientExist = FALSE;
-	if(IsProcessExistByName(L"arr_srvs.exe") || IsProcessExistByName(L"arr_isrv.exe"))
-	{
-		bSPXClientExist = TRUE;
-	}
-
-	do 
-	{
-		hRet = SHGetFolderPath(NULL, CSIDL_COMMON_PROGRAMS, NULL, SHGFP_TYPE_CURRENT, szPath);
-		if(SUCCEEDED(hRet))
-		{
-			Log(LOG_INFO, (L"DeleteShortcuts(): Path of common programs: %s\n", szPath));
-			strShortcutPath = szPath;
-			strShortcutPath += L"\\";
-			strShortcutPath += VPN_PROVIDEER_NAME;
-			if (bSPXClientExist)
-			{
-				strShortcutPath += L"\\";
-				RemoveFile(strShortcutPath + VPN_CLIENT_NAME + L".lnk");
-				RemoveFile(strShortcutPath + CLIENT_LOGGER_LINK_DISPLAY_NAME + L".lnk");
-				RemoveFile(strShortcutPath + CLIENT_UNINSTALL_LINK_DISPLAY_NAME + L".lnk");
-				RemoveFile(strShortcutPath + CLIENT_CLEANTOOL_LINK_DISPLAY_NAME + L".lnk");
-			}
-			else
-			{
-				EmptyDirectory(strShortcutPath);
-			}
-		}
-		else
-		{
-			Log(LOG_WARNING, ("DeleteShortcuts(): Failed to get path of common programs.\n"));
-			break;
-		}
-
-	}while(0);
-
-	memset(szPath, 0, MAX_PATH);
-
-	//2 remove path of 'User name\Start Menu\Programs'
-	do 
-	{
-		hRet = SHGetFolderPath(NULL, CSIDL_PROGRAMS, NULL, SHGFP_TYPE_CURRENT, szPath);
-		if(SUCCEEDED(hRet))
-		{
-			Log(LOG_INFO, (L"DeleteShortcuts(): Path of current user common programs: %s\n", szPath));
-			strShortcutPath = szPath;
-			strShortcutPath += L"\\";
-			strShortcutPath += VPN_PROVIDEER_NAME;
-			if (bSPXClientExist)
-			{
-				strShortcutPath += L"\\";
-				RemoveFile(strShortcutPath + VPN_CLIENT_NAME + L".lnk");
-				RemoveFile(strShortcutPath + CLIENT_LOGGER_LINK_DISPLAY_NAME + L".lnk");
-				RemoveFile(strShortcutPath + CLIENT_UNINSTALL_LINK_DISPLAY_NAME + L".lnk");
-				RemoveFile(strShortcutPath + CLIENT_CLEANTOOL_LINK_DISPLAY_NAME + L".lnk");
-			}
-			else
-			{
-				EmptyDirectory(strShortcutPath);
-			}
-		}
-		else
-		{
-			Log(LOG_WARNING, ("DeleteShortcuts(): Failed to get path of current user common programs.\n"));
-			break;
-		}
-
-	}while(0);
-
-	memset(szPath, 0, MAX_PATH);
-
-
-	//3 remove path of 'All Users\Desktop\Array L3 VPN Connect.lnk'
-	do 
-	{
-		hRet = SHGetFolderPath(NULL, CSIDL_COMMON_DESKTOPDIRECTORY , NULL, SHGFP_TYPE_CURRENT, szPath);
-		if(SUCCEEDED(hRet))
-		{
-			Log(LOG_INFO, (L"DeleteShortcuts(): Path of all user desktop: %s\n", szPath));
-			strShortcutPath = szPath;
-			strShortcutPath += L"\\";
-			strShortcutPath +=	VPN_CLIENT_NAME;
-			strShortcutPath += L".lnk";
-			RemoveFile(strShortcutPath);
-		}
-		else
-		{
-			Log(LOG_WARNING, ("DeleteShortcuts(): Failed to get path of all user desktop.\n"));
-			break;
-		}
-
-	} while (0);
-
-	//4 remove path of 'user name\Desktop\Array L3 VPN Connect.lnk'
-	do 
-	{
-		hRet = SHGetFolderPath(NULL, CSIDL_DESKTOPDIRECTORY , NULL, SHGFP_TYPE_CURRENT, szPath);
-		if(SUCCEEDED(hRet))
-		{
-			Log(LOG_INFO, (L"DeleteShortcuts(): Path of all user desktop: %s\n", szPath));
-			strShortcutPath = szPath;
-			strShortcutPath += L"\\";
-			strShortcutPath += VPN_CLIENT_NAME;
-			strShortcutPath += L".lnk";
-			RemoveFile(strShortcutPath);
-		}
-		else
-		{
-			Log(LOG_WARNING, ("DeleteShortcuts(): Failed to get path of all user desktop.\n"));
-			break;
-		}
-
-	} while (0);
-
-	return true;
-}
-
-bool CFileFunc::DeleteMSIFiles()
-{
-	wchar_t wchCurrentPath[MAX_PATH] = {0};
-	GetWindowsDirectory(wchCurrentPath, MAX_PATH); // c:\windows
-	PathRemoveFileSpec(wchCurrentPath);
-	PathRemoveFileSpec(wchCurrentPath);
-	if(Is64bitOS())
-	{
-		PathAddExtension(wchCurrentPath, L"\\Program Files (x86)\\Array Networks\\MSIInstallManager");
-	}
-	else
-	{
-		PathAddExtension(wchCurrentPath, L"Program Files\\Array Networks\\MSIInstallManager");
-	}
-
-	if (PathFileExists(wchCurrentPath))
-	{
-		if(EmptyDirectory(wchCurrentPath))
-		{
-			Log(LOG_INFO, (L"CFileFunc delete MSI local files: %s success\n", wchCurrentPath));
-		}
-		else
-		{
-			Log(LOG_INFO, (L"CFileFunc delete MSI local files: %s failed\n", wchCurrentPath));
-			return false;
-		}
-	}
-
-	return true;
-}
-
-bool CFileFunc::DeleteConfigureFile()
-{
-	wstring strConfigurePath = GetAllUserAppDataPath();
-	strConfigurePath += L"\\";
-	strConfigurePath += VPN_DEFAULT_FOLDER_NAME;
-	strConfigurePath += L"\\";
-	strConfigurePath += CONFIGURE_FILE;
-	if (PathFileExists(strConfigurePath.c_str()))
-	{
-		if (!RemoveFile(strConfigurePath.c_str()))
-		{
-			Log(LOG_INFO, (L"CFileFunc delete Configure files: %s failed\n", strConfigurePath.c_str()));
-			return false;
-		}
-		Log(LOG_INFO, (L"CFileFunc delete Configure files: %s success\n", strConfigurePath.c_str()));
-		return true;
-	}
-	return true;
-}
-
-bool CClientSecurityFunc::run()
-{
-	Log(LOG_INFO, (L"CClientSecurityFunc: Start to delete ClientSecurity component\n"));
-	bool bRet  = true;
-	if (!DeleteTempClientSecurityFiles())
-	{
-		bRet = false;
-	}
-	DeleteDownloadProgramFiles(CLIENTSECURITY_LANGUAGE_1028_NAME);
-	DeleteDownloadProgramFiles(CLIENTSECURITY_LANGUAGE_1033_NAME);
-	DeleteDownloadProgramFiles(CLIENTSECURITY_LANGUAGE_1041_NAME);
-	DeleteDownloadProgramFiles(CLIENTSECURITY_LANGUAGE_2052_NAME);
-	DeleteDownloadProgramFiles(CLIENTSECURITY_ACTIVEX_NAME);
-	DeleteDownloadProgramFiles(CLIENTSECURITY_ACTIVEX_INF_NAME);
-	if (Is64bitOS())
-	{
-		DeleteDownloadProgramFiles(CLIENTSECURITY_ACTIVEX_64BIT_NAME);
-		DeleteDownloadProgramFiles(CLIENTSECURITY_ACTIVEX_INF_64BIT_NAME);
-		SHDeleteKey(HKEY_CLASSES_ROOT, L"Wow6432Node\\CLSID\\{EE64AC11-5480-444E-AB2F-A9780EC929D5}");
-	}
-	SHDeleteKey(HKEY_CLASSES_ROOT, L"CLSID\\{EE64AC11-5480-444E-AB2F-A9780EC929D5}");
-	Log(LOG_INFO, (L"CClientSecurityFunc: Delete ClientSecurity component finish\n"));
-	return bRet;
-}
-
-bool CClientSecurityFunc::DeleteTempClientSecurityFiles()
-{
-	bool bRet = true;
-	wchar_t szTempPath[MAX_PATH] = {'\0'}, szTargetFile[MAX_PATH] = {'\0'};
-	GetTempPath(MAX_PATH,szTempPath);
-	_stprintf_s(szTargetFile,L"%s%s", szTempPath, CLIENTSECURITY_NAME);
-
-
-	if (PathFileExists(szTargetFile))
-	{
-		if (EmptyDirectory(szTargetFile))
-		{
-			Log(LOG_INFO, (L"CClientSecurityFunc: DeleteCSFiles: %s success\n", szTargetFile));
-		} 
-		else
-		{
-			Log(LOG_WARNING, (L"CClientSecurityFunc: DeleteCSFiles: %s error\n", szTargetFile));
-			bRet = false;
-		}
-	}
-
-	memset(szTargetFile, 0, MAX_PATH);
-
-	_stprintf_s(szTargetFile,L"%sLow\\%s", szTempPath, CLIENTSECURITY_NAME);
-	if (PathFileExists(szTargetFile))
-	{
-		if (EmptyDirectory(szTargetFile))
-		{
-			Log(LOG_INFO, (L"CClientSecurityFunc: DeleteCSFiles: %s success\n", szTargetFile));
-		} 
-		else
-		{
-			Log(LOG_WARNING, (L"CClientSecurityFunc: DeleteCSFiles: %s error\n", szTargetFile));
-			bRet = false;
-		}
-	}
-	return bRet;
-}
-
-bool CClientSecurityFunc::DeleteDownloadProgramFiles(LPCWSTR lpClientSecurityFileName)
-{
-	wchar_t szPath[MAX_PATH] = {'\0'};
-	GetWindowsDirectory(szPath, MAX_PATH);
-	_tcscat_s(szPath, ACTIVEX_CACHE_PATH);
-	_tcscat_s(szPath, L"\\");
-	_tcscat_s(szPath, lpClientSecurityFileName);
-	if (DeleteFile(szPath))
-	{
-		Log(LOG_INFO, (L"CClientSecurityFunc: DeleteDownloadProgramFiles: %s success\n", szPath));
-	} 
-	else
-	{
-		Log(LOG_WARNING, (L"CClientSecurityFunc: DeleteDownloadProgramFiles: %s error\n", szPath));
-	}
-
-	memset(szPath, 0, sizeof(szPath));
-	GetWindowsDirectory(szPath, MAX_PATH);
-	_tcscat_s(szPath, ACTIVEX_CACHE_PATH);
-	_tcscat_s(szPath, L"\\CONFLICT.1\\");
-	_tcscat_s(szPath, lpClientSecurityFileName);
-	if (DeleteFile(szPath))
-	{
-		Log(LOG_INFO, (L"CClientSecurityFunc: DeleteDownloadProgramFiles: %s success\n", szPath));
-	} 
-	else
-	{
-		Log(LOG_WARNING, (L"CClientSecurityFunc: DeleteDownloadProgramFiles: %s error\n", szPath));
-	}
-
-	memset(szPath, 0, sizeof(szPath));
-	GetWindowsDirectory(szPath, MAX_PATH);
-	_tcscat_s(szPath, ACTIVEX_CACHE_PATH);
-	_tcscat_s(szPath, L"\\CONFLICT.100\\");
-	_tcscat_s(szPath, lpClientSecurityFileName);
-	if (DeleteFile(szPath))
-	{
-		Log(LOG_INFO, (L"CClientSecurityFunc: DeleteDownloadProgramFiles: %s success\n", szPath));
-	} 
-	else
-	{
-		Log(LOG_WARNING, (L"CClientSecurityFunc: DeleteDownloadProgramFiles: %s error\n", szPath));
-	}
-	return true;
-}
-
-bool CHWIDFunc::run()
-{
-	Log(LOG_INFO, (L"CHWIDFunc: Start to delete HWID component\n"));
-	bool bRet = true;
-	if (Is64bitOS())
-	{
-		if (!DeleteHWIDFiles(HWID_ACTIVEX_FILE_NAME_X64))
-		{
-			bRet = false;
-		}
-
-		if (!DeleteHWIDFiles(HWID_ACTIVEX_INF_NAME_X64))
-		{
-			bRet = false;
-		}
-		SHDeleteKey(HKEY_CLASSES_ROOT, L"Wow6432Node\\CLSID\\{C96F218E-0C9A-48C0-A09C-CA2CB7C6E892}");
-	} 
-	if (!DeleteHWIDFiles(HWID_ACTIVEX_FILE_NAME))
-	{
-		bRet = false;
-	}
-	if (!DeleteHWIDFiles(HWID_ACTIVEX_INF_NAME))
-	{
-		bRet = false;
-	}
-	SHDeleteKey(HKEY_CLASSES_ROOT, L"CLSID\\{C96F218E-0C9A-48C0-A09C-CA2CB7C6E892}");
-	Log(LOG_INFO, (L"CHWIDFunc: Delete HWID component finish\n"));
-	return bRet;
-}
-
-bool CHWIDFunc::DeleteHWIDFiles(LPCWSTR lpHWIDFileName)
-{
-	wchar_t szPath[MAX_PATH] = {'\0'};
-	GetSystemDirectory(szPath, MAX_PATH);
-	_tcscat_s(szPath, L"\\");
-	_tcscat_s(szPath, lpHWIDFileName);
-	if (PathFileExists(szPath))
-	{
-		if (DeleteFile(szPath))
-		{
-			Log(LOG_INFO, (L"CHWIDFunc: DeleteHWIDFiles: %s success\n", szPath));
-		} 
-		else
-		{
-			Log(LOG_INFO, (L"CHWIDFunc: DeleteHWIDFiles: %s error\n", szPath));
-			return false;
-		}
-	}
-
-	if (Is64bitOS())
-	{
-		memset(szPath, 0, sizeof(szPath));
-		GetSystemWow64Directory(szPath, MAX_PATH);
-
-		_tcscat_s(szPath, L"\\");
-		_tcscat_s(szPath, lpHWIDFileName);
-
-		if (PathFileExists(szPath))
-		{
-			if (DeleteFile(szPath))
-			{
-				Log(LOG_INFO, (L"CHWIDFunc: DeleteHWIDFiles: %s success\n", szPath));
-			} 
-			else
-			{
-				Log(LOG_INFO, (L"CHWIDFunc: DeleteHWIDFiles: %s error\n", szPath));
-				return false;
-			}
-		}
-	}
-	return true;
-}
+	}
+
+	Log(LOG_INFO, (L"RepairRegInstaller: start\n"));
+	wchar_t wchValue[MAX_PATH] = {'\0'};
+	DWORD dwType = REG_SZ;
+	DWORD dwSize = sizeof(wchValue);
+	DWORD dwRet = SHGetValue(HKEY_LOCAL_MACHINE, VPN_ADAPTER_INSTALLER_REG_PATH, VPN_ADAPTER_INSTALLER_REG_NAME, &dwType, wchValue, &dwSize);
+	if(dwRet != ERROR_SUCCESS || _tcsicmp(wchValue, VPN_ADAPTER_INSTALLER_REG_VALUE) != 0)
+	{
+		Log(LOG_INFO, (L"RepairRegInstaller: the value was changed, we should repair it:%s\n", wchValue));
+		dwRet = SHSetValue(HKEY_LOCAL_MACHINE, VPN_ADAPTER_INSTALLER_REG_PATH, VPN_ADAPTER_INSTALLER_REG_NAME, REG_SZ, VPN_ADAPTER_INSTALLER_REG_VALUE, (_tcslen(VPN_ADAPTER_INSTALLER_REG_VALUE)+1)*2);
+		if(dwRet != ERROR_SUCCESS)
+		{
+			Log(LOG_WARNING, (L"RepairRegInstaller: SHSetValue failed, err is %d\n", dwRet));
+		}
+		else
+		{
+			Log(LOG_INFO, (L"RepairRegInstaller: SHSetValue success.\n"));
+		}
+	}
+	else
+	{
+		Log(LOG_INFO, (L"RepairRegInstaller: the value correct, no need repair\n"));
+	}
+}
+
+int CVNICFunc::fnRemove_ByDevID(LPCTSTR hwID)
+{
+	RepairRegInstaller();
+
+	wchar_t szPath[MAX_PATH] = {'\0'};
+	GetModuleFileNameW(GetModuleHandle(NULL), szPath, MAX_PATH);
+	PathRemoveFileSpec(szPath);
+	PathAppend(szPath, DEVCON_EXE_NAME);
+	if(!PathFileExists(szPath))
+	{
+		Log(LOG_WARNING, (L"fnRemove_ByDevID: file%s not found\n", szPath));
+		return CFG_FAILURE;
+	}
+
+	Log(LOG_INFO, (L"fnRemove_ByDevID: file %s found\n", szPath));
+
+	HANDLE   hRead,   hWrite; 
+	SECURITY_ATTRIBUTES   sec; 
+	sec.nLength   =   sizeof(SECURITY_ATTRIBUTES); 
+	sec.bInheritHandle   =   TRUE; 
+	sec.lpSecurityDescriptor   =   NULL; 
+	BOOL   fResult   =   CreatePipe(&hRead,   &hWrite,   &sec,   0); 
+
+	STARTUPINFO si; 
+	PROCESS_INFORMATION pi; 
+	ZeroMemory(&si, sizeof(STARTUPINFO));
+	si.cb = sizeof(STARTUPINFO);
+	si.wShowWindow = SW_HIDE; 
+	si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; 
+	si.hStdOutput   =   hWrite; 
+	si.hStdInput   =   hRead; 
+	si.hStdError   =   hWrite;
+
+	CString csCommand;
+	csCommand.Format(L"\"%s\" remove  \"%s\"", szPath, VNIC_DEV_ID);
+	Log(LOG_INFO, (L"csCommand:%s\n", csCommand));
+
+	if(!::CreateProcess(NULL, csCommand.GetBuffer(0), NULL, NULL, TRUE, NULL, NULL, NULL, &si, &pi))
+	{ 
+		Log(LOG_WARNING, (L"CreateProcess failed, error:%d, command is %s", GetLastError(), csCommand.GetBuffer(0)));
+		return CFG_FAILURE;
+	}
+
+	if(pi.hProcess == NULL)
+	{
+		Log(LOG_WARNING,(L"CreateProcess: hProcess is null\n"));
+		return CFG_FAILURE;
+	}
+	// show info to user when cache cleaner triggered and exit.
+	DWORD dwRe = ::WaitForSingleObject(pi.hProcess, 60*1000);
+	if(WAIT_OBJECT_0 == dwRe)
+	{
+		Log(LOG_INFO, ("Process devcon.exe has exit\n"));
+	}
+	else
+	{
+		Log(LOG_INFO, ("WaitForSingleObject timeout!\n"));
+	}
+	char szBuffer[MAX_PATH]  =  {0};
+	if(fResult) 
+	{
+		DWORD  dwReadLen   =   0;
+
+		fResult = ReadFile(hRead, szBuffer, MAX_PATH, &dwReadLen, NULL);
+		Log(LOG_ERROR, ("Adapter removed: return: %s\n", szBuffer));
+	}
+
+	if(pi.hProcess)
+	{
+		CloseHandle(pi.hProcess);
+	}
+	if(pi.hThread)
+	{
+		CloseHandle(pi.hThread);
+	}
+
+	if(StrStrIA(szBuffer, "device(s) were removed") != NULL)
+	{
+		return CFG_EXIT_OK;
+	}
+
+	return CFG_EXIT_OK;
+}
+
+BOOL CVNICFunc::UninstallDevice(LPCTSTR INFFile)
+{
+	Log(LOG_INFO, (L"VPN L3 Installer : enter UninstallDevice.\n"));
+
+	BOOL ReturnValue = FALSE;
+	g_cStrInf = INFFile;
+	CComVariant varParam;
+	V_VT(&varParam) = VT_UI4;
+	VARIANT_BOOL vbCancel = VARIANT_FALSE;
+	HANDLE hThread = NULL;
+	hThread = (HANDLE) _beginthreadex(NULL, 0, ThreadUninstallDevice, NULL, 0, NULL);
+	int iNum = 0;
+	DWORD dwValue = 0;
+
+	Sleep(1000);
+	V_UI4(&varParam) = 2403;
+	while(iNum < 2*60) //sleep 60 seconds
+	{
+		dwValue = 0;
+		wchar_t szRegPath[MAX_PATH] = {'\0'};
+		DWORD dwType = REG_DWORD;
+		DWORD dwSize = sizeof(dwValue);
+		_stprintf_s(szRegPath, MAX_PATH, L"%s\\%s", AIM_REG_PATH, SSLVPN_COMPONENT_CLSID);
+		SHGetValue(HKEY_LOCAL_MACHINE, szRegPath, VNIC_UNINSTALL_STATUS, &dwType, &dwValue, &dwSize);
+		if(dwValue != VNIC_FINISHED)
+		{
+			Sleep(500);
+			continue;
+		}
+		break;
+	}
+	V_UI4(&varParam) = 2403;
+
+	wchar_t szRegPath[MAX_PATH] = {'\0'};
+	_stprintf_s(szRegPath, MAX_PATH, L"%s\\%s", AIM_REG_PATH, SSLVPN_COMPONENT_CLSID);
+
+	dwValue = VNIC_NONE;
+	SHSetValue(HKEY_LOCAL_MACHINE, szRegPath, VNIC_UNINSTALL_STATUS, REG_DWORD, &dwValue, sizeof(dwValue));
+
+
+	DWORD dwType = REG_DWORD;
+	DWORD dwSize = sizeof(dwValue);
+	DWORD dwRet = SHGetValue(HKEY_LOCAL_MACHINE, szRegPath, VNIC_UNINSTALL_RETURNVALUE, &dwType, &dwValue, &dwSize);
+	if(dwRet != ERROR_SUCCESS)
+	{
+		Log(LOG_WARNING, (L"Query cmdUpdate value: can not get the value, error is %d\n", dwRet));
+	}
+	else
+	{
+		ReturnValue  = (BOOL)dwValue;
+	}
+
+	if(hThread != NULL)
+	{
+		CloseHandle(hThread);
+	}
+
+	return ReturnValue;
+}
+
+BOOL GetDeviceandClassID(LPTSTR INFFile, LPTSTR  DeviceID OPTIONAL, LPTSTR  DeviceDesc OPTIONAL)
+{
+	HINF  hInfFile;
+	INFCONTEXT InfLine;
+	wchar_t   LineText[MAX_PATH] = { 0 }, DeviceWarring[MAX_PATH] = { 0 };
+	wchar_t*   HardwareID;
+	UINT err;
+
+	//Get Device ID from the inf file.
+	hInfFile = SetupOpenInfFile(INFFile, NULL, INF_STYLE_WIN4, &err);
+	if(hInfFile == INVALID_HANDLE_VALUE)
+	{
+		Log(LOG_ERROR, (L"VPN Installer : in GetDeviceandClassID Can not open the INF file:%s\n", INFFile));
+		return FALSE;
+	}
+	if(SetupFindFirstLine(hInfFile, L"Manufacturer", NULL, &InfLine) == FALSE)
+	{
+		Log(LOG_ERROR, (L"VPN Installer : in GetDeviceandClassID Can not get the INF Manufacturer sections\n"));
+		SetupCloseInfFile(hInfFile);
+		return FALSE;
+	}
+	if(SetupGetLineText(&InfLine, NULL, NULL, NULL, LineText, MAX_PATH, NULL) == FALSE)
+	{
+		Log(LOG_ERROR, (L"VPN Installer : in GetDeviceandClassID can not get the keyword provider from the maunfacturer section.\n"));
+		SetupCloseInfFile(hInfFile);
+		return FALSE;
+	}
+	//the inf file is 
+	//[Manufacturer]
+	//%l_Provider% = ArrayNetworks,NTx86
+	//the old is
+	//[Manufacturer]
+	//%l_Provider% = ArrayNetworks
+	for(unsigned int i=0;i<_tcslen(LineText);i++)
+	{
+		if(LineText[i]==',')
+		{
+			LineText[i]='\0';
+			break;
+		}
+	}
+	if(SetupFindFirstLine(hInfFile, LineText, NULL, &InfLine) == FALSE)
+	{
+		Log(LOG_ERROR, (L"VPN Installer : in GetDeviceandClassID Can not get the INF Device sections.\n"));
+		SetupCloseInfFile(hInfFile);
+		return FALSE;
+	}
+	if(SetupGetLineText(&InfLine, NULL, NULL, NULL, LineText, MAX_PATH, NULL) == FALSE)
+	{
+		Log(LOG_ERROR, (L"VPN Installer : in GetDeviceandClassID can not get the keyword provider from the device section.\n"));
+		SetupCloseInfFile(hInfFile);
+		return FALSE;
+	}
+	//i must clear the string.
+	LineText[_tcslen(LineText)]=LineText[_tcslen(LineText)+1] = '\0';
+	//the inf file can not be changed anyway!!!!!!!!!!!!!!!,it must be as follows:
+	//%DeviceDescription%  =   ATP.ndi,     VPNATP
+	HardwareID = wcschr(LineText, L',');
+	if(HardwareID == NULL)
+	{
+		Log(LOG_ERROR, (L"VPN Installer : in GetDeviceandClassID can not get the HardwareID from the device section.\n"));
+		SetupCloseInfFile(hInfFile);
+		return FALSE;		
+	}
+	HardwareID++;
+
+	//get the device description.
+	if(DeviceDesc)
+	{
+		if(SetupFindFirstLine(hInfFile, L"Strings", L"DeviceDescription", &InfLine) == FALSE)
+		{	
+			if(SetupFindFirstLine(hInfFile, L"Strings", L"l_DeviceDescription", &InfLine) == FALSE)
+			{
+				Log(LOG_ERROR, (L"VPN Installer : in GetDeviceandClassID Can not get the INF String sections.\n"));
+				SetupCloseInfFile(hInfFile);
+				return FALSE;
+			}
+		}
+		if(SetupGetLineText(&InfLine, NULL, NULL, NULL, DeviceWarring, MAX_PATH, NULL) == FALSE)
+		{
+			Log(LOG_ERROR, (L"VPN Installer : in GetDeviceandClassID can not get the keyword string from the string section.\n"));
+			SetupCloseInfFile(hInfFile);
+			return FALSE;
+		}
+	}
+	SetupCloseInfFile(hInfFile);
+	if(DeviceID)
+	{
+		lstrcpy(DeviceID, HardwareID);
+	}
+	if(DeviceDesc)
+	{
+		lstrcpy(DeviceDesc, DeviceWarring);
+	}
+	return TRUE;
+}
+
+bool DeleteEnumDevice()
+{
+	HDEVINFO        devs = INVALID_HANDLE_VALUE;
+	SP_DEVINFO_DATA devInfo;
+	HKEY            hDeviceKey = NULL;
+	HKEY            hEnumKey = NULL;
+	TCHAR            EnumPath[MAX_PATH] = {'\0'};
+	TCHAR RegPath[MAX_PATH] = {'\0'};
+	TCHAR            szHardwareId[MAX_PATH]= {'\0'};
+	TCHAR TempKey[MAX_PATH]= {'\0'};
+	TCHAR			DeviceEnumPath[20][MAX_PATH] = {0};
+	int             Length, iEnumNum;
+	bool            bReturn = false;
+
+#define MAX_ENUM_DEVICE_NUMBER     20
+
+	Log(LOG_INFO, (L" enter DeleteEnumDevice........\n"));
+	devs = SetupDiGetClassDevsEx(NULL,
+		NULL,
+		NULL,
+		(DIGCF_ALLCLASSES) | DIGCF_PRESENT,
+		NULL,
+		L"",
+		NULL);
+
+	if(devs == INVALID_HANDLE_VALUE) 
+	{
+		Log(LOG_ERROR, (L" in DeleteEnumDevice,SetupDiGetClassDevsEx failed.\n"));
+		goto final;
+	}
+
+	//open the device key
+	_stprintf_s(RegPath, MAX_PATH, _T("%s\\%s"), DEVICE_REGISTER_PATH, DEVICE_ENUM_PATH);
+	if(RegOpenKey(HKEY_LOCAL_MACHINE, RegPath, &hDeviceKey) == ERROR_SUCCESS)
+	{
+		Log(LOG_INFO, (L" in DeleteEnumDevice,RegOpenKeyA success:%s.\n", RegPath));
+	}
+	else
+	{
+		Log(LOG_INFO, (L" in DeleteEnumDevice,RegOpenKeyA failed:%s.\n", RegPath));
+		goto final;
+	}
+	Length = sizeof(TempKey);
+	iEnumNum = 0;
+	//enum the device enum key
+	while(RegEnumKeyEx(hDeviceKey, iEnumNum++, TempKey, (ULONG*)&Length, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
+	{
+		_stprintf_s(EnumPath, MAX_PATH, _T("%s\\%s"), DEVICE_ENUM_PATH, TempKey);
+		_stprintf_s(RegPath, MAX_PATH, _T("%s\\%s"), DEVICE_REGISTER_PATH, EnumPath);
+		if(RegOpenKey(HKEY_LOCAL_MACHINE, RegPath, &hEnumKey) == ERROR_SUCCESS)
+		{
+			Log(LOG_INFO, (L" in DeleteEnumDevice,RegOpenKeyA success:%s.\n", RegPath));
+		}
+		else
+		{
+			Log(LOG_INFO, (L" in DeleteEnumDevice,RegOpenKeyA failed:%s.\n", RegPath));
+			continue;
+		}
+		Length = MAX_PATH;
+		memset(szHardwareId, MAX_PATH, 0);
+		if(RegQueryValueEx(hEnumKey, L"HardwareID", NULL, NULL, (UCHAR*)szHardwareId, (ULONG*)&Length) == ERROR_SUCCESS)
+		{
+			Log(LOG_INFO, (L" in DeleteEnumDevice, Reg query success.\n"));
+			RegCloseKey(hEnumKey);
+
+			if(_tcsicmp(szHardwareId, VNIC_DEV_ID) == 0)
+			{
+				//this is our device;
+				Log(LOG_INFO, (L" in DeleteEnumDevice,this is our device.\n"));
+			}
+			else
+			{
+				Log(LOG_INFO, (L" in DeleteEnumDevice,this is not our device.\n"));
+				continue;
+			}
+		}
+		else
+		{
+			Log(LOG_INFO, (L" in DeleteEnumDevice,Regquery failed.\n"));
+			RegCloseKey(hEnumKey);
+			Length = MAX_PATH;
+			continue;
+		}
+		//restore the device enum path.
+		if(iEnumNum < MAX_ENUM_DEVICE_NUMBER)
+		{
+			_tcscpy(DeviceEnumPath[iEnumNum], EnumPath);
+		}
+		else
+		{
+			Log(LOG_INFO, (L"in DeleteEnumDevice,too many enum path......\n"));
+		}
+		Length = MAX_PATH;
+	}
+	//delete the matched device
+	for(iEnumNum = 0; iEnumNum < MAX_ENUM_DEVICE_NUMBER; iEnumNum++)
+	{
+		if(_tcslen(DeviceEnumPath[iEnumNum]) == 0)
+		{
+			continue;
+		}
+		memset(&devInfo, 0, sizeof(devInfo));
+		devInfo.cbSize = sizeof(devInfo);
+		//clear the device enum path.
+		memset(EnumPath, 0, sizeof(EnumPath));
+		_tcscpy(EnumPath, DeviceEnumPath[iEnumNum]);
+		if(!SetupDiOpenDeviceInfo(devs, EnumPath, NULL, 0, &devInfo))
+		{
+			Log(LOG_INFO, (L"in DeleteEnumDevice,SetupDiOpenDeviceInfo failed.:%s\n", EnumPath));
+			//delete the device register path,//root\net\000x
+			_tcscpy(TempKey, &EnumPath[9]);
+			if(SHDeleteKey (hDeviceKey, TempKey) == ERROR_SUCCESS)
+			{
+				Log(LOG_INFO, (L"in DeleteEnumDevice,delete Key success:%s.\n", TempKey));
+			}
+			else
+			{
+				Log(LOG_INFO, (L"in DeleteEnumDevice,delete Key failed:%s.\n", TempKey));
+			}
+			continue;
+		}
+
+		if(!SetupDiCallClassInstaller(DIF_REMOVE, devs, &devInfo))
+		{
+			Log(LOG_INFO, (L"in DeleteEnumDevice,SetupDiCallClassInstaller failed.error:%0x\n", GetLastError()));
+		}
+		else
+		{
+			Log(LOG_INFO, (L"in DeleteEnumDevice,SetupDiCallClassInstaller succeed.\n"));
+			bReturn = true;
+		}
+	}
+	RegCloseKey(hDeviceKey);
+	RegCloseKey(hDeviceKey);
+
+
+final:   
+	if(devs != INVALID_HANDLE_VALUE) 
+	{
+		SetupDiDestroyDeviceInfoList(devs);
+	}
+	Log(LOG_INFO, (L" leave DeleteEnumDevice........\n"));
+	return bReturn;
+}
+
+void ClearVNICRegister_NetworkConnection()
+{
+	HKEY            hDeviceKey = NULL, hEnumKey = NULL, hDevicePathKey = NULL;
+	wchar_t         wchName[MAX_PATH] = {'\0'}, RegPath[MAX_PATH] = {'\0'}, TempPath[MAX_PATH] = {'\0'} ,HardWareIdInfo[MAX_PATH] = {'\0'}, DeviceInstanceID[MAX_PATH] = {'\0'}, DeviceNameInfo[MAX_PATH] = {'\0'};
+	int             iSubkeyNumber = 0, Length = 0;
+	DWORD           dwRet = 0;
+
+	_stprintf_s(RegPath, L"%s\\Descriptions", NETWORK_CONNECTION);
+	_stprintf_s(wchName, L"%s%s", VPN_PROVIDEER_NAME, VPN_ADAPTER_POSTFIX);
+	dwRet = SHDeleteValue(HKEY_LOCAL_MACHINE, RegPath, wchName); 
+	Log(LOG_INFO, (L"VNIC adapter number remove finished, ret is %d\n", dwRet));
+
+	//open the device key
+	_stprintf_s(RegPath, L"%s", NETWORK_CONNECTION);
+	dwRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, RegPath, 0, KEY_READ, &hDeviceKey);
+	if(dwRet != ERROR_SUCCESS)
+	{
+		Log(LOG_ERROR, (L"In Clear VNIC Register,RegOpenKey failed:%d.\n", dwRet));
+		return;
+	}
+
+	Length = sizeof(TempPath);
+	iSubkeyNumber = 0;
+	//enum the device enum key
+	while(RegEnumKeyEx(hDeviceKey, iSubkeyNumber++, TempPath, (ULONG*)&Length, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
+	{
+		_stprintf_s(RegPath, L"%s\\%s\\%s", NETWORK_CONNECTION, TempPath, L"Connection");
+		dwRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, RegPath, 0, KEY_READ, &hEnumKey);
+		if(dwRet != ERROR_SUCCESS)
+		{
+			memset(TempPath,0,sizeof(TempPath));
+			Length = MAX_PATH;
+			continue;
+		}
+		bool bShouldDeleteTempKey = false;
+		Length = MAX_PATH;
+		memset(DeviceNameInfo, MAX_PATH, 0);
+		dwRet = RegQueryValueEx(hEnumKey, L"Name", NULL, NULL, (LPBYTE)DeviceNameInfo, (LPDWORD)&Length);
+		if(dwRet == ERROR_SUCCESS)
+		{
+			wchar_t szCompanyName[MAX_PATH] = {'\0'};
+			GetCompanyName(szCompanyName);
+			_tcscat(szCompanyName, VPN_ADAPTER_POSTFIX);
+			if(StrStrIW(DeviceNameInfo, szCompanyName) != NULL)
+			{
+				bShouldDeleteTempKey = true;
+			}
+		}
+		else
+		{
+			Log(LOG_INFO, (L"In Clear VNIC Register: Name query failed, ret is %d\n", dwRet));
+		}
+
+		Length = MAX_PATH;
+		memset(DeviceInstanceID, MAX_PATH, 0);
+		dwRet = RegQueryValueEx(hEnumKey, L"PnpInstanceID", NULL, NULL, (LPBYTE)DeviceInstanceID, (LPDWORD)&Length);
+		if(dwRet == ERROR_SUCCESS)
+		{
+			if(StrStrIW(DeviceInstanceID, DEVICE_ENUM_PATH) != NULL)
+			{
+				//this is root device;
+				_stprintf_s(RegPath, L"%s\\%s", DEVICE_REGISTER_PATH, DeviceInstanceID);
+				dwRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, RegPath, 0, KEY_READ, &hDevicePathKey);
+				if(dwRet == ERROR_SUCCESS)
+				{
+					Length = MAX_PATH;
+					memset(HardWareIdInfo, MAX_PATH, 0);
+					dwRet = RegQueryValueEx(hDevicePathKey, L"HardwareID", NULL, NULL, (LPBYTE)HardWareIdInfo, (LPDWORD)&Length);
+					if(dwRet == ERROR_SUCCESS)
+					{
+						if(_tcsicmp(HardWareIdInfo, VNIC_DEV_ID) == 0)
+						{
+							//this is our device;
+							bShouldDeleteTempKey = true;
+							dwRet = SHDeleteKey(HKEY_LOCAL_MACHINE, RegPath);
+							Log(LOG_INFO, (L"In Clear VNIC Register,reg %s was deleted, return value is %d\n", RegPath, dwRet));
+						}
+
+					}
+					else
+					{
+						Log(LOG_INFO, (L"In Clear VNIC Register: DeviceDesc query failed, ret is %d\n", dwRet));
+					}
+				}
+				else
+				{
+					Log(LOG_INFO, (L"In Clear VNIC Register: reg open failed, ret is %d\n", dwRet));
+				}
+
+			}
+		}
+		if(bShouldDeleteTempKey)
+		{
+			dwRet = SHDeleteKey(hDeviceKey, TempPath);
+			Log(LOG_INFO, (L"In Clear VNIC Register,reg %s was deleted, return value is %d\n", TempPath, dwRet));
+		}
+
+
+		memset(TempPath,0,sizeof(TempPath));
+		RegCloseKey(hDevicePathKey);
+		hDevicePathKey = NULL;
+		RegCloseKey(hEnumKey);
+		hEnumKey = NULL;
+		Length = MAX_PATH;
+
+	}
+	if(hDeviceKey)
+	{
+		RegCloseKey(hDeviceKey);
+	}
+	if(hEnumKey)
+	{
+		RegCloseKey(hEnumKey);
+	}
+	if(hDevicePathKey)
+	{
+		RegCloseKey(hDevicePathKey);
+	}
+}
+
+void ClearVNICRegister_EnumDevice()
+{
+	HKEY            hDeviceKey = NULL, hEnumKey = NULL;
+	wchar_t         RegPath[MAX_PATH] = {'\0'}, TempPath[MAX_PATH] = {'\0'} ,HardWareIdInfo[MAX_PATH] = {'\0'};
+	int             iSubkeyNumber = 0, Length = 0;
+	DWORD           dwRet = 0;
+
+
+	//open the device key
+	_stprintf_s(RegPath, L"%s\\Root\\NET", DEVICE_REGISTER_PATH);
+	dwRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, RegPath, 0, KEY_READ, &hDeviceKey);
+	if(dwRet != ERROR_SUCCESS)
+	{
+		Log(LOG_INFO, (L"In Clear VNIC Register, RegOpenKey root\\net failed: %d.\n", dwRet));
+		return;
+	}
+
+	Length = sizeof(TempPath);
+	iSubkeyNumber = 0;
+	//enum the device enum key
+	while(RegEnumKeyEx(hDeviceKey, iSubkeyNumber++, TempPath, (ULONG*)&Length, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
+	{
+		_stprintf_s(RegPath, L"%s\\Root\\NET\\%s", DEVICE_REGISTER_PATH, TempPath);
+		dwRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, RegPath, 0, KEY_READ, &hEnumKey);
+		if(dwRet != ERROR_SUCCESS)
+		{
+			memset(TempPath,0,sizeof(TempPath));
+			Length = MAX_PATH;
+			continue;
+		}
+
+		Length = MAX_PATH;
+		memset(HardWareIdInfo, MAX_PATH, 0);
+		dwRet = RegQueryValueEx(hEnumKey, L"HardwareID", NULL, NULL, (LPBYTE)HardWareIdInfo, (LPDWORD)&Length);
+		if(dwRet == ERROR_SUCCESS)
+		{
+			if(_tcsicmp(HardWareIdInfo, VNIC_DEV_ID) == 0)
+			{
+				//this is our device;
+				dwRet = SHDeleteKey(HKEY_LOCAL_MACHINE, RegPath);
+				Log(LOG_INFO, (L"In Clear VNIC Register,reg %s was deleted, return value is %d\n", RegPath, dwRet));
+			}
+		}
+
+		memset(TempPath,0,sizeof(TempPath));
+		RegCloseKey(hEnumKey);
+		hEnumKey = NULL;
+		Length = MAX_PATH;
+	}
+
+	if(hDeviceKey)
+	{
+		RegCloseKey(hDeviceKey);
+	}
+	if(hEnumKey)
+	{
+		RegCloseKey(hEnumKey);
+	}
+}
+
+void ClearATPRegistry()
+{
+	HKEY            hDeviceKey;
+	wchar_t         TempPath[MAX_PATH]={0};
+	int iSubkeyNumber = 0, iLength;
+	DWORD dwRet = 0;
+	dwRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"SYSTEM\\", 0, KEY_READ, &hDeviceKey);
+	if(dwRet != ERROR_SUCCESS)
+	{
+		Log(LOG_ERROR,(L"RegOpenKey fail! Please check!\n"));
+		return;
+	}
+
+	iLength = sizeof(TempPath);
+	while( RegEnumKeyEx(hDeviceKey, iSubkeyNumber++, TempPath, (ULONG*)&iLength, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
+	{
+		wchar_t regpath[MAX_PATH];
+		if (StrStrIW(TempPath,L"ControlSet") != NULL )
+		{
+			memset(regpath,0,sizeof(regpath));
+			_stprintf_s(regpath,L"SYSTEM\\%s\\Services\\",TempPath);
+			DetectATPRegAndRemove(regpath, true);
+		}
+
+		memset(TempPath,0,sizeof(TempPath));
+		iLength = sizeof(TempPath);
+	}
+	RegCloseKey(hDeviceKey);
+}
+
+bool DetectATPRegAndRemove(wchar_t *regpath, bool bRemoveATPReg)
+{
+	HKEY            hDeviceKey = NULL;
+	wchar_t         TempPath[MAX_PATH];
+	int iSubkeyNumber = 0,iLength;
+	DWORD dwRet = 0;
+	bool bRet = false;
+
+	dwRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, regpath, 0, KEY_READ, &hDeviceKey);
+	if(dwRet != ERROR_SUCCESS)
+	{
+		Log(LOG_INFO,(L"Remove ATP Reg: reg open %s failed, error is %d\n", regpath, dwRet));
+		return bRet;
+	}
+
+	iLength = sizeof(TempPath);
+	while(RegEnumKeyEx(hDeviceKey, iSubkeyNumber++, TempPath, (ULONG*)&iLength, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
+	{
+		if(_tcsicmp(TempPath, L"ATP") == 0)
+		{
+			if(bRemoveATPReg)
+			{
+				SHDeleteKey(hDeviceKey, TempPath);
+			}
+			bRet = true;
+		}
+
+		memset(TempPath,0,sizeof(TempPath));
+		iLength = sizeof(TempPath);
+	}
+	RegCloseKey(hDeviceKey);
+	return bRet;
+}
+
+bool CServiceFunc::run()
+{
+	Log(LOG_INFO, (L"CServiceFunc: Start to Uninstall service\n"));
+	SetInstallStatus(SSLVPN_COMPONENT_CLSID, aisRemovingService);
+	if (!RemoveVPNService())
+	{
+		Log(LOG_WARNING, (L"CServiceFunc: Uninstall service failed\n"));
+		return false;
+	}
+	Log(LOG_INFO, (L"CServiceFunc: Start to Uninstall service success\n"));
+	return true;
+}
+
+bool CServiceFunc::RemoveVPNService()
+{
+	bool bServiceFileExist = false;
+	bool bRet = true;
+	int iErrorCode = 0;
+	wchar_t szVPNServiceFilePath[MAX_PATH] = {'\0'}, szRegPath[MAX_PATH] = {'\0'}, szWebVPNServiceFilePath[MAX_PATH] = {'\0'}, szVPNInstallManagerFilePath[MAX_PATH] = {'\0'};
+
+	DWORD dwType = REG_EXPAND_SZ;
+	DWORD dwSize = sizeof(szVPNServiceFilePath);
+	_stprintf_s(szRegPath, MAX_PATH, L"SYSTEM\\CurrentControlSet\\Services\\%s", ARR_VPNSERVICE_NAME);
+	DWORD dwRet = SHGetValue(HKEY_LOCAL_MACHINE, szRegPath, IMAGEPATH_NAME, &dwType, szVPNServiceFilePath, &dwSize);
+	if(dwRet != ERROR_SUCCESS)
+	{
+		Log(LOG_INFO, (L"RemoveVPNService: can not get the com file path from reg, dwRet is %d\n", dwRet));
+	}
+	else
+	{
+		//
+		int iLength = _tcslen(szVPNServiceFilePath); //
+		Log(LOG_INFO, (L"RemoveVPNService: old path string: %s \n", szVPNServiceFilePath));
+		for(int i = 0; i < iLength-2 ; i++) //
+		{
+			szVPNServiceFilePath[i] = szVPNServiceFilePath[i+1];
+		}
+		szVPNServiceFilePath[iLength-2] = '\0';  //
+		Log(LOG_INFO, (L"RemoveVPNService: new path string is %s\n", szVPNServiceFilePath));
+		if(PathFileExists(szVPNServiceFilePath))
+		{
+			Log(LOG_INFO, (L"RemoveVPNService: file %s exist\n", szVPNServiceFilePath));
+			bServiceFileExist = true;
+		}
+	}
+
+	if(!bServiceFileExist)
+	{
+		wchar_t szAppDir[MAX_PATH] = {'\0'};
+		GetApplicationDirectory(szAppDir);
+		_stprintf_s(szVPNServiceFilePath, MAX_PATH, L"%s\\%s", szAppDir, ARR_VPNSERVICE_FILE_NAME);
+		if(!PathFileExists(szVPNServiceFilePath))
+		{
+			Log(LOG_INFO, (L"RemoveVPNService: file %s is not exist\n", szVPNServiceFilePath));
+		}
+	}
+
+	if (IsCOMServiceExist(ARR_VPNSERVICE_NAME))
+	{
+		if(bRet && !RemoveCOMService(szVPNServiceFilePath, true))
+		{
+			Log(LOG_INFO, (L"RemoveVPNService: remove VPN service failed\n"));
+			bRet = false;
+		}
+	}
+	
+	Sleep(1000);//
+
+	CString csFilePath = szVPNServiceFilePath; //c:\program files\...\..\VPNService.exe
+	csFilePath = csFilePath.Left(csFilePath.GetLength() - _tcslen(ARR_VPNSERVICE_FILE_NAME));
+	_stprintf_s(szWebVPNServiceFilePath, MAX_PATH, L"%s%s", csFilePath, ARR_WEBVPN_SERVICE_FILE_NAME);
+	if(!PathFileExists(szWebVPNServiceFilePath))
+	{
+		Log(LOG_INFO, (L"RemoveVPNService: file %s is not exist\n", szWebVPNServiceFilePath));
+	}
+	if(!StopProcessByProcessName(ARR_WEBVPN_SERVICE_FILE_NAME))
+	{
+		Log(LOG_INFO, (L"RemoveVPNService: peocess %s is also running\n", ARR_WEBVPN_SERVICE_FILE_NAME));
+	}
+	
+	if (IsCOMServiceExist(ARR_WEBVPN_SERVICE_NAME))
+	{
+		if(!RemoveCOMService(szWebVPNServiceFilePath, false))
+		{
+			Log(LOG_INFO, (L"RemoveVPNService: remove Web vpn service failed\n"));
+			bRet = false;
+		}
+	}
+
+	csFilePath = szVPNServiceFilePath;
+	csFilePath = csFilePath.Left(csFilePath.GetLength() - _tcslen(ARR_VPNSERVICE_INSTALL_PATH));
+	_stprintf_s(szVPNInstallManagerFilePath, MAX_PATH, L"%s%s\\%s", csFilePath, INSTALL_MANAGER_NAME, ARR_AIM_FILE_NAME);
+	if(!PathFileExists(szVPNInstallManagerFilePath))
+	{
+		Log(LOG_INFO, (L"RemoveVPNService: file %s is not exist\n", szVPNInstallManagerFilePath));
+	}
+	if(!StopProcessByProcessName(ARR_AIM_FILE_NAME))
+	{
+		Log(LOG_INFO, (L"RemoveVPNService: peocess %s is also running\n", ARR_AIM_FILE_NAME));
+	}
+
+	if (IsCOMServiceExist(ARR_AIM_SERVICE_NAME))
+	{
+		if(!RemoveCOMService(szVPNInstallManagerFilePath, false))
+		{
+			Log(LOG_INFO, (L"RemoveVPNService: remove VPNInstallManager service failed\n"));
+			bRet = false;
+		}
+	}
+
+	Log(LOG_INFO, (L"RemoveVPNService: finished and ret is %d\n", bRet));
+	return bRet;
+}
+
+bool CActiveXCFunc::run()
+{
+	bool bRet = true;
+	Log(LOG_INFO, (L"CActiveXCFunc: Start to Uninstall ActiveX\n"));
+	if(!DeleteActiveXComponent(ARR_ACTIVEX_INF_NAME_X64))
+	{
+		bRet = false;
+	}
+	if(!DeleteActiveXComponent(ARR_ACTIVEX_INF_NAME))
+	{
+		bRet = false;
+	}
+	if(!DeleteActiveXComponent(VPNINIT_FILE_NAME))
+	{
+		bRet = false;
+	}
+	if(!DeleteActiveXComponent(ARR_ACTIVEX_FILE_NAME))
+	{
+		bRet = false;
+	}
+	if (Is64bitOS())
+	{
+		SHDeleteKey(HKEY_CLASSES_ROOT, L"Wow6432Node\\CLSID\\{47C6ECF4-2DDE-4001-836B-5BF6ED9BC2DC}");
+	}
+	SHDeleteKey(HKEY_CLASSES_ROOT, L"CLSID\\{47C6ECF4-2DDE-4001-836B-5BF6ED9BC2DC}");
+	Log(LOG_INFO, (L"CActiveXCFunc: Uninstall ActiveX finish\n"));
+	return bRet;
+}
+
+bool CActiveXCFunc::DeleteActiveXComponent(LPCTSTR lpActiveXName)
+{
+	wchar_t szPath[MAX_PATH] = {'\0'}, szSystemPath[MAX_PATH] = {'\0'};
+	GetSystemDirectory(szSystemPath, MAX_PATH);
+	
+	_stprintf_s(szPath, MAX_PATH, L"%s\\%s", szSystemPath, lpActiveXName);
+	Log(LOG_INFO, (L"Delete ActiveX: szPath:%s\n", szPath));
+	if (PathFileExists(szPath))
+	{
+		Log(LOG_INFO, (L"Delete ActiveX: szPath:%s exist\n", szPath));
+		if (!DeleteFile(szPath))
+		{
+			Log(LOG_ERROR, (L"Delete ActiveX:%d failed\n", GetLastError()));
+			return false;
+		}
+	} 
+	else
+	{
+		Log(LOG_INFO, (L"Delete ActiveX: szPath:%s is not exist\n", szPath));
+	}
+
+	if (Is64bitOS())
+	{
+		memset(szSystemPath, 0, sizeof(szSystemPath));
+		GetSystemWow64Directory(szSystemPath, MAX_PATH);
+
+		_stprintf_s(szPath, MAX_PATH, L"%s\\%s", szSystemPath, lpActiveXName);
+		Log(LOG_INFO, (L"Delete ActiveX: szPath:%s\n", szPath));
+		if (PathFileExists(szPath))
+		{
+			Log(LOG_INFO, (L"Delete ActiveX: szPath:%s exist\n", szPath));
+			if (!DeleteFile(szPath))
+			{
+				Log(LOG_ERROR, (L"Delete ActiveX:%d failed\n", GetLastError()));
+				return false;
+			}
+		} 
+		else
+		{
+			Log(LOG_INFO, (L"Delete ActiveX: szPath:%s is not exist\n", szPath));
+		}
+	}
+	return true;
+}
+
+bool CRegFunc::run()
+{
+	Log(LOG_INFO, (L"CRegFunc: Start to delete Reg\n"));
+	SetInstallStatus(SSLVPN_COMPONENT_CLSID, aisDeletingReg);
+	if(!DeleteComponentIDRegs())
+	{
+		Log(LOG_WARNING, (L"CRegFunc: DeleteComponentIDRegs failed\n"));
+	}
+	if(!DeleteUninstallRegs())
+	{
+		Log(LOG_WARNING, (L"CRegFunc: DeleteUninstallRegs failed\n"));
+	}
+	if(!DeleteMSIRegs())
+	{
+		Log(LOG_WARNING, (L"CRegFunc: DeleteUninstallRegs failed\n"));
+	}
+	Log(LOG_INFO, (L"CRegFunc: delete Reg finish\n"));
+	return true;
+}
+
+bool CRegFunc::DeleteComponentIDRegs()
+{
+	DWORD dwRet = 0;
+	wchar_t szRegPath[MAX_PATH] = {'\0'};
+	_stprintf_s(szRegPath, MAX_PATH, L"%s\\%s",AIM_REG_PATH, SSLVPN_COMPONENT_CLSID);
+
+	dwRet = SHDeleteKey(HKEY_LOCAL_MACHINE, szRegPath);
+	if(dwRet != ERROR_SUCCESS)
+	{
+		Log(LOG_WARNING, (L"DeleteComponentIDRegs: reg delete key failed, error is %d\n", dwRet));
+	}
+
+	//delete auto run reg, so that can resume outside proxy
+	dwRet = SHDeleteValue(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", L"WebVPN");
+	if(dwRet != ERROR_SUCCESS)
+	{
+		Log(LOG_WARNING, (L"DeleteComponentIDRegs: reg delete auto run key failed, error is %d\n", dwRet));
+	}
+
+	// Delete LaunchMhttpd and LaunchMotionPro startup entries
+	SHDeleteValue(HKEY_LOCAL_MACHINE, AUTORUN_REG_PATH, REG_AUTO_LAUNCH_MHTTPD);
+	SHDeleteValue(HKEY_LOCAL_MACHINE, AUTORUN_REG_PATH, REG_AUTO_LAUNCH_MOTIONPRO);
+	if (Is64bitOS())
+	{
+		SHDeleteValue(HKEY_LOCAL_MACHINE, AUTORUN_REG_PATH_WOW64, REG_AUTO_LAUNCH_MHTTPD);
+		SHDeleteValue(HKEY_LOCAL_MACHINE, AUTORUN_REG_PATH_WOW64, REG_AUTO_LAUNCH_MOTIONPRO);
+	}
+
+	//delete IE particular setting reg
+	dwRet = SHDeleteKey(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Internet Explorer\\Low Rights\\ElevationPolicy\\{82680856-28A3-4099-AD55-7C5201D3194D}");
+	if(dwRet != ERROR_SUCCESS)
+	{
+		Log(LOG_WARNING, (L"DeleteComponentIDRegs: reg delete IE key failed, error is %d\n", dwRet));
+	}
+
+	if(Is64bitOS())
+	{
+		dwRet = SHDeleteKey(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Wow6432Node\\Microsoft\\Internet Explorer\\Low Rights\\ElevationPolicy\\{82680856-28A3-4099-AD55-7C5201D3194D}");
+		if(dwRet != ERROR_SUCCESS)
+		{
+			Log(LOG_WARNING, (L"DeleteComponentIDRegs: reg delete 32bitIE key failed, error is %d\n", dwRet));
+		}
+
+		if (SHDeleteValue(HKEY_LOCAL_MACHINE, AUTORUN_REG_PATH, STANDALONE_AUTORUN) != ERROR_SUCCESS)
+		{
+			Log(LOG_WARNING, (L"Reg delete key VPN failed.\n"));
+		}
+	}
+
+	if (SHDeleteKey(HKEY_LOCAL_MACHINE, VPN_REG_PATH) != ERROR_SUCCESS)
+	{
+		Log(LOG_WARNING, (L"Reg delete key VPN failed.\n"));
+	}
+
+	wchar_t wchOldValue[512] = {0};
+	DWORD dwType = REG_SZ;
+	DWORD dwSize = sizeof(wchOldValue);
+	dwRet = SHGetValue(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon"), _T("Shell"), &dwType, wchOldValue, &dwSize);
+	Log(LOG_INFO, (L"DeleteComponentIDRegs: before set shell value, old value:%s, ret:%d\n", wchOldValue, dwRet));
+
+	if(StrStrIW(wchOldValue, L"StandaloneVPN.exe") != NULL)
+	{
+		dwRet = SHSetValue(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon"), _T("Shell"), REG_SZ, L"explorer.exe", (_tcslen(L"explorer.exe") + 1)*2);
+		Log(LOG_INFO, ("DeleteComponentIDRegs: set value for shell finished, ret:%u\n", dwRet));
+	}
+
+	return true;
+}
+
+bool CRegFunc::DeleteUninstallRegs()
+{
+	wchar_t szRegPath[MAX_PATH] = {'\0'}, szRegWow64Path[MAX_PATH] = {'\0'};
+
+	DWORD hRet = 0;
+	hRet = SHDeleteKey(HKEY_LOCAL_MACHINE, MSI_REGEDIT_DELETE);
+	if(hRet != ERROR_SUCCESS)
+	{
+		Log(LOG_INFO, (L"SHDeleteKey failed, error is %d\n", hRet));
+	}
+
+	_stprintf_s(szRegPath, MAX_PATH-1, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\%s", SSLVPN_DEFAULT_APPNAME);
+	_stprintf_s(szRegWow64Path, MAX_PATH-1, L"SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\%s", SSLVPN_DEFAULT_APPNAME);
+
+
+	DWORD dwRet = SHDeleteKey(HKEY_LOCAL_MACHINE, szRegPath);
+	if(dwRet != ERROR_SUCCESS)
+	{
+		Log(LOG_WARNING, (L"DeleteUninstallRegs: failed , the ret is %d\n", dwRet));
+		return false;
+	}
+
+	if(Is64bitOS())
+	{
+		dwRet = SHDeleteKey(HKEY_LOCAL_MACHINE, szRegWow64Path);
+		if(dwRet != ERROR_SUCCESS)
+		{
+			Log(LOG_WARNING, (L"DeleteUninstallRegs: failed in Wow64 , the ret is %d\n", dwRet));
+		}
+	}
+	return true;
+}
+
+bool CRegFunc::DeleteMSIRegs()
+{
+	DWORD dwRet = 0;
+
+	dwRet = SHDeleteKey(HKEY_CURRENT_USER, MSI_REGEDIT_MEMORY);
+	if (dwRet != ERROR_SUCCESS)
+	{
+		Log(LOG_INFO, (L"SHDeleteKey msi failed, error is %d\n", dwRet));
+	}
+	else
+	{
+		Log(LOG_INFO, (L"SHDeleteKey msi success\n"));
+	}
+
+	DeleteSubKeysbyName(HKEY_CLASSES_ROOT, L"Installer\\Products", L"ProductName", VPN_CLIENT_NAME);
+	SHDeleteKey(HKEY_CLASSES_ROOT, L"Installer\\Products\\F131988C510D00A488582C3E983569A0");
+
+	DeleteSubKeysbyName(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Classes\\Installer\\Products", L"ProductName", VPN_CLIENT_NAME);
+	DeleteSubKeysbyName(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Group Policy\\AppMgmt", L"Deployment Name", VPN_CLIENT_NAME);
+	DeleteSubKeysbyName(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Products", L"DisplayName", VPN_CLIENT_NAME);
+
+	SHDeleteKey(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Classes\\Installer\\Products\\F131988C510D00A488582C3E983569A0");
+	SHDeleteKey(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Products\\F131988C510D00A488582C3E983569A0");
+	
+
+	wstring strRegPath = L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\";
+	if(Is64bitOS())
+	{
+		strRegPath = L"SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\";
+		SHDeleteKey(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Wow6432Node\\Classes\\Installer\\Products\\F131988C510D00A488582C3E983569A0");
+		SHDeleteKey(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Products\\F131988C510D00A488582C3E983569A0");
+		DeleteSubKeysbyName(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Wow6432Node\\Classes\\Installer\\Products", L"ProductName", VPN_CLIENT_NAME);
+		DeleteSubKeysbyName(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Group Policy\\AppMgmt", L"Deployment Name", VPN_CLIENT_NAME);
+		DeleteSubKeysbyName(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Products", L"DisplayName", VPN_CLIENT_NAME);
+	}
+	strRegPath += MSI_REGEDIT_CLSID;
+	dwRet = SHDeleteKey(HKEY_LOCAL_MACHINE, strRegPath.c_str());
+	Log(LOG_INFO, (L"SHDeleteKey %s finished, ret is %d\n", strRegPath.c_str(), dwRet));
+
+	//DeleteSubKeysbyName(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall", L"DisplayName", VPN_CLIENT_NAME);
+	//DeleteSubKeysbyName(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall", L"DisplayName", VPN_CLIENT_NAME);
+
+	return true;
+}
+
+BOOL CRegFunc::DeleteSubKeysbyName(HKEY hRootKey, LPCTSTR lpRegPath, LPCTSTR lpKeyName, LPCTSTR lpKeyValue)
+{
+	Log(LOG_INFO, (L"DeleteSubKeysbyName: keyPath:%s, keyName:%s, keyValue:%s\n", lpRegPath, lpKeyName, lpKeyValue));
+	HKEY hKey = NULL, hEnumKey = NULL;
+	DWORD dwRet = RegOpenKeyEx(hRootKey, lpRegPath, 0, KEY_ALL_ACCESS, &hKey);
+	if(dwRet != ERROR_SUCCESS)
+	{
+		Log(LOG_INFO, (L"DeleteSubKeysbyName: RegOpenKeyEx failed, dwRet:%d\n", dwRet));
+		return FALSE;
+	}
+
+	DWORD dwIndex = 0, dwBufferSize = MAX_PATH;
+	DWORD dwType = REG_SZ, dwSize = 0;
+	wchar_t wchValue[MAX_PATH] = {0}, szProductName[MAX_PATH] = {'\0'};
+	wstring wstrPath = L"";
+
+	//enum the device enum key
+	while(RegEnumKeyEx(hKey, dwIndex++, wchValue, &dwBufferSize, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
+	{
+		memset(szProductName, 0, sizeof(szProductName));
+		dwType = REG_SZ;
+		dwSize = sizeof(szProductName);
+		wstrPath = lpRegPath;
+		wstrPath += L"\\";
+		wstrPath += wchValue;
+		dwRet = SHGetValue(hRootKey, wstrPath.c_str(), lpKeyName, &dwType, szProductName, &dwSize);
+		if(dwRet == ERROR_SUCCESS && StrCmpIW(szProductName, lpKeyValue) == 0)
+		{
+			Log(LOG_INFO, (L"DeleteSubKeysbyName: delete reg key: %s\n", wstrPath.c_str()));
+			SHDeleteKey(hRootKey, wstrPath.c_str());
+		}
+
+		memset(wchValue, 0, sizeof(wchValue));
+		dwBufferSize = MAX_PATH;		
+	}
+
+	if(hKey != NULL)
+	{
+		RegCloseKey(hKey);
+	}
+	Log(LOG_INFO, (L"DeleteSubKeysbyName: finished\n"));
+	return TRUE;
+}
+
+bool CFileFunc::run()
+{
+	Log(LOG_INFO, (L"CFileFunc: Start to delete Local files\n"));
+	bool bRet = true;
+	if(!DeleteComponentFiles())
+	{
+		Log(LOG_WARNING, (L"CFileFunc:DeleteComponentFiles failed\n"));
+		bRet = false;
+	}
+	if(!DeleteTempFiles())
+	{
+		Log(LOG_WARNING, (L"CFileFunc:DeleteTempFiles failed\n"));
+		bRet = false;
+	}
+	if (!DeleteConfigureFile())
+	{
+		Log(LOG_WARNING, (L"CFileFunc:DeleteConfigureFile failed\n"));
+		bRet = false;
+	}
+	DeleteCompanyShortcuts();
+	DeleteMSIFiles();
+	Log(LOG_INFO, (L"CFileFunc: delete Local files finish\n"));
+	return bRet;
+}
+
+bool CFileFunc::DeleteComponentFiles()
+{
+	bool bRet = true;
+	wchar_t szPath[MAX_PATH] = {'\0'};
+	GetApplicationDirectory(szPath);
+	Log(LOG_INFO, (L"DeteleCompanyVPNFolder: start delete folder %s\n", szPath));
+	if (PathFileExists(szPath))
+	{
+		if(EmptyDirectory(szPath))
+		{
+			Log(LOG_INFO, (L"DeleteComponentFiles: %s success\n", szPath));
+		}
+		else
+		{
+			Log(LOG_INFO, (L"DeleteComponentFiles: %s failed\n", szPath));
+			bRet = false;
+		}
+	}
+	memset(szPath, 0, sizeof(szPath));
+	GetInstallManagerDirectory(szPath);
+	Log(LOG_INFO, (L"DeteleCompanyVPNFolder: start delete folder %s\n", szPath));
+	if (PathFileExists(szPath))
+	{
+		if(EmptyDirectory(szPath))
+		{
+			Log(LOG_INFO, (L"DeleteComponentFiles: %s success\n", szPath));
+		}
+		else
+		{
+			Log(LOG_INFO, (L"DeleteComponentFiles: %s failed\n", szPath));
+			bRet = false;
+		}
+	}
+	return bRet;
+}
+
+bool CFileFunc::DeleteTempFiles()
+{
+	wchar_t szTempPath[MAX_PATH] = {'\0'}, szTargetFile[MAX_PATH] = {'\0'};
+	GetTempPath(MAX_PATH,szTempPath);
+	_stprintf_s(szTargetFile,L"%s%s", szTempPath, VPN_DEFAULT_FOLDER_NAME);
+	EmptyDirectory(szTargetFile);
+
+	memset(szTargetFile, 0, MAX_PATH);
+	_stprintf_s(szTargetFile,L"%s\\Low\\%s", szTempPath, VPN_DEFAULT_FOLDER_NAME);
+	EmptyDirectory(szTargetFile);
+
+	return true;
+}
+
+bool CFileFunc::DeleteCompanyShortcuts()
+{
+	HRESULT hRet;
+	TCHAR   szPath[MAX_PATH] = {0};
+	CString strShortcutPath = L"";
+
+	BOOL bSPXClientExist = FALSE;
+	if(IsProcessExistByName(L"arr_srvs.exe") || IsProcessExistByName(L"arr_isrv.exe"))
+	{
+		bSPXClientExist = TRUE;
+	}
+
+	do 
+	{
+		hRet = SHGetFolderPath(NULL, CSIDL_COMMON_PROGRAMS, NULL, SHGFP_TYPE_CURRENT, szPath);
+		if(SUCCEEDED(hRet))
+		{
+			Log(LOG_INFO, (L"DeleteShortcuts(): Path of common programs: %s\n", szPath));
+			strShortcutPath = szPath;
+			strShortcutPath += L"\\";
+			strShortcutPath += VPN_PROVIDEER_NAME;
+			if (bSPXClientExist)
+			{
+				strShortcutPath += L"\\";
+				RemoveFile(strShortcutPath + VPN_CLIENT_NAME + L".lnk");
+				RemoveFile(strShortcutPath + CLIENT_LOGGER_LINK_DISPLAY_NAME + L".lnk");
+				RemoveFile(strShortcutPath + CLIENT_UNINSTALL_LINK_DISPLAY_NAME + L".lnk");
+				RemoveFile(strShortcutPath + CLIENT_CLEANTOOL_LINK_DISPLAY_NAME + L".lnk");
+			}
+			else
+			{
+				EmptyDirectory(strShortcutPath);
+			}
+		}
+		else
+		{
+			Log(LOG_WARNING, ("DeleteShortcuts(): Failed to get path of common programs.\n"));
+			break;
+		}
+
+	}while(0);
+
+	memset(szPath, 0, MAX_PATH);
+
+	//2 remove path of 'User name\Start Menu\Programs'
+	do 
+	{
+		hRet = SHGetFolderPath(NULL, CSIDL_PROGRAMS, NULL, SHGFP_TYPE_CURRENT, szPath);
+		if(SUCCEEDED(hRet))
+		{
+			Log(LOG_INFO, (L"DeleteShortcuts(): Path of current user common programs: %s\n", szPath));
+			strShortcutPath = szPath;
+			strShortcutPath += L"\\";
+			strShortcutPath += VPN_PROVIDEER_NAME;
+			if (bSPXClientExist)
+			{
+				strShortcutPath += L"\\";
+				RemoveFile(strShortcutPath + VPN_CLIENT_NAME + L".lnk");
+				RemoveFile(strShortcutPath + CLIENT_LOGGER_LINK_DISPLAY_NAME + L".lnk");
+				RemoveFile(strShortcutPath + CLIENT_UNINSTALL_LINK_DISPLAY_NAME + L".lnk");
+				RemoveFile(strShortcutPath + CLIENT_CLEANTOOL_LINK_DISPLAY_NAME + L".lnk");
+			}
+			else
+			{
+				EmptyDirectory(strShortcutPath);
+			}
+		}
+		else
+		{
+			Log(LOG_WARNING, ("DeleteShortcuts(): Failed to get path of current user common programs.\n"));
+			break;
+		}
+
+	}while(0);
+
+	memset(szPath, 0, MAX_PATH);
+
+
+	//3 remove path of 'All Users\Desktop\Array L3 VPN Connect.lnk'
+	do 
+	{
+		hRet = SHGetFolderPath(NULL, CSIDL_COMMON_DESKTOPDIRECTORY , NULL, SHGFP_TYPE_CURRENT, szPath);
+		if(SUCCEEDED(hRet))
+		{
+			Log(LOG_INFO, (L"DeleteShortcuts(): Path of all user desktop: %s\n", szPath));
+			strShortcutPath = szPath;
+			strShortcutPath += L"\\";
+			strShortcutPath +=	VPN_CLIENT_NAME;
+			strShortcutPath += L".lnk";
+			RemoveFile(strShortcutPath);
+		}
+		else
+		{
+			Log(LOG_WARNING, ("DeleteShortcuts(): Failed to get path of all user desktop.\n"));
+			break;
+		}
+
+	} while (0);
+
+	//4 remove path of 'user name\Desktop\Array L3 VPN Connect.lnk'
+	do 
+	{
+		hRet = SHGetFolderPath(NULL, CSIDL_DESKTOPDIRECTORY , NULL, SHGFP_TYPE_CURRENT, szPath);
+		if(SUCCEEDED(hRet))
+		{
+			Log(LOG_INFO, (L"DeleteShortcuts(): Path of all user desktop: %s\n", szPath));
+			strShortcutPath = szPath;
+			strShortcutPath += L"\\";
+			strShortcutPath += VPN_CLIENT_NAME;
+			strShortcutPath += L".lnk";
+			RemoveFile(strShortcutPath);
+		}
+		else
+		{
+			Log(LOG_WARNING, ("DeleteShortcuts(): Failed to get path of all user desktop.\n"));
+			break;
+		}
+
+	} while (0);
+
+	return true;
+}
+
+bool CFileFunc::DeleteMSIFiles()
+{
+	wchar_t wchCurrentPath[MAX_PATH] = {0};
+	GetWindowsDirectory(wchCurrentPath, MAX_PATH); // c:\windows
+	PathRemoveFileSpec(wchCurrentPath);
+	PathRemoveFileSpec(wchCurrentPath);
+	if(Is64bitOS())
+	{
+		PathAddExtension(wchCurrentPath, L"\\Program Files (x86)\\Array Networks\\MSIInstallManager");
+	}
+	else
+	{
+		PathAddExtension(wchCurrentPath, L"Program Files\\Array Networks\\MSIInstallManager");
+	}
+
+	if (PathFileExists(wchCurrentPath))
+	{
+		if(EmptyDirectory(wchCurrentPath))
+		{
+			Log(LOG_INFO, (L"CFileFunc delete MSI local files: %s success\n", wchCurrentPath));
+		}
+		else
+		{
+			Log(LOG_INFO, (L"CFileFunc delete MSI local files: %s failed\n", wchCurrentPath));
+			return false;
+		}
+	}
+
+	return true;
+}
+
+bool CFileFunc::DeleteConfigureFile()
+{
+	wstring strConfigurePath = GetAllUserAppDataPath();
+	strConfigurePath += L"\\";
+	strConfigurePath += VPN_DEFAULT_FOLDER_NAME;
+	strConfigurePath += L"\\";
+	strConfigurePath += CONFIGURE_FILE;
+	if (PathFileExists(strConfigurePath.c_str()))
+	{
+		if (!RemoveFile(strConfigurePath.c_str()))
+		{
+			Log(LOG_INFO, (L"CFileFunc delete Configure files: %s failed\n", strConfigurePath.c_str()));
+			return false;
+		}
+		Log(LOG_INFO, (L"CFileFunc delete Configure files: %s success\n", strConfigurePath.c_str()));
+		return true;
+	}
+	return true;
+}
+
+bool CClientSecurityFunc::run()
+{
+	Log(LOG_INFO, (L"CClientSecurityFunc: Start to delete ClientSecurity component\n"));
+	bool bRet  = true;
+	if (!DeleteTempClientSecurityFiles())
+	{
+		bRet = false;
+	}
+	DeleteDownloadProgramFiles(CLIENTSECURITY_LANGUAGE_1028_NAME);
+	DeleteDownloadProgramFiles(CLIENTSECURITY_LANGUAGE_1033_NAME);
+	DeleteDownloadProgramFiles(CLIENTSECURITY_LANGUAGE_1041_NAME);
+	DeleteDownloadProgramFiles(CLIENTSECURITY_LANGUAGE_2052_NAME);
+	DeleteDownloadProgramFiles(CLIENTSECURITY_ACTIVEX_NAME);
+	DeleteDownloadProgramFiles(CLIENTSECURITY_ACTIVEX_INF_NAME);
+	if (Is64bitOS())
+	{
+		DeleteDownloadProgramFiles(CLIENTSECURITY_ACTIVEX_64BIT_NAME);
+		DeleteDownloadProgramFiles(CLIENTSECURITY_ACTIVEX_INF_64BIT_NAME);
+		SHDeleteKey(HKEY_CLASSES_ROOT, L"Wow6432Node\\CLSID\\{EE64AC11-5480-444E-AB2F-A9780EC929D5}");
+	}
+	SHDeleteKey(HKEY_CLASSES_ROOT, L"CLSID\\{EE64AC11-5480-444E-AB2F-A9780EC929D5}");
+	Log(LOG_INFO, (L"CClientSecurityFunc: Delete ClientSecurity component finish\n"));
+	return bRet;
+}
+
+bool CClientSecurityFunc::DeleteTempClientSecurityFiles()
+{
+	bool bRet = true;
+	wchar_t szTempPath[MAX_PATH] = {'\0'}, szTargetFile[MAX_PATH] = {'\0'};
+	GetTempPath(MAX_PATH,szTempPath);
+	_stprintf_s(szTargetFile,L"%s%s", szTempPath, CLIENTSECURITY_NAME);
+
+
+	if (PathFileExists(szTargetFile))
+	{
+		if (EmptyDirectory(szTargetFile))
+		{
+			Log(LOG_INFO, (L"CClientSecurityFunc: DeleteCSFiles: %s success\n", szTargetFile));
+		} 
+		else
+		{
+			Log(LOG_WARNING, (L"CClientSecurityFunc: DeleteCSFiles: %s error\n", szTargetFile));
+			bRet = false;
+		}
+	}
+
+	memset(szTargetFile, 0, MAX_PATH);
+
+	_stprintf_s(szTargetFile,L"%sLow\\%s", szTempPath, CLIENTSECURITY_NAME);
+	if (PathFileExists(szTargetFile))
+	{
+		if (EmptyDirectory(szTargetFile))
+		{
+			Log(LOG_INFO, (L"CClientSecurityFunc: DeleteCSFiles: %s success\n", szTargetFile));
+		} 
+		else
+		{
+			Log(LOG_WARNING, (L"CClientSecurityFunc: DeleteCSFiles: %s error\n", szTargetFile));
+			bRet = false;
+		}
+	}
+	return bRet;
+}
+
+bool CClientSecurityFunc::DeleteDownloadProgramFiles(LPCWSTR lpClientSecurityFileName)
+{
+	wchar_t szPath[MAX_PATH] = {'\0'};
+	GetWindowsDirectory(szPath, MAX_PATH);
+	_tcscat_s(szPath, ACTIVEX_CACHE_PATH);
+	_tcscat_s(szPath, L"\\");
+	_tcscat_s(szPath, lpClientSecurityFileName);
+	if (DeleteFile(szPath))
+	{
+		Log(LOG_INFO, (L"CClientSecurityFunc: DeleteDownloadProgramFiles: %s success\n", szPath));
+	} 
+	else
+	{
+		Log(LOG_WARNING, (L"CClientSecurityFunc: DeleteDownloadProgramFiles: %s error\n", szPath));
+	}
+
+	memset(szPath, 0, sizeof(szPath));
+	GetWindowsDirectory(szPath, MAX_PATH);
+	_tcscat_s(szPath, ACTIVEX_CACHE_PATH);
+	_tcscat_s(szPath, L"\\CONFLICT.1\\");
+	_tcscat_s(szPath, lpClientSecurityFileName);
+	if (DeleteFile(szPath))
+	{
+		Log(LOG_INFO, (L"CClientSecurityFunc: DeleteDownloadProgramFiles: %s success\n", szPath));
+	} 
+	else
+	{
+		Log(LOG_WARNING, (L"CClientSecurityFunc: DeleteDownloadProgramFiles: %s error\n", szPath));
+	}
+
+	memset(szPath, 0, sizeof(szPath));
+	GetWindowsDirectory(szPath, MAX_PATH);
+	_tcscat_s(szPath, ACTIVEX_CACHE_PATH);
+	_tcscat_s(szPath, L"\\CONFLICT.100\\");
+	_tcscat_s(szPath, lpClientSecurityFileName);
+	if (DeleteFile(szPath))
+	{
+		Log(LOG_INFO, (L"CClientSecurityFunc: DeleteDownloadProgramFiles: %s success\n", szPath));
+	} 
+	else
+	{
+		Log(LOG_WARNING, (L"CClientSecurityFunc: DeleteDownloadProgramFiles: %s error\n", szPath));
+	}
+	return true;
+}
+
+bool CHWIDFunc::run()
+{
+	Log(LOG_INFO, (L"CHWIDFunc: Start to delete HWID component\n"));
+	bool bRet = true;
+	if (Is64bitOS())
+	{
+		if (!DeleteHWIDFiles(HWID_ACTIVEX_FILE_NAME_X64))
+		{
+			bRet = false;
+		}
+
+		if (!DeleteHWIDFiles(HWID_ACTIVEX_INF_NAME_X64))
+		{
+			bRet = false;
+		}
+		SHDeleteKey(HKEY_CLASSES_ROOT, L"Wow6432Node\\CLSID\\{C96F218E-0C9A-48C0-A09C-CA2CB7C6E892}");
+	} 
+	if (!DeleteHWIDFiles(HWID_ACTIVEX_FILE_NAME))
+	{
+		bRet = false;
+	}
+	if (!DeleteHWIDFiles(HWID_ACTIVEX_INF_NAME))
+	{
+		bRet = false;
+	}
+	SHDeleteKey(HKEY_CLASSES_ROOT, L"CLSID\\{C96F218E-0C9A-48C0-A09C-CA2CB7C6E892}");
+	Log(LOG_INFO, (L"CHWIDFunc: Delete HWID component finish\n"));
+	return bRet;
+}
+
+bool CHWIDFunc::DeleteHWIDFiles(LPCWSTR lpHWIDFileName)
+{
+	wchar_t szPath[MAX_PATH] = {'\0'};
+	GetSystemDirectory(szPath, MAX_PATH);
+	_tcscat_s(szPath, L"\\");
+	_tcscat_s(szPath, lpHWIDFileName);
+	if (PathFileExists(szPath))
+	{
+		if (DeleteFile(szPath))
+		{
+			Log(LOG_INFO, (L"CHWIDFunc: DeleteHWIDFiles: %s success\n", szPath));
+		} 
+		else
+		{
+			Log(LOG_INFO, (L"CHWIDFunc: DeleteHWIDFiles: %s error\n", szPath));
+			return false;
+		}
+	}
+
+	if (Is64bitOS())
+	{
+		memset(szPath, 0, sizeof(szPath));
+		GetSystemWow64Directory(szPath, MAX_PATH);
+
+		_tcscat_s(szPath, L"\\");
+		_tcscat_s(szPath, lpHWIDFileName);
+
+		if (PathFileExists(szPath))
+		{
+			if (DeleteFile(szPath))
+			{
+				Log(LOG_INFO, (L"CHWIDFunc: DeleteHWIDFiles: %s success\n", szPath));
+			} 
+			else
+			{
+				Log(LOG_INFO, (L"CHWIDFunc: DeleteHWIDFiles: %s error\n", szPath));
+				return false;
+			}
+		}
+	}
+	return true;
+}
Index: /branches/rel_ag_9_4_5/windows/InstallerDLL/RegFunc.cpp
===================================================================
--- /branches/rel_ag_9_4_5/windows/InstallerDLL/RegFunc.cpp	(revision 20638)
+++ /branches/rel_ag_9_4_5/windows/InstallerDLL/RegFunc.cpp	(working copy)
@@ -102,6 +102,21 @@
 		dwRet = SHDeleteKey(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Wow6432Node\\VPN2");
 		Log(LOG_INFO, (L"Delete reg vpn2 finished, ret:%d\n", dwRet));
 	}
+
+	// Delete LaunchMhttpd and LaunchMotionPro startup entries
+	dwRet = SHDeleteValue(HKEY_LOCAL_MACHINE, AUTORUN_REG_PATH, REG_AUTO_LAUNCH_MHTTPD);
+	Log(LOG_INFO, (L"Delete reg auto run LaunchMhttpd finished, ret:%d\n", dwRet));
+	dwRet = SHDeleteValue(HKEY_LOCAL_MACHINE, AUTORUN_REG_PATH, REG_AUTO_LAUNCH_MOTIONPRO);
+	Log(LOG_INFO, (L"Delete reg auto run LaunchMotionPro finished, ret:%d\n", dwRet));
+
+	if (Is64bitOS())
+	{
+		dwRet = SHDeleteValue(HKEY_LOCAL_MACHINE, AUTORUN_REG_PATH_WOW64, REG_AUTO_LAUNCH_MHTTPD);
+		Log(LOG_INFO, (L"Delete reg auto run LaunchMhttpd (Wow64) finished, ret:%d\n", dwRet));
+		dwRet = SHDeleteValue(HKEY_LOCAL_MACHINE, AUTORUN_REG_PATH_WOW64, REG_AUTO_LAUNCH_MOTIONPRO);
+		Log(LOG_INFO, (L"Delete reg auto run LaunchMotionPro (Wow64) finished, ret:%d\n", dwRet));
+	}
+
 	if (!DeleteUninstallRegsMP())
 	{
 		Log(LOG_WARNING, (L"DeleteRegs: DeleteMPUninstallRegs failed\n"));
