gzytom
驱动牛犊
驱动牛犊
  • 注册日期2003-02-09
  • 最后登录2003-08-26
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:10551回复:26

用setup api安装modem成功后,在拨号连接里无法使用

楼主#
更多 发布于:2003-08-16 15:05
我用setup api安装modem成功了,设备管理器可以正常看到这个modem,也可以正常检测,但在拨号连接里就是无法使用,老是提示找不到modem。如果我用硬件向导装modem就可以用。是不是modem驱动安装完还要在注册表登记什么?大虾指教啊,江湖救急!

最新喜欢:

kb219kb219
znsoft
管理员
管理员
  • 注册日期2001-03-23
  • 最后登录2023-10-25
  • 粉丝300
  • 关注6
  • 积分910分
  • 威望14796点
  • 贡献值7点
  • 好评度2410点
  • 原创分5分
  • 专家分100分
  • 社区居民
  • 最爱沙发
  • 社区明星
沙发#
发布于:2003-08-16 17:09
我的msn : ma13910206425@hotmail.com
http://www.zndev.com 免费源码交换网 ----------------------------- 软件创造价值,驱动提供力量! 淡泊以明志,宁静以致远。 ---------------------------------- 勤用搜索,多查资料,先搜再问。
gzytom
驱动牛犊
驱动牛犊
  • 注册日期2003-02-09
  • 最后登录2003-08-26
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2003-08-17 00:32
痛苦挣扎后几个小时终于解决了。原来我是在modem安装完后再修改注册表键AttachTo使Modem绑在一个端口上,后来发现这是不行的,因为Modem安装过程中有一个向RAS注册的过程,必须在这个过程之前设置好AttachTo。但在SetupDiCallClassInstaller(DIF_INSTALLDEVICE,)之前AttachTo所在的主键还没有生成,没办法设置AttachTo,最后写了一个CoInstaller了事。
EricGaoxp
驱动牛犊
驱动牛犊
  • 注册日期2002-11-01
  • 最后登录2016-01-07
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地板#
发布于:2003-08-18 14:09
to gzytom
可否把你的CoInstaller部分代码发给我参考一下,我在这儿遇到的问题和你的很相似,谢谢!

我的mail:
EricGaoxp@hotmail.com
从头再来!越过一路风景,无悔!
gzytom
驱动牛犊
驱动牛犊
  • 注册日期2003-02-09
  • 最后登录2003-08-26
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2003-08-18 16:41
to gzytom
可否把你的CoInstaller部分代码发给我参考一下,我在这儿遇到的问题和你的很相似,谢谢!

我的mail:
EricGaoxp@hotmail.com
 


其实很简单,在安装前我把需要绑定的端口名称放在注册表某个地方下(我这里用的是HKCR\\Environment\\MDMCOM),然后在CoInstaller里读出这个值。用共享内存或者其他什么方式也可以的,不过我觉得用注册表方便。

DWORD CALLBACK ModemCoInstallProc (
                                DI_FUNCTION  InstallFunction,
                                HDEVINFO  DeviceInfoSet,
                                PSP_DEVINFO_DATA  DeviceInfoData,
                                PCOINSTALLER_CONTEXT_DATA  Context
                                )
{            
    if(InstallFunction == DIF_INSTALLDEVICE)
    {
        char szInstanceID[255];
        char buffer[1024];
        DWORD cbData;
        HKEY hKey;

        char szComPort[10] = { 0 };

        if(RegOpenKey(HKEY_CURRENT_USER , \"Environment\" , &hKey)==ERROR_SUCCESS)
        {
            cbData = sizeof(szComPort);
            if(RegQueryValueEx(hKey , \"MDMCOM\" , NULL , NULL , (LPBYTE)szComPort , &cbData)==ERROR_SUCCESS)
            {
                if(SetupDiGetDeviceInstanceId(DeviceInfoSet , DeviceInfoData ,
                    szInstanceID , 1024 , NULL))
                {        
                    if(GetOsType() < OS_NT4)
                        strcpy(buffer , \"System\\\\CurrentControlSet\\\\Services\\\\Class\\\\\");
                    else
                        strcpy(buffer , \"SYSTEM\\\\CurrentControlSet\\\\Control\\\\Class\\\\\");
                    
                    cbData = 1024 - strlen(buffer);
                    
                    if(RegQueryDeviceProperty(szInstanceID , NULL , \"Driver\" ,
                        NULL , (PBYTE)(buffer + strlen(buffer)), &cbData)==ERROR_SUCCESS)
                    {
                        if(RegOpenKey(HKEY_LOCAL_MACHINE, buffer,&hKey)==ERROR_SUCCESS)
                        {
                            RegSetValueEx(hKey , \"AttachedTo\", 0 , REG_SZ , (LPBYTE)szComPort ,
                                strlen(szComPort));
                            
                            RegCloseKey(hKey);
                        }
                    }
                }
            }
            RegCloseKey(hKey);
        }
    }
    return NO_ERROR;
}


[编辑 -  8/18/03 by  gzytom]
EricGaoxp
驱动牛犊
驱动牛犊
  • 注册日期2002-11-01
  • 最后登录2016-01-07
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2003-08-19 08:54
可不可以把你的所有代码发给我,我还是不是很明白,呵呵,我是新手,刚接触这方面不到一个星期,或者你可以上msn吗,我的msn是
:EricGaoxp@hotmail.com
从头再来!越过一路风景,无悔!
MDK
MDK
驱动牛犊
驱动牛犊
  • 注册日期2002-05-20
  • 最后登录2004-02-19
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2003-08-21 19:17
我也想解决这样的问题,请问如何将CoInstaller如何将你的回调结合在一起了,没玩过CoInstaller,请指点!
gzytom
驱动牛犊
驱动牛犊
  • 注册日期2003-02-09
  • 最后登录2003-08-26
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2003-08-22 12:22
可不可以把你的所有代码发给我,我还是不是很明白,呵呵,我是新手,刚接触这方面不到一个星期,或者你可以上msn吗,我的msn是
:EricGaoxp@hotmail.com


哈哈,我也是新手啊。代码我基本都贴出来了啊。
gzytom
驱动牛犊
驱动牛犊
  • 注册日期2003-02-09
  • 最后登录2003-08-26
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2003-08-22 12:24
我也想解决这样的问题,请问如何将CoInstaller如何将你的回调结合在一起了,没玩过CoInstaller,请指点!


看不大懂你的意思:(。CoInstaller是有系统调用的。在INF文件注册后就可以。不过98不能用,郁闷。
MDK
MDK
驱动牛犊
驱动牛犊
  • 注册日期2002-05-20
  • 最后登录2004-02-19
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2003-08-22 13:41
to gzytom :
98下确实是不能用,因为setupapi.dll使用了一些NTDLL.DLL的函数导
入,98下没有的,即使拷过来也不能用。
我的意思就是怎么让这个回调函数于你的主程序组合在一起。我想要实现运行这个程序后,就可以指定串口和INF文件,自动安装标准33K的调制解调器。无需用户在去选择和干预。
不知能不能给你的主程序也拿出来让大家学习学习。
下面是DDK下根据指定的INF和HardWareID来自动安装驱动的函数例程,请问如何将它和你的回调组合在一起使用,达到上述目的?

BOOL InstallRootEnumDriver(IN LPTSTR HardwareId, IN LPTSTR InfFile,OUT PBOOL RebootRequest OPTIONAL)
{
HDEVINFO DeviceInfoSet=0;
SP_DEVINFO_DATA DeviceInfoData;
GUID ClassGUID;
TCHAR ClassName[MAX_CLASS_NAME_LEN];
DWORD err;

if (!SetupDiGetINFClass(InfFile,&ClassGUID,ClassName,sizeof(ClassName),0))
{

return DisplayError(TEXT(\"SetupDiINFClass\"));
}

DeviceInfoSet=SetupDiCreateDeviceInfoList(&ClassGUID,0);

if (DeviceInfoSet==INVALID_HANDLE_VALUE)
{
return DisplayError(TEXT(\"SetupCreateDeviceInfoList\"));
}

DeviceInfoData.cbSize=sizeof(SP_DEVINFO_DATA);

if (!SetupDiCreateDeviceInfo(DeviceInfoSet,ClassName,&ClassGUID,NULL,0,
DICD_GENERATE_ID,&DeviceInfoData))
{
DisplayError(TEXT(\"CreateDeviceInfo\"));
goto cleanup_DeviceInfo;
}

if(!SetupDiSetDeviceRegistryProperty(DeviceInfoSet,
        &DeviceInfoData,
        SPDRP_HARDWAREID,
        (LPBYTE)HardwareId,
        (lstrlen(HardwareId)+1+1)*sizeof(TCHAR)))
    {
        DisplayError(TEXT(\"SetDeviceRegistryProperty\"));
        goto cleanup_DeviceInfo;
    }

   if (!SetupDiCallClassInstaller(DIF_REGISTERDEVICE,
        DeviceInfoSet,
        &DeviceInfoData))
    {
        DisplayError(TEXT(\"CallClassInstaller(REGISTERDEVICE)\"));
        goto cleanup_DeviceInfo;
    }
    
    //
    // The element is now registered. We must explicitly remove the
    // device using DIF_REMOVE, if we encounter any failure from now on.
    //
    
    //
    // Install the Driver.
    //
    if (!UpdateDriverForPlugAndPlayDevices(0,
        HardwareId,
        InfFile,
        INSTALLFLAG_FORCE,
        RebootRequest))
    {
        DWORD err = GetLastError();
        DisplayError(TEXT(\"UpdateDriverForPlugAndPlayDevices\"));
        
        if (!SetupDiCallClassInstaller(
            DIF_REMOVE,
            DeviceInfoSet,
            &DeviceInfoData))
        {
            DisplayError(TEXT(\"CallClassInstaller(REMOVE)\"));
        }
        SetLastError(err);
    }
    
    //
    //  Cleanup.
    //    
cleanup_DeviceInfo:
    err = GetLastError();
    SetupDiDestroyDeviceInfoList(DeviceInfoSet);
    SetLastError(err);
    
    return err == NO_ERROR;
}

gzytom
驱动牛犊
驱动牛犊
  • 注册日期2003-02-09
  • 最后登录2003-08-26
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
10楼#
发布于:2003-08-22 14:53
to gzytom :
98下确实是不能用,因为setupapi.dll使用了一些NTDLL.DLL的函数导
入,98下没有的,即使拷过来也不能用。
我的意思就是怎么让这个回调函数于你的主程序组合在一起。我想要实现运行这个程序后,就可以指定串口和INF文件,自动安装标准33K的调制解调器。无需用户在去选择和干预。
不知能不能给你的主程序也拿出来让大家学习学习。
下面是DDK下根据指定的INF和HardWareID来自动安装驱动的函数例程,请问如何将它和你的回调组合在一起使用,达到上述目的?

 


哦,我明白你的意思了。98下也有setupapi.dll,而且好像还没有什么函数不可以用吧?DDK下那个例子除了一个函数不能用:UpdateDriverForPlugAndPlayDevices,它是在newdev.dll里的,其他都可以用。其实这个UpdateDriverForPlugAndPlayDevices也可以用SetupDiXX类函数替代。下面是我的主程序的一个片断,仿照DDK写的,98下可以有条件的正常运行(见我后面的解释):

BOOL FindExistingDevice(IN LPGUID lpGUID ,
                        IN LPCTSTR lpszHardwareID ,
                        OUT LPTSTR lpszInstanceID OPTIONAL)
{
    HDEVINFO hdi = NULL;
    SP_DEVINFO_DATA hDev = { 0 } ;
    hDev.cbSize = sizeof(SP_DEVINFO_DATA);
    DWORD dwEnumIndex;
    char buffer[1024];
    DWORD cbData;
    BOOL fFound = FALSE;

    try
    {
        if((hdi = SetupDiGetClassDevs(lpGUID , NULL , NULL , 0))==NULL)
            throw STException(\"SetupDiGetClassDevs\");
        
        dwEnumIndex = 0;
        while(SetupDiEnumDeviceInfo(hdi , dwEnumIndex++ , &hDev))
        {
            if(SetupDiGetDeviceRegistryProperty(hdi , &hDev ,
                SPDRP_HARDWAREID , NULL , (PBYTE)buffer , 1024 , &cbData))
            {
                char *p;
                for (p=buffer;*p&&(p<&buffer[cbData]);p+=strlen(p)+sizeof(char))
                {                
                    if (stricmp(lpszHardwareID,p)==0)
                    {
                        printf(\"Found! [%s]\\n\",p);

                        if(!SetupDiGetDeviceInstanceId(hdi , &hDev , buffer , 1024 , NULL))
                            throw STException(\"SetupDiGetDeviceInstanceId\");
                        
                        if(lpszInstanceID!=NULL)
                            strcpy(lpszInstanceID , buffer);
                        fFound = TRUE;
                        break;
                    }
                }

                if(fFound)
                    break;
            }
        }
    }
    catch(STException &e)
    {        
        LogMessage(\"%s failed , err = %x.\\n\" , e.getMessage() , GetLastError());
    }
                
    if(hdi != NULL)
        SetupDiDestroyDeviceInfoList(hdi);

    return fFound;
}

int InstallRootEnumeratedDriver(IN LPGUID lpGUID,
                  IN LPCTSTR lpszHardwareID ,
                  IN LPCTSTR lpszDescription,
                  IN LPCTSTR lpszInfName OPTIONAL,
                  OUT LPTSTR lpszInstanceID OPTIONAL,
                  OUT LPBOOL pfNeedReboot OPTIONAL
                  )
{
    int ret = ERROR_SUCCESS;
    DWORD dwEnumIndex;
    char szClassName[100];

    HDEVINFO hdi = NULL;
    SP_DEVINFO_DATA hDev = { 0 } ;
    SP_DEVINSTALL_PARAMS hInstParam = { 0 } ;
    SP_DRVINFO_DATA hDrv = { 0 } ;
    hDev.cbSize = sizeof(SP_DEVINFO_DATA);
    hInstParam.cbSize = sizeof(SP_DEVINSTALL_PARAMS);
    hDrv.cbSize = sizeof(SP_DRVINFO_DATA);

    try
    {
        //检测设备是否已经安装
        if(FindExistingDevice(lpGUID , lpszHardwareID , lpszInstanceID))
            return ERROR_SUCCESS;

        if(!SetupDiClassNameFromGuid(lpGUID , szClassName , sizeof(szClassName) ,NULL))
            throw STException(\"SetupDiCreateDeviceInfoList\");
            
        if((hdi = SetupDiCreateDeviceInfoList(lpGUID , NULL))==NULL)
            throw STException(\"SetupDiCreateDeviceInfoList\");    

        //创建新设备信息。如果设备已经存在,有异常产生    
        if(!SetupDiCreateDeviceInfo(hdi , szClassName, lpGUID , lpszDescription, NULL , DICD_GENERATE_ID , &hDev))
            throw STException(\"SetupDiCreateDeviceInfo\");
        
        if(!SetupDiGetDeviceInstanceId(hdi ,  &hDev ,lpszInstanceID , MAX_PATH , NULL))
                throw STException(\"SetupDiGetDeviceInstanceId\");
        
        //获得设备安装参数
        if(!SetupDiGetDeviceInstallParams(hdi , &hDev , &hInstParam))
            throw STException(\"SetupDiGetDeviceInstallParams\");

        //修改参数
        if(lpszInfName!=NULL && strlen(lpszInfName)!=0)
        {
            DWORD fattr = GetFileAttributes(lpszInfName);
            if(fattr == -1)
                throw STException(\"GetFileAttributes\");

            if(!(fattr & FILE_ATTRIBUTE_DIRECTORY))
                hInstParam.Flags = hInstParam.Flags | DI_ENUMSINGLEINF;
            strcpy(hInstParam.DriverPath , lpszInfName);
        }        
        hInstParam.FlagsEx = hInstParam.FlagsEx | DI_FLAGSEX_ALLOWEXCLUDEDDRVS;

        //设置设备安装参数
        if(!SetupDiSetDeviceInstallParams(hdi, &hDev , &hInstParam))
            throw STException(\"SetupDiSetDeviceInstallParams\");

        //获得设备驱动信息列表
        if(!SetupDiBuildDriverInfoList(hdi, &hDev , SPDIT_CLASSDRIVER))
            throw STException(\"SetupDiBuildDriverInfoList\");

        //获得设备的驱动程序
        dwEnumIndex = 0;
        while(SetupDiEnumDriverInfo(hdi , &hDev , SPDIT_CLASSDRIVER  ,
            dwEnumIndex++ , &hDrv))
        {
            if(stricmp(hDrv.Description , lpszDescription)==0)
                break;
        }

        //选定这个驱动程序
        if(!SetupDiSetSelectedDriver(hdi , &hDev , &hDrv))
            throw STException(\"SetupDiSetSelectedDriver\");

        //注册设备
        if(!SetupDiRegisterDeviceInfo(hdi , &hDev , 0 , NULL , NULL , NULL))
            throw STException(\"SetupDiRegisterDeviceInfo\");
    
        //注册Co-Installer
        if(!SetupDiRegisterCoDeviceInstallers(hdi , &hDev))
            throw STException(\"SetupDiRegisterCoDeviceInstallers\");
        
        //安装设备
        if(!SetupDiCallClassInstaller(DIF_INSTALLDEVICE , hdi , &hDev))
            throw STException(\"SetupDiInstallDevice\");
        
        if(pfNeedReboot!=NULL)
        {
            if(SetupDiGetDeviceInstallParams(hdi , &hDev , &hInstParam))
                *pfNeedReboot = ((hInstParam.Flags & DI_NEEDRESTART)
                || (hInstParam.Flags & DI_NEEDREBOOT));
            else
                pfNeedReboot = FALSE;
        }

    }
    catch(STException &e)
    {
        ret = GetLastError();

        //反注册设备
        if(hDev.DevInst != 0)
            SetupDiRemoveDevice(hdi , &hDev);

        LogMessage(\"%s failed , err = %x.\\n\" , e.getMessage() , ret);
    }
    
    if(hdi!=NULL)
        SetupDiDestroyDeviceInfoList(hdi);

    return ret;
}


int InstallSuntekModem(LPCTSTR lpszComName)
{    
    int ret = ERROR_SUCCESS;
    char szInfPath[ MAX_PATH ] = { 0 };
    char szInstanceID[ MAX_PATH ] = { 0 };
    char szHardwareID[ MAX_PATH ] = { 0 };
    char szDeviceDesc[ MAX_PATH ] = { 0 };
    char buffer[1024];

    HKEY hKey = NULL;
    HINF hInf = NULL;
    INFCONTEXT hContext;
    DWORD cbData;

    GetWindowsDirectory(szInfPath , MAX_PATH);
    strcat(szInfPath , \"\\\\inf\\\\xxxx.inf\");

    hInf = SetupOpenInfFile(szInfPath , NULL , INF_STYLE_WIN4 , NULL);
    if(hInf != INVALID_HANDLE_VALUE)
    {        
        if(SetupFindFirstLine(hInf , \"Manufacturer\" , NULL , &hContext))
        {    
            if(SetupGetStringField(&hContext , 1 , buffer , sizeof(buffer) , NULL))
            {    
                if(SetupFindFirstLine(hInf , buffer , NULL , &hContext))
                {
                    //获得设备描述
                    SetupGetStringField(&hContext , 0 , szDeviceDesc ,  sizeof(szDeviceDesc) , NULL);
                    //获得HardwareID
                    SetupGetStringField(&hContext , 2,  szHardwareID , sizeof(szHardwareID) , NULL);
                }
            }
        }

        SetupCloseInfFile(hInf);

        if(RegCreateKey(HKEY_CURRENT_USER , \"Environment\" , &hKey)==ERROR_SUCCESS)
            RegSetValueEx(hKey , \"MDMCOM\" , 0 , REG_SZ , (LPBYTE)lpszComName , strlen(lpszComName));

        if((ret = InstallRootEnumeratedDriver((LPGUID)&GUID_MODEM , szHardwareID ,
            szDeviceDesc, szInfPath , szInstanceID , NULL))!=ERROR_SUCCESS)
            return ret;

        if(hKey!=NULL)
        {
            RegDeleteValue(hKey , \"MDMCOM\");
            RegCloseKey(hKey);
        }
   }

    return ret;
}

上面的代码结合我先前贴出的CoInstaller可以在2k/xp下完整地解决安装Modem
的问题。在98下有两个问题,一个是对某些设备的驱动在运行到SetupDiCreateDeviceInfo时会弹出新硬件安装的wizard,十分讨厌。不过好像Modem没有。解决办法也不难,对于会弹出wizard的设备,可以通过直接写注册表完成创建过程(也幸好98下可以直接修改enum)。
第二是98下不支持Co-Installer,实在不知道怎么及时地设置Attach键值,以致装完后拨号网络认不出Modem,
需要重启后才认。这是我目前没办法解决的。望哪位大虾可以指点迷津。



[编辑 -  8/22/03 by  gzytom]
MDK
MDK
驱动牛犊
驱动牛犊
  • 注册日期2002-05-20
  • 最后登录2004-02-19
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
11楼#
发布于:2003-08-25 18:27
十分感谢你的回信。
GUID_MODEM是指Modem的Guid还是你的MODEM的GUID呢?
另外安装的这个MODEM是内MODEM还是虚拟MODEM
gzytom
驱动牛犊
驱动牛犊
  • 注册日期2003-02-09
  • 最后登录2003-08-26
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
12楼#
发布于:2003-08-25 20:40
十分感谢你的回信。
GUID_MODEM是指Modem的Guid还是你的MODEM的GUID呢?
另外安装的这个MODEM是内MODEM还是虚拟MODEM


Modem得GUID。虚拟Modem。
EricGaoxp
驱动牛犊
驱动牛犊
  • 注册日期2002-11-01
  • 最后登录2016-01-07
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
13楼#
发布于:2003-08-26 09:05
/*

 Copyright (c) Microsoft Corporation.  All rights reserved.

 Created By : Rohit Raina

 Creation Date : May 27, 2001

*/

#include <stdio.h>
#include <tchar.h>
#include <windows.h>  
#include <newdev.h>
#include <devguid.h>
#include <setupapi.h>
#include <cfgmgr32.h>
#include <windef.h>
#include <stdlib.h>
#include <ras.h>

#define MAX_CLASS_NAME_LEN 32
#define MAX__DESC 256
TCHAR chComPort[10];
TCHAR chFriendlyName[256];


void DisplayError(TCHAR * ErrorName)
{
    DWORD Err = GetLastError();
    LPVOID lpMessageBuffer = NULL;
    
    if (FormatMessage(
        FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
        NULL,
        Err,  
        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
        (LPTSTR) &lpMessageBuffer,  
        0,  
        NULL ))
        _tprintf(_T(\"%s FAILURE: %s\\n\"),ErrorName,(TCHAR *)lpMessageBuffer);
    else
        _tprintf(_T(\"%s FAILURE: (0x%08x)\\n\"),ErrorName,Err);
    
    if (lpMessageBuffer) LocalFree( lpMessageBuffer ); // Free system buffer

    SetLastError(Err);
    return;
}

BOOL  GetFriendlyName(LPTSTR HardwareId)
{
HDEVINFO DeviceInfoSet;
    SP_DEVINFO_DATA DeviceInfoData;
    DWORD i,err;
    BOOL Found;

//
// Create a Device Information Set with all present devices.
//

DeviceInfoSet = SetupDiGetClassDevs(NULL, // All Classes
       0,
      0,
    DIGCF_ALLCLASSES | DIGCF_PRESENT ); // All devices present on system

if (DeviceInfoSet == INVALID_HANDLE_VALUE)
{
DisplayError(_T(\"GetClassDevs(All Present Devices)\"))  ;
return FALSE;
}

_tprintf(_T(\"\\n\\nSearch for Device ID: [%s]\\n\\n\"),HardwareId);

//
//  Enumerate through all Devices.
//

Found = FALSE;
i = err = 0;

DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);

//for (i=0;SetupDiEnumDeviceInfo(DeviceInfoSet,i,&DeviceInfoData);i++)
while ( !Found && SetupDiEnumDeviceInfo(DeviceInfoSet, i++, &DeviceInfoData))
{
DWORD DataT;
LPTSTR p,buffer = NULL;
DWORD buffersize = 1024;
   
  //
  // We won\'t know the size of the HardwareID buffer until we call
  // this function. So call it with a null to begin with, and then
  // use the required buffer size to Alloc the nessicary space.
  // Keep calling we have success or an unknown failure.
  //
  while (!SetupDiGetDeviceRegistryProperty(
  DeviceInfoSet,
  &DeviceInfoData,
  SPDRP_HARDWAREID,
  &DataT,
  (PBYTE)buffer,
  1024,
  &buffersize))
{
if (GetLastError() == ERROR_INVALID_DATA) {
//
// May be a Legacy Device with no HardwareID. Continue.
//
break;
}
   else if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
              //
// We need to change the buffer size.
//
if (buffer)
LocalFree(buffer);
              buffer = (char *)LocalAlloc(LPTR,buffersize);
}
else
{
  //
  // Unknown Failure.
      //
DisplayError(_T(\"GetDeviceRegistryProperty\"));
err = 1;
break;
}
}
   
if (GetLastError() == ERROR_INVALID_DATA)
   continue;

if( err) break;
   
   //
   // Compare each entry in the buffer multi-sz list with our HardwareID.
   //
for (p=buffer;*p&&(p<&buffer[buffersize]);p+=lstrlen(p)+sizeof(TCHAR))
{
_tprintf(_T(\"Comparing device ID: [%s]\\n\"),p);

if (!_tcscmp(HardwareId,p))
{
_tprintf(_T(\"Found! [%s]\\n\"),p);
Found = TRUE;
break;
}
}

if (buffer) LocalFree(buffer);
       //if (Found) break;
}

if(Found)
{
DWORD dwData, dwBufferSize;
if(!SetupDiGetDeviceRegistryProperty(
DeviceInfoSet,
&DeviceInfoData,
SPDRP_FRIENDLYNAME,
&dwData,
(PBYTE)chFriendlyName,
256,
&dwBufferSize))
return FALSE;
}
if (GetLastError() != NO_ERROR)
{
DisplayError(_T(\"EnumDeviceInfo\"));
}

    //
    //  Cleanup.
    //

    err = GetLastError();
    SetupDiDestroyDeviceInfoList(DeviceInfoSet);
    SetLastError(err);

    return err == NO_ERROR;

}

BOOL WriteToRegistry(LPTSTR FrendlyName)
{
TCHAR chBirdFriendlyNameReg[] = \"Bird_AD3C0BDD-F9A9-488b-AEA2-5CA08CF506B0_Class\\\\BirdModem\";
HKEY hBirdKey;
//TCHAR szFriendlyNam[] = \"BirdModem\";
//DWORD dwType, dwSize;
// TCHAR szReturn[256];
LONG lReturn = RegOpenKeyEx(HKEY_CLASSES_ROOT, chBirdFriendlyNameReg, 0, KEY_QUERY_VALUE | KEY_SET_VALUE, &hBirdKey);
if(lReturn != ERROR_SUCCESS)
{
lReturn = RegCreateKey(HKEY_CLASSES_ROOT, chBirdFriendlyNameReg, &hBirdKey);
if(lReturn != ERROR_SUCCESS)
return FALSE;

lReturn = RegSetValueEx(hBirdKey, (LPCTSTR)\"Modem FriendlyName\", 0, REG_SZ, (const byte *)chFriendlyName, 256);
if(lReturn != ERROR_SUCCESS)
return FALSE;
}
  
RegCloseKey(hBirdKey);

//lReturn = RegOpenKey(hBirdKey, )
return TRUE;

}

BOOL GetAvailablePort()
{

HKEY hKeyClass;
    TCHAR strKey[] = \"HARDWARE\\\\DEVICEMAP\\\\SERIALCOMM\";
TCHAR szPortNum[10];
TCHAR szReturn[10];
DWORD  dwSize;
DWORD dwType;
TCHAR strSubKey[256];

LONG lReturn = RegOpenKey(HKEY_LOCAL_MACHINE, strKey, &hKeyClass);
if(lReturn != ERROR_SUCCESS)
return FALSE;    
for(int i = 0; i < 5; i++)
{
//strcpy(strSubKey, strKey);
_itoa(i, szPortNum, 10);
strcpy(strSubKey, \"\\\\Device\\\\Serial\");
strcat(strSubKey, szPortNum);
      
lReturn = RegQueryValueEx(hKeyClass, strSubKey, NULL, &dwType, (BYTE*)szReturn, &dwSize);
if(lReturn != ERROR_SUCCESS)
break;
else
{
if(strcmp(szReturn, \"COM1\") == 0 || strcmp(szReturn, \"COM2\") == 0)
continue;
else
                strcpy(chComPort, szReturn);
}
}
RegCloseKey(hKeyClass);

return TRUE;
}

BOOL PortExists(TCHAR* szPortName)
/*++

Routine Description:

    This routine checks if the port name supplied is a valid one or not

Arguments:

    szPortName - Supplies a string containing a port name (like COM1, COM2)

Return Value:

    The function returns TRUE if it finds a match for port name,
otherwise it returns a FALSE.

--*/
{
TCHAR szDevDesc[MAX__DESC];
BOOL match = FALSE;
// GUID const CLASS_GUID = GUID_DEVCLASS_PORTS;
GUID const CLASS_GUID = {0x4d36e978L, 0xe325, 0x11ce, {0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18}};

HDEVINFO hDevInfo;

hDevInfo = SetupDiGetClassDevs((LPGUID)&CLASS_GUID, NULL, NULL, DIGCF_PRESENT);

if ( INVALID_HANDLE_VALUE != hDevInfo)
{
SP_DEVINFO_DATA  devInfoElem;
int index = 0;
devInfoElem.cbSize = sizeof(SP_DEVINFO_DATA);

while ( SetupDiEnumDeviceInfo(hDevInfo, index++, &devInfoElem))
{
HKEY hKeyDev = SetupDiOpenDevRegKey(hDevInfo, &devInfoElem, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_READ);
if (INVALID_HANDLE_VALUE != hKeyDev) {
WORD length = sizeof(szDevDesc);
if(ERROR_SUCCESS == RegQueryValueEx(hKeyDev, _T((const char *)\"PortName\"), NULL, NULL, (unsigned char *)szDevDesc, (LPDWORD)&length) ) {
RegCloseKey(hKeyDev);
printf(\"\\t\\tComparing :  %s\\twith\\t%s\\n\", szPortName, szDevDesc);
if (! _tcsicmp(szPortName, szDevDesc)) {
match = TRUE;
break;
}
}
}
} // while
SetupDiDestroyDeviceInfoList(hDevInfo);
}
return match;
}

BOOL
RegisterModem(
    IN  HDEVINFO          hdi,
    IN  PSP_DEVINFO_DATA  pdevData,
    IN  LPCTSTR           pszPort)
/*++

Routine Description:

    This routine registers a modem device and writes \"AttachedTo\" string to registry
-- this value represents the Port to which Modem is attached.

Arguments:

hdi -- Device Info Set -- containing the modem Device Info element.
    pdevData -- Pointer the the modem device information element.
    szPortName -- Supplies a string containing port name the modem is to be attached to (like COM1, COM2).

Return Value:

    The function returns TRUE if it was able to register the modem and write the \"AttachedTo\" string to registry,
otherwise it returns a FALSE.

Note : Once the device is registered using SetupDiRegisterDeviceInfo(...), we need to remove
it explicitly in case of an error here after -- may be call SetupDiCallClassInstaller(...) with a DIF_REMOVE function.

--*/
{
BOOL bRet;
SP_DRVINFO_DATA drvData;
DWORD nErr = NO_ERROR;
DWORD dwRet;
TCHAR const c_szAttachedTo[] = _T(\"AttachedTo\");
HKEY hKeyDev;
bRet = FALSE;

if( !SetupDiRegisterDeviceInfo(hdi, pdevData, 0, NULL, NULL, NULL) )
{
DisplayError(\"Register Device 1\\n\");
return bRet;
}

hKeyDev = SetupDiOpenDevRegKey(hdi, pdevData, DICS_FLAG_GLOBAL, 0, DIREG_DRV, KEY_ALL_ACCESS); //// This call fails....

if( (INVALID_HANDLE_VALUE == hKeyDev) && ( ERROR_KEY_DOES_NOT_EXIST == GetLastError()) )
{
hKeyDev = SetupDiCreateDevRegKey(hdi, pdevData, DICS_FLAG_GLOBAL, 0, DIREG_DRV, NULL, NULL);

if( INVALID_HANDLE_VALUE == hKeyDev )
{
DisplayError(_T(\"SetupDi Open+Create DevRegKey failed: \"));
return FALSE;
}
}
else {
DisplayError(_T(\"Can not open DriverKey: \"));
return FALSE;
}

    if (ERROR_SUCCESS != (dwRet = RegSetValueEx (hKeyDev, c_szAttachedTo, 0, REG_SZ,
(PBYTE)pszPort, (lstrlen(pszPort)+1)*sizeof(TCHAR))))
{
DisplayError(_T(\"RegSetValueEx :\"));

            SetLastError (dwRet);
            bRet = FALSE;
}
RegCloseKey (hKeyDev);
/*  
if(!SetupDiBuildDriverInfoList(hdi, pdevData, SPDIT_CLASSDRIVER))
return FALSE;

//获得设备的驱动程序
DWORD dwEnumIndex = 0;
while(SetupDiEnumDriverInfo(hdi , pdevData , SPDIT_CLASSDRIVER ,
dwEnumIndex++ , &drvData))
{
if(stricmp(drvData.Description , \"标准 33600 bps 调制解调器\")==0)
break;
}

//选定这个驱动程序
if(!SetupDiSetSelectedDriver(hdi , pdevData , &drvData))
   return false;

*/
if( !SetupDiRegisterDeviceInfo(hdi, pdevData, 0, NULL, NULL, NULL) )
    {
DisplayError(_T(\"Register Device 2\"));
        return FALSE;
}

if ( !SetupDiGetSelectedDriver(hdi, pdevData, &drvData)) {
DisplayError(_T(\"SetupDiGetSelectedDriver Failed: \"));

}

return TRUE;
}

BOOL FindExistingDevice(IN LPTSTR HardwareId)
/*++

Routine Description:

    This routine finds an existing devnode if present.

Arguments:

    HardwareIdList - Supplies a string containing a hardware ID to
    be associated with the device.

Return Value:

    The function returns TRUE if it is successful.

    Otherwise it returns FALSE and the logged error can be retrieved
    with a call to GetLastError.

    The most common error will be ERROR_NO_MORE_ITEMS, which means the
    function could not find a devnode with the HardwareID.

--*/
{
    HDEVINFO DeviceInfoSet;
    SP_DEVINFO_DATA DeviceInfoData;
    DWORD i,err;
    BOOL Found;

//
// Create a Device Information Set with all present devices.
//

DeviceInfoSet = SetupDiGetClassDevs(NULL, // All Classes
       0,
      0,
       DIGCF_ALLCLASSES | DIGCF_PRESENT ); // All devices present on system

if (DeviceInfoSet == INVALID_HANDLE_VALUE)
{
DisplayError(_T(\"GetClassDevs(All Present Devices)\"))  ;
return FALSE;
}

_tprintf(_T(\"\\n\\nSearch for Device ID: [%s]\\n\\n\"),HardwareId);

//
//  Enumerate through all Devices.
//

Found = FALSE;
i = err = 0;

DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);

//for (i=0;SetupDiEnumDeviceInfo(DeviceInfoSet,i,&DeviceInfoData);i++)
while ( !Found && SetupDiEnumDeviceInfo(DeviceInfoSet, i++, &DeviceInfoData))
{
DWORD DataT;
LPTSTR p,buffer = NULL;
DWORD buffersize = 1024;
   
  //
  // We won\'t know the size of the HardwareID buffer until we call
  // this function. So call it with a null to begin with, and then
  // use the required buffer size to Alloc the nessicary space.
  // Keep calling we have success or an unknown failure.
  //
  while (!SetupDiGetDeviceRegistryProperty(
  DeviceInfoSet,
  &DeviceInfoData,
  SPDRP_HARDWAREID,
  &DataT,
  (PBYTE)buffer,
  1024,
  &buffersize))
{
if (GetLastError() == ERROR_INVALID_DATA) {
//
// May be a Legacy Device with no HardwareID. Continue.
//
break;
}
   else if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
              //
// We need to change the buffer size.
//
if (buffer)
LocalFree(buffer);
              buffer = (char *)LocalAlloc(LPTR,buffersize);
}
else
{
  //
  // Unknown Failure.
      //
DisplayError(_T(\"GetDeviceRegistryProperty\"));
err = 1;
break;
}
}
   
if (GetLastError() == ERROR_INVALID_DATA)
   continue;

if( err) break;
   
   //
   // Compare each entry in the buffer multi-sz list with our HardwareID.
   //
for (p=buffer;*p&&(p<&buffer[buffersize]);p+=lstrlen(p)+sizeof(TCHAR))
{
_tprintf(_T(\"Comparing device ID: [%s]\\n\"),p);

if (!_tcscmp(HardwareId,p))
{
_tprintf(_T(\"Found! [%s]\\n\"),p);
Found = TRUE;
break;
}
}

if (buffer) LocalFree(buffer);
       //if (Found) break;
}

if (GetLastError() != NO_ERROR)
{
DisplayError(_T(\"EnumDeviceInfo\"));
}

    //
    //  Cleanup.
    //

    err = GetLastError();
    SetupDiDestroyDeviceInfoList(DeviceInfoSet);
    SetLastError(err);

    return err == NO_ERROR;
}


BOOL
InstallRootEnumeratedDriver(IN  LPTSTR HardwareId,
    IN  LPTSTR INFFile,
    IN LPTSTR MdmPort,
    OUT PBOOL  RebootRequired  OPTIONAL
    )
/*++

Routine Description:

    This routine creates and installs a new root-enumerated devnode.

Arguments:

    HardwareIdList - Supplies a multi-sz list containing one or more hardware
    IDs to be associated with the device.  These are necessary in order
    to match up with an INF driver node when we go to do the device
    installation.

    InfFile - Supplies the full path to the INF File to be used when
    installing this device.

    RebootRequired - Optionally, supplies the address of a boolean that is
    set, upon successful return, to indicate whether or not a reboot is
    required to bring the newly-installed device on-line.

Return Value:

    The function returns TRUE if it is successful.

    Otherwise it returns FALSE and the logged error can be retrieved
    with a call to GetLastError.

--*/
{
    HDEVINFO DeviceInfoSet = 0;
    SP_DEVINFO_DATA DeviceInfoData;
    GUID ClassGUID;
    TCHAR ClassName[MAX_CLASS_NAME_LEN];
    DWORD err;
// HKEY hKeyDev;
BOOL Remove = FALSE;
    
    //
    // Use the INF File to extract the Class GUID.
    //
    if (!SetupDiGetINFClass(INFFile,&ClassGUID,ClassName,sizeof(ClassName),0))
    {
        DisplayError(_T(\"GetINFClass\"));
return FALSE;
    }
    
    //
    // Create the container for the to-be-created Device Information Element.
    //
    DeviceInfoSet = SetupDiCreateDeviceInfoList(&ClassGUID,0);
    if(DeviceInfoSet == INVALID_HANDLE_VALUE)
    {
        DisplayError(_T(\"CreateDeviceInfoList\"));
return FALSE;
    }


do {
//
// Now create the element.
// Use the Class GUID and Name from the INF file.
//
DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
if (!SetupDiCreateDeviceInfo(DeviceInfoSet,
ClassName,
&ClassGUID,
NULL,
0,
DICD_GENERATE_ID,
&DeviceInfoData))
{
DisplayError(_T(\"CreateDeviceInfo\"));
break;
}

//
// Add the HardwareID to the Device\'s HardwareID property.
//
if(!SetupDiSetDeviceRegistryProperty(DeviceInfoSet,
&DeviceInfoData,
SPDRP_HARDWAREID,
(LPBYTE)HardwareId,
(lstrlen(HardwareId)+1+1)*sizeof(TCHAR)))
{
DisplayError(_T(\"SetDeviceRegistryProperty\"));
break;
}

if ( !RegisterModem(DeviceInfoSet, &DeviceInfoData, MdmPort) )
{
Remove = TRUE;
break;
}

//
// Install the Driver.
//
if (!UpdateDriverForPlugAndPlayDevices(0,
HardwareId,
INFFile,
INSTALLFLAG_FORCE,
RebootRequired))
{
DisplayError(_T(\"UpdateDriverForPlugAndPlayDevices\"));
Remove = TRUE;
break;
}

} while (FALSE);

if(Remove) {

//Delete Device Instance that was registered using SetupDiRegisterDeviceInfo
// May through an error if Device not registered -- who cares??

SetupDiCallClassInstaller(
           DIF_REMOVE,
           DeviceInfoSet,
           &DeviceInfoData);
}

    //
    //  Cleanup.
    //    

    err = GetLastError();
    SetupDiDestroyDeviceInfoList(DeviceInfoSet);
    SetLastError(err);
    
    return (err == NO_ERROR && !Remove);
}

void addRasDail()
{
//创建电话簿
char * lpszEntry = \"DOEASY\";
char * lpszDeviceType = \"modem\";
char * lpszPhoneNumber = \"*99***1#\";
char * lpszPhoneBook = NULL;
char lpszDeviceName[MAX__DESC];

//find BIRD_USB Registy alias
if( GetFriendlyName( _TEXT(\"mdmgen336\")) ){
strcpy( lpszDeviceName, chFriendlyName );
}

if(RasValidateEntryName(lpszPhoneBook, lpszEntry) != ERROR_ALREADY_EXISTS)//检测拨号网络是否存在
{
RASENTRY rasEntry;
ZeroMemory(&rasEntry, sizeof(rasEntry));
rasEntry.dwSize = sizeof(rasEntry);
strcpy(rasEntry.szLocalPhoneNumber,lpszPhoneNumber);
rasEntry.dwfNetProtocols = RASNP_NetBEUI;
rasEntry.dwFramingProtocol = RASNP_Ip;//设置为TcpIP协议
strcpy(rasEntry.szDeviceType, lpszDeviceType);
strcpy(rasEntry.szDeviceName, lpszDeviceName);
DWORD dwRV = RasSetEntryProperties(lpszPhoneBook, lpszEntry, &rasEntry,sizeof(rasEntry), NULL, 0);
}
// return \"DOEASY\";
}


int __cdecl _tmain(int argc, _TCHAR **argv, _TCHAR **envp)
/*++
Routine Discription:

    Entry point to install.exe.
    Parse the command line, call subroutines.

Arguments:
    
    Standard console \'c\' application arguments.

    argv[1] - Full path of INF file.
    argv[2] - PnP HardwareID of device.

Return Value:
    
    Standard Console ERRORLEVEL values:

    0 - Install Successfull, no reboot required.
    1 - Install Successfull, reboot required.
    2 - Install Failure.
    
--*/
{
    WIN32_FIND_DATA FindFileData;
    BOOL RebootRequired = 0; // Must be cleared.

    //
    // Verify the Arguments.
    //
char szInfPath[256];
GetWindowsDirectory(szInfPath , MAX_PATH);
strcat(szInfPath , \"\\\\inf\\\\mdmgen.inf\");


GetAvailablePort();
argv[1] = new char[256];
argv[2] = new char[256];
strcpy(argv[1] ,  szInfPath);
strcpy(argv[2], chComPort);
argv[3] = \"mdmgen336\";
/*
    if (argc != 4)
    {
        _tprintf(\"usage: %s <INF_File> COMP <Hardware_ID>\\n\", argv[0]);
        return 2; // Install Failure
    }
*/
if(!PortExists(argv[2])) {
_tprintf(_T(\"\\nInvalid Port... exiting\"));
return 2; // Invalid Port supplied
}

    if (FindFirstFile(argv[1],&FindFileData)==INVALID_HANDLE_VALUE)    {
        _tprintf(_T(\"  File not found.\\n\"));
        _tprintf(_T(\"usage: install <INF_File> COMP  <Hardware_ID>\\n\"));
        return 2; // Install Failure
    }

    //
    // if this device allready exists
    //
    if (FindExistingDevice(argv[3])) {
        //
        // No Need to Create a Device Node, just update the current devnode.
        //
        if (!UpdateDriverForPlugAndPlayDevices(0, // No Window Handle
            argv[3], // Hardware ID
            argv[1], // FileName
            INSTALLFLAG_FORCE,
            &RebootRequired))
        {
            DisplayError(_T(\"UpdateDriverForPlugAndPlayDevices\"));
            return 2; // Install Failure
        }
    }
    else
    {
        if (GetLastError()!= ERROR_NO_MORE_ITEMS) {
            //
            // An unknown failure from FindExistingDevice()
            //
            return 2; // Install Failure
        }

        //
        // Driver Does not exist, Create and call the API.
        // HardwareID must be a multi-sz string, which argv[2] is.
        //

   if (!InstallRootEnumeratedDriver(argv[3], // HardwareID
           argv[1], // FileName
           argv[2], // Modem Port
           &RebootRequired))
   {
if(GetFriendlyName(argv[3]))
{
WriteToRegistry(chFriendlyName);    
addRasDail();
}
return 2; // Install Failure
   }
    }

    _tprintf(_T(\"Driver Installed successfully.\\n\"));

    if (RebootRequired) {
        _tprintf(_T(\"(Reboot Required)\\n\"));
        return 1; // Install Success, reboot required.
    }
    

    return 0; // Install Success, no reboot required.
}



以上代码是安装一个标准的336Modem,运行的前提是必须有一个COM存在,可以在xp和2k下运行!
从头再来!越过一路风景,无悔!
MDK
MDK
驱动牛犊
驱动牛犊
  • 注册日期2002-05-20
  • 最后登录2004-02-19
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
14楼#
发布于:2003-08-26 10:11
to:gzytom,EricGaoxp
谢谢俩位的慷慨解囊,不知你们是用在什么MODEM上的?我是用在CDMA MODEM上的。
gzytom你的代码我试过,我将GUIDMODEM代入的是MODEM的ClassGUID
{4D36E96D-E325-11CE-BFC1-08002BE10318}。但是在运行到SetupDiClassNameFromGuid函数时报了一个错误0xe0000206。不知为什么,另外不知你coinstall这方面是在那学的,这方面的资料很少,大部分是E文的。
EricGaoxp你的代码我试一试再说。
gzytom
驱动牛犊
驱动牛犊
  • 注册日期2003-02-09
  • 最后登录2003-08-26
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
15楼#
发布于:2003-08-26 12:29
to:gzytom,EricGaoxp
谢谢俩位的慷慨解囊,不知你们是用在什么MODEM上的?我是用在CDMA MODEM上的。
gzytom你的代码我试过,我将GUIDMODEM代入的是MODEM的ClassGUID
{4D36E96D-E325-11CE-BFC1-08002BE10318}。但是在运行到SetupDiClassNameFromGuid函数时报了一个错误0xe0000206。不知为什么,另外不知你coinstall这方面是在那学的,这方面的资料很少,大部分是E文的。
EricGaoxp你的代码我试一试再说。
 


我的也是CDMA Modem啊,//hand,呵呵。0xe0000206是指不合法的
类。怎么你的机子连Modem的类都没有。自己用写注册表方法手工添加应该也行的。不过我想不会的,是不是你的DEFINE_GUID写错了?coinstall不是很复杂的东西,msdn就有,不过e文是肯定的了。EricGaoxp的代码就可以不使用coinstaller了,一直没考虑过SetupDiCreateDevRegKey这个函数,原来有这个妙用。
MDK
MDK
驱动牛犊
驱动牛犊
  • 注册日期2002-05-20
  • 最后登录2004-02-19
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
16楼#
发布于:2003-08-26 12:55
原来都是用在CDMA MODEM上的呀!有缘有缘
MODEM的ClassGuid不是4D36E96D-E325-11CE-BFC1-08002BE10318吗
我用DEFINE_GUID(GUID_MODEM,0x4D36E96D,0x0e325,0x11ce,0xbfc1,0x08,0x00,0x2b,0xe1,0x03,0x18);
写的有什么错误吗?
另外你不知你用过DDK下的那个例子程序(通过.inf安装驱动程序)在调用UpdateDriverForPlugAndPlayDevices时在WIN2000下返回0xe0000203,但在XP返回0,这个ERROR又是什么意思?
gzytom 其实在2000下可以设置Enum权限,然后修改它的键值(98可直接修怍),不用通过setupapi

gzytom
驱动牛犊
驱动牛犊
  • 注册日期2003-02-09
  • 最后登录2003-08-26
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
17楼#
发布于:2003-08-26 14:27
原来都是用在CDMA MODEM上的呀!有缘有缘
MODEM的ClassGuid不是4D36E96D-E325-11CE-BFC1-08002BE10318吗
我用DEFINE_GUID(GUID_MODEM,0x4D36E96D,0x0e325,0x11ce,0xbfc1,0x08,0x00,0x2b,0xe1,0x03,0x18);
写的有什么错误吗?
另外你不知你用过DDK下的那个例子程序(通过.inf安装驱动程序)在调用UpdateDriverForPlugAndPlayDevices时在WIN2000下返回0xe0000203,但在XP返回0,这个ERROR又是什么意思?
gzytom 其实在2000下可以设置Enum权限,然后修改它的键值(98可直接修怍),不用通过setupapi

 


你写错了吧,应该是DEFINE_GUID (GUID_MODEM , 0x4D36E96D, 0xE325, 0x11CE,0xBF,0xC1,0x08,0x00,0x2B,0xE1,0x03,0x18);
0xe0000203是没有选择驱动,是不是你的INF不正确。0就是成功拉。

是不是用RegSetKeySecurity?我没用过这个函数。
MDK
MDK
驱动牛犊
驱动牛犊
  • 注册日期2002-05-20
  • 最后登录2004-02-19
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
18楼#
发布于:2003-08-26 14:50
//注册表权限调整使EvenyOne可写可读
//AllowRegKeyForEveryone
(HKEY_LOCAL_MACHINE,\'system\\currentcontrolset\\enum\');

function AllowRegKeyForEveryone(Key: HKEY; Path: string): Boolean;
var
  WidePath: PWideChar;
  Len: Integer;
begin
  case Key of
    HKEY_LOCAL_MACHINE:
      Path := \'MACHINE\\\' + Path;
    HKEY_CURRENT_USER:
      Path := \'CURRENT_USER\\\' + Path;
    HKEY_CLASSES_ROOT:
      Path := \'CLASSES_ROOT\\\' + Path;
    HKEY_USERS:
      Path := \'USERS\\\' + Path;
  end;
  Len := (Length(Path)+1)*SizeOf(WideChar);
  GetMem(WidePath,Len);
  MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, PChar(Path), -1, WidePath, Len);
  Result := SetNamedSecurityInfoW(PChar(WidePath),SE_REGISTRY_KEY,
    DACL_SECURITY_INFORMATION, nil, nil, nil, nil) = ERROR_SUCCESS;
  FreeMem(WidePath);
end;
dingshine
驱动小牛
驱动小牛
  • 注册日期2002-04-12
  • 最后登录2007-12-24
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
19楼#
发布于:2003-08-30 11:41
看了各位大侠的帖子,感触颇深。我现在在做GPRS MODEM,用了一根USB数据线连接手机,在PC机上虚拟了一个串口,现在软件编写完成,可是MODEM的添加却仍然需要用户手动添加,非常麻烦。我们自己做了一个MODEM的inf文件,不知道怎么在setup过程中就把MODEM添加到USB数据线虚拟的那个串口上去。
驱动,俺不懂,有没有人管啊?
上一页
游客

返回顶部