现在的位置: 首页 > 综合 > 正文

usb驱动自动安装中遇到的问题

2012年03月03日 ⁄ 综合 ⁄ 共 3453字 ⁄ 字号 评论关闭

主要有四个步骤:

1.        根据“协作安装程序应用一例”编写dll

2.        函数实现dll的注册

3.        然后预安装

4.        插入设备测试

1.        根据“协作安装程序应用一例”编写dll

Dll是基于win32的dll程序,入口函数的声明如下:

extern "C"__declspec(dllexport)HRESULT NACoInstallEntryPoint(  //HRESULT
         IN     DI_FUNCTION               InstallFunction,
         IN     HDEVINFO                  DeviceInfoSet,
         IN     PSP_DEVINFO_DATA          DeviceInfoData,  OPTIONAL
         IN OUT PCOINSTALLER_CONTEXT_DATAContext
         );

实现如下:

HRESULT NACoInstallEntryPoint(
	__in     DI_FUNCTION               InstallFunction,
	__in     HDEVINFO                  DeviceInfoSet,
	__in     PSP_DEVINFO_DATA          DeviceInfoData,  OPTIONAL
	__inout PCOINSTALLER_CONTEXT_DATA Context
	)
{      MessageBox(NULL, L"OK", L"Test", MB_OK);
	switch (InstallFunction)
	{
	case DIF_UNREMOVE:
		break;
	case DIF_SELECTBESTCOMPATDRV:
		MessageBox(NULL, L"DIF_SELECTBESTCOMPATDRV", L"Test", MB_OK);
		if (DeviceInfoData)
		{
			SP_DRVINFO_DATA sDrvInfoData;
			DWORD MemberIndex = 0;
			memset((void*)&sDrvInfoData, 0,  sizeof(SP_DRVINFO_DATA));
			sDrvInfoData.cbSize =  sizeof(SP_DRVINFO_DATA);
			if(SetupDiEnumDriverInfo(DeviceInfoSet, DeviceInfoData, SPDIT_COMPATDRIVER, MemberIndex++, &sDrvInfoData))
			{
				SP_DRVINSTALL_PARAMS sDrvInstallParams;
				memset((void*)&sDrvInstallParams, 0,  sizeof(SP_DRVINSTALL_PARAMS));

				sDrvInstallParams.cbSize =  sizeof(SP_DRVINSTALL_PARAMS);

				OutputDebugString(sDrvInfoData.Description);

				if(!SetupDiGetDriverInstallParams(DeviceInfoSet, DeviceInfoData, &sDrvInfoData, &sDrvInstallParams))
				{
					MessageBox(NULL, L"SetupDiGetDriverInstallParams error", L"Test", MB_OK);
				}
				else
				{
					MessageBox(NULL, L"SetupDiGetDriverInstallParams ok", L"Test", MB_OK);
				}

				sDrvInstallParams.Rank = 0;

				if(!SetupDiSetDriverInstallParams(DeviceInfoSet, DeviceInfoData, &sDrvInfoData, &sDrvInstallParams))
				{
					MessageBox(NULL, L"SetupDiSetDriverInstallParams error", L"Test", MB_OK);
				}
				else
				{	
					MessageBox(NULL, L"SetupDiSetDriverInstallParams OK", L"Test", MB_OK);
				}

			}
			else
			{
				if(GetLastError()  == ERROR_INVALID_USER_BUFFER)
					MessageBox(NULL, L"SetupDiEnumDriverInfo error11", L"Test", MB_OK);

				MessageBox(NULL, L"SetupDiEnumDriverInfo error", L"Test", MB_OK);
			}
		}
		else
		{
			MessageBox(NULL, L"DeviceInfoData error", L"Test", MB_OK);
		}
		break;
}
return NO_ERROR;
} 

2.        函数实现dll的注册

           dll的注册我是写函数实现的,DDK里面说是修改inf文件实现但是我改了以后没成功,所以才自己写函数实现的。

           1)写注册表 

                  WriteReg();

           2)拷贝dll文件到系统目录

                   

 bool flag = CopyFile(strRoot+L"\\NACoinstaller.dll", "C:\\WINDOWS\\system32\\NACoinstaller.dll", FALSE);

         

void WriteReg(void)
{
	HKEY    hReg;
	char szName[MAX_PATH];
	strcpy(szName, "{25DBCE51-6C8F-4A72-8A6D-B54C2B4FC835}");
	char szData[MAX_PATH];
//	strcpy(szData, "NACoinstall.dll, NACoInstallEntryPoint");
	strcpy(szData, "NACoinstaller.dll, NACoInstallEntryPoint");
	DWORD dw;//-1表示创建失败 0表示创建成功

	dw = RegOpenKeyExA(HKEY_LOCAL_MACHINE,"SYSTEM\\CurrentControlSet\\Control\\CoDeviceInstallers",0,KEY_WRITE,&hReg);
	if(dw != ERROR_SUCCESS)
	{
		AfxMessageBox("RegOpenKeyExA失败");
	}
	dw = RegSetValueEx(hReg, szName, 0, REG_MULTI_SZ, (LPBYTE)szData, strlen(szData));
	if(dw != ERROR_SUCCESS)
	{
		AfxMessageBox("RegSetValueEx失败");
	}
	RegCloseKey(hReg);	
}

3.        然后预安装

          原装设备是调用SetupCopyOEMInf实现的。代码如下:

其中

szInfFile表示inf文件的全路径,asDesName是成功后生产的oemx.inf文件名

if(FALSE == SetupCopyOEMInf(
		szInfFile,
		NULL,      // 和SPOST_PATH一起使用时设为NULL,表示和inf文件同目录即c:/tmp
		SPOST_PATH,
		SP_COPY_NOOVERWRITE,
		(PSTR)asDesPath,	
		MAX_PATH,
		NULL,	
		(PSTR *)&asDesName))	
	{
		if(GetLastError() == ERROR_FILE_EXISTS)	
		{
			nResult = 1;       // 已安装
			AfxMessageBox("已安装");
		}
		else
		{
			nResult = -1;      // 失败
			AfxMessageBox("失败");
		}
	}
	else	
	{	
		nResult = 0;        // 成功	
		AfxMessageBox("成功");
	}	
	CString str;
	str.Format("%s", asDesName);
	m_oemName.SetWindowTextA(str);

4.        插入设备测试

           经过以上3步,写dll, 注册dll, 预安装,插入设备,依次弹出下列对话框,说明rank值已经被修改了

         

但是接下来又弹出,提示“句柄无效”

点击完成以后,弹出

安装失败!!!!

如果不注册dll,直接预安装后插入设备。依次弹出下列对话框:

本来直接预安装以后点击下一步可以成功安装的,估计是我测试太多次了,某些地方没卸载干净导致了这个错误。不知道如何才能把系统恢复干净。

抱歉!评论已关闭.