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

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

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

最新喜欢:

kb219kb219
lijianjun714
驱动小牛
驱动小牛
  • 注册日期2006-08-24
  • 最后登录2009-09-24
  • 粉丝0
  • 关注0
  • 积分23分
  • 威望349点
  • 贡献值0点
  • 好评度162点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2008-11-24 18:04
可否提供INF文件看看, 谢谢!
lishu2002
驱动牛犊
驱动牛犊
  • 注册日期2005-09-02
  • 最后登录2011-08-14
  • 粉丝2
  • 关注0
  • 积分32分
  • 威望165点
  • 贡献值0点
  • 好评度6点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2008-10-13 15:45
不知道搂主能不能看到,你那个RegQueryDeviceProperty里面调用的什么函数呢,MSDN中没有RegQueryDeviceProperty呢
smith02
驱动牛犊
驱动牛犊
  • 注册日期2002-11-11
  • 最后登录2005-10-21
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地板#
发布于:2005-03-04 11:13
[quote]

我的也是CDMA Modem啊,//hand,呵呵。0xe0000206是指不合法的
类。怎么你的机子连Modem的类都没有。自己用写注册表方法手工添加应该也行的。不过我想不会的,是不是你的DEFINE_GUID写错了?coinstall不是很复杂的东西,msdn就有,不过e文是肯定的了。EricGaoxp的代码就可以不使用coinstaller了,一直没考虑过SetupDiCreateDevRegKey这个函数,原来有这个妙用。


请问Error Code: 0xe0000206是指不合法的, 还有0xe0000203是没有选择驱动
这些ErrorCode的注解在哪里可以找到啊?我在MSDN里怎么没发现呢?多谢多谢 [/quote]

各位大虾还在吗?帮帮我啊
smith02
驱动牛犊
驱动牛犊
  • 注册日期2002-11-11
  • 最后登录2005-10-21
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2005-03-02 14:28


我的也是CDMA Modem啊,//hand,呵呵。0xe0000206是指不合法的
类。怎么你的机子连Modem的类都没有。自己用写注册表方法手工添加应该也行的。不过我想不会的,是不是你的DEFINE_GUID写错了?coinstall不是很复杂的东西,msdn就有,不过e文是肯定的了。EricGaoxp的代码就可以不使用coinstaller了,一直没考虑过SetupDiCreateDevRegKey这个函数,原来有这个妙用。


请问Error Code: 0xe0000206是指不合法的, 还有0xe0000203是没有选择驱动
这些ErrorCode的注解在哪里可以找到啊?我在MSDN里怎么没发现呢?多谢多谢
eaglewzhy
驱动牛犊
驱动牛犊
  • 注册日期2004-01-06
  • 最后登录2005-06-30
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2005-01-26 15:54
我在2000下试了gzytom的Co-Installer程序,inf中增加了以下几行,自己重新创建了一个win32动态库FlyingCard.dll,库中定义了一个回调函数ModemCoInstallProc,当主程序运行到SetupDiRegisterCoDeviceInstallers(hdi , &hDev) 时候,会提示指定动态库FlyingCard.dll的位置,当调用
SetupDiCallClassInstaller(DIF_INSTALLDEVICE , hdi , &hDev)时候,一直没调用期望出现的ModemCoInstallProc回调,所以就没有达到gzytom叙述中的给AttachTo设置值,不知道是什么原因?我是刚看这一块东东,望各位指教

[DestinationDirs]
ModemCopyFilesSection = 11

[Modem.NT.CoInstallers]  
CopyFiles = ModemCopyFilesSection
AddReg = Modem.NT.CoInstallers_AddReg

[ModemCopyFilesSection]
FlyingCard.dll
 
[Modem.NT.CoInstallers_AddReg]
HKR,,CoInstallers32,0x00010000,"FlyingCard.dll, ModemCoInstallProc"


[编辑 -  1/26/05 by  eaglewzhy]
smalldou
驱动牛犊
驱动牛犊
  • 注册日期2004-05-14
  • 最后登录2005-04-01
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2004-05-21 16:55

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

[编辑 -  8/22/03 by  gzytom]


我试了试gzytom的程序,在win2k上没有问题。在win98上执行的时候,到SetupDiCreateDeviceInfo(hdi , szClassName, lpGUID , lpszDescription, NULL , DICD_GENERATE_ID , &hDev)
一句就会报错,错误号为:0x0000000d,看了帮助说这是“数据错误”,我的hdi是前面函数得到的句柄,szClassName是“Modem”,lpGUID 是GUID const CLASS_GUID = {0x4D36E96DL, 0xe325, 0x11ce, {0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18}};
符值过来的,hDev是SP_DEVINFO_DATA结构,初始化为0的。。。。实在是看不出来哪里错了呀:(
请各位给支个招行不??
谢谢了
jinwutong
驱动牛犊
驱动牛犊
  • 注册日期2003-11-17
  • 最后登录2004-02-11
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2003-12-02 11:30
现在安装MODEM什么都成功了 想卸载这个MODEM,怎么做?大虾帮忙了!
dingshine
驱动小牛
驱动小牛
  • 注册日期2002-04-12
  • 最后登录2007-12-24
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2003-08-30 11:41
看了各位大侠的帖子,感触颇深。我现在在做GPRS MODEM,用了一根USB数据线连接手机,在PC机上虚拟了一个串口,现在软件编写完成,可是MODEM的添加却仍然需要用户手动添加,非常麻烦。我们自己做了一个MODEM的inf文件,不知道怎么在setup过程中就把MODEM添加到USB数据线虚拟的那个串口上去。
驱动,俺不懂,有没有人管啊?
MDK
MDK
驱动牛犊
驱动牛犊
  • 注册日期2002-05-20
  • 最后登录2004-02-19
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
9楼#
发布于: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;
gzytom
驱动牛犊
驱动牛犊
  • 注册日期2003-02-09
  • 最后登录2003-08-26
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
10楼#
发布于: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分
11楼#
发布于: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分
12楼#
发布于: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分
13楼#
发布于: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你的代码我试一试再说。
EricGaoxp
驱动牛犊
驱动牛犊
  • 注册日期2002-11-01
  • 最后登录2016-01-07
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
14楼#
发布于: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下运行!
从头再来!越过一路风景,无悔!
gzytom
驱动牛犊
驱动牛犊
  • 注册日期2003-02-09
  • 最后登录2003-08-26
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
15楼#
发布于:2003-08-25 20:40
十分感谢你的回信。
GUID_MODEM是指Modem的Guid还是你的MODEM的GUID呢?
另外安装的这个MODEM是内MODEM还是虚拟MODEM


Modem得GUID。虚拟Modem。
MDK
MDK
驱动牛犊
驱动牛犊
  • 注册日期2002-05-20
  • 最后登录2004-02-19
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
16楼#
发布于: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分
17楼#
发布于: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分
18楼#
发布于: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分
19楼#
发布于:2003-08-22 12:24
我也想解决这样的问题,请问如何将CoInstaller如何将你的回调结合在一起了,没玩过CoInstaller,请指点!


看不大懂你的意思:(。CoInstaller是有系统调用的。在INF文件注册后就可以。不过98不能用,郁闷。
上一页
游客

返回顶部