Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / C++ [игнор отключен] [закрыт для гостей] / А как установить/обновить драйвер для одного конкретного модема? / 9 сообщений из 9, страница 1 из 1
22.05.2014, 13:46
    #38648983
Дмитрий77
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
А как установить/обновить драйвер для одного конкретного модема?
Упрощенно (обработку ошибок опустил) процедура установки "Стандартный модем 14400" такая:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
InstallRootEnumeratedDriver(argv[3], // HardwareID=mdmgen144
	argv[1], // FileName = C:\Windows\inf\mdmgen.inf
	argv[2], // Modem Port =COM25 (AttachedTo)
	&RebootRequired)


BOOL
InstallRootEnumeratedDriver(IN  LPTSTR HardwareId,
    IN  LPTSTR INFFile,
    IN	LPTSTR MdmPort,
    OUT PBOOL  RebootRequired  OPTIONAL
    )
{
    HDEVINFO DeviceInfoSet = 0;
    SP_DEVINFO_DATA DeviceInfoData;
    GUID	ClassGUID;
    TCHAR	ClassName[MAX_CLASS_NAME_LEN];
     
    // Use the INF File to extract the Class GUID. 
    SetupDiGetINFClass(INFFile,&ClassGUID,ClassName,sizeof(ClassName),0)
    // Create the container for the to-be-created Device Information Element.
    DeviceInfoSet = SetupDiCreateDeviceInfoList(&ClassGUID,0);
    // Now create the element. 
    // Use the Class GUID and Name from the INF file.
    DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
    SetupDiCreateDeviceInfo(DeviceInfoSet,
			ClassName,
			&ClassGUID,
			NULL,
			0,
			DICD_GENERATE_ID,
			&DeviceInfoData)
     // Add the HardwareID to the Device's HardwareID property.
     SetupDiSetDeviceRegistryProperty(DeviceInfoSet,
			&DeviceInfoData,
			SPDRP_HARDWAREID,
			(LPBYTE)HardwareId,
			(lstrlen(HardwareId)+1+1)*sizeof(TCHAR))
     RegisterModem(DeviceInfoSet, &DeviceInfoData, MdmPort)
....
BOOL
RegisterModem(
    IN  HDEVINFO          hdi,
    IN  PSP_DEVINFO_DATA  pdevData,
    IN  LPCTSTR           pszPort)
{
...
  SetupDiRegisterDeviceInfo(hdi, pdevData, 0, NULL, NULL, NULL);
  hKeyDev = SetupDiCreateDevRegKey(hdi, pdevData, DICS_FLAG_GLOBAL, 0, DIREG_DRV, NULL, NULL);
  RegSetValueEx (hKeyDev, c_szAttachedTo, 0, REG_SZ,
		(PBYTE)pszPort, (lstrlen(pszPort)+1)*sizeof(TCHAR));
  SetupDiRegisterDeviceInfo(hdi, pdevData, 0, NULL, NULL, NULL) 
...


Код этот рабочий.
После выполнения кода в диспетчере устройств появляется
Модемы -> Неизвестное Устройство
Код экземпляра устройства = ROOT\MODEM\0003 (например)
Коды (ID) оборудования =mdmgen144

Но драйвер еще не установлен.
Чтобы его установить есть следующие варианты:

1)
Код: plaintext
1.
2.
3.
4.
5.
     if (!UpdateDriverForPlugAndPlayDevices(0, // No Window Handle
            argv[3], // Hardware ID=mdmgen144
            argv[1], // FileName=C:\Windows\inf\mdmgen.inf
            INSTALLFLAG_FORCE,
            &RebootRequired))


2) эквивалент
Код: plaintext
1.
devcon update C:\Windows\inf\mdmgen.inf mdmgen144


3) Ручками выбрать в диспетчере устройств "обновить драйвер".

3-й вариант обновляет драйвер ТОЛЬКО ДЛЯ ROOT\MODEM\0003
Первые два - для всех девайсов с Hardware ID=mdmgen144

Мне естественно нужен программный вариант (первые два).

Но есть проблема. UpdateDriverForPlugAndPlayDevices обновляет все девайсы вида mdmgen144, а не только вновь установленный ROOT\MODEM\0003.

Т.е. если я устанавливаю 10 модемов, то я их быстро устанавливаю кодом выше, а затем ставлю драйвера через UpdateDriverForPlugAndPlayDevices. Здесь все хорошо.
А если у меня УЖЕ УСТАНОВЛЕНО 50 штук, а я хочу добавить 51-й, то UpdateDriverForPlugAndPlayDevices будет молотить по всем 51 модему, что естественно =ВРЕМЯ и не есть хорошо.

Вопрос: как установить драйвер для одного конкретного ROOT\MODEM\0003 без молотильни по всем установленным mdmgen144?

Я искал в msdn, не нашел.

Пробовал после RegisterModem вставлять InstallSelectedDriver function , выдает ошибку.
Пробовал смотреть на DiInstallDevice/DiInstallDriver но эти ф-ции для Висты и выше, а хотелось бы чтоб на XP работало.

Т.е. мне как-то надо программно реализовать "3-й вариант".

И кстати вопрос. Как без залезания в реестр указать "AttachedTo" (на какой COM порт сажать модем). Потому что как это делает код выше
RegSetValueEx (hKeyDev, c_szAttachedTo
- это "трюк".
...
Рейтинг: 0 / 0
22.05.2014, 14:05
    #38649035
Дмитрий77
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
А как установить/обновить драйвер для одного конкретного модема?
Оригинальный код некогда взят отсюда:
Программным способом установки драйверов для модема не PNP в системе Windows 2000

Надо сказать, что оригинальный код - это вообще задница при использовании в лоб.
Потому что там UpdateDriverForPlugAndPlayDevices вызывается после установки КАЖДОГО модема (если не дважды).
Т.е. если буквально устанавливать 10 модемов, вызывая это приложение 10 раз
То
при установке 2-го будут обновляться 1-й и 2-й
при установке 3-го будут обновляться 1-й, 2-й и 3-й
...
при установке 10-го будут обновляться 1-й, 2-й,... 9-й и 10-й

Понятно что это превращается в пытку для компьютера и пользователя.
Поэтому я по крайней мере выкинул UpdateDriverForPlugAndPlayDevices из основного кода
и запускаю эту команду отдельно в конце один раз.

Но это все равно не решает проблемы с ДОустановкой единственного 11-го модема (когда первые 10 уже установлены).
UpdateDriverForPlugAndPlayDevices будет молотить по всем ранее установленным.
...
Рейтинг: 0 / 0
23.05.2014, 04:30
    #38649713
Дмитрий77
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
А как установить/обновить драйвер для одного конкретного модема?
Дмитрий77Пробовал после RegisterModem вставлять InstallSelectedDriver function , выдает ошибку.
Плохо пробовал. Именно ее и надо использовать (если драйвер уже установлен в системе). Только эту кухню надо готовить.
А UpdateDriverForPlugAndPlayDevices -ей можно страховаться на случай отсутствия установленного драйвера:

Вот такая концовка должна быть:

Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
  ' Install the Driver
  ' http://support.microsoft.com/kb/889763/ru
  ' первая попытка (InstallSelectedDriver) - устанавливаем драйвер только для данного девайса
  ' в расчете на то что сам драйвер уже установлен в системе
  
  ' InstallSelectedDriver works on the selected device and on the
  ' selected driver on that device. Therefore, set this device as the
  ' selected one in the device information list.
  bResult = SetupDiSetSelectedDevice(hDeviceInfoSet, m_DeviceInfoData)
  If bResult = False Then
    Debug.Print "SetupDiSetSelectedDevice Error " & RaiseAPIErrorByNumber(Err.LastDllError)
    GoTo ForceInstall
  End If
  
  ' Build up a Driver Information List.
  ' Build a compatible driver list, meaning only include the
  ' driver nodes that match one of the hardware or compatible Ids of
  ' the device.
  bResult = SetupDiBuildDriverInfoList(hDeviceInfoSet, m_DeviceInfoData, SPDIT_COMPATDRIVER)
  If bResult = False Then
    Debug.Print "SetupDiBuildDriverInfoList Error " & RaiseAPIErrorByNumber(Err.LastDllError)
    GoTo ForceInstall
  End If
  
  ' Pick the best driver in the list of drivers that was built.
  bResult = SetupDiCallClassInstaller(DIF_SELECTBESTCOMPATDRV, hDeviceInfoSet, m_DeviceInfoData)
  If bResult = False Then
    Debug.Print "SetupDiCallClassInstaller Error " & RaiseAPIErrorByNumber(Err.LastDllError)
    GoTo ForceInstall
  End If
  
  ' Get the selected driver node.
  ' Note: If this list does not contain any drivers, this call
  ' will fail with ERROR_NO_DRIVER_SELECTED.
  m_DriverInfoData.cbSize = LenB(m_DriverInfoData)
  bResult = SetupDiGetSelectedDriver(hDeviceInfoSet, m_DeviceInfoData, m_DriverInfoData)
  If bResult = False Then
    Debug.Print "SetupDiGetSelectedDriver Error " & RaiseAPIErrorByNumber(Err.LastDllError)
    GoTo ForceInstall
  End If
  
  Dim dwRebootRequired As Long
  bResult = InstallSelectedDriver(0, hDeviceInfoSet, 0&, 0&, dwRebootRequired)
  If bResult = False Then
    Debug.Print "InstallSelectedDriver Error " & RaiseAPIErrorByNumber(Err.LastDllError)
    GoTo ForceInstall
  Else
    If dwRebootRequired = DI_NEEDREBOOT Then RebootRequired = True
    InstallModem = True
    Debug.Print "InstallSelectedDriver OK."
    GoTo Cleanup
  End If
    
ForceInstall:
  'если драйвер еще не установлен (например при первой установке такого девайса)
  'то используем UpdateDriverForPlugAndPlayDevices с явным указанием INF-файла
  'избегаем использовать этот метод, т.к. он обновляет драйвера для всех
  'ранее установленных девайсов с таким же Hardware_ID, в чем нет необходимости
  bResult = UpdateDriverForPlugAndPlayDevices(0&, Hardware_ID, INF_File, _
   INSTALLFLAG_FORCE, RebootRequired)
  If bResult = False Then
    Debug.Print "UpdateDriverForPlugAndPlayDevices Error " & RaiseAPIErrorByNumber(Err.LastDllError)
    bRemove = True
    GoTo Cleanup
  Else
    InstallModem = True
    Debug.Print "UpdateDriverForPlugAndPlayDevices OK."
    GoTo Cleanup
  End If



Полный код здесь:
Возможно ли программно установить модем?

Хотя подозреваю что придется таки допиливать C++. VB6 под x64 не бывает, а на x64 нужен objfre_wnet_amd64.
...
Рейтинг: 0 / 0
26.05.2014, 13:31
    #38651998
Дмитрий77
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
А как установить/обновить драйвер для одного конкретного модема?
Дмитрий77А UpdateDriverForPlugAndPlayDevices -ей можно страховаться на случай отсутствия установленного драйвера:
В принципе UpdateDriverForPlugAndPlayDevices вообще не нужна.
Конкретный INF у меня все равно везде фигурирует, поэтому правильнее
задать INF явно через DeviceInstallParams As SP_DEVINSTALL_PARAMS и DI_ENUMSINGLEINF.
Просто на VB6 я немного запутался со структурами и не сумел задать DeviceInstallParams.DriverPath, поэтому пошел напролом, рассчитывая на уже имеющийся в системе SPDIT_COMPATDRIVER и подстраховываясь через UpdateDriverForPlugAndPlayDevices на случай отсутствия. Но сейчас уже все получилось и сделал "четкую" процедуру.
Теперь имеем "Установка только из указанного INF" (неважно, установлен ли уже подходящий драйвер в системе или еще нет).
Т.е. у меня теперь всегда работает InstallSelectedDriver (строго заданный драйвер на строго заданный девайс).

Вот собственно допиленная концовка кода (на C++):
Но что интересно. Говорят в C++ проще. Однако в VB6 InstallSelectedDriver достаточно задекларировать со ссылкой на newdev.dll.
А в C++ надо городить огород с *PINSTALLSELECTEDDRIVER и GetProcAddress, чтобы эту ф-цию достать, потому что ее типа почему-то не добавили в h-файлы.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
192.
193.
//
// The following is the prototype for the newdev!InstallSelectedDriver API.
//
typedef
BOOL
(*PINSTALLSELECTEDDRIVER)(
  HWND hwndParent,
  HDEVINFO DeviceInfoSet,
  LPCWSTR Reserved,
  BOOL Backup,
  PDWORD pReboot    
  );

...

    TCHAR NewDevPath[MAX_PATH];
    HMODULE hNewDev = NULL;
    PINSTALLSELECTEDDRIVER pInstallSelectedDriver = NULL;
    DWORD dwRebootRequired;

...
		//
		// Install the Driver.
		//

    // http://support.microsoft.com/kb/889763/ru
    // первая попытка (InstallSelectedDriver) - устанавливаем драйвер только для данного девайса
    // в DeviceInstallParams указываем устанавливать драйвер строго из заданного INF

    // InstallSelectedDriver works on the selected device and on the
    // selected driver on that device. Therefore, set this device as the
    // selected one in the device information list.
    if (!SetupDiSetSelectedDevice(DeviceInfoSet, &DeviceInfoData))
    {
      DisplayError(_T("SetupDiSetSelectedDevice"));
      goto ForceInstall;
    }

    //=====================================
    // You now have a SP_DEVINFO_DATA structure
    // representing your device.  Next, get a SP_DRVINFO_DATA
    // structure to install on that device.
    DeviceInstallParams.cbSize = sizeof(DeviceInstallParams);
    if (!SetupDiGetDeviceInstallParams(DeviceInfoSet,
                                       &DeviceInfoData,
                                       &DeviceInstallParams)) {
      DisplayError(_T("SetupDiGetDeviceInstallParams"));
      goto ForceInstall;
    }

    // Only build the driver list out of the passed-in INF.  
    // To do this, set the DI_ENUMSINGLEINF flag, and copy the
    // full path of the INF into the DriverPath field of the 
    // DeviceInstallParams structure.
    DeviceInstallParams.Flags |= DI_ENUMSINGLEINF;
    if (FAILED(StringCchCopy(DeviceInstallParams.DriverPath,
                             SIZECHARS(DeviceInstallParams.DriverPath),
                             INFFile))) {
      // The file path that was passed in was too big.
      SetLastError(ERROR_INVALID_PARAMETER);
      DisplayError(_T("StringCchCopy"));
      goto ForceInstall;
    }

    // Set the DI_FLAGSEX_ALLOWEXCLUDEDDRVS flag so that you can use
    // this INF even if it is marked as ExcludeFromSelect.
    // ExcludeFromSelect means do not show the INF in the legacy Add   
    // Hardware Wizard.
    DeviceInstallParams.FlagsEx |= DI_FLAGSEX_ALLOWEXCLUDEDDRVS;
    if (!SetupDiSetDeviceInstallParams(DeviceInfoSet,
                                       &DeviceInfoData,
                                       &DeviceInstallParams)) {
      DisplayError(_T("SetupDiSetDeviceInstallParams"));
      goto ForceInstall;
    }
    //=====================================

    // Build up a Driver Information List.
    // Build a compatible driver list, meaning only include the
    // driver nodes that match one of the hardware or compatible Ids of
    // the device.
    if (!SetupDiBuildDriverInfoList(DeviceInfoSet,
                                    &DeviceInfoData,
                                    SPDIT_COMPATDRIVER)) {
      DisplayError(_T("SetupDiBuildDriverInfoList"));
      goto ForceInstall;
    }

    // Pick the best driver in the list of drivers that was built.
    if (!SetupDiCallClassInstaller(DIF_SELECTBESTCOMPATDRV,
                                   DeviceInfoSet,
                                   &DeviceInfoData)) {
      DisplayError(_T("SetupDiCallClassInstaller"));
      goto ForceInstall;
    }
  
    // Get the selected driver node.
    // Note: If this list does not contain any drivers, this call
    // will fail with ERROR_NO_DRIVER_SELECTED.
    DriverInfoData.cbSize = sizeof(DriverInfoData);
    if (!SetupDiGetSelectedDriver(DeviceInfoSet,
                                  &DeviceInfoData,
                                  &DriverInfoData)) {
      DisplayError(_T("SetupDiGetSelectedDriver"));
      goto ForceInstall;
    }

    // At this point, you have a valid SP_DEVINFO_DATA structure and a
    // valid SP_DRVINFO_DATA structure.
    // Load newdev.dll, GetProcAddress(InstallSelectedDriver), and call     
    // that API.
    //
    // To be more secure, make sure to load the newdev.dll file from the
    // system 32 directory.
    if (GetSystemDirectory(NewDevPath, SIZECHARS(NewDevPath)) == 0) {
      DisplayError(_T("GetSystemDirectory"));
      goto ForceInstall;
    }

    if (FAILED(StringCchCat(NewDevPath, SIZECHARS(NewDevPath), TEXT("\\NEWDEV.DLL")))) {
      SetLastError(ERROR_INSUFFICIENT_BUFFER);
      DisplayError(_T("StringCchCat"));
      goto ForceInstall;
    }

    hNewDev = LoadLibrary(NewDevPath);
    if (!hNewDev) {
      DisplayError(_T("LoadLibrary"));
      goto ForceInstall;
    }

    pInstallSelectedDriver = (PINSTALLSELECTEDDRIVER)GetProcAddress(hNewDev, "InstallSelectedDriver");
    if (!pInstallSelectedDriver) {
      DisplayError(_T("GetProcAddress"));
      goto ForceInstall;
    }

    // Call pInstallSelectedDriver to install the selected driver on
    // the selected device.
    if (!pInstallSelectedDriver(NULL,
                           DeviceInfoSet,
                           NULL,
                           FALSE,
                           &dwRebootRequired)) {
      DisplayError(_T("InstallSelectedDriver"));
      goto ForceInstall;
    } else {
      if (dwRebootRequired & (DI_NEEDREBOOT | DI_NEEDRESTART)) {
        // A reboot is required.
        * RebootRequired = TRUE;
      }
			break;
    }

ForceInstall:
    //по сути этот код не нужен
    //используем UpdateDriverForPlugAndPlayDevices с явным указанием INF-файла
    //избегаем использовать этот метод, т.к. он обновляет драйвера для всех
    //ранее установленных девайсов с таким же Hardware_ID, в чем нет необходимости
    //чисто для подстраховки, раз уж сделано
		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.
    //    
    if (hNewDev) {
      FreeLibrary(hNewDev);
      hNewDev = NULL;
    }
...
...
Рейтинг: 0 / 0
05.06.2014, 20:19
    #38662954
Дмитрий77
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
А как установить/обновить драйвер для одного конкретного модема?
Дмитрий77maytonДмитрий77,
Если по делу, вроде как с модемами все получилось. Единственное, что бесит - "AttachedTo" приходится доставать "ручками из реестра"-ничего умнее не нашел/не придумал (хотя это вполне надежно).
Думаю что всё ОК. Другого источника информации ты не найдёшь.
WMI скорее всего является просто интерфейсом к тому-же реестру.
Понимаешь, когда я читаю название порта:
Код: vbnet
1.
2.
3.
4.
        hKeyDev = SetupDiOpenDevRegKey(hDeviceInfoSet, m_DeviceInfoData, _
         DICS_FLAG_GLOBAL, 0&, DIREG_DRV, KEY_QUERY_VALUE)
...
        strAttachedTo = GetRegValue(hKeyDev, "", "AttachedTo", "", False)


-это еще более менее прилично выглядит.

А когда я назначаю название порта в процессе установки нового модема,
16072864
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
  hKeyDev = SetupDiOpenDevRegKey(hDeviceInfoSet, m_DeviceInfoData, _
   DICS_FLAG_GLOBAL, 0&, DIREG_DRV, KEY_ALL_ACCESS)
  If (hKeyDev = INVALID_HANDLE_VALUE) Then 'This call fails....
    hKeyDev = SetupDiCreateDevRegKey(hDeviceInfoSet, m_DeviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DRV, 0, vbNullString)
...
    End If
  End If
  dwRet = RegSetValueEx(hKeyDev, "AttachedTo", 0&, REG_SZ, COM_Port, CLng(Len(COM_Port) + 1))
...


то попахивает какой-то подтасовкой.
Смотри, SetupDiOpenDevRegKey всегда ошибается (драйвер пока не установлен и ветка реестра на этот момент отсутствует - я проверял, останавливая код через MsgBox-ы),
поэтому я создаю пустую ветку SetupDiCreateDevRegKey и бухаю туда в лоб единственный параметр "AttachedTo", все остальное дописывается туда позже - при установке драйвера.

Если я не допишу "AttachedTo", т.е. не пропишу его в реестр и установлю драйвер модема, то модем установится, но в "AttachedTo" будет "набор китайских иероглифов". То бишь он эти иероглифы из какого-то элемента какой-то структуры (который не проинициализирован и поэтому там мусор) откуда-то берет.
Опять же, эта билиберда (с дописыванием"AttachedTo" извините через задницу) надежно работает, и в оригинальном примере "с Microsoft", 16055031 , автор использует именно этот кривой на мой взгляд метод.
Я довольно много искал поиском по инету, не я первый задаю этот вопрос, но все кто задавали ответа не нашли.
Кучу всего перерыл, перелопатил SetupDi... , глядел в PnP Configuration Manager Functions уже дорвался до RegisterDeviceNotification function . Не нашел, не то чтоб без этого никак, но бесит уже просто. COM порт, на котором висит модем - довольно важное понятие для любого модема и должен быть способ назначить его без ковыряния реестра (хотя бы при установке).
Здесь еще конечно такой момент. Я устанавливаю модем в слепую (т.е. могу даже без проверки наличия порта COM# который бухаю в AttachedTo -могу установить на несуществующий порт). Т.е. я не использую PnP.

Но есть другой пример. Если брать родное приложение t38modem Вячеслава Фролова, вешать его на виртуальную пару com0com , причем com0com порты назначать в классе "Порты" (есть там такая возможность), то при запуске t38modem модем детектится через PnP и авто-устанавливается причем как-то же авто-приаттачивается на тот порт на котором обнаружился.
PnP метод в этом примере мне не нравится, т.к. он глючноватый с учетом виртуальности модема и портов,
поэтому предпочитаю вешать драйвера модемов на порты "ручками" как описано (автоматическая, но слепая процедура установки драйвера модема на заданный COM# без проверки существования COM#).
Давно с этим PnP ковырялся, но думаю смогу воспроизвести, только дальше то куда копать.


Есть еще идеи куда копать? Как модему грамотно порт подсунуть?
Идея в том, что при PnP-обнаружении COM# думаю автоматом запихивается в какую-то структуру.
При ручной установке SetupDi.. кодом здесь приведенным это COM#(AttachedTo) место в структуре остается незаполненным и там находится "мусор".
Что за место? Как запихнуть туда COM#?
...
Рейтинг: 0 / 0
06.06.2014, 11:51
    #38663382
Basil A. Sidorov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
А как установить/обновить драйвер для одного конкретного модема?
"Драйвер модема" - текстовый файл, в который записаны строки инициализации, запросов и откликов.
Если программа полагается на данные из этого файла - "драйвер" модема нужен.
Если она и "сама с усама" - достаточно имени COM-порта.
...
Рейтинг: 0 / 0
06.06.2014, 16:23
    #38663861
Дмитрий77
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
А как установить/обновить драйвер для одного конкретного модема?
Basil A. SidorovЕсли она и "сама с усама" - достаточно имени COM-порта.
Это все понятно.
Но драйвер модема иногда необходим как "переходник".
Microsoft Fax например не умеет работать с COM#, а видит только "модемы".

Давайте еще раз четко сформулирую вопрос с приложением исходников и exe-шников (см. вложение).

Для того чтобы установить "стандартный модем 14400" (HardwareID=mdmgen144 описан в стандартном файле mdmgen.inf из поставки Win) на порт COM35 (наличие порта не обязательно), выполняется команда:

Код: plaintext
1.
mdminst.exe c:\windows\inf\mdmgen COM35 mdmgen144


(не мусорит, новоустановленный модем можно удалить из диспетчера устройств или панели управления кнопкой <удалить>, так что пробовать кто хочет - безопасно)

Мне не нравится "код через Ж", который назначает этот COM35, конкретно:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
	TCHAR const c_szAttachedTo[] = _T("AttachedTo");
...
	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);



Т.е. код тупо пишет COM35 в
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\{4D36E96D-E325-11CE-BFC1-08002BE10318}\XXXX
причем hKey на момент вызова кода еще не записана (SetupDiOpenDevRegKey //// This call fails....),
код мухлюет, он заранее создает этот hkey(SetupDiCreateDevRegKey) и бабахает туда AttachedTo="COM35".

Я думаю так.
На момент подготовки установки модема у нас есть
hdi -A handle to the device information set that contains a device information element that represents the device
pdevData -A pointer to an SP_DEVINFO_DATA structure that specifies the device information element in DeviceInfoSet
причем в этих структурах уже прописано, что новый девайс у нас ClassGUID=<"Modem">,

Т.е. я считаю что должен быть способ запихнуть туда COM35 (культурным методом)
т.е. в device information set(набор модемов) + SP_DEVINFO_DATA(конкретный модем, установить который нам предстоит)

А в реестр оно пропишет COM35 само (при выполнении pInstallSelectedDriver, когда ветка туда и пишется).
Я хочу сказать, что должна быть какая-то modem-specific структура привязанная к SP_DEVINFO_DATA
видимо копать в сторону
pdevData.DevInst -An opaque handle to the device instance (also known as a handle to the devnode)
-куда и можно "присунуть" наш COM35 на момент подготовки к установке.
...
Рейтинг: 0 / 0
06.06.2014, 17:07
    #38663937
Дмитрий77
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
А как установить/обновить драйвер для одного конкретного модема?
По сути надо раскручивать pdevData.DevInst (devnode), там эти структуры и сидят. Но не вижу я никаких документаций на эту тему. И это точно выходит за рамки SetupDi...
...
Рейтинг: 0 / 0
08.06.2014, 20:18
    #38664732
Дмитрий77
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
А как установить/обновить драйвер для одного конкретного модема?
IoGetDeviceObjectPointer routine ?
И рыться в DEVICE_OBJECT structure ?
Не ??? Горячо? Холодно?

На VB6 (чего я обычно пытаюсь первым делом) не осилил. Я даже догадался что надо декларировать Lib "Ntoskrnl.exe" (обычно dll), но в таком виде
Код: vbnet
1.
2.
3.
Public Declare Function IoGetDeviceObjectPointer Lib "Ntoskrnl.exe" _
 (ByVal ObjectName As String, ByVal DesiredAccess As Long, _
 ByRef pFileObject As Long, ByRef pDeviceObject As Long) As Long


ничего кроме краша не получаю (хотя ф-цию Dll Entry он находит).
Видимо p as Long здесь не прокатит, и надо декларировать структуры и передавать ByRef. Но там черт ногу свернет.

На C++ через DDK пробовать? Скажем используя шаблон modem.zip что выше.
Пример использования IoGetDeviceObjectPointer нашел:
Simple LoopBack Filter Driver

Только вот туда ли копаю? Разбираться в этих вещах тяжело, а ну как опять промажу мимо. Где гарантия что это не очередная оболочка типа SetupDi... или CM_...?
...
Рейтинг: 0 / 0
Форумы / C++ [игнор отключен] [закрыт для гостей] / А как установить/обновить драйвер для одного конкретного модема? / 9 сообщений из 9, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]