使用INF文件以编程方式安装驱动程序的方法(C++)

6

请问有人能告诉我如何通过编程方式安装第三方设备驱动程序,如果提供了所有必需的文件,例如inf文件、.sys等。此解决方案应该在Windows2000上最低支持操作系统。

我尝试将.inf文件复制到Win文件夹\INF文件夹中,并将sys文件复制到Win文件夹\system32\drivers中,但每次插入设备时,Windows都会弹出“发现新硬件”用户界面,这正是我想要避免的。

以下是我尝试过的内容,但该函数返回错误87(参数不正确)

HINF HInf;                
UINT ErrorLine;            
BOOL bRes = FALSE;
PBOOL FileWasInUse = FALSE;

LPCSTR szSourceFileName = _T("C:\\Drivers_HypercomP1320\\hypvcpusb.inf");
LPCSTR szInfFileName  = _T("hypvcpusb.inf");
PVOID Context = NULL;

HInf = SetupOpenInfFile ( szSourceFileName, NULL, INF_STYLE_WIN4, &ErrorLine);          

LPCSTR  SourceFile = ("hypvcp.sys");
LPCSTR SourcePathRoot = _T("C:\\Drivers_HypercomP1320");
LPCSTR DestinationName = _T("C:\\WINDOWS\\system32\\drivers\\hypvcp.sys");

bRes = SetupInstallFileEx ( HInf, NULL, SourceFile, SourcePathRoot, DestinationName, SP_COPY_FORCE_IN_USE,
                            (PSP_FILE_CALLBACK)CopyMsgHandler, Context, FileWasInUse);   

DWORD dwVal = GetLastError();

SetupCloseInfFile(HInf);


// Callback function
UINT CopyMsgHandler (UINT Context, UINT Notification,UINT_PTR Param1, UINT_PTR Param2)
{
    UINT rtnValue = NO_ERROR;
    return rtnValue;
}

感谢您的选择。

右键单击INF文件,然后单击安装。 - Aristos
1
各位,感谢回复,但是驱动程序的安装必须使用C、C++编程实现。 - newdev1
3个回答

3

是的。您可以通过调用

SC_HANDLE manager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (manager)
{
    wprintf(L"Opened SC Manager\n");
}
else
{
    wprintf(L"Open SC Manager failed\n");
    return;
}

然后,将存储在szInfFileName中的.inf文件调用:
HInf = SetupOpenInfFile(szInfFileName.c_str(), NULL, INF_STYLE_WIN4, &ErrorLine);

然后你调用:
if (SetupInstallFileEx(HInf, NULL, SourceFile, SourcePathRoot, DestinationName, SP_COPY_NEWER_OR_SAME, NULL, Context, &FileWasInUse) == NULL)

SourceFile = 驱动程序文件名(以.sys结尾) SourcePathRoot = 驱动程序文件所在路径(应该是您的程序运行的路径) DestinationName = 要安装的驱动程序的完整路径(例如:

c:\windows\system32\drivers\yourdriver.sys 

接下来是注册表。您需要在以下位置为您的驱动程序添加一个条目:

HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\

这个条目(键)应该包括以下内容:驱动程序名称、显示名称、描述、错误控制和组。
接下来的步骤是,您可以使用以下方式启动驱动程序:
SC_HANDLE service = CreateService(manager,
                    DRIVER_NAME,
                    DRIVER_NAME,
                    SERVICE_ALL_ACCESS,
                    SERVICE_KERNEL_DRIVER,
                    SERVICE_AUTO_START,
                    SERVICE_ERROR_NORMAL,
                    KeyName,
                    NULL, NULL, NULL, NULL, NULL);

当KeyName是注册表条目中出现的System32下的驱动程序路径时。例如:
system32\drivers\yourdriver.sys

最后一步:
BOOL result = StartService(service, 0, NULL);

并进行清理

CloseServiceHandle(manager)

非常好的教程,介绍了如何从用户模式代码安装和启动驱动程序。 - Lewis Kelsey
你好,我正在尝试在SYSTEM下运行的Windows服务中安装我的minifilter驱动程序。问题是我正在使用C#。我尝试了您提到的PInvoke方法,但我找不到如何PInvoke SetupInstallFileEx。您有任何想法如何从我的Windows服务中安装驱动程序吗? - Darksody
最好使用C++。 - Michael Haephrati
启动服务或者一般情况下启动我的驱动会导致 GenuineIntel.sys 蓝屏,而在此之前,我的 DriverEntry 从未被调用,原因完全不明。 - Lewis Kelsey

2

我使用批处理文件进行了快速测试,但是该API在Windows Vista上无法安装驱动程序。当我插入设备时,Windows弹出“找到新硬件”界面RUNDLL32.EXE SETUPAPI.DLL,InstallHinfSection TI3410.Uni 128 C:\ Drivers_Test \ Testusb.inf。 - newdev1

2

可能是您对

PBOOL FileWasInUse = FALSE;

的使用有误。您应该将其更改为

BOOL FileWasInUse = FALSE;

并在函数调用中使用 &FileWasInUse 参数(请注意 & 字符)。


+1 MSDN 表示此参数是必需的,传递空指针将导致错误 87。 - Ben Voigt
你说得对,现在函数执行正确了,但是一旦我插入设备,“发现新硬件”向导仍然会弹出。我甚至尝试重新启动电脑并再次插入设备,但结果相同。是否有其他方法可以用来安装驱动程序? - newdev1
@newdev1:我真的不知道,我只是发现了编程错误。但对我来说,这似乎是一个新问题的好素材! - engf-010

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接