/* 

要使用本模块，需要在.htm的head部分中加入以下说明：

<OBJECT ID="DrvCert" WIDTH="0" HEIGHT="0" CODEBASE="DrvCertC.dll" CLASSID="CLSID:2FD68643-4BCE-4EF5-B7B8-F0F1192FDE86"></OBJECT>
<SCRIPT LANGUAGE ="JavaScript" SRC="Setting.js"></SCRIPT>
<SCRIPT LANGUAGE ="JavaScript" SRC="DynamicPrompt.js"></SCRIPT>
<SCRIPT LANGUAGE ="JavaScript" FOR="window" EVENT="onload">
<!--
	// 如果.htm中有其他onload()事件处理函数，都要一并放在这里，否则，程序不会做任何事情，且导致中断执行
	PromptInit()
//-->
</SCRIPT>
<SCRIPT LANGUAGE="JavaScript" FOR="DrvCert" EVENT="OnProcessRate( FinishRate , sMessage )">
<!--
	DispProgressInfo( FinishRate/10 , sMessage )
//-->
</SCRIPT>
<SCRIPT LANGUAGE="JavaScript" SRC="SoapXml.js"></SCRIPT>
<SCRIPT LANGUAGE="JavaScript" SRC="drvcert.js"></SCRIPT>
*/

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 如果要在当前用户页面上显示调试信息
// 置标志为true
// 否则置为false
var g_TestingInfoDisp = false

var g_TimeOffset = null
//DIP给用户颁发的用户证书颁发者项目中的关键字
var USER_CERT_ISSUER_NAME_E_DRIVERS_CN						= "e-drivers.cn"	//Issuer Cert
// 下面的URL的主机指的是DIP域名
// 即drvinst.html中ServerName(input type="hidden")所指定的地址，ServerName一般值为"dispatch.e-drivers.cn"
// 
var HTML_URL_PROMPT_USER_WILL_SEND_OUT_DEVICE_INFO			= "Prompt-1.htm"
										

var SOAP_URL_AUTO_REG_NEW_USER								= "/html/AutoRegUser.htm"
var SOAP_URL_DISPATCH_DSP									= "/soap/DispatchDSP.asp"
var SOAP_URL_GET_TIME										= "/soap/GetTime.asp"
var SOAP_URL_GET_COMM_CERT									= "/soap/GetCommCert.asp"
//var SOAP_URL_GET_ISSUER_CERT								= "/soap/GetDSPCert.asp"
var SOAP_URL_GET_DP_KEY										= "/soap/GetDPKey.asp"

var SOAP_REQ_GET_DSP_INFO_MATHOD_NAME						= "GetDSPInfo"

var SOAP_REQ_ISSUE_SVC_CERT_MATHOD_NAME						= "IssueSvcCert"
var SOAP_REQ_ISSUE_SVC_CERT_PARAMETER_DEPLOY_INFO_TAG		= "DeployInfo"
var SOAP_REQ_ISSUE_SVC_CERT_PARAMETER_DEPLOY_NUMBER_TAG		= "DeployNumber"

var SOAP_REQ_DOWNLOAD_DRIVER_MATHOD_NAME					= "DownloadDriver"
var SOAP_REQ_DOWNLOAD_DRIVER_PARAMETER_DEPLOY_NUMBER_TAG	= "DeployNumber"

// 该标签虽然与SoapXml.js中相同，但不要删除；否则，会出错！
var SOAP_RET_ERROR_STRING_TAG			= "faultstring"

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function IsObjectInstalled( Object )
{
	if(typeof(Object) == "object")
	{
		if( (Object.object != null) )
		{
			// We found Object!
			return true;
		}
	}
return false
}

function SoapAcquireDSPAndDrvInfo( row )
{

	var DSPInfo = new Array()
	
	if (!IsObjectInstalled(DrvCert)) { DSPInfo["Success"] = false; return (DSPInfo);}
	if (!IsObjectInstalled(DrvInst)) { DSPInfo["Success"] = false; return (DSPInfo);}

	var EndURI = "";
	var AlertInfo="Testing info:\n";
	var SoapRequestXML = "";
	var ReturnXML="";

	CreateDymanicDocElement( "newElement" )

////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////  申请完DSP用户证书后,再根据DSP要求注册与DSP用户证书绑定的用户信息  ////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////

	// 设置当前任务占总任务的百分比
	SetCurProcessBeginEndPercent( 0 , 5 )
	// 10.5%
	DispProgressInfo( 100 , "正在查找驱动服务厂商...")
	DrvCert.UIRefresh()
	// 查找DIP用户证书
	//  USER_CERT_ISSUER_NAME_E_DRIVERS_CN即DIP给用户颁发的用户证书颁发者项目中的关键字
	var IssuerNameSubString = USER_CERT_ISSUER_NAME_E_DRIVERS_CN;//"e-drivers.cn"
	var CertContext = FindAndOpenUserCertByIssuer( IssuerNameSubString );
	// 如果没有DIP用户证书，则颁发
	if (!CertContext) 
	{
		//DispProgressInfo( 100 , "Open user cert issued by '" + IssuerNameSubString + "' failed");
		//var Hostname = location.hostname
		//if (Hostname == "") Hostname = "http://" + ServerName.value
		var Hostname = ServerName.value
		DrvInst.DownloadHostname = Hostname;

		if ( !DrvInst.ConnectAddressLocal( Hostname ) )
		{
			DSPInfo["Error"] = "服务站点" + Hostname + "的服务尚未开通<br>错误原因：" + DrvInst.StatusString
			DSPInfo["Success"] = false; 
			return (DSPInfo);
		}
		showModalDialog( "http://" + Hostname + SOAP_URL_AUTO_REG_NEW_USER, null, 'dialogWidth:400px;dialogHeight:300px;center:yes');

		CertContext = FindAndOpenUserCertByIssuer( IssuerNameSubString );
		if (!CertContext)
		{
			DSPInfo["Error"] = "无法找到用户证书"
			DSPInfo["Success"] = false; 
			return (DSPInfo);
		}
	}

	SetCurProcessBeginEndPercent( 5,10 )
//	DispProgressInfo( 100 , "正在打开用户证书...")
	// 11%
	DispProgressInfo( 100 )
	DrvCert.UIRefresh()

	var CertProvider = DrvCert.OpenCertProvider( CertContext , 1 );//1:Current_user_location 2:Local_machine_location
	if (CertProvider == null || CertProvider == "") 
	{
		DispProgressInfo( 100 , "Open cert provider failed(cert handle=" + CertContext + "): " + DrvCert.ErrorString); 
		{ DSPInfo["Success"] = false; return (DSPInfo);}
	}

	// 总进程12%
	SetCurProcessBeginEndPercent( 10 , 20 )
//	DispProgressInfo( 100 , "正在获取用户证书标识信息...")
	// 12%
	DispProgressInfo( 100 )
	DrvCert.UIRefresh()

	var CertKeyPhysicalID = DrvCert.GetCertKeyPhysicalID( CertProvider , 1);//1:Current_user_location 2:Local_machine_location
	if ( CertKeyPhysicalID == "" || CertKeyPhysicalID == null)
	{
		DSPInfo["Error"] = "Get cert key Physical-ID error<br>" + + DrvCert.ErrorString
		DSPInfo["Success"] = false; 
		return (DSPInfo);
	}

	var CertContent = DrvCert.GetCertContent( CertContext )
	if (CertContent == null || CertContent == "")
	{
		DSPInfo["Error"] = "Can not get content for cert " + CertContent 
		DSPInfo["Success"] = false; 
		return (DSPInfo);
	}
	var CertIssuer  = IssuerNameSubString

	SetCurProcessBeginEndPercent( 20 , 30 )
//	DispProgressInfo( 100 , "正在准备查找驱动服务信息...")
	// 12.5%
	DispProgressInfo( 50 )
	DrvCert.UIRefresh()

	SoapRequestXML = "";
	SoapRequestXML += '<?xml version="1.0" encoding="UTF-16" standalone="no"?>\n';
	SoapRequestXML += '<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">\n';
	SoapRequestXML += "   <SOAP-ENV:Header xmlns:wsu =\"http://schemas.xmlsoap.org/ws/2002/07/utility\" ";
	SoapRequestXML += "                    xmlns:wsse=\"http://schemas.xmlsoap.org/ws/2002/07/secext\" >\n";
	SoapRequestXML += "      <CertInfo>\n";
	SoapRequestXML += "         <CertContent>"		+ CertContent		+ "</CertContent>\n";
	SoapRequestXML += "         <CertPhysicalID>"	+ CertKeyPhysicalID + "</CertPhysicalID>\n";
	SoapRequestXML += "         <CertIssuer>"		+ CertIssuer		+ "</CertIssuer>\n";
	SoapRequestXML += "      </CertInfo>\n";
//
// Timestamp节内容由下面StampXml()函数自动填写 
//
//	SoapRequestXML += "      <Timestamp>\n";
//	SoapRequestXML += "         <Created>2004-03-08 12:00:00</Created>\n";
//	SoapRequestXML += "         <Expires>2004-03-08 12:05:00</Expires>\n";
//	SoapRequestXML += "         <Format>UTC</Format>\n";
//	SoapRequestXML += "      </Timestamp>\n";

//
// SignInfo节内容由下面SignXml()函数自动填写
//
//	SoapRequestXML += "      <m:SignInfo xmlns:m=\"http://e-drivers.cn/soap/\">\n";
//	SoapRequestXML += "         <m:SignValue>DewqdAYBStswtTgh875</m:SignValue>\n";
//	SoapRequestXML += "      </m:SignInfo>\n";
//
	SoapRequestXML += "   </SOAP-ENV:Header>\n";
	
	var DeviceListInfo		= GetDeviceListInfoToXml()
	var MACIDs				= GetNetCardInfo()
	var MainBoardInfo		= GetMainBoardInfo()
	var CPUInfo				= GetCPUInfo()
	var DiskInfo			= GetDiskInfo()
	var OSInfo				= GetOSInfo()
	var ProblemDeviceInfo	= GetDeviceDownloadDriverInfoToXml( row )
	// 12.8%
	DispProgressInfo( 80 )
	DrvCert.UIRefresh()

	SoapRequestXML += "   <SOAP-ENV:Body>\n";
	SoapRequestXML += "     <n:" + SOAP_REQ_GET_DSP_INFO_MATHOD_NAME + " xmlns:n=\"http://e-drivers.cn/soap/\">\n";
	SoapRequestXML += DeviceListInfo	+ "\n"
	SoapRequestXML += CPUInfo			+ "\n"
	SoapRequestXML += MainBoardInfo		+ "\n"
	SoapRequestXML += DiskInfo			+ "\n"
	SoapRequestXML += MACIDs			+ "\n"
	SoapRequestXML += OSInfo			+ "\n"
	SoapRequestXML += ProblemDeviceInfo + "\n"
	SoapRequestXML += "     </n:" + SOAP_REQ_GET_DSP_INFO_MATHOD_NAME + ">\n";
	SoapRequestXML += "   </SOAP-ENV:Body>\n";

	SoapRequestXML += "</SOAP-ENV:Envelope>";


	// 12.9%
	DispProgressInfo( 90 )
	DrvCert.UIRefresh()
/*

	SetCurProcessBeginEndPercent( 30 , 40 )
//	DispProgressInfo( 0 , "正在校对时间...")
	//13%
	DispProgressInfo( 0 )
	DrvCert.UIRefresh()
	
	var StampTime = new Array()
	StampTime = GetStampTime()					//StampTime = GetUTCDateTime()
	var CreateStampTime = StampTime["Create"]
	var ExpireStampTime = StampTime["Expire"]
	var DateTimeFormat    = "VirtualTime"

	SetCurProcessBeginEndPercent( 40 , 50 )
//	DispProgressInfo( 60 , "正在准备时间戳...")
	//14%
	DispProgressInfo( 0 )
	DrvCert.UIRefresh()
	
	var PackagedXml = StampXml( SoapRequestXML , CreateStampTime , ExpireStampTime , DateTimeFormat )
	if ( PackagedXml == null || PackagedXml == "")
	{
		DSPInfo["Error"] = "在请求DSP信息时签署XML时间戳失败"
		DSPInfo["Success"] = false; 
		return (DSPInfo);
	}

//	DispProgressInfo( 100 , "正在准备签名信息...")
	//14.5%
	DispProgressInfo( 50 )
	DrvCert.UIRefresh()
	var SignData = XmlToText( PackagedXml );
	if (SignData == null || SignData== "")
	{
		DSPInfo["Error"] = "在请求DSP信息时转换XML文本失败"
		DSPInfo["Success"] = false; 
		return (DSPInfo);
	}
	//14.8%
	DispProgressInfo( 80 )
	DrvCert.UIRefresh()
	var SignValue = DrvCert.SignDataInString( CertContext , SignData );
	if (SignValue == null || SignValue == "" )
	{
		DSPInfo["Error"] = "在为XML内容签名时失败"
		DSPInfo["Success"] = false; 
		return (DSPInfo);
	}
	//14.9%
	DispProgressInfo( 90 )
	DrvCert.UIRefresh()
	var SignedXml = SignXml( PackagedXml , SignValue );
	if ( SignedXml == null)
	{
		DSPInfo["Error"] = "在请求DSP信息时对XML签名失败"
		DSPInfo["Success"] = false; 
		return (DSPInfo);
	}

	PackagedXml = SignedXml
	//15%
	DispProgressInfo( 100 )
	DrvCert.UIRefresh()


//	AlertInfo += "\n[] Soap request xml text-value is:\n" + SignData
//	AlertInfo += "\n[] Soap request xml sign-value is:\n" + SignValue


*/

///////////////////////////////////// 新加 ////////////////////////////////////////////////////////////////////////

	var CertLocation = 1 // Current_user_location
	var SoapFinalXMLInfo = SignStampEncryptXMLEx( 
								ServerName.value + SOAP_URL_GET_COMM_CERT , 
								ServerName.value + SOAP_URL_GET_TIME ,
								SoapRequestXML , 
								CertContext , 
								CertLocation )
	if (!SoapFinalXMLInfo["Success"] )
	{
		return false
	}
	AlertInfo += "[] 原始SOAP包是：\n" + SoapRequestXML + "\n"
	AlertInfo += "[] 经过“签名/盖时间戳/证书加密”后的SOAP包是：\n" + SoapFinalXMLInfo["Xml"] + "\n"

	var PackagedXml = SoapFinalXMLInfo["Xml"]

/////////////////////////////////////////////////////////////////////////////////////////////////////////////

	SetCurProcessBeginEndPercent( 50 , 60 )
	if ( !DrvCert.CloseCertProvider( CertProvider )) DispProgressInfo( 100 , "Close cert provider failed(provider=" + CertProvider + ")");
	CertProvider = null;
//	DispProgressInfo( 100 , "正在关闭用户证书密钥...")
	DispProgressInfo( 100 )
	DrvCert.UIRefresh()
	SetCurProcessBeginEndPercent( 60 , 70 )
	if ( !DrvCert.CloseUserCert( CertContext )) DispProgressInfo( 100 , "Close cert handle failed(handle=" + CertContext + ")");
	CertContext = null;
//	DispProgressInfo( 100 , "正在关闭用户证书...")
	DispProgressInfo( 100 )
	DrvCert.UIRefresh()

	// 由于有可能程序是从本地启动的（而不是从INTERNET启动的）或是从DSP网站启动的，因此必须指定e-drivers.cn的SOAP服务器地址
	// 这样做的好处是本程序可以很好地工作在“在线”和“离线”两种方式下
	var Hostname = ServerName.value
	EndURI = Hostname + SOAP_URL_DISPATCH_DSP

	// 设置当前任务占总任务的百分比
	SetCurProcessBeginEndPercent( 70 , 90 )
//	DispProgressInfo( 0 , "正在查找驱动服务信息...")
	DispProgressInfo( 0 )
	ReturnXML = DrvCert.SoapClientRequest( EndURI , PackagedXml );
	if (ReturnXML == null || ReturnXML == "")
	{
		DSPInfo["Error"] = "SOAP请求没有回应"
		DSPInfo["Success"] = false; 
		return (DSPInfo);
	}

	AlertInfo += "\n[] request package is : \n\n" + PackagedXml + "\n";
	AlertInfo += "\n[] return package is :\n\n" + ReturnXML + "\n";

	var ErrorInfo = GetInfoByTagFromXml( ReturnXML, SOAP_RET_ERROR_STRING_TAG )
	SetCurProcessBeginEndPercent( 90 , 100 )
	DrvCert.UIRefresh()
	if (ErrorInfo != null) 
	{
		DispProgressInfo( 100 , ErrorInfo )
	}
	else
	{
		// 检查返回的XML内容签名，看内容是否确实是e-drivers.cn提供的、内容是否被修改过
		var CheckInfo = CheckSoapServerSignValue( ReturnXML )
		if (!CheckInfo["Success"])
		{
			// 如果不是一般错误（一般是非法格式的XML，没有DSP签名或签名无效）
			if ( ErrorInfo == null)
			{
				ErrorInfo = "返回的驱动服务信息格式错误:<br>"+ CheckInfo["ErrorInfo"]
			}
			// 如果是一般错误（比如：时间戳超时等）
			else
			{
				AlertInfo += CheckInfo["ErrorInfo"]
			}
		}
	}
	if (!DrvCert.ReleaseProvider())
	{
		DispProgressInfo( 100 , "Release CSP failed\n" + DrvCert.ErrorString);
	}
	else
	{
		AlertInfo += "\n[] CSP released !" + "\n";
	}

	if ( ErrorInfo == "" || ErrorInfo == null )
	{
		//DispProgressInfo( 100 , "查找驱动服务信息成功")
		DispProgressInfo( 100 )
	}
	if (g_TestingInfoDisp) newElement.innerText = AlertInfo

	/*     返回信息XML

	<?xml version="1.0" encoding="UTF-16" standalone="no"?>
	<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
	 <SOAP-ENV:Header xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
	  <Timestamp>
		<Created>2004-5-8 3:15:23</Created>
		<Expires>2004-5-8 8:15:23</Expires>
		<Format>UTC</Format></Timestamp>
		<SignInfo>
			<SignValue>RiGL...wiX0NFNdIgdUonoVg==</SignValue>
		</SignInfo>
	 </SOAP-ENV:Header>
	 <SOAP-ENV:Body xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
	  <m:GetDSPInfoResponse xmlns:m="http://e-drivers.cn/soap/">
	   <Result>
		<RegResult>User device info add to DB success( user cert serial-number : 81 2C 50 CB  )</RegResult>
		<GetSvcCertInfoURL>http://server/soap/DrvDown.asp</GetSvcCertInfoURL>
		<UserCertIssuerURL>http://server/soap/DrvCert.asp</UserCertIssuerURL>
		<MatchingDeviceID>USB\ROOT_HUB</MatchingDeviceID>
		//<IssuerCertSubString>e-drivers.cn</IssuerCertSubString>
		<UserCertIssuerSubjectKeyWord>e-drivers.cn</UserCertIssuerSubjectKeyWord>
		//<DriverVersion>5.0.2195.1</DriverVersion>
		//<DriverDate>12-9-1999</DriverDate>
		//<DriverProvider>Microsoft</DriverProvider>
		//<DriverSize>123680</DriverSize>
		<BuyNumber>21</BuyNumber>
		<IfSubmitAllDeviceInfo>true</IfSubmitAllDeviceInfo>
	   </Result>
	  </m:GetDSPInfoResponse>
	 </SOAP-ENV:Body>
	</SOAP-ENV:Envelope>
	*/	
	DSPInfo = GetDSPInfoFromSoapReturnXml( ReturnXML )
	//DSPInfo["DrvAspUrl"				]
	//DSPInfo["CerAspUrl"				]
	//DSPInfo["DeviceID"				]
	//DSPInfo["Issuer"					]
	//DSPInfo["BuyNumber"				]
	//DSPInfo["SubmitAllDeviceFlag"		]

	if (	DSPInfo["DrvAspUrl"] && DSPInfo["CerAspUrl"] && DSPInfo["DeviceID"] && DSPInfo["Issuer"] && 
			DSPInfo["BuyNumber"] != undefined && DSPInfo["SubmitAllDeviceFlag"] != undefined )
	{
		DSPInfo["Success"] = true
		DSPInfo["Error"] = ErrorInfo
	}
	else
	{
		DSPInfo["Success"] = false
		DSPInfo["Error"] = ErrorInfo
	}

	// free all temp memory
	if (DeviceListInfo) DeviceListInfo = null
	if (CPUInfo)		CPUInfo = null
	if (MainBoardInfo)  MainBoardInfo = null
	if (DiskInfo)		DiskInfo = null
	if (MACIDs)			MACIDs = null
	if (OSInfo)			OSInfo = null
	if (ProblemDeviceInfo) ProblemDeviceInfo = null
	if (SoapRequestXML) SoapRequestXML = null
	if (PackagedXml)	PackagedXml = null
	if (ReturnXML)		ReturnXML = null
	if (CertKeyPhysicalID)	CertKeyPhysicalID = null
	if (CertContent)	CertContent = null
//	if (SignValue)		SignValue = null
//	if (SignedXml)		SignedXml = null
	if (AlertInfo)		AlertInfo = null

return (DSPInfo);
}
function GetNetCardInfo()
{
	var Xml = DrvCert.GetAdaptersPhysicalAddress()
	// 替换“&”字符为“&amp;”
	Xml = Xml.replace(/(\&)/gi ,"&amp;");
return (Xml)
}
function GetMainBoardInfo()
{
	var Xml =  DrvCert.GetMainboardInfo()
    if ( !Xml ) 
        Xml = DrvCert.GetMainBoardInfoByWMI()

    // 2006-4-27 <..
    var xmlDoc = new ActiveXObject("Microsoft.XMLDOM")
    xmlDoc.async = false;
    xmlDoc.loadXML( Xml );

    if (!xmlDoc) 
    {
        Xml = DrvCert.GetMainBoardInfoByWMI()
    }
    else
    {
        var objNode = xmlDoc.selectSingleNode("//MainBoardItem" )
        // 2006-5-12 <<<<..........................................
        //
        //if (!objNode) 
        //    Xml = DrvCert.GetMainBoardInfoByWMI()
        //
        var objChildNodes = objNode.childNodes
        if ( !objChildNodes || !objChildNodes.length ) 
                Xml = DrvCert.GetMainBoardInfoByWMI()
        //
        // 2006-5-12 ........................................>>>>>>
    }
    xmlDoc = null
    // 2006-4-27 ..>
	// 替换“&”字符为“&amp;”
	Xml = Xml.replace(/(\&)/gi ,"&amp;");
return (Xml)
}
function GetCPUInfo()
{
	var Xml = DrvCert.GetCPUInfo()
	// 替换“&”字符为“&amp;”
	Xml = Xml.replace(/(\&)/gi ,"&amp;");
return (Xml)
}
function GetDiskInfo()
{
	var Xml =  DrvCert.GetDiskInfo()
	// 替换“&”字符为“&amp;”
	Xml = Xml.replace(/(\&)/gi ,"&amp;");
return (Xml)
}
function GetOSInfo()
{
	var Xml =  DrvCert.GetOSInfo()
	// 替换“&”字符为“&amp;”
	Xml = Xml.replace(/(\&)/gi ,"&amp;");
return (Xml)
}
function GetPublicKeyInfo( PublicKey )
{
//<PublicKeyInfo>
//	<PublicKeyItem>
//		<PublicKey>asdf87sdddh</PublicKey>
//	</PublicKeyItem>
//</PublicKeyInfo>
	var PublicKeyInfoStr = ""
	PublicKeyInfoStr += "<PublicKeyInfo>\n"
	PublicKeyInfoStr += "\t<PublicKeyItem>\n"
	PublicKeyInfoStr += "\t\t<PublicKey>" + PublicKey + "</PublicKey>\n"
	PublicKeyInfoStr += "\t</PublicKeyItem>\n"
	PublicKeyInfoStr += "</PublicKeyInfo>\n"
return ( PublicKeyInfoStr )
}
function CheckSoapServerSignValue( SoapReturnXml )
{
	var CheckInfo = new Array()

	var SoapServerOrgXmlAndSignData = new Array()
	SoapServerOrgXmlAndSignData = GetOrgXmlAndSign( SoapReturnXml )

	if ( SoapServerOrgXmlAndSignData["Error"] != "" )
	{
		CheckInfo["ErrorInfo"] = "\nGet soap returned xml error(" + SoapServerOrgXmlAndSignData["Error"] + ")\n"
		CheckInfo["Success"]   = false
		return (CheckInfo)
	}

	var VerifyString		= XmlToText( SoapServerOrgXmlAndSignData["Xml"] )
	var SignValueInBASE64	= SoapServerOrgXmlAndSignData["Sign"]


	//var DSPName = "e-drivers.cn"
	var DSPName = GetXmlSingleNodeText( SoapReturnXml , SOAP_RET_HEADER_USER_CERT_ISSUER_SUBJECT_KEYWORD_TAG )//= "UserCertIssuerSubjectKeyWord"
	var CertHandle  = DrvCert.FindDSPCertByName( DSPName )
	if ( !CertHandle ) 
	{
		CheckInfo["ErrorInfo"] = "\nOpen DSP cert error(DSP name=" + DSPName + ")\n"
		CheckInfo["Success"]   = false
		return (CheckInfo)
	}
	bSuccess		= DrvCert.VerifyStringByBASE64Sign( CertHandle , VerifyString , SignValueInBASE64 )
	if (!bSuccess)
	{
		CheckInfo["ErrorInfo"] = "\nVerify soap xml and signature error(" + DrvCert.ErrorString + ")\n"
		CheckInfo["Success"]   = false
		if (CertHandle) DrvCert.CloseUserCert( CertHandle )
		return (CheckInfo)
	}

	CheckInfo["Success"] = DrvCert.CloseUserCert( CertHandle )

	return (CheckInfo)
}


function GetStampTime( ServerTime )
{
	var ServerVirtualTime , LocalTime
	var StampDate = new Array()
	var objDate = new Date()

	if (!ServerTime)
	{
		// 只在从未调用过/soap/GetTime.asp时执行一次，以后都按上次的结果来用
		// 但由于DSP可以有多个，每个的虚时间都可能不同，因此取消该优化措施
		//if (g_TimeOffset == null)
		{
			//var Hostname = location.hostname
			//if (Hostname == "") Hostname = ServerName.value
			var Hostname = "http://" + ServerName.value
			var EndURI = Hostname + SOAP_URL_GET_TIME

			var RequestXml = ""
			RequestXml += '<?xml version="1.0" encoding="UTF-16" standalone="no"?>\n';
			RequestXml += '<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">'
			RequestXml += ' <SOAP-ENV:Body>'
			RequestXml += '  <' + SOAP_REQ_TIME_METHOD_NAME + '></' + SOAP_REQ_TIME_METHOD_NAME + '>'
			RequestXml += ' </SOAP-ENV:Body>'
			RequestXml += '</SOAP-ENV:Envelope>'

			var ReturnXML = DrvCert.SoapClientRequest( EndURI , RequestXml );
			ServerVirtualTime = GetXmlSingleNodeText( ReturnXML , SOAP_RET_BODY_DATE_TIME_TAG )
		}
	}
	else
	{
		ServerVirtualTime = ServerTime
	}


	LocalTime = objDate.getTime()
	//g_TimeOffset = 3599859
	g_TimeOffset = LocalTime - ServerVirtualTime

	StampDate["Create"] = objDate.getTime() - g_TimeOffset
	StampDate["Expire"] = StampDate["Create"] + g_ExpireSeconds * 1000
return ( StampDate )
}
function CheckDSPUserCert( DSPInfo )
{
	//	DSPInfo["Issuer"   ]	// 颁发DSP用户证书的颁发者是谁？如果DSP使用e-drivers.cn的用户证书，则颁发者是e-drivers.cn；否则，是DSP。
	//	DSPInfo["CerAspUrl"]	// 颁发DSP用户证书的URL是什么？如果DSP使用e-drivers.cn的用户证书，则URL是e-drivers.cn的用户证书颁发地址；否则，是DSP URL。
	//	DSPInfo["DrvAspUrl"]	// 查询DSP服务证书参数的URL是什么？
	//	DSPInfo["DeviceID" ]	// 查询哪个设备的服务证书？
	//	//DSPInfo["DrvVer"   ]
	//	//DSPInfo["DrvDate"  ]
	//	//DSPInfo["DrvVendor"]
	//	//DSPInfo["DrvSize"  ]
	//	DSPInfo["BuyNumber"]
	//	DSPInfo["SubmitAllDeviceFlag"]
	SetCurProcessBeginEndPercent( 0 , 100 )
	DispProgressInfo( 0 , "正在查找\"" + DSPInfo["Issuer"] + "\"用户证书...")
	DrvCert.UIRefresh()

	var CertContext = FindAndOpenUserCertByIssuer( DSPInfo["Issuer"] )

	// 执行到这里，若找到DSP用户证书，CertContext != 0；否则，CertContext = 0。
	// 若没有用户证书
	if (!CertContext)
	{
		// 若DSP要定制自己的用户证书，则DSPInfo["CerAspUrl"]就是颁发DSP用户证书服务URL地址。
		// 该地址由客户端SOAP查询e-drivers.cn服务器返回，该值其实是DSP发布的“驱动服务信息—用户证书服务URL”信息项。
		//
		// 颁发DSP用户证书服务可以是自动模式也可以是手工模式。
		// 自动模式下DSP给用户颁发一个通用信息（或者说空白信息）的证书，没有用户信息与该证书绑定，但用户以后可
		// 以自己修改用户信息；手工模式下用户要填写注册信息，DSP审批后颁发用户证书，同时DSP将用户证书与注册信
		// 息绑定并在DSP内部注册。
		//
		showModalDialog( DSPInfo["CerAspUrl"], null, 'dialogWidth:500px;dialogHeight:300px;center:yes;resizable:yes;' );
		CertContext = FindAndOpenUserCertByIssuer( DSPInfo["Issuer"] )
		if (!CertContext)
		{
			DispMessageInfo("颁发DSP(" + DSPInfo["Issuer"] + ")用户证书失败")
			return false
		}
	}
	else
	{
		DispProgressInfo( 100 )
	}

	// 关闭DSP用户证书
	if (CertContext) DrvCert.CloseUserCert( CertContext )
return true
}
function FindAndOpenUserCertByIssuer( IssuerName )
{

	// 证书存储区位置
	// 1: CERT_SYSTEM_STORE_CURRENT_USER
	// 2: CERT_SYSTEM_STORE_LOCAL_MACHINE
	//
	// 证书存储区
	// "DrvCert"
	//
	// 找到第一个DSP证书
	var FindHandle = DrvCert.CreateCertFind( 1 , "DrvCert" );
	// 证书查找标志
	// 0: 查找任何证书
	// 1: 查找颁发者名称中包含函数第一个参数特征串的证书
	// 2: 查找证书主题中包含函数第一个参数特征串的证书
	var CertContext = DrvCert.CertFind( IssuerName , 1 , FindHandle , 0 ) // 0 : 查找第一个证书
	var CertContextOld
	var ServerTime = 0
	while( CertContext )
	{
		CertContextOld = CertContext

		// 若找到的当前证书不是用户证书
		if (DrvCert.GetCertClass(CertContext) != "1")
		{
			// 找下个用户证书
			CertContext = DrvCert.CertFind( IssuerName , 1 , FindHandle , CertContext )
		}
		// 若找到的当前证书是用户证书，还要检查用户证书是否未生效或已失效？
		else
		{
			var UserCertNotBefore = Date.parse( DrvCert.GetCertNotBefore( CertContext ) )
			var UserCertNotAfter  = Date.parse( DrvCert.GetCertNotAfter(  CertContext ) )
			// 通过e-drivers.cn/soap/GetTime.asp取当前时间
			if (!ServerTime) ServerTime = GetServerTime( ServerName.value + SOAP_URL_GET_TIME )
			// 如果用户证书没有在有效期内（即未生效或已失效）
			if ( !( UserCertNotBefore <= ServerTime && ServerTime<= UserCertNotAfter ) )
			{
				// 找下个用户证书
				CertContext = DrvCert.CertFind( IssuerName , 1 , FindHandle , CertContext )
			}
			else
			{
				break;
			}
		}
		// 如果当前查找证书不是要找的用户证书，则进行善后处理：关闭上次找到证书的CertContext
		// （当前CertContext不能关闭，还要用它查找下一个）
		if (CertContextOld) DrvCert.CloseUserCert( CertContextOld )
	}

	DrvCert.CloseCertFind( FindHandle )


// DrvCert.FindCertByIssuer()方法只能找到一个证书，无法查找到下一个证书；
// 要查找到下一个证书，请用DrvCert.CreateCertFind() / DrvCert.CertFind() / DrvCert.CloseCertFind()
// 故原来的查找证书的方法被废除：
// 
//	var CertContext = DrvCert.FindCertByIssuer( IssuerName , 0 )
//
//	while ( CertContext )
//	{
//		// 若找到的当前证书不是用户证书
//		if (DrvCert.GetCertClass(CertContext) != "1")
//		{
//			// 找到下个DSP证书
//			CertContext = DrvCert.FindCertByIssuer( IssuerName , CertContext )
//		}
//		// 若找到的当前证书是用户证书
//		else
//		{
//			break;
//		}
//	}
return (CertContext)
}
function FindDSPSvcCertByCertInfo( DSPSvcCertInfo )
{
	//DSPSvcCertInfo["Issuer"		]
	//DSPSvcCertInfo["Class"		]
	//DSPSvcCertInfo["NotBefore"	]
	//DSPSvcCertInfo["NotAfter"		]
	//DSPSvcCertInfo["LocaleServerTimeOffset"]
	//DSPSvcCertInfo["DeviceID"		]
	//DSPSvcCertInfo["IssueURL"		]
	//DSPSvcCertInfo["DownloadURL"	]
	var objTime = new Date()
	var CurServerTime = objTime.getTime() - DSPSvcCertInfo["LocaleServerTimeOffset"]

	if (!DSPSvcCertInfo["Issuer"]) DSPSvcCertInfo["Issuer"]="!!!!!!!!"
	///////////////////////////////////
	//
	// 证书存储区
	// "DrvCert"													 
	//																// 证书存储区位置                      
	// 找到第一个DSP证书											// 1: CERT_SYSTEM_STORE_CURRENT_USER   
	var FindHandle = DrvCert.CreateCertFind( 1 , "DrvCert" );		// 2: CERT_SYSTEM_STORE_LOCAL_MACHINE 
	// 第二个参数：证书查找标志
	//		
	// 0: 查找任何证书
	// 1: 查找颁发者名称中包含函数第一个参数特征串的证书
	// 2: 查找证书主题中包含函数第一个参数特征串的证书
	//
	// 第四个参数：
	//
	// 0   :查找第一个证书
	// !=0 :查找上一个证书上下文匹配的下一个证书
	//
	var CertContext = DrvCert.CertFind( DSPSvcCertInfo["Issuer"] , 1 , FindHandle , 0 ) 
	var CertContextOld
	while( CertContext )
	{	
		CertContextOld = CertContext

		// 若找到的当前证书不是指定的服务证书类别
		if (DrvCert.GetCertClass(CertContext) != DSPSvcCertInfo["Class"] )
		{
			// 找下个DSP颁发的服务证书
			CertContext = DrvCert.CertFind( DSPSvcCertInfo["Issuer"] , 1 , FindHandle , CertContext )
		}
		// 若找到的当前证书是指定类别的DSP服务证书
		else
		{
			var NotBefore = Date.parse(DrvCert.GetCertNotBefore( CertContext ))
			var NotAfter  = Date.parse(DrvCert.GetCertNotAfter( CertContext ))

			// 如果当前时间不在证书有效时间内，就视为证书无效，继续找下一个
			if ( CurServerTime > NotAfter || CurServerTime < NotBefore )
			{
				// 找下个DSP颁发的服务证书
				CertContext = DrvCert.CertFind( DSPSvcCertInfo["Issuer"] , 1 , FindHandle , CertContext )
			}
			else
			{	// 如果证书的类别、时间都有效，再查找服务证书的设备标识是否是/soap/GetSvcCertInfo.asp返回的值，
				if (DrvCert.GetCertDeviceID(CertContext) != DSPSvcCertInfo["DeviceID"] )
				{
					// 找下个DSP颁发的服务证书
					CertContext = DrvCert.CertFind( DSPSvcCertInfo["Issuer"] , 1 , FindHandle , CertContext )
				}
				// 若是证书的类别、时间、设备标识都有效，中断查找，返回找到的CertContext
				else
				{
					break;
				}
			}
		}

		if (CertContextOld) DrvCert.CloseUserCert( CertContextOld )
	}

	DrvCert.CloseCertFind( FindHandle )

return (CertContext)
}
// 查询用户请求的驱动服务对应的驱动服务证书的特征信息，以便供客户端判断是否需要申请新的服务证书还是使用已有的服务证书。
// 如果根据驱动服务证书的特征信息没有找到相应的服务证书，就要向DSP的驱动服务证书发放服务（IssueSvcCert.asp）申请发放服
// 务证书。
//
// 比如：请求驱动服务的设备有DeviceID，调用SOAP驱动服务证书查询服务后返回驱动服务要求的服务证书特征有：
//       DSP名称、驱动DeivceID、驱动服务类型（是用户服务证书还是访问服务证书）、服务证书的有效期限等。
// 如果在用户端找不到符合要求的服务证书，就向DSP的驱动服务证书发放服务（IssueSvcCert.asp）申请发放服务证书。
//
function CheckDSPSvcCert( DSPDrvInfo )
{
	//	DSPDrvInfo["Issuer"   ]	// 颁发DSP用户证书的颁发者是谁？如果DSP使用e-drivers.cn的用户证书，则颁发者是e-drivers.cn；否则，是DSP。
	//	DSPDrvInfo["CerAspUrl"]	// 颁发DSP用户证书的URL是什么？如果DSP使用e-drivers.cn的用户证书，则URL是e-drivers.cn的用户证书颁发地址；否则，是DSP URL。
	//	DSPDrvInfo["DrvAspUrl"]	// 查询DSP服务证书参数的URL是什么？
	//	DSPDrvInfo["DeviceID" ]	// 查询哪个设备的服务证书？
	//  DSPDrvInfo["DevRow"   ] // 该设备在drvinst.js中的内部标识（设备列表中的行号）
	//	//DSPDrvInfo["DrvVer"   ]
	//	//DSPDrvInfo["DrvDate"  ]
	//	//DSPDrvInfo["DrvVendor"]
	//	//DSPDrvInfo["DrvSize"  ]
	//	DSPDrvInfo["BuyNumber"]
	//	DSPDrvInfo["SubmitAllDeviceFlag"]
	SetCurProcessBeginEndPercent( 0 , 10 )
	// 40%
	DispProgressInfo( 0 , "正在查找\"" + DSPDrvInfo["Issuer"] + "\"服务证书...")
	DrvCert.UIRefresh()

	CreateDymanicDocElement( "newElement2" )

	//var DeviceID = DSPDrvInfo["DeviceID" ]
	//DeviceID = DeviceID.replace(/(\&)/gi ,"&amp;");

	var RequestXml = ""
	RequestXml += '<?xml version="1.0" encoding="UTF-16" standalone="no"?>\n';
	RequestXml += '<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">\n'
	RequestXml += ' <SOAP-ENV:Body>\n'
	RequestXml += '  <'  + SOAP_REQ_SERVICE_CERT_INFO_MATHOD_NAME + '>\n' 
	//RequestXml += '    <' + SOAP_REQ_SERVICE_CERT_INFO_ITEM_DEVICE_ID_TAG + '>' + DeviceID + '</' + SOAP_REQ_SERVICE_CERT_INFO_ITEM_DEVICE_ID_TAG + '>\n'
	RequestXml += '    <' + SOAP_REQ_SERVICE_CERT_INFO_BUY_NUMBER_TAG + '>' + DSPDrvInfo["BuyNumber"] + '</' + SOAP_REQ_SERVICE_CERT_INFO_BUY_NUMBER_TAG + '>\n'
	RequestXml += '  </' + SOAP_REQ_SERVICE_CERT_INFO_MATHOD_NAME + '>\n'
	RequestXml += ' </SOAP-ENV:Body>\n'
	RequestXml += '</SOAP-ENV:Envelope>\n'

	SetCurProcessBeginEndPercent( 10 , 40 )
	//43%
	DispProgressInfo( 0 )
	DrvCert.UIRefresh()

	// DSPDrvInfo["DrvAspUrl"] = "http://dsp-server/soap/GetSvcCertInfo.asp"
	var ReturnXML = DrvCert.SoapClientRequest( DSPDrvInfo["DrvAspUrl"] , RequestXml );
	//<?xml version="1.0" encoding="UTF-16" standalone="no"?>
	//<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
	//  <SOAP-ENV:Body SOAP-ENV:encodingStyle="">
	//    <m:GetSvcCertInfoResponse xmlns:m="http://e-drivers.cn/soap/">
	//        <Result>
	//            <Issuer>e-drivers.cn</Issuer>
	//            <Class>105</Class>
	//            <NotBefore>2004/01/24  00:13:19</NotBefore>
	//            <NotAfter>2005/01/24  00:23:19</NotAfter>
	//            <DateTime>1084779426640</DateTime>
	//            <DeviceID>PCI\VEN_1106&amp;DEV_3065&amp;SUBSYS_14011186&amp;REV_43</DeviceID>
	//            <SvcCertIssuerUrl>http://dsp-server/soap/IssueSvcCert.asp</SvcCertIssuerUrl>
	//            <DownloadDriverUrl>http://dsp-server/soap/DownloadDriver.asp</DownloadDriverUrl>
	//        </Result>
	//    </m:GetSvcCertInfoResponse>
	//  </SOAP-ENV:Body>
	//</SOAP-ENV:Envelope>
	//
	//var SOAP_RET_BODY_SERVICE_CERT_INFO_ISSUER_TAG				= "Issuer"
	//var SOAP_RET_BODY_SERVICE_CERT_INFO_CLASS_TAG					= "Class"
	//var SOAP_RET_BODY_SERVICE_CERT_INFO_NOT_BEFORE_TAG			= "NotBefore"
	//var SOAP_RET_BODY_SERVICE_CERT_INFO_NOT_AFTER_TAG				= "NotAfter"
	//var SOAP_RET_BODY_SERVICE_CERT_INFO_DATE_TIME_TAG				= "DateTime"
	//var SOAP_RET_BODY_SERVICE_CERT_INFO_DEVICE_ID_TAG				= "DeviceID"
	//var SOAP_RET_BODY_SERVICE_CERT_INFO_SUBMIT_NUMBER_TAG         = "SubmitNumber"
	//var SOAP_RET_BODY_SERVICE_CERT_INFO_DEPLOY_NUMBER_TAG         = "DeployNumber"
	//var SOAP_RET_BODY_SERVICE_CERT_INFO_ENCRYPT_KEY_ID_TAG        = "EncryptKeyID"
	//var SOAP_RET_BODY_SERVICE_CERT_INFO_ISSUE_SVC_CERT_URL_TAG	= "SvcCertIssuerUrl"
    //var SOAP_RET_BODY_SERVICE_CERT_INFO_DOWNLOAD_DRIVER_URL_TAG	= "DownloadDriverUrl"

	var ServiceCertIssuer		= GetXmlSingleNodeText( ReturnXML , SOAP_RET_BODY_SERVICE_CERT_INFO_ISSUER_TAG )
	var ServiceCertClass		= GetXmlSingleNodeText( ReturnXML , SOAP_RET_BODY_SERVICE_CERT_INFO_CLASS_TAG )
	var ServiceCertNotBefore	= GetXmlSingleNodeText( ReturnXML , SOAP_RET_BODY_SERVICE_CERT_INFO_NOT_BEFORE_TAG )
	var ServiceCertNotAfter		= GetXmlSingleNodeText( ReturnXML , SOAP_RET_BODY_SERVICE_CERT_INFO_NOT_AFTER_TAG )
	var ServerActualTime		= GetXmlSingleNodeText( ReturnXML , SOAP_RET_BODY_SERVICE_CERT_INFO_DATE_TIME_TAG )
	var ServiceCertDeviceID		= GetXmlSingleNodeText( ReturnXML , SOAP_RET_BODY_SERVICE_CERT_INFO_DEVICE_ID_TAG )

	var ServiceCertSubmitNumber	= GetXmlSingleNodeText( ReturnXML , SOAP_RET_BODY_SERVICE_CERT_INFO_SUBMIT_NUMBER_TAG )
	var ServiceCertDeployNumber	= GetXmlSingleNodeText( ReturnXML , SOAP_RET_BODY_SERVICE_CERT_INFO_DEPLOY_NUMBER_TAG )
	var ServiceCertEncryptKeyID	= GetXmlSingleNodeText( ReturnXML , SOAP_RET_BODY_SERVICE_CERT_INFO_ENCRYPT_KEY_ID_TAG )

	var ServiceCertIssuerURL	= GetXmlSingleNodeText( ReturnXML , SOAP_RET_BODY_SERVICE_CERT_INFO_ISSUE_SVC_CERT_URL_TAG )
    var DownloadDriverURL		= GetXmlSingleNodeText( ReturnXML , SOAP_RET_BODY_SERVICE_CERT_INFO_DOWNLOAD_DRIVER_URL_TAG )

	var DSPSvcCertInfo = new Array()
	DSPSvcCertInfo["Issuer"]		= ServiceCertIssuer
	DSPSvcCertInfo["Class"]			= ServiceCertClass
	DSPSvcCertInfo["NotBefore"]		= ServiceCertNotBefore
	DSPSvcCertInfo["NotAfter"]		= ServiceCertNotAfter
	var objTime = new Date()
	DSPSvcCertInfo["LocaleServerTimeOffset"]	= objTime.getTime() - ServerActualTime
	DSPSvcCertInfo["DeviceID"]		= ServiceCertDeviceID
	DSPSvcCertInfo["SubmitNumber"]	= ServiceCertSubmitNumber
	DSPSvcCertInfo["DeployNumber"]	= ServiceCertDeployNumber
	DSPSvcCertInfo["EncryptKeyID"]	= ServiceCertEncryptKeyID
	DSPSvcCertInfo["IssueURL"]		= ServiceCertIssuerURL
	DSPSvcCertInfo["DownloadURL"]	= DownloadDriverURL
	DSPSvcCertInfo["Success"]		= true

	if (g_TestingInfoDisp) newElement2.innerText =	"\n[] request package is :\n\n" + RequestXml +
													"\n[] return package is :\n\n"  + ReturnXML

	var CertContext

	if (!ServiceCertIssuer || !ServiceCertClass || !ServerActualTime || !ServiceCertIssuerURL || !ServiceCertDeviceID || !DownloadDriverURL )
	{
		DispMessageInfo("请求驱动服务证书信息失败")
		DSPSvcCertInfo["Success"] = false
	}
	// 如果是"105-预付费访问服务证书"，就无条件颁发证书
	else if ( DSPSvcCertInfo["Class"] == "105" )
	{
		DSPSvcCertInfo["Success"] = CreateAndImportDSPSvcCert( DSPDrvInfo , DSPSvcCertInfo )
		//DispProgressInfo( 100 , "颁发驱动服务证书成功")
		DispProgressInfo( 100 )
	}
	// 如果是"104：预付费用户服务证书"，需要先查找证书是否已经颁发
	else if ( DSPSvcCertInfo["Class"] == "104" )
	{
		CertContext = FindDSPSvcCertByCertInfo( DSPSvcCertInfo )

		// 执行到这里，若CertContext不是null，表示找到了指定类别的服务证书；否则，表示未找到。

		// 未找到DSP指定类别的服务证书，申请颁发
		if ( !CertContext )
		{
			DSPSvcCertInfo["Success"] = CreateAndImportDSPSvcCert( DSPDrvInfo , DSPSvcCertInfo )
			//DispProgressInfo( 100 , "颁发驱动服务证书成功")
			DispProgressInfo( 100 )
		}
		else
		{
			if ( !DrvCert.CloseUserCert( CertContext )) DispProgressInfo( 100 , "Close cert handle failed(handle=" + CertContext + ")");
			CertContext = null;
			//DispProgressInfo( 100 , "相关的驱动服务证书已找到")
			DispProgressInfo( 100 )
		}
	}

	if (g_TestingInfoDisp) newElement2.innerText =	"\n[] request package is :\n\n" + RequestXml +
													"\n[] return package is :\n\n"  + ReturnXML


return(DSPSvcCertInfo)
}

function CreateAndImportDSPSvcCert( DSPDrvInfo , DSPSvcCertInfo )
{
	//DSPSvcCertInfo["Issuer"		]
	//DSPSvcCertInfo["Class"		]
	//DSPSvcCertInfo["NotBefore"	]
	//DSPSvcCertInfo["NotAfter"		]
	//DSPSvcCertInfo["LocaleServerTimeOffset"	]
	//DSPSvcCertInfo["DeviceID"		]
	//DSPSvcCertInfo["SubmitNumber"	]
	//DSPSvcCertInfo["DeployNumber"	]
	//DSPSvcCertInfo["EncryptKeyID"	]
	//DSPSvcCertInfo["IssueURL"		]	
	//DSPSvcCertInfo["DownloadURL"	]

	//	DSPDrvInfo["Issuer"   ]	// 颁发DSP用户证书的颁发者是谁？如果DSP使用e-drivers.cn的用户证书，则颁发者是e-drivers.cn；否则，是DSP。
	//	DSPDrvInfo["CerAspUrl"]	// 颁发DSP用户证书的URL是什么？如果DSP使用e-drivers.cn的用户证书，则URL是e-drivers.cn的用户证书颁发地址；否则，是DSP URL。
	//	DSPDrvInfo["DrvAspUrl"]	// 查询DSP服务证书参数的URL是什么？
	//	DSPDrvInfo["DeviceID" ]	// 查询哪个设备的服务证书？
	//  DSPDrvInfo["DevRow"   ] // 该设备在drvinst.js中的内部标识（设备列表中的行号）
	//	DSPDrvInfo["BuyNumber"]
	//	DSPDrvInfo["SubmitAllDeviceFlag"]

	var CertSize = 1024

	if ( !DrvCert.SelectProvider( CertSize ) )
	{
		DispMessageInfo( "select a CSP for 1024-bit public/private key error\n" + DrvCert.ErrorString)
		return false;
	}
	// 在DrvCert.SelectProvider()和DrvCert.ReleaseProvider()期间屏蔽任何DispProgressInfo()和DispMessageInfo()
	// 可以避免EXCEPTION_ACCESS_VIOLATION错误的发生
	//
	//DispMessageInfo( "正在生成证书密钥对..." )

	// key is not exportable
	if (!DrvCert.GenKey(false))
	{
		DispMessageInfo( " generate a public/private key error\n" + DrvCert.ErrorString);
		return false
	}
	
	// 在DrvCert.SelectProvider()和DrvCert.ReleaseProvider()期间屏蔽任何DispProgressInfo()和DispMessageInfo()
	// 可以避免EXCEPTION_ACCESS_VIOLATION错误的发生
	//
	//DispMessageInfo( "正在读取密钥对公钥..." )

	var DSPPublicKey = DrvCert.GetPublicKeyInBASE64()

	if ( DSPPublicKey == null || DSPPublicKey == "")
	{
		DispMessageInfo( "GetPublicKeyInBASE64() failed" + DrvCert.ErrorString);
	}
	
	// move in
	if (!DrvCert.ReleaseProvider())
	{
		DispMessageInfo( "Release CSP failed\n" + DrvCert.ErrorString);
	}

	var SvcCert = SoapAcquireDSPDrvCert( DSPDrvInfo , DSPSvcCertInfo , DSPPublicKey )

	if (SvcCert["Success"])
	{
		if (!DrvCert.ImportCert( SvcCert["Cert"] ))
		{
			DispMessageInfo( "Import Cert failed\n" + DrvCert.ErrorString);
		}
	}

//  move out
//
//	if (!DrvCert.ReleaseProvider())
//	{
//		DispMessageInfo( "Release CSP failed\n" + DrvCert.ErrorString);
//	}

return SvcCert["Success"]
}
function SoapAcquireDSPDrvCert( DSPDrvInfo , DSPSvcCertInfo , DSPPublicKey )
{
	//DSPSvcCertInfo["Issuer"		]
	//DSPSvcCertInfo["Class"		]
	//DSPSvcCertInfo["NotBefore"	]
	//DSPSvcCertInfo["NotAfter"		]
	//DSPSvcCertInfo["LocaleServerTimeOffset"	]
	//DSPSvcCertInfo["DeviceID"		]
	//DSPSvcCertInfo["SubmitNumber"	]
	//DSPSvcCertInfo["DeployNumber"	]
	//DSPSvcCertInfo["EncryptKeyID"	]
	//DSPSvcCertInfo["IssueURL"		]	
	//DSPSvcCertInfo["DownloadURL"	]

	//	DSPDrvInfo["Issuer"   ]	// 颁发DSP用户证书的颁发者是谁？如果DSP使用e-drivers.cn的用户证书，则颁发者是e-drivers.cn；否则，是DSP。
	//	DSPDrvInfo["CerAspUrl"]	// 颁发DSP用户证书的URL是什么？如果DSP使用e-drivers.cn的用户证书，则URL是e-drivers.cn的用户证书颁发地址；否则，是DSP URL。
	//	DSPDrvInfo["DrvAspUrl"]	// 查询DSP服务证书参数的URL是什么？
	//	DSPDrvInfo["DeviceID" ]	// 查询哪个设备的服务证书？
	//  DSPDrvInfo["DevRow"   ] // 该设备在drvinst.js中的内部标识（设备列表中的行号）
	//	DSPDrvInfo["BuyNumber"]
	//	DSPDrvInfo["SubmitAllDeviceFlag"]

	var row			= DSPDrvInfo["DevRow"]
	var EndURI		= DSPSvcCertInfo["IssueURL"]
	//var objTime = new Date()
	//var ServerTime	= objTime.getTime() - DSPSvcCertInfo["LocaleServerTimeOffset"]

	var IssueDSPSvcCertInfo = new Array()
	
	var AlertInfo="Testing info:\n";
	var SoapRequestXML = "";
	var ReturnXML="";

	CreateDymanicDocElement( "newElement3" )

////////////////////////////////////////////////////////////////////////////////////////////////////////
// 申请DSP驱动服务证书需要用户出示用户证书
////////////////////////////////////////////////////////////////////////////////////////////////////////
	SetCurProcessBeginEndPercent( 40 , 80 )
	//52%-64%
//	DispProgressInfo( 100 , "正在查找服务证书...")
	DispProgressInfo( 0 )
	DrvCert.UIRefresh()

	var IssuerNameSubString = DSPDrvInfo["Issuer"]	
	var CertContext = FindAndOpenUserCertByIssuer( IssuerNameSubString );
	if (!CertContext) 
	{
		DispProgressInfo( 100 , "无法找到"+DSPDrvInfo["Issuer"]+"的用户证书");
		return 
	}
//	DispProgressInfo( 100 , "正在打开用户证书...")
	// 52+1.2=53.2%
	DispProgressInfo( 10 )
	DrvCert.UIRefresh()
	var CertProvider = DrvCert.OpenCertProvider( CertContext , 1);//1:Current_user_location 2:Local_machine_location
	if (!CertProvider) 
	{
		DispProgressInfo( 100 , "Open cert provider failed(cert handle=" + CertContext + ") : " + DrvCert.ErrorString); 
		return
	}

//	DispProgressInfo( 100 , "正在获取用户证书标识信息...")
	//54.4%
	DispProgressInfo( 20 )
	DrvCert.UIRefresh()
	var CertKeyPhysicalID = DrvCert.GetCertKeyPhysicalID( CertProvider , 1);//1:Current_user_location 2:Local_machine_location
	if ( CertKeyPhysicalID == null )
	{
		DispProgressInfo( 100 , "Get cert key Physical-ID error <br>" + + DrvCert.ErrorString);
		return
	}

	var CertContent = DrvCert.GetCertContent( CertContext )
	if (!CertContent)
	{
		DispMessageInfo( "Get cert content error" )
		return
	}
	var CertIssuer  = IssuerNameSubString

//	DispProgressInfo( 100 , "正在准备查找驱动服务信息...")
	//54.4+1.2=55.6%
	DispProgressInfo( 30 )
	DrvCert.UIRefresh()

	SoapRequestXML = "";
	SoapRequestXML += '<?xml version="1.0" encoding="UTF-16" standalone="no"?>\n';
	SoapRequestXML += '<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">\n';
	SoapRequestXML += "   <SOAP-ENV:Header xmlns:wsu =\"http://schemas.xmlsoap.org/ws/2002/07/utility\" ";
	SoapRequestXML += "                    xmlns:wsse=\"http://schemas.xmlsoap.org/ws/2002/07/secext\" >\n";
	SoapRequestXML += "      <CertInfo>\n";
	SoapRequestXML += "         <CertContent>"		+ CertContent		+ "</CertContent>\n";
	SoapRequestXML += "         <CertPhysicalID>"	+ CertKeyPhysicalID + "</CertPhysicalID>\n";
	SoapRequestXML += "         <CertIssuer>"		+ CertIssuer		+ "</CertIssuer>\n";
	SoapRequestXML += "      </CertInfo>\n";
//
// Timestamp节内容由下面StampXml()函数自动填写 
//
//	SoapRequestXML += "      <Timestamp>\n";
//	SoapRequestXML += "         <Created>2004-03-08 12:00:00</Created>\n";
//	SoapRequestXML += "         <Expires>2004-03-08 12:05:00</Expires>\n";
//	SoapRequestXML += "         <Format>UTC</Format>\n";
//	SoapRequestXML += "      </Timestamp>\n";

//
// SignInfo节内容由下面SignXml()函数自动填写
//
//	SoapRequestXML += "      <m:SignInfo xmlns:m=\"http://e-drivers.cn/soap/\">\n";
//	SoapRequestXML += "         <m:SignValue>DewqdAYBStswtTgh875</m:SignValue>\n";
//	SoapRequestXML += "      </m:SignInfo>\n";
//
	SoapRequestXML += "   </SOAP-ENV:Header>\n";

	SoapRequestXML += "   <SOAP-ENV:Body>\n";
	SoapRequestXML += "     <n:" + SOAP_REQ_ISSUE_SVC_CERT_MATHOD_NAME + " xmlns:n=\"http://e-drivers.cn/soap/\">\n";
	// 如果服务授权证书购买了“提交用户设备信息”服务项，则提交用户设备信息
	if ( DSPDrvInfo["SubmitAllDeviceFlag"] )
	{
		var DeviceListInfo		= GetDeviceListInfoToXml()
		var MACIDs				= GetNetCardInfo()
		var MainBoardInfo		= GetMainBoardInfo()
		var CPUInfo				= GetCPUInfo()
		var DiskInfo			= GetDiskInfo()
		var OSInfo				= GetOSInfo()

		SoapRequestXML += DeviceListInfo	+ "\n"
		SoapRequestXML += CPUInfo			+ "\n"
		SoapRequestXML += MainBoardInfo		+ "\n"
		SoapRequestXML += DiskInfo			+ "\n"
		SoapRequestXML += MACIDs			+ "\n"
		SoapRequestXML += OSInfo			+ "\n"
	}
	var ProblemDeviceInfo	= GetDeviceDownloadDriverInfoToXml( row )
	var PublicKeyInfo		= GetPublicKeyInfo( DSPPublicKey )

	SoapRequestXML += ProblemDeviceInfo + "\n"
	SoapRequestXML += PublicKeyInfo		+ "\n"
	SoapRequestXML += "      <" + SOAP_REQ_ISSUE_SVC_CERT_PARAMETER_DEPLOY_INFO_TAG  + ">\n";	// DeployInfo
	SoapRequestXML += "         <" + SOAP_REQ_ISSUE_SVC_CERT_PARAMETER_DEPLOY_NUMBER_TAG + ">"	//DeployNumber
								   + DSPSvcCertInfo["DeployNumber"] 
							+ "</" + SOAP_REQ_ISSUE_SVC_CERT_PARAMETER_DEPLOY_NUMBER_TAG + ">\n";//DeployNumber
	SoapRequestXML += "      </" + SOAP_REQ_ISSUE_SVC_CERT_PARAMETER_DEPLOY_INFO_TAG + ">\n";	// DeployInfo
	SoapRequestXML += "     </n:" + SOAP_REQ_ISSUE_SVC_CERT_MATHOD_NAME + ">\n";
	SoapRequestXML += "   </SOAP-ENV:Body>\n";

	SoapRequestXML += "</SOAP-ENV:Envelope>";
/*

//	DispProgressInfo( 0 , "正在校对时间...")
	//55.6+1.2=56.8%
	DispProgressInfo( 40 )
	DrvCert.UIRefresh()
	
	var StampTime = new Array()
	// 换算本机时间到DSP的服务器时间
	StampTime = GetStampTime( )
	var CreateStampTime = StampTime["Create"]
	var ExpireStampTime = StampTime["Expire"]
	var DateTimeFormat    = "ActualTime"

//	DispProgressInfo( 60 , "正在准备时间戳...")
	// 58%
	DispProgressInfo( 50 )
	DrvCert.UIRefresh()
	
	var PackagedXml = StampXml( SoapRequestXML , CreateStampTime , ExpireStampTime , DateTimeFormat )
	if ( PackagedXml == null)
	{
		DispProgressInfo( 100 , "在请求"+DSPDrvInfo["Issuer"]+"服务证书时签署XML时间戳失败")
		{ IssueDSPSvcCertInfo["Success"] = false; return (IssueDSPSvcCertInfo);}
	}

//	DispProgressInfo( 100 , "正在准备签名信息...")
	//59.2%
	DispProgressInfo( 60 )
	DrvCert.UIRefresh()
	var SignData = XmlToText( PackagedXml );
	if (SignData == null)
	{
		DispProgressInfo( 100 , "在请求"+DSPDrvInfo["Issuer"]+"时转换XML文本失败")
		{ IssueDSPSvcCertInfo["Success"] = false; return (IssueDSPSvcCertInfo);}
	}
	//59.2+1.2=60.4%
	DispProgressInfo( 70 )
	DrvCert.UIRefresh()
	var SignValue = DrvCert.SignDataInString( CertContext , SignData );
	var SignedXml = SignXml( PackagedXml , SignValue );
	if ( SignedXml == null)
	{
		DispProgressInfo( 100 , "在请求"+DSPDrvInfo["Issuer"]+"时对XML签名失败")
		{ IssueDSPSvcCertInfo["Success"] = false; return (IssueDSPSvcCertInfo);}
	}
	PackagedXml = SignedXml

//	AlertInfo += "\n[] Soap request xml text-value is:\n" + SignData
//	AlertInfo += "\n[] Soap request xml sign-value is:\n" + SignValue
*/
///////////////////////////////////// 新加 ////////////////////////////////////////////////////////////////////////

	var DSPHostname = ""
	// 如果URL以"http://"开始
	if ( DSPSvcCertInfo["IssueURL"].match(/^http:\/\//i) )
	{
		// 取"http://"后面第一个"/"前面的内容
		DSPHostname = DSPSvcCertInfo["IssueURL"].replace(/^http:\/\/(.*)/i , "$1" )
		var DSPHostnameArray = DSPHostname.split("/")
	}
	// 如果URL没有以"http://"开始
	else
	{
		// 取URl第一个"/"前的所有内容作为DSP主机地址
		DSPHostname = DSPSvcCertInfo["IssueURL"]
		var DSPHostnameArray = DSPHostname.split("/")
	}
	var CertLocation = 1 // Current_user_location
	var SoapFinalXMLInfo = SignStampEncryptXMLEx( 
								DSPHostnameArray[0] + SOAP_URL_GET_COMM_CERT , 
								DSPHostnameArray[0] + SOAP_URL_GET_TIME ,
								SoapRequestXML , 
								CertContext , 
								CertLocation )
	if (!SoapFinalXMLInfo["Success"] )
	{
		return false
	}
	AlertInfo += "[] 原始SOAP包是：\n" + SoapRequestXML + "\n"
	AlertInfo += "[] 经过“签名/盖时间戳/证书加密”后的SOAP包是：\n" + SoapFinalXMLInfo["Xml"] + "\n"

	var PackagedXml = SoapFinalXMLInfo["Xml"]

/////////////////////////////////////////////////////////////////////////////////////////////////////////////


//	DispProgressInfo( 100 , "正在关闭用户证书密钥...")
	// 60.4+1.2=61.6%
	DispProgressInfo( 80 )
	DrvCert.UIRefresh()
	if ( !DrvCert.CloseCertProvider( CertProvider )) DispProgressInfo( 100 , "Close cert provider failed(provider=" + CertProvider + ")");
	CertProvider = null;
	// 61.6+1.2=62.8%
	DispProgressInfo( 90 )
	DrvCert.UIRefresh()
	if ( !DrvCert.CloseUserCert( CertContext )) DispProgressInfo( 100 , "Close cert handle failed(handle=" + CertContext + ")");
	CertContext = null;

	//64%
	DispProgressInfo( 100 )
	DrvCert.UIRefresh()
	
	SetCurProcessBeginEndPercent( 80 , 95 )
//	DispProgressInfo( 0 , "正在查找驱动服务信息...")
	// 64%-68.5%
	DispProgressInfo( 100 )
	DrvCert.UIRefresh()
	ReturnXML = DrvCert.SoapClientRequest( EndURI , PackagedXml );
	if (!ReturnXML)
	{
		DispMessageInfo( "在请求"+DSPDrvInfo["Issuer"]+"服务证书时SOAP返回信息无效")
		return
	}

	AlertInfo += "\n[] request package is : \n\n" + PackagedXml + "\n";
	AlertInfo += "\n[] return package is :\n\n" + ReturnXML + "\n";
	
	if (g_TestingInfoDisp) newElement3.innerText = AlertInfo

	/*     返回信息XML

<?xml version="1.0" encoding="UTF-16" standalone="no"?>
<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
 <SOAP-ENV:Header xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
  <IssuerCertSubString>e-drivers.cn</IssuerCertSubString>
  <Timestamp><Created>2004-5-15 3:43:46</Created><Expires>2004-5-15 3:48:46</Expires><Format>UTC</Format></Timestamp><SignInfo><SignValue>dNNWBRwKgTIvWRVY8M7skidSrXpsYzpkLlIHltmftAM1LEHurWt+i3UgtScnj6C7MCso8ifwqdss9XRtN85TUc81UIrsVu4zEBYBZ0pBvfpwD0gf7blIUsT0eQDd1a+nMcHKlhp6ajTnZ++nb6uz9myXuyB9f/iG9Syz1jeiRcrKgX9QBnJI2OUMj4fxwBUcJYUirpFv7UI6ZEq4wnfCpmHPwQOHtXhnxTQy/794rJ/M2uczVfn8rbWS8dxKwTfKzQBAt7tzy5bY3aoeYd9GfmHvs7g09acPZxDP76A2+KC8+ZOjs1x4xSK1L52r/pzyfsjUDGOpCywk3yRYNMq3mg==</SignValue></SignInfo></SOAP-ENV:Header>
 <SOAP-ENV:Body xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
  <m:IssueSvcCertResponse xmlns:m="http://e-drivers.cn/soap/">
   <Result>
    <RegResult>MIIDqDCCApCgAwIBAgIEy1AssTANBgkqhkiG9w0BAQUFADAkMQswCQYDVQQGEwJDTjEVMBMGA1UEAxMMZS1kcml2ZXJzLmNuMB4XDTA0MDUxNTAzNDM0NloXDTA0MDUxNTAzNDM0NlowdzEsMCoGA1UEAxMjbGVub3ZvIHNlcnZpY2UgY2VydCAyMDA0LTUtMTUgMTE6NDMxFTATBgNVBAoTDGUtZHJpdmVycy5jbjEjMCEGA1UECxMabGVub3ZvIHNlcnZpY2UgY2VydCBpc3N1ZXIxCzAJBgNVBAYTAkNOMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC6cj1EnSYB8JUtyYkrf1stWa+qTuu1CZDw8Ewhrj4y4AYxltWOQXmbY9W/biUYkhybb+cPz665fuTHGgvaMB/kWg1v62XdTlCToxMHcgFLUW235ax06lz9AkODQJVE5mg+ooW1tbuJYV1WUC3Sphu90QUEAM2wHhqrC1EoUj8zBQIDAQABo4IBETCCAQ0wHQYDVR0OBBYEFAX8WarNlHPrgJ5qPzudgg5TeUbaMBMGA1UdJQQMMAoGCCsGAQUFBwMCMIGDBgNVHQEEfDB6gBTRg3DEXI5GPpA2Gz13SG2mSUS50aFWMFQxGzAZBgNVBAsTEmUtZHJpdmVycy5jbiBHcm91cDEWMBQGA1UEChMNZS1zb2Z0d2FyZS5jbjEdMBsGA1UEAxMUZS1kcml2ZXJzLmNuIFJvb3QgQ0GCCmEEiscAAAAAAA0wEAYHVR2HaYdpAQQFBAMxMDQwIQYHVR2HaYdpAgQWBBTb9hDipleHWWsBCagmnBZ3qT+wvTANBgdVHYdph2kDBAIEADANBgdVHYdph2kEBAIEADANBgkqhkiG9w0BAQUFAAOCAQEAjtyvrivTe12fwblXh+FoEcBuyCpcB3IKRQTRmZAMFV9rQB/iJq6CXWJ0hQwRnaM1CQHuhFF9H9MXqUfBM8SmuBdQ+U0jNuBqB060swpDUULze8chNUh4GxLXPCLuw+l5iwRYq7LkCfBSiGpSUBXJsaH4+NtG+z03ZWmK+x5I26vujuwWomFlAJ1XSo4dldF9H5JUnxjKU1gGNae0DB2gnYfwsnV0RrRDQpoKHhceZxC9Ox5mV0iKBDFlwLQkaOpcT2d3mpHIziP+Sjm217ex8fv7yq/CJVjw2Nsf/xwWTMUDkMPEevlzTxm+enayly3i7wJuuayziISA0KI6nSDZxw==</RegResult>
   </Result>
  </m:IssueSvcCertResponse>
 </SOAP-ENV:Body>
</SOAP-ENV:Envelope>
	*/	

	var ErrorInfo = GetInfoByTagFromXml( ReturnXML, SOAP_RET_ERROR_STRING_TAG )
	SetCurProcessBeginEndPercent( 95 , 100 )
//	DispProgressInfo( 0 , "正在查找驱动服务信息...")
	//68.5+0.9=69.4%
	DispProgressInfo( 60 )
	DrvCert.UIRefresh()
	if (ErrorInfo != null) 
	{
		DispProgressInfo( 100 , ErrorInfo )
	}
	else
	{
		// 检查返回的XML内容签名，看内容是否确实是e-drivers.cn提供的、内容是否被修改过
		var CheckInfo = CheckSoapServerSignValue( ReturnXML )
		if (!CheckInfo["Success"])
		{
			// 如果不是一般错误（一般是非法格式的XML，没有DSP签名或签名无效）
			if ( ErrorInfo == null)
			{
				DispProgressInfo( 100 , "在请求"+DSPDrvInfo["Issuer"]+"服务证书时返回的驱动服务信息格式错误")
			}
			// 如果是一般错误（比如：时间戳超时等）
			else
			{
				//AlertInfo += CheckInfo["ErrorInfo"]
				DispMessageInfo( CheckInfo["ErrorInfo"] )
			}
		}
	}
//////////////////////////////////////////  	


	if ( ErrorInfo == "" || ErrorInfo == null )
	{
		//DispProgressInfo( 100 , "查找驱动服务信息成功")
		DispProgressInfo( 100 )
	}

	IssueDSPSvcCertInfo["Cert"]		= GetInfoByTagFromXml( ReturnXML, SOAP_RET_BODY_REG_RESULT_TAG )

	if (IssueDSPSvcCertInfo["Cert"])
	{
		IssueDSPSvcCertInfo["Success"]	= true
	}
	else
	{
		IssueDSPSvcCertInfo["Success"]	= false
	}
	//70%
	DispProgressInfo( 100 )
	DrvCert.UIRefresh()

	// free all temp memory
	if (DeviceListInfo) DeviceListInfo = null
	if (CPUInfo)		CPUInfo = null
	if (MainBoardInfo)  MainBoardInfo = null
	if (DiskInfo)		DiskInfo = null
	if (MACIDs)			MACIDs = null
	if (OSInfo)			OSInfo = null
	if (ProblemDeviceInfo) ProblemDeviceInfo = null
	if (SoapRequestXML) SoapRequestXML = null
	if (PackagedXml)	PackagedXml = null
	if (ReturnXML)		ReturnXML = null
	if (CertKeyPhysicalID)	CertKeyPhysicalID = null
	if (CertContent)	CertContent = null
	//if (SignValue)		SignValue = null
	//if (SignedXml)		SignedXml = null
	if (AlertInfo)		AlertInfo = null

return (IssueDSPSvcCertInfo);
}
function SoapAcquireDSPDownloadDrv( SvcCertInfo , DSPDrvInfo , DeviceInfo )
{
    //  SvcCertInfo["Issuer"    ]	// 驱动服务证书的颁发者（或叫DSP厂商）
	//  SvcCertInfo["Class"     ]	// 驱动服务证书的类别（对服务证书目前为：104/105）
	//  SvcCertInfo["NotBefore" ]	// 驱动服务证书的生效日期
	//  SvcCertInfo["NotAfter"  ]	// 驱动服务证书的失效日期
	//  SvcCertInfo["LocaleServerTimeOffset"]	// 本机与DSP服务器的时间偏差（以毫秒计）
	//  SvcCertInfo["DeviceID"  ]	// 驱动服务证书的扩展项——设备标识符（用来区分同一DSP厂商的不同驱动服务，或不同DSP厂商的不同驱动服务）
	//  SvcCertInfo["IssueURL"  ]	// DSP颁发驱动服务证书服务的网络地址
	//  SvcCertInfo["DownloadURL"]	// DSP下载驱动服务的网络地址
	//	SvcCertInfo["SubmitNumber"	]
	//	SvcCertInfo["DeployNumber"	]
	//	SvcCertInfo["EncryptKeyID"	]

	//	DSPDrvInfo["Issuer"   ]		// 颁发DSP用户证书的颁发者是谁？如果DSP使用e-drivers.cn的用户证书，则颁发者是e-drivers.cn；否则，是DSP。
	//	DSPDrvInfo["CerAspUrl"]		// 颁发DSP用户证书的URL是什么？如果DSP使用e-drivers.cn的用户证书，则URL是e-drivers.cn的用户证书颁发地址；否则，是DSP URL。
	//	DSPDrvInfo["DrvAspUrl"]		// 查询DSP服务证书参数的URL是什么？
	//	DSPDrvInfo["DeviceID" ]		// 查询哪个设备的服务证书？
	//  DSPDrvInfo["DevRow"   ]		// 设备在drvinst.js中的内部标识
	//	//DSPDrvInfo["DrvVer"   ]		// 驱动程序的版本
	//	//DSPDrvInfo["DrvDate"  ]		// 驱动程序的日期
	//	//DSPDrvInfo["DrvVendor"]		// 驱动程序的提供商
	//	//DSPDrvInfo["DrvSize"  ]		// 驱动程序包的大小
	//	DSPDrvInfo["BuyNumber"]
	//	DSPDrvInfo["SubmitAllDeviceFlag"]
	//	DSPDrvInfo["Success"  ]		// 申请DSP及相关驱动信息是否成功（若失败，则以上项目都无效）

	//  DeviceInfo["DeviceRow"			]
	//  DeviceInfo["DeviceIndex"		]
	//  DeviceInfo["DeviceClassID"		]
	//  DeviceInfo["DeviceClassType"	]
	//  DeviceInfo["DeviceStatus"		]
	//  DeviceInfo["DeviceProblem"		]
	//  DeviceInfo["DeviceName"			]
	//  DeviceInfo["DriverBackupStatus"	]
	//  DeviceInfo["HardwareID"			]
	//  DeviceInfo["CompatibleID"		]
	//  DeviceInfo["MatchingDeviceId"	]
	//  DeviceInfo["DriverDate"			]
	//  DeviceInfo["DriverVer"			]
	//  DeviceInfo["DriverProvider"		]
	var DownloadDrvInfo = new Array()

	var EndURI = "";
	var AlertInfo="Testing info:\n";
	var SoapRequestXML = "";
	var ReturnXML="";

	CreateDymanicDocElement( "newElement4" )

////////////////////////////////////////////////////////////////////////////////////////////////////////

	// 设置当前任务占总任务的百分比
	SetCurProcessBeginEndPercent( 0 , 5 )
	// 71.5%
	DispProgressInfo( 100 , "正在从\""+DSPDrvInfo["Issuer"]+"\"下载驱动..." )
	DrvCert.UIRefresh()

	var IssuerNameSubString = DSPDrvInfo["Issuer"];//"e-drivers.cn"
	var CertContext = FindAndOpenUserCertByIssuer( IssuerNameSubString );
	if (!CertContext) 
	{
		DispProgressInfo( 100 , "无法找到\""+DSPDrvInfo["Issuer"]+"\"用户证书");
		DownloadDrvInfo["Success"] = false; 
		return ( DownloadDrvInfo )
	}

	SetCurProcessBeginEndPercent( 5,10 )
//	DispProgressInfo( 100 , "正在打开用户证书...")
	//73%
	DispProgressInfo(100)
	DrvCert.UIRefresh()
	var CertProvider = DrvCert.OpenCertProvider( CertContext , 1);//1:Current_user_location 2:Local_machine_location
	if (!CertProvider)
	{
		DispProgressInfo( 100 , "Open cert provider failed(cert handle=" + CertContext + ") : " + DrvCert.ErrorString); 
		DownloadDrvInfo["Success"] = false; 
		return ( DownloadDrvInfo )
	}

	// 总进程76%
	SetCurProcessBeginEndPercent( 10 , 20 )
//	DispProgressInfo( 100 , "正在获取用户证书标识信息...")
	// total 73%
	DispProgressInfo( 0 )
	DrvCert.UIRefresh()
	var CertKeyPhysicalID = DrvCert.GetCertKeyPhysicalID( CertProvider , 1);//1:Current_user_location 2:Local_machine_location
	if ( CertKeyPhysicalID == "" )
	{
		DispProgressInfo( 100 , "Get cert key Physical-ID error " + DrvCert.ErrorString);
		DownloadDrvInfo["Success"] = false; 
		return ( DownloadDrvInfo )
	}
	// total 73.6%
	DispProgressInfo( 20 )
	DrvCert.UIRefresh()

	var CertContent = DrvCert.GetCertContent( CertContext )
	if (!CertContent || CertContent == null)
	{
		DispMessageInfo( "Get cert content error<br>" + DrvCert.ErrorString);
		DownloadDrvInfo["Success"] = false; 
		return ( DownloadDrvInfo )
	}

	var CertIssuer  = IssuerNameSubString

	// total 74.2%
	DispProgressInfo( 40 )
	DrvCert.UIRefresh()
	// 取DSP服务证书内容和PhysicalID
	var SvcCertContext = FindDSPSvcCertByCertInfo( SvcCertInfo )
	if (!SvcCertContext)
	{
		DispMessageInfo("未找到" + SvcCertInfo["Issuer"] + "颁发的\"" + SvcCertInfo["DeviceID"] + "\"设备" + SvcCertInfo["Class"] + "类服务证书" )
		DownloadDrvInfo["Success"] = false; 
		return ( DownloadDrvInfo )
	}
	// total 74.8%
	DispProgressInfo( 60 )
	DrvCert.UIRefresh()
	var SvcCertProvider = DrvCert.OpenCertProvider( SvcCertContext , 1)//1:Current_user_location 2:Local_machine_location
	if (!SvcCertProvider) 
	{
		DispMessageInfo( "Open cert provider failed(cert handle=" + SvcCertContext + ") : " + DrvCert.ErrorString); 
		DownloadDrvInfo["Success"] = false; 
		return ( DownloadDrvInfo )
	}
	// total 75.4%
	DispProgressInfo( 80 )
	DrvCert.UIRefresh()
	var SvcCertKeyPhysicalID = DrvCert.GetCertKeyPhysicalID( SvcCertProvider , 1);//1:Current_user_location 2:Local_machine_location
	if ( SvcCertKeyPhysicalID == "" )
	{
		DispMessageInfo( "Get cert key Physical-ID error<br>" + DrvCert.ErrorString);
		DownloadDrvInfo["Success"] = false; 
		return ( DownloadDrvInfo )
	}
	
	// total 75.7%
	DispProgressInfo( 90 )
	DrvCert.UIRefresh()
	var SvcCertContent = DrvCert.GetCertContent( SvcCertContext )
	if (!SvcCertContent || SvcCertContent == null)
	{
		DispMessageInfo( "Get cert content error<br>" + DrvCert.ErrorString);
		DownloadDrvInfo["Success"] = false; 
		return ( DownloadDrvInfo )
	}

	// total 76%
	DispProgressInfo( 100 )
	DrvCert.UIRefresh()


	SoapRequestXML = "";
	SoapRequestXML += '<?xml version="1.0" encoding="UTF-16" standalone="no"?>\n';
	SoapRequestXML += '<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">\n';
	SoapRequestXML += "   <SOAP-ENV:Header xmlns:wsu =\"http://schemas.xmlsoap.org/ws/2002/07/utility\" ";
	SoapRequestXML += "                    xmlns:wsse=\"http://schemas.xmlsoap.org/ws/2002/07/secext\" >\n";
	SoapRequestXML += "      <SignCertInfo>\n";
	SoapRequestXML += "         <UserCertContent>"		+ CertContent			+ "</UserCertContent>\n";
	SoapRequestXML += "         <UserCertPhysicalID>"	+ CertKeyPhysicalID		+ "</UserCertPhysicalID>\n";
	SoapRequestXML += "         <CertContent>"			+ SvcCertContent		+ "</CertContent>\n";
	SoapRequestXML += "         <CertPhysicalID>"		+ SvcCertKeyPhysicalID  + "</CertPhysicalID>\n";
	SoapRequestXML += "         <CertIssuer>"			+ SvcCertInfo["Issuer"]	+ "</CertIssuer>\n";
	SoapRequestXML += "      </SignCertInfo>\n";
//
// Timestamp节内容由下面StampXml()函数自动填写 
//
//	SoapRequestXML += "      <Timestamp>\n";
//	SoapRequestXML += "         <Created>2004-03-08 12:00:00</Created>\n";
//	SoapRequestXML += "         <Expires>2004-03-08 12:05:00</Expires>\n";
//	SoapRequestXML += "         <Format>UTC</Format>\n";
//	SoapRequestXML += "      </Timestamp>\n";

//
// SignInfo节内容由下面SignXml()函数自动填写
//
//	SoapRequestXML += "      <m:SignInfo xmlns:m=\"http://e-drivers.cn/soap/\">\n";
//	SoapRequestXML += "         <m:SignValue>DewqdAYBStswtTgh875</m:SignValue>\n";
//	SoapRequestXML += "      </m:SignInfo>\n";
//
	SoapRequestXML += "   </SOAP-ENV:Header>\n";


	SoapRequestXML += "   <SOAP-ENV:Body>\n";
	SoapRequestXML += "     <n:" + SOAP_REQ_DOWNLOAD_DRIVER_MATHOD_NAME + " xmlns:n=\"http://e-drivers.cn/soap/\">\n"; // DownloadDriver
	SoapRequestXML += "			<" + SOAP_REQ_DOWNLOAD_DRIVER_PARAMETER_DEPLOY_NUMBER_TAG + ">" // DeployNumber
								   + SvcCertInfo["DeployNumber"] 
							+ "</" + SOAP_REQ_DOWNLOAD_DRIVER_PARAMETER_DEPLOY_NUMBER_TAG + ">\n"
	SoapRequestXML += "     </n:" + SOAP_REQ_DOWNLOAD_DRIVER_MATHOD_NAME + ">\n";
	SoapRequestXML += "   </SOAP-ENV:Body>\n";

	SoapRequestXML += "</SOAP-ENV:Envelope>";

	SetCurProcessBeginEndPercent( 20 , 30 )
//	DispProgressInfo( 100 , "正在准备下载驱动请求...")
	// total 79%
	DispProgressInfo( 100 )
	DrvCert.UIRefresh()

	var StampTime = new Array()
	// 该函数在无参数调用时将产生一个SOAP调用以读e-drivers.cn服务器时间
	// 有参数时，参数是哪个DSP的服务器时间的就换算本机时间到该DSP服务器时间
	StampTime = GetStampTime( )		
	var CreateStampTime = StampTime["Create"]
	var ExpireStampTime = StampTime["Expire"]
	var DateTimeFormat    = "VirtualTime"

	SetCurProcessBeginEndPercent( 30 , 40 )
//	DispProgressInfo( 0 , "正在校对时间...")
	// total 82%
	DispProgressInfo( 100 )
	DrvCert.UIRefresh()

	SetCurProcessBeginEndPercent( 40 , 50 )
	
	var PackagedXml = StampXml( SoapRequestXML , CreateStampTime , ExpireStampTime , DateTimeFormat )
	if ( PackagedXml == null)
	{
		DispProgressInfo( 100 , "在请求下载"+DSPDrvInfo["Issuer"]+"驱动时签署XML时间戳失败")
		DownloadDrvInfo["Success"] = false; 
		return ( DownloadDrvInfo )
	}
//	DispProgressInfo( 60 , "正在准备时间戳...")
	//total 83.8%
	DispProgressInfo( 60 )
	DrvCert.UIRefresh()

//	DispProgressInfo( 100 , "正在准备签名信息...")
//	DrvCert.UIRefresh()
	var SignData = XmlToText( PackagedXml );
	if (SignData == null)
	{
		DispProgressInfo( 100 , "在请求下载"+DSPDrvInfo["Issuer"]+"驱动时转换XML文本失败")
		DownloadDrvInfo["Success"] = false
		return ( DownloadDrvInfo )
	}
//	DispProgressInfo( 60 , "正在准备时间戳...")
	// total 84.4%
	DispProgressInfo( 80 )
	DrvCert.UIRefresh()

	var SignValue = DrvCert.SignDataInString( SvcCertContext , SignData );
	var SignedXml = SignXml( PackagedXml , SignValue );
	if ( SignedXml == null)
	{
		DispProgressInfo( 100 , "在请求下载"+DSPDrvInfo["Issuer"]+"驱动时对XML签名失败")
		DownloadDrvInfo["Success"] = false; 
		return ( DownloadDrvInfo )
	}
	PackagedXml = SignedXml
//	DispProgressInfo( 60 , "正在准备时间戳...")
	// total 85%
	DispProgressInfo( 100 )
	DrvCert.UIRefresh()

//	AlertInfo += "\n[] Soap request xml text-value is:\n" + SignData
//	AlertInfo += "\n[] Soap request xml sign-value is:\n" + SignValue

	SetCurProcessBeginEndPercent( 50 , 60 )
//	DispProgressInfo( 100 , "正在关闭用户证书密钥...")
	// 88%
	DispProgressInfo( 100 )
	DrvCert.UIRefresh()
	if ( !DrvCert.CloseCertProvider( CertProvider )) DispProgressInfo( 100 , "Close cert provider failed(provider=" + CertProvider + ")");
	CertProvider = null;
	SetCurProcessBeginEndPercent( 60 , 70 )
//	DispProgressInfo( 100 , "正在关闭用户证书...")
	// 91%
	DispProgressInfo( 100 )
	DrvCert.UIRefresh()
	if ( !DrvCert.CloseUserCert( CertContext )) DispProgressInfo( 100 , "Close cert handle failed(handle=" + CertContext + ")");
	CertContext = null;

	EndURI = SvcCertInfo["DownloadURL"]
	
	SetCurProcessBeginEndPercent( 70 , 90 )
//	DispProgressInfo( 0 , "正在下载驱动...")
	// from 91%-97%
	DispProgressInfo( 0 )
	ReturnXML = DrvCert.SoapClientRequest( EndURI , PackagedXml );
	if (!ReturnXML)
	{
		DispProgressInfo( 100 , "在请求下载"+DSPDrvInfo["Issuer"]+"驱动时SOAP返回信息无效")
		DownloadDrvInfo["Success"] = false
		return ( DownloadDrvInfo )
	}
	AlertInfo += "\n[] request package is : \n\n" + PackagedXml + "\n";
	AlertInfo += "\n[] return package is :\n\n"   + ReturnXML   + "\n";

	var ErrorInfo = GetInfoByTagFromXml( ReturnXML, SOAP_RET_ERROR_STRING_TAG )
	var ErrorCode = GetInfoByTagFromXml( ReturnXML, SOAP_RET_ERROR_CODE_TAG )
	SetCurProcessBeginEndPercent( 90 , 100 )
	DrvCert.UIRefresh()

	if (ErrorInfo != null) 
	{
		DispProgressInfo( 100 , ErrorInfo )
		DrvCert.DeleteCert( SvcCertContext )
		DownloadDrvInfo["Success"] = false
		return ( DownloadDrvInfo )
	}

	// 	ReturnXML返回结果：
	//
	//        <SOAP-ENV:Body SOAP-ENV:encodingStyle="">
	//            <m:DownloadDriverResponse xmlns:m="http://e-drivers.cn/soap/" SOAP-ENV:encodingStyle="">
	//                <Result>
	//                    <DrvContent>...</DrvContent>
	//                    <DrvClass>Net</DrvClass>
	//                    <DrvDate>08/11/2004</DrvDate>
	//                    <DrvSize>17232</DrvSize>
	//                    <DrvVer>2.52</DrvVer>
	//                    <DrvCatFileName>netdlfet.cat</DrvCatFileName>
	//                    <DrvInfFileName>NETDLFET.INF</DrvInfFileName>
	//                    <DrvInfSection>VT3065.ndi</DrvInfSection>
	//                    <DrvProvider>D-LINK</DrvProvider>
	//                </Result>
	//            </m:DownloadDriverResponse>
	//        </SOAP-ENV:Body>
	//
	DownloadDrvInfo["Success"]			= true
	DownloadDrvInfo["DrvContent"]		= GetInfoByTagFromXml( ReturnXML, "DrvContent" )
	DownloadDrvInfo["DrvClass"	]		= GetInfoByTagFromXml( ReturnXML, "DrvClass" )
	DownloadDrvInfo["DrvDate"	]		= GetInfoByTagFromXml( ReturnXML, "DrvDate" )
	DownloadDrvInfo["DrvSize"	]		= GetInfoByTagFromXml( ReturnXML, "DrvSize" )
	DownloadDrvInfo["DrvVer"	]		= GetInfoByTagFromXml( ReturnXML, "DrvVer" )
	DownloadDrvInfo["CatFileName"]		= GetInfoByTagFromXml( ReturnXML, "DrvCatFileName" )
	DownloadDrvInfo["InfFileName"]		= GetInfoByTagFromXml( ReturnXML, "DrvInfFileName" )
	DownloadDrvInfo["DrvInfSection"]	= GetInfoByTagFromXml( ReturnXML, "DrvInfSection"  )
	DownloadDrvInfo["DrvProvider"]		= GetInfoByTagFromXml( ReturnXML, "DrvProvider"  )

	if ( !DrvCert.CloseCertProvider( SvcCertProvider )) DispProgressInfo( 100 , "Close cert provider failed(provider=" + SvcCertProvider + ")");
	SvcCertProvider = null;

	if ( !DrvCert.CloseUserCert( SvcCertContext )) DispProgressInfo( 100 , "Close cert handle failed(handle=" + SvcCertContext + ")");
	SvcCertContext = null;

	if (!DrvCert.ReleaseProvider())
	{
		DispProgressInfo( 100 , "Release CSP failed\n" + DrvCert.ErrorString);
	}
	else
	{
		AlertInfo += "\n[] CSP released !" + "\n";
	}

	if ( ErrorInfo == "" || ErrorInfo == null )
	{
		//DispProgressInfo( 100 , "下载驱动成功")
		DispProgressInfo( 100 )
	}
	if (g_TestingInfoDisp) newElement4.innerText = AlertInfo

	// free all temp memory
	if (SoapRequestXML)		SoapRequestXML		= null
	if (PackagedXml)		PackagedXml			= null
	if (ReturnXML)			ReturnXML			= null
	if (CertKeyPhysicalID)	CertKeyPhysicalID	= null
	if (CertContent)		CertContent			= null
	if (SignValue)			SignValue			= null
	if (SignedXml)			SignedXml			= null
	if (AlertInfo)			AlertInfo			= null
//DownloadDrvInfo["Success"			]
//DownloadDrvInfo["DrvContent"		]
//DownloadDrvInfo["DrvClass"		]
//DownloadDrvInfo["DrvDate"			]
//DownloadDrvInfo["DrvSize"			]
//DownloadDrvInfo["DrvVer"			]
//DownloadDrvInfo["CatFileName"		]
//DownloadDrvInfo["InfFileName"		]
//DownloadDrvInfo["DrvInfSection"	]
//DownloadDrvInfo["DrvProvider"		]
return ( DownloadDrvInfo )
}	
// 2006-6-9 <<<.................................................................................................
//function GetCookie(sName)
//{
//  // cookies are separated by semicolons
//  var aCookie = document.cookie.split("; ");
//  for (var i=0; i < aCookie.length; i++)
//  {
//    // a name/value pair (a crumb) is separated by an equal sign
//    var aCrumb = aCookie[i].split("=");
//    if (sName == aCrumb[0]) 
//      return unescape(aCrumb[1]);
//  }
//
//  // a cookie with the requested name does not exist
//  return null;
//}
//function SetCookie( sName, sValue )
//{
//	var time = new Date();
//	time.setTime(  Date.parse( "12-31-2999 0:0:00" ) )
//	document.cookie = sName + "=" + escape(sValue) + "; path=\; expires=" + time.toGMTString();
//}
//function DelCookie(sName)
//{
//  document.cookie = sName + "=" + escape("") + "; path=\; expires=Fri, 31 Dec 1999 23:59:59 GMT;";
//}
// 2006-6-9 ..................................................................................................>>>
function ClientDeployDriver( DownloadDrvInfo , DeviceInfo , SvcCertInfo )
{
	//DownloadDrvInfo["Success"			]
	//DownloadDrvInfo["DrvContent"		]
	//DownloadDrvInfo["DrvClass"		]
	//DownloadDrvInfo["DrvDate"			]
	//DownloadDrvInfo["DrvSize"			]
	//DownloadDrvInfo["DrvVer"			]
	//DownloadDrvInfo["CatFileName"		]
	//DownloadDrvInfo["InfFileName"		]
	//DownloadDrvInfo["DrvInfSection"	]
	//DownloadDrvInfo["DrvProvider"		]

	//  DeviceInfo["DeviceRow"			]
	//  DeviceInfo["DeviceIndex"		]
	//  DeviceInfo["DeviceClassID"		]
	//  DeviceInfo["DeviceClassType"	]
	//  DeviceInfo["DeviceStatus"		]
	//  DeviceInfo["DeviceProblem"		]
	//  DeviceInfo["DeviceName"			]
	//  DeviceInfo["DriverBackupStatus"	]
	//  DeviceInfo["HardwareID"			]
	//  DeviceInfo["CompatibleID"		]
	//  DeviceInfo["MatchingDeviceId"	]
	//  DeviceInfo["DriverDate"			]
	//  DeviceInfo["DriverVer"			]
	//  DeviceInfo["DriverProvider"		]
	
    //SvcCertInfo["Issuer"					]
	//SvcCertInfo["Class"					]
	//SvcCertInfo["NotBefore"				]
	//SvcCertInfo["NotAfter"				]
	//SvcCertInfo["LocaleServerTimeOffset"	]
	//SvcCertInfo["DeviceID"				]
	//SvcCertInfo["SubmitNumber"			]
	//SvcCertInfo["DeployNumber"			]
	//SvcCertInfo["EncryptKeyID"			]
	//SvcCertInfo["IssueURL"				]
	//SvcCertInfo["DownloadURL"				]
	//SvcCertInfo["Success"					]
	
	// 将下载的驱动程序包编码内容保存到： 
	//
	// "%Document and Setting%/%User%/Application Data/e-Software/
	//      e-Drivers/DownloadDriver/%Manufacturer%/%DeviceClass%/%Instance%/"
	SetCurProcessBeginEndPercent( 0 , 30 )
	DispProgressInfo( 0 )
	DrvCert.UIRefresh()
	// 
	//#define CSIDL_DESKTOP                   0x0000        // <desktop>
	//#define CSIDL_INTERNET                  0x0001        // Internet Explorer (icon on desktop)
	//#define CSIDL_PROGRAMS                  0x0002        // Start Menu\Programs
	//#define CSIDL_CONTROLS                  0x0003        // My Computer\Control Panel
	//#define CSIDL_PRINTERS                  0x0004        // My Computer\Printers
	//#define CSIDL_PERSONAL                  0x0005        // My Documents
	//#define CSIDL_FAVORITES                 0x0006        // <user name>\Favorites
	//#define CSIDL_STARTUP                   0x0007        // Start Menu\Programs\Startup
	//#define CSIDL_RECENT                    0x0008        // <user name>\Recent
	//#define CSIDL_SENDTO                    0x0009        // <user name>\SendTo
	//#define CSIDL_BITBUCKET                 0x000a        // <desktop>\Recycle Bin
	//#define CSIDL_STARTMENU                 0x000b        // <user name>\Start Menu
	//#define CSIDL_MYDOCUMENTS               0x000c        // logical "My Documents" desktop icon
	//#define CSIDL_MYMUSIC                   0x000d        // "My Music" folder
	//#define CSIDL_MYVIDEO                   0x000e        // "My Videos" folder
	//#define CSIDL_DESKTOPDIRECTORY          0x0010        // <user name>\Desktop
	//#define CSIDL_DRIVES                    0x0011        // My Computer
	//#define CSIDL_NETWORK                   0x0012        // Network Neighborhood (My Network Places)
	//#define CSIDL_NETHOOD                   0x0013        // <user name>\nethood
	//#define CSIDL_FONTS                     0x0014        // windows\fonts
	//#define CSIDL_TEMPLATES                 0x0015
	//#define CSIDL_COMMON_STARTMENU          0x0016        // All Users\Start Menu
	//#define CSIDL_COMMON_PROGRAMS           0X0017        // All Users\Start Menu\Programs
	//#define CSIDL_COMMON_STARTUP            0x0018        // All Users\Startup
	//#define CSIDL_COMMON_DESKTOPDIRECTORY   0x0019        // All Users\Desktop
	//#define CSIDL_APPDATA                   0x001a        // <user name>\Application Data
	//#define CSIDL_PRINTHOOD                 0x001b        // <user name>\PrintHood
	//#define CSIDL_LOCAL_APPDATA             0x001c        // <user name>\Local Settings\Applicaiton Data (non roaming)
	//#define CSIDL_ALTSTARTUP                0x001d        // non localized startup
	//#define CSIDL_COMMON_ALTSTARTUP         0x001e        // non localized common startup
	//#define CSIDL_COMMON_FAVORITES          0x001f
	//#define CSIDL_INTERNET_CACHE            0x0020
	//#define CSIDL_COOKIES                   0x0021
	//#define CSIDL_HISTORY                   0x0022
	//#define CSIDL_COMMON_APPDATA            0x0023        // All Users\Application Data
	//#define CSIDL_WINDOWS                   0x0024        // GetWindowsDirectory()
	//#define CSIDL_SYSTEM                    0x0025        // GetSystemDirectory()
	//#define CSIDL_PROGRAM_FILES             0x0026        // C:\Program Files
	//#define CSIDL_MYPICTURES                0x0027        // C:\Program Files\My Pictures
	//#define CSIDL_PROFILE                   0x0028        // USERPROFILE
	//#define CSIDL_SYSTEMX86                 0x0029        // x86 system directory on RISC
	//#define CSIDL_PROGRAM_FILESX86          0x002a        // x86 C:\Program Files on RISC
	//#define CSIDL_PROGRAM_FILES_COMMON      0x002b        // C:\Program Files\Common
	//#define CSIDL_PROGRAM_FILES_COMMONX86   0x002c        // x86 Program Files\Common on RISC
	//#define CSIDL_COMMON_TEMPLATES          0x002d        // All Users\Templates
	//#define CSIDL_COMMON_DOCUMENTS          0x002e        // All Users\Documents
	//#define CSIDL_COMMON_ADMINTOOLS         0x002f        // All Users\Start Menu\Programs\Administrative Tools
	//#define CSIDL_ADMINTOOLS                0x0030        // <user name>\Start Menu\Programs\Administrative Tools
	//#define CSIDL_CONNECTIONS               0x0031        // Network and Dial-up Connections
	//#define CSIDL_COMMON_MUSIC              0x0035        // All Users\My Music
	//#define CSIDL_COMMON_PICTURES           0x0036        // All Users\My Pictures
	//#define CSIDL_COMMON_VIDEO              0x0037        // All Users\My Video
	//#define CSIDL_RESOURCES                 0x0038        // Resource Direcotry
	//#define CSIDL_RESOURCES_LOCALIZED       0x0039        // Localized Resource Direcotry
	//#define CSIDL_COMMON_OEM_LINKS          0x003a        // Links to All Users OEM specific apps
	//#define CSIDL_CDBURN_AREA               0x003b        // USERPROFILE\Local Settings\Application Data\Microsoft\CD Burning
	//// unused                               0x003c
	//#define CSIDL_COMPUTERSNEARME           0x003d        // Computers Near Me (computered from Workgroup membership)
	//#define CSIDL_FLAG_CREATE               0x8000        // combine with CSIDL_ value to force folder creation in SHGetFolderPath()
	//#define CSIDL_FLAG_DONT_VERIFY          0x4000        // combine with CSIDL_ value to return an unverified folder path
	//#define CSIDL_FLAG_NO_ALIAS             0x1000        // combine with CSIDL_ value to insure non-alias versions of the pidl
	//#define CSIDL_FLAG_PER_USER_INIT        0x0800        // combine with CSIDL_ value to indicate per-user init (eg. upgrade)
	//#define CSIDL_FLAG_MASK                 0xFF00        // mask for all possible flag values
	var CurUserAppDataFolderPath = DrvCert.GetFolderPath( 36 )	// 36 0x24 - CSIDL_WINDOWS  
	                                                            // 26 0x1a - CSIDL_APPDATA 
	if ( !CurUserAppDataFolderPath )
	{
		DispMessageInfo( "无法获取当前用户的%Application Data%文件夹路径" )
		return false
	}
	DispProgressInfo( 20 )
	DrvCert.UIRefresh()

//	// 获得下载的目录名的实例值 - "DownloadInstance"
//	var ValueDataString = ""
//	var InstanceNumber = 0
//	var hDownloadKey  = DrvCert.RegCreateKey( 2				 , "SOFTWARE\\Walker" ) 
//	var hDownloadKey2 = DrvCert.RegCreateKey( hDownloadKey   , "MyDrivers" )
//	var ValueData     = DrvCert.RegQueryValue( hDownloadKey2 , "DownloadInstance" )
//	if (!ValueData)
//	{
//		InstanceNumber  = 1
//		ValueDataString =	"<RegInfo>"
//						+		"<RegValueType>REG_DWORD</RegValueType>"
//						+		"<RegValueData>" + InstanceNumber + "</RegValueData>"
//						+	"</RegInfo>"	
//		DrvCert.RegSetValue( hDownloadKey2 , "DownloadInstance" , ValueDataString )
//	}
//	else
//	{
//		InstanceNumber  = parseInt(ValueData.toString(10)) + 1
//		ValueDataString =	"<RegInfo>"
//						+		"<RegValueType>REG_DWORD</RegValueType>"
//						+		"<RegValueData>" + InstanceNumber + "</RegValueData>"
//						+	"</RegInfo>"	
//		DrvCert.RegSetValue( hDownloadKey2 , "DownloadInstance" , ValueDataString )
//	}
//	DrvCert.RegCloseKey( hDownloadKey  )
//	DrvCert.RegCloseKey( hDownloadKey2 )
	var hKey  = DrvCert.RegCreateKey( 2     , "SOFTWARE\\Walker" ) 
	var hKey2 = DrvCert.RegCreateKey( hKey  , "MyDrivers" )
	var hKey3 = DrvCert.RegCreateKey( hKey2 , "DownloadDrv" ) 
	var hKey4 = DrvCert.RegCreateKey( hKey3 , DownloadDrvInfo["DrvProvider"]  + "&" + DownloadDrvInfo["DrvClass"]) 
	var ValueData = DrvCert.RegQueryValue( hKey4 , "InstanceNumbers" )

	var ValueDataString = ""
	var InstanceNumber = 0
	if (!ValueData)
	{
		InstanceNumber  = 1
		ValueDataString =	"<RegInfo>"
						+		"<RegValueType>REG_DWORD</RegValueType>"
						+		"<RegValueData>" + InstanceNumber + "</RegValueData>"
						+	"</RegInfo>"	
		DrvCert.RegSetValue( hKey4 , "InstanceNumbers" , ValueDataString )
	}
	else
	{
		InstanceNumber  = parseInt(ValueData.toString(10)) + 1
		ValueDataString =	"<RegInfo>"
						+		"<RegValueType>REG_DWORD</RegValueType>"
						+		"<RegValueData>" + InstanceNumber + "</RegValueData>"
						+	"</RegInfo>"	
		DrvCert.RegSetValue( hKey4 , "InstanceNumbers" , ValueDataString )
	}

	// F:\Documents and Settings\Administrator.SERVER.002\Application Data
	//CurUserAppDataFolderPath += "\\" + "e-Software"				+		//E-SOFTWARE_MFG_NAME
	//							"\\" + "e-Drivers"					+		//E-SOFTWARE_PRODUCT_NAME
	//							"\\" + "DownloadDrv"				+ 
	//							"\\" + DownloadDrvInfo["DrvProvider"] +
	//							"\\" + DownloadDrvInfo["DrvClass"]    +
	//							"\\" + InstanceNumber

	// F:\Windows\MyDrivers\DownloadDrv\D-LINK&Net\1
	CurUserAppDataFolderPath += "\\" + "MyDrivers\\DownloadDrv"		  +
								"\\" + DownloadDrvInfo["DrvProvider"] + 
								"\\" + DownloadDrvInfo["DrvClass"]    +
								"\\" + InstanceNumber

	// F:\Documents and Settings\Administrator.SERVER.002\Application Data\e-Software\DownloadDrv\D-Link\Net\0000\
	var DownloadDrvFileName = CurUserAppDataFolderPath + "\\Download.cab"

	if ( !DrvCert.SaveBASE64ToBinFile( DownloadDrvInfo["DrvContent"] , DownloadDrvFileName ) )
	{
		DispMessageInfo( "保存下载的驱动程序包到文件失败<br>" + DownloadDrvFileName )
		return false
	}
	else
	{
		//DispMessageInfo( "保存下载的驱动程序包到文件成功<br>" + DownloadDrvFileName )
	}
	DispProgressInfo( 40 )
	DrvCert.UIRefresh()

	// 展开.cab文件内容
	if ( !DrvCert.ExtractCabToPath( DownloadDrvFileName , CurUserAppDataFolderPath ) )
	{
		DispMessageInfo( "无法解压缩驱动程序包" )
		return false
	}
	DispProgressInfo( 80 )
	DrvCert.UIRefresh()

	// 删除下载的.cab文件，只保留解包后的.enc文件、.inf文件和.sign文件
	DrvCert.DeleteFile( DownloadDrvFileName )	// 不关心删除是否成功
	DispProgressInfo( 100 )
	DrvCert.UIRefresh()

	SetCurProcessBeginEndPercent( 30 , 40 )
	// 通过e-drivers.cn校验.cab内容的有效性
	//
	//

	SetCurProcessBeginEndPercent( 40 , 60 )
    //SvcCertInfo["Issuer"					]
	//SvcCertInfo["Class"					]
	//SvcCertInfo["NotBefore"				]
	//SvcCertInfo["NotAfter"				]
	//SvcCertInfo["LocaleServerTimeOffset"	]
	//SvcCertInfo["DeviceID"				]
	//SvcCertInfo["SubmitNumber"			]
	//SvcCertInfo["DeployNumber"			]
	//SvcCertInfo["EncryptKeyID"			]
	//SvcCertInfo["IssueURL"				]
	//SvcCertInfo["DownloadURL"				]
	//SvcCertInfo["Success"					]
	//
	// 请求e-drivers.cn返回.cab的加密密钥
	var DencryptKey = GetDriverPackageDencryptKey( SvcCertInfo )
	if ( !DencryptKey )
	{
		return false
	}
	
	SetCurProcessBeginEndPercent( 60 , 70 )
	// 找到.enc文件并得到文件名EncFileName
	//
	var FileNameXml = DrvCert.FindFileInPath( CurUserAppDataFolderPath + "\\*.enc" )
	var EncFileName = GetXmlSingleNodeText( FileNameXml , "FileItem0" )
	if (!EncFileName)
	{
		DispMessageInfo( "驱动程序包内容错误" )
		return false
	}
	// 将.enc文件内容读出
	var DataInBASE64 = DrvCert.GetBASE64StringFromBinFile( CurUserAppDataFolderPath + "\\" + EncFileName )

	// 用返回的加密密钥解开.enc加密驱动程序包。得到DrvFiles.cab
	var DecryptedDataInBASE64 = DrvCert.DencryptDataByKey( DataInBASE64 , DencryptKey )
	DrvCert.SaveBASE64ToBinFile( DecryptedDataInBASE64 , CurUserAppDataFolderPath + "\\DrvFiles.cab" )


	SetCurProcessBeginEndPercent( 70 , 80 )
	// 解开DrvFiles.cab的内容
	DrvCert.ExtractCabToPath( CurUserAppDataFolderPath + "\\DrvFiles.cab" , CurUserAppDataFolderPath )
	DrvCert.DeleteFile( CurUserAppDataFolderPath + "\\DrvFiles.cab" )

	SetCurProcessBeginEndPercent( 80 , 90 )
	// 删除.enc、.inf、.sign文件
	DrvCert.DeleteFile( CurUserAppDataFolderPath + "\\" + EncFileName )

	var FileNameXml = DrvCert.FindFileInPath( CurUserAppDataFolderPath + "\\*.inf" )
	var InfFileName = GetXmlSingleNodeText( FileNameXml , "FileItem0" )
	if (InfFileName) DrvCert.DeleteFile( CurUserAppDataFolderPath + "\\" + InfFileName )

	var FileNameXml  = DrvCert.FindFileInPath( CurUserAppDataFolderPath + "\\*.sign" )
	var SignFileName = GetXmlSingleNodeText( FileNameXml , "FileItem0" )
	if (SignFileName) DrvCert.DeleteFile( CurUserAppDataFolderPath + "\\" + SignFileName )

	SetCurProcessBeginEndPercent( 90 , 100 )
//	// 将.cab内容摘要保存到注册表，以便可以使用户可以恢复故障设备的驱动
//	//
//	//		HKEY_LOCAL_MACHINE\SOFTWARE\Walker\MyDrivers\Download\Net&D-LINK\0000
//	//		1 : HKEY_CURRENT_USER
//	//		2 : HKEY_LOCAL_MACHINE
//	//		3 : HKEY_CLASSES_ROOT
//	//		4 : HKEY_CURRENT_CONFIG
//	//		5 : HKEY_USERS
//	var hKey  = DrvCert.RegCreateKey( 2     , "SOFTWARE\\Walker" ) 
//	var hKey2 = DrvCert.RegCreateKey( hKey  , "MyDrivers" )
//	var hKey3 = DrvCert.RegCreateKey( hKey2 , "DownloadDrv" ) 
//	var hKey4 = DrvCert.RegCreateKey( hKey3 , DownloadDrvInfo["DrvProvider"]  + "&" + DownloadDrvInfo["DrvClass"]) 
//
//	//var hKey  = DrvCert.RegCreateKey( 2 , "SOFTWARE\\Walker" ) 
//	//var hKey2 = DrvCert.RegCreateKey( 2 , "SOFTWARE\\Walker\\MyDrivers" ) 
//	//var hKey3 = DrvCert.RegCreateKey( 2 , "SOFTWARE\\Walker\\MyDrivers\\DownloadDrv" ) 
//	//var hKey4 = DrvCert.RegCreateKey( 2 , "SOFTWARE\\Walker\\MyDrivers\\DownloadDrv\\" + DownloadDrvInfo["DrvProvider"] + "&" + DownloadDrvInfo["DrvClass"] ) 
//
//	var ValueData = DrvCert.RegQueryValue( hKey4 , "InstanceNumbers" )
//
//	var ValueDataString = ""
//	var InstanceNumber = 0
//	if (!ValueData)
//	{
//		InstanceNumber  = 1
//		ValueDataString =	"<RegInfo>"
//						+		"<RegValueType>REG_DWORD</RegValueType>"
//						+		"<RegValueData>" + InstanceNumber + "</RegValueData>"
//						+	"</RegInfo>"	
//		DrvCert.RegSetValue( hKey4 , "InstanceNumbers" , ValueDataString )
//	}
//	else
//	{
//		InstanceNumber  = parseInt(ValueData.toString(10)) + 1
//		ValueDataString =	"<RegInfo>"
//						+		"<RegValueType>REG_DWORD</RegValueType>"
//						+		"<RegValueData>" + InstanceNumber + "</RegValueData>"
//						+	"</RegInfo>"	
//		DrvCert.RegSetValue( hKey4 , "InstanceNumbers" , ValueDataString )
//	}

	var hKey5 = DrvCert.RegCreateKey( hKey4 , InstanceNumber ) 
	var ValueDataString =	"<RegInfo>"
						+		"<RegValueType>REG_SZ</RegValueType>"
						+		"<RegValueData>" + CurUserAppDataFolderPath + "</RegValueData>"
						+	"</RegInfo>"	
	DrvCert.RegSetValue( hKey5 , "BackupBaseDir" , ValueDataString )

	// 0x00000080：驱动程序是通过网络下载的 
	// 0x00080000：当前驱动是由应用程序或用户安装的
	var DrvBackupStatus = 0x00000080 | 0x00080000 
	// 如果驱动程序包内有.CAT文件，就设置标志位
	if ( DownloadDrvInfo["CatFileName"] ) DrvBackupStatus |= 0x00040000
	ValueDataString =		"<RegInfo>"
						+		"<RegValueType>REG_DWORD</RegValueType>"
						+		"<RegValueData>" + DrvBackupStatus.toString(10) + "</RegValueData>"
						+	"</RegInfo>"	
	DrvCert.RegSetValue( hKey5 , "BackupDriverStatus" , ValueDataString )
	
	ValueDataString =		"<RegInfo>"
						+		"<RegValueType>REG_SZ</RegValueType>"
						+		"<RegValueData>" + DownloadDrvInfo["CatFileName"] + "</RegValueData>"
						+	"</RegInfo>"	
	DrvCert.RegSetValue( hKey5 , "CatalogFileName" , ValueDataString )

	ValueDataString =		"<RegInfo>"
						+		"<RegValueType>REG_SZ</RegValueType>"
						+		"<RegValueData></RegValueData>"
						+	"</RegInfo>"	
	DrvCert.RegSetValue( hKey5 , "DeviceDesc" , ValueDataString )

	ValueDataString =		"<RegInfo>"
						+		"<RegValueType>REG_SZ</RegValueType>"
						+		"<RegValueData>" + DownloadDrvInfo["DrvDate"] + "</RegValueData>"
						+	"</RegInfo>"	
	DrvCert.RegSetValue( hKey5 , "DrvDate" , ValueDataString )

	ValueDataString =		"<RegInfo>"
						+		"<RegValueType>REG_SZ</RegValueType>"
						+		"<RegValueData>" + DownloadDrvInfo["DrvVer"] + "</RegValueData>"
						+	"</RegInfo>"	
	DrvCert.RegSetValue( hKey5 , "DrvVersion" , ValueDataString )

	ValueDataString =		"<RegInfo>"
						+		"<RegValueType>REG_SZ</RegValueType>"
						+		"<RegValueData>" + SvcCertInfo["DeviceID"] + "</RegValueData>"
						+	"</RegInfo>"	
	DrvCert.RegSetValue( hKey5 , "HardwareID" , ValueDataString.replace(/&/gi ,"&amp;") )

	ValueDataString =		"<RegInfo>"
						+		"<RegValueType>REG_MULTI_SZ</RegValueType>"
						+		"<RegValueData>" + DeviceInfo["HardwareID"].replace(/;/gi ," ") 
												 + DeviceInfo["CompatibleID"].replace(/;/gi ," ")
							   + "</RegValueData>"
						+	"</RegInfo>"	
	DrvCert.RegSetValue( hKey5 , "HardwareIDsCompatibleIDs" , ValueDataString.replace(/&/gi ,"&amp;") )


	ValueDataString =		"<RegInfo>"
						+		"<RegValueType>REG_SZ</RegValueType>"
						+		"<RegValueData>" + DownloadDrvInfo["DrvInfSection"] + "</RegValueData>"
						+	"</RegInfo>"	
	DrvCert.RegSetValue( hKey5 , "InfSection" , ValueDataString )



	ValueDataString =		"<RegInfo>"
						+		"<RegValueType>REG_SZ</RegValueType>"
						+		"<RegValueData>" + DownloadDrvInfo["InfFileName"] + "</RegValueData>"
						+	"</RegInfo>"	
	DrvCert.RegSetValue( hKey5 , "SystemInfName" , ValueDataString )

	DrvCert.RegCloseKey( hKey  )
	DrvCert.RegCloseKey( hKey2 )
	DrvCert.RegCloseKey( hKey3 )
	DrvCert.RegCloseKey( hKey4 )
	DrvCert.RegCloseKey( hKey5 )
return true
}
// 从SOAP_URL_GET_DP_KEY下载驱动程序包DP的解密密钥
function GetDriverPackageDencryptKey( SvcCertInfo )
{
    //  SvcCertInfo["Issuer"      ]	// 驱动服务证书的颁发者（或叫DSP厂商）
	//  SvcCertInfo["Class"       ]	// 驱动服务证书的类别（对服务证书目前为：104/105）
	//  SvcCertInfo["NotBefore"   ]	// 驱动服务证书的生效日期
	//  SvcCertInfo["NotAfter"    ]	// 驱动服务证书的失效日期
	//  SvcCertInfo["LocaleServerTimeOffset"]	// 本机与DSP服务器的时间偏差（以毫秒计）
	//  SvcCertInfo["DeviceID"    ]	// 驱动服务证书的扩展项——设备标识符（用来区分同一DSP厂商的不同驱动服务，或不同DSP厂商的不同驱动服务）
	//	SvcCertInfo["SubmitNumber"]
	//	SvcCertInfo["DeployNumber"]
	//	SvcCertInfo["EncryptKeyID"]
	//  SvcCertInfo["IssueURL"    ]	// DSP颁发驱动服务证书服务的网络地址
	//  SvcCertInfo["DownloadURL" ]	// DSP下载驱动服务的网络地址
	//  SvcCertInfo["Success"     ]

	var DencryptKey = ""

	var EndURI = "";
	var AlertInfo="Testing info:\n";
	var SoapRequestXML = "";
	var ReturnXML="";

	CreateDymanicDocElement( "newElement5" )

////////////////////////////////////////////////////////////////////////////////////////////////////////

	DispProgressInfo( 0 )
	DrvCert.UIRefresh()

	// 取DSP服务证书内容和PhysicalID
	var SvcCertContext = FindDSPSvcCertByCertInfo( SvcCertInfo )
	if (!SvcCertContext)
	{
		DispMessageInfo("未找到" + SvcCertInfo["Issuer"] + "颁发的\"" + SvcCertInfo["DeviceID"] + "\"设备" + SvcCertInfo["Class"] + "类服务证书" )
		return ( DencryptKey )
	}
	DispProgressInfo( 10 )
	DrvCert.UIRefresh()

	var SvcCertProvider = DrvCert.OpenCertProvider( SvcCertContext , 1)//1:Current_user_location 2:Local_machine_location
	if (!SvcCertProvider) 
	{
		DispMessageInfo( "Open cert provider failed(cert handle=" + SvcCertContext + ") : " + DrvCert.ErrorString); 
		return ( DencryptKey )
	}
	DispProgressInfo( 20 )
	DrvCert.UIRefresh()

	var SvcCertKeyPhysicalID = DrvCert.GetCertKeyPhysicalID( SvcCertProvider , 1);//1:Current_user_location 2:Local_machine_location
	if ( SvcCertKeyPhysicalID == "" )
	{
		DispMessageInfo( "Get cert key Physical-ID error<br>" + DrvCert.ErrorString);
		return ( DencryptKey )
	}
	DispProgressInfo( 30 )
	DrvCert.UIRefresh()

	var SvcCertContent = DrvCert.GetCertContent( SvcCertContext )
	if (!SvcCertContent || SvcCertContent == null)
	{
		DispMessageInfo( "Get cert content error<br>" + DrvCert.ErrorString);
		return ( DencryptKey )
	}
	DispProgressInfo( 40 )
	DrvCert.UIRefresh()


	SoapRequestXML = "";
	SoapRequestXML += '<?xml version="1.0" encoding="UTF-16" standalone="no"?>\n';
	SoapRequestXML += '<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">\n';
	SoapRequestXML += "   <SOAP-ENV:Header xmlns:wsu =\"http://schemas.xmlsoap.org/ws/2002/07/utility\" ";
	SoapRequestXML += "                    xmlns:wsse=\"http://schemas.xmlsoap.org/ws/2002/07/secext\" >\n";
	SoapRequestXML += "      <SignCertInfo>\n";
	SoapRequestXML += "         <CertContent>"		+ SvcCertContent		+ "</CertContent>\n";
	SoapRequestXML += "         <CertPhysicalID>"	+ SvcCertKeyPhysicalID  + "</CertPhysicalID>\n";
	SoapRequestXML += "      </SignCertInfo>\n";
	//
	// Timestamp节内容由下面StampXml()函数自动填写 
	//
	//	SoapRequestXML += "      <Timestamp>\n";
	//	SoapRequestXML += "         <Created>2004-03-08 12:00:00</Created>\n";
	//	SoapRequestXML += "         <Expires>2004-03-08 12:05:00</Expires>\n";
	//	SoapRequestXML += "         <Format>UTC</Format>\n";
	//	SoapRequestXML += "      </Timestamp>\n";

	//
	// SignInfo节内容由下面SignXml()函数自动填写
	//
	//	SoapRequestXML += "      <m:SignInfo xmlns:m=\"http://e-drivers.cn/soap/\">\n";
	//	SoapRequestXML += "         <m:SignValue>DewqdAYBStswtTgh875</m:SignValue>\n";
	//	SoapRequestXML += "      </m:SignInfo>\n";
	//
	SoapRequestXML += "   </SOAP-ENV:Header>\n";

	SoapRequestXML += "   <SOAP-ENV:Body>\n";
	SoapRequestXML += "     <n:GetDPKey xmlns:n=\"http://e-drivers.cn/soap/\">\n"; // DownloadDriver
	SoapRequestXML += "			<EncryptKeyID>" + SvcCertInfo["EncryptKeyID"] + "</EncryptKeyID>\n"
	SoapRequestXML += "			<SubmitNumber>" + SvcCertInfo["SubmitNumber"] + "</SubmitNumber>\n"
	SoapRequestXML += "     </n:GetDPKey>\n";
	SoapRequestXML += "   </SOAP-ENV:Body>\n";
	SoapRequestXML += "</SOAP-ENV:Envelope>";

	// 该函数在无参数调用时将产生一个SOAP调用以读e-drivers.cn服务器时间
	// 有参数时，参数是哪个DSP的服务器时间的就换算本机时间到该DSP服务器时间
	var objTime = new Date()
	//var StampTime = new Array()
	var StampTime = GetStampTime( objTime.getTime() - SvcCertInfo["LocaleServerTimeOffset"] )		
	var CreateStampTime = StampTime["Create"]
	var ExpireStampTime = StampTime["Expire"]
	var DateTimeFormat    = "VirtualTime"

	var PackagedXml = StampXml( SoapRequestXML , CreateStampTime , ExpireStampTime , DateTimeFormat )
	if ( PackagedXml == null)
	{
		DispProgressInfo( 100 , "在请求下载驱动密钥时签署XML时间戳失败")
		return ( DencryptKey )
	}

	var SignData = XmlToText( PackagedXml );
	if (SignData == null)
	{
		DispProgressInfo( 100 , "在请求下载驱动密钥时转换XML文本失败")
		return ( DencryptKey )
	}

	var SignValue = DrvCert.SignDataInString( SvcCertContext , SignData );
	var SignedXml = SignXml( PackagedXml , SignValue );
	if ( SignedXml == null)
	{
		DispProgressInfo( 100 , "在请求下载驱动密钥时对XML签名失败")
		return ( DencryptKey )
	}
	PackagedXml = SignedXml

	var Hostname = ServerName.value
	EndURI = Hostname + SOAP_URL_GET_DP_KEY	// "/soap/GetDPKey.asp"
	
	ReturnXML = DrvCert.SoapClientRequest( EndURI , PackagedXml );
	if (!ReturnXML)
	{
		DispProgressInfo( 100 , "在请求下载驱动密钥时SOAP返回信息无效")
		DownloadDrvInfo["Success"] = false
		return ( DencryptKey )
	}
	AlertInfo += "\n[] request package is : \n\n" + PackagedXml + "\n";
	AlertInfo += "\n[] return package is :\n\n"   + ReturnXML   + "\n";

	var ErrorInfo = GetInfoByTagFromXml( ReturnXML, SOAP_RET_ERROR_STRING_TAG )
	var ErrorCode = GetInfoByTagFromXml( ReturnXML, SOAP_RET_ERROR_CODE_TAG )

	if (ErrorInfo != null) 
	{
		DispProgressInfo( 100 , ErrorInfo )
		return ( DencryptKey )
	}

	// 	ReturnXML返回结果：
	//
	DencryptKey	= GetInfoByTagFromXml( ReturnXML, "KeyInBASE64" )

	if ( !DrvCert.CloseCertProvider( SvcCertProvider )) DispProgressInfo( 100 , "Close cert provider failed(provider=" + SvcCertProvider + ")");
	SvcCertProvider = null;

	if ( !DrvCert.CloseUserCert( SvcCertContext )) DispProgressInfo( 100 , "Close cert handle failed(handle=" + SvcCertContext + ")");
	SvcCertContext = null;

	if (!DrvCert.ReleaseProvider())
	{
		DispProgressInfo( 100 , "Release CSP failed\n" + DrvCert.ErrorString);
	}
	else
	{
		AlertInfo += "\n[] CSP released !" + "\n";
	}

	if ( ErrorInfo == "" || ErrorInfo == null )
	{
		//DispProgressInfo( 100 , "下载驱动密钥成功")
	}
	if (g_TestingInfoDisp) newElement5.innerText = AlertInfo

	// free all temp memory
	if (SoapRequestXML			!= undefined )			SoapRequestXML		= null
	if (PackagedXml				!= undefined )			PackagedXml			= null
	if (ReturnXML				!= undefined )			ReturnXML			= null
	if (SvcCertKeyPhysicalID	!= undefined )			SvcCertKeyPhysicalID= null
	if (SvcCertContent			!= undefined )			SvcCertContent		= null
	if (SignValue				!= undefined )			SignValue			= null
	if (SignedXml				!= undefined )			SignedXml			= null
	if (AlertInfo				!= undefined )			AlertInfo			= null

return ( DencryptKey )
}

// 2006-6-19 <<<...........................................................................................................



////////////////////////////////////////////////////////////////////////////////////////////////////////////
//function FindAndOpenDSPCertBySubCA( )
//{
//	// 先打开SUBCA证书
//	var SubCACertContext = DrvCert.OpenCertInX509( SUB_CA_CERT_CONTEXT_IN_X509_BASE64 )
//	// 若打开失败
//	if (!SubCACertContext) return (0)
//	//alert( "Subject = " + DrvCert.GetCertSubject( SubCACertContext ) + "\n" + 
//	//       "Issuer  = " + DrvCert.GetCertIssuer(  SubCACertContext ) + "\n" )
//
//
//	// 证书存储区位置
//	// 1: CERT_SYSTEM_STORE_CURRENT_USER
//	// 2: CERT_SYSTEM_STORE_LOCAL_MACHINE
//	//
//	// 证书存储区
//	// "DrvCert"
//	//
//	// 找到第一个DSP证书
//	//var FindHandle = DrvCert.CreateCertFind( 2 , "my" );
//	var FindHandle = DrvCert.CreateCertFind( 1 , "DrvCert" );
//	// 证书查找标志
//	// 0: 查找任何证书
//	// 1: 查找颁发者名称中包含函数第一个参数特征串的证书
//	// 2: 查找证书主题中包含函数第一个参数特征串的证书
//	var CertContext = DrvCert.CertFind( "" , 1 , FindHandle , 0 ) // 0 : 查找第一个证书
//	var CertContextOld
//	while( CertContext )
//	{
//		CertContextOld = CertContext
//
//		// 若找到的当前证书不是DSP身份证书
//		//  0：未知类
//		//  1：个人用户身份证书
//		//  2：企业用户身份证书
//		//  3：DSP身份证书
//		// 31：DSP邮件证书
//		// 32：DSP通讯证书
//		//  4：DSA（driver serivce agent）身份证书
//		//  5：OSP（outsourcing service provider）身份证书
//		//  6：企业身份证书
//		//100：驱动服务授权证书
//		//101：代理服务授权证书
//		//102：付费用户服务证书
//		//103：付费访问服务证书
//		//104：预付费用户服务证书
//		//105：预付费访问服务证书
//		//106：帐户服务证书
//		//107：企业服务证书
//		//
//
//		// 若找到的当前证书是DSP通讯证书
//		if (DrvCert.GetCertClass(CertContext) == "32")
//		{
//			var CertNotBefore = Date.parse( DrvCert.GetCertNotBefore( CertContext ) )
//			var CertNotAfter  = Date.parse( DrvCert.GetCertNotAfter(  CertContext ) )
//			var objTime = new Date()
//			var CurServerTime = objTime.getTime()
//			// 若DSP身份证书在有效期内
//			if (( CertNotBefore < CurServerTime ) && ( CurServerTime < CertNotAfter )) 
//			{
//				// 若DSP通讯证书是SUBCA颁发的
//				//var DSPCertContextInPFX = DrvCert.GetCertContent( CertContext )
//				//var DSPCertContext = DrvCert.OpenCertInPFX( DSPCertContextInPFX )
//				//if ( DrvCert.CheckDSPCertIssuedBySubCACert( DSPCertContext , SubCACertContext ) ) 
//				//{
//				//	DrvCert.CloseCert( DSPCertContext )
//				//	break;
//				//}
//				//else
//				//{
//				//	DrvCert.CloseCert( DSPCertContext )
//				//}
//
//
//				// 且DSP身份证书是由e-drivers.cn颁发的
//				if ( DrvCert.CheckDSPCertIssuedBySubCACert( CertContext , SubCACertContext ) ) break
//			}
//		}
//		// 找下个DSP通讯证书
//		CertContext = DrvCert.CertFind( "" , 1 , FindHandle , CertContext )	
//		if ( CertContextOld && CertContext!= CertContextOld) DrvCert.CloseUserCert( CertContextOld )
//	}
//
//	DrvCert.CloseCertFind( FindHandle )
//	DrvCert.CloseUserCert( SubCACertContext )
//
//return (CertContext)
//}
