Возможно ли программно установить модем? - VB

Узнай цену своей работы

Формулировка задачи:

Т.е. без панели управления и без запуска "мастера".
Конкретно "Стандартный модем 14400"

Решение задачи: «Возможно ли программно установить модем?»

textual
Листинг программы
Option Explicit

Public Type GUID
  Data1 As Long
  Data2 As Integer
  Data3 As Integer
  Data4(7) As Byte
End Type

Public Const ERROR_KEY_DOES_NOT_EXIST = 2
Public Const ERROR_INSUFFICIENT_BUFFER = 122&
Public Const INVALID_HANDLE_VALUE = -1

'Device Installation Structures
Public Type SP_DEVINFO_DATA
  cbSize As Long
  ClassGuid As GUID
  DevInst As Long
  Reserved As Long
End Type

'Flags -Flags that control installation and user interface operations.
Public Const DI_ENUMSINGLEINF = &H10000
'FlagsEx -Additional flags that provide control over installation and user interface operations.
Public Const DI_FLAGSEX_ALLOWEXCLUDEDDRVS = &H800

Public Type SP_DEVINSTALL_PARAMS
  cbSize As Long
  Flags As Long
  FlagsEx As Long
  hWndParent As Long
  InstallMsgHandler As Long 'PSP_FILE_CALLBACK
  InstallMsgHandlerContext As Long 'PVOID
  FileQueue As Long 'HSPFILEQ
  ClassInstallReserved As Long 'ULONG_PTR
  Reserved As Long
  DriverPath(MAX_PATH - 1) As Byte ' A-version
End Type

Public Const LINE_LEN = 256

Public Type SP_DRVINFO_DATA
  cbSize As Long
  DriverType As Long
  Reserved As Long
  Description(LINE_LEN - 1) As Byte ' A-version
  MfgName(LINE_LEN - 1) As Byte ' A-version
  ProviderName(LINE_LEN - 1) As Byte ' A-version
  DriverDate As FILETIME
  DriverVersion(1) As Long 'DWORDLONG -одного Long недостаточно!
End Type

'Public Device Installation Functions

Public Const DI_NEEDREBOOT = &H100
Public Const DI_NEEDRESTART = &H80

Public Declare Function InstallSelectedDriver Lib "newdev.dll" _
 (ByVal hWndParent As Long, ByVal DeviceInfoSet As Long, _
 ByVal Reserved As Long, ByVal Backup As Long, ByRef bReboot As Long) As Boolean

'DriverType - The type of driver list to build.
Public Const SPDIT_COMPATDRIVER = &H2

Public Declare Function SetupDiBuildDriverInfoList Lib "setupapi.dll" _
 (ByVal DeviceInfoSet As Long, _
 ByRef DeviceInfoData As SP_DEVINFO_DATA, _
 ByVal DriverType As Long) As Boolean

'Device Installation Function Codes
Public Const DIF_REMOVE = &H5
Public Const DIF_SELECTBESTCOMPATDRV = &H17

Public Declare Function SetupDiCallClassInstaller Lib "setupapi.dll" _
 (ByVal InstallFunction As Long, _
 ByVal DeviceInfoSet As Long, _
 ByRef DeviceInfoData As SP_DEVINFO_DATA) As Boolean

'CreationFlags - controls how the device information element is created
Public Const DICD_GENERATE_ID = 1

Public Declare Function SetupDiCreateDeviceInfo _
 Lib "setupapi.dll" Alias "SetupDiCreateDeviceInfoA" _
 (ByVal DeviceInfoSet As Long, _
 ByVal DeviceName As String, ByRef ClassGuid As GUID, _
 ByVal DeviceDescription As String, ByVal hWndParent As Long, _
 ByVal CreationFlags As Long, ByRef DeviceInfoData As SP_DEVINFO_DATA) As Boolean
 
Public Declare Function SetupDiCreateDeviceInfoList Lib "setupapi.dll" _
 (ByRef ClassGuid As GUID, Optional ByVal hWndParent As Long) As Long
 
'Scope - where the information is stored. The key created can be global or hardware profile-specific.
Public Const DICS_FLAG_GLOBAL = &H1
'KeyType -The type of registry storage key to create.
Public Const DIREG_DRV = 2

Public Declare Function SetupDiCreateDevRegKey _
 Lib "setupapi.dll" Alias "SetupDiCreateDevRegKeyA" _
 (ByVal DeviceInfoSet As Long, _
 ByRef DeviceInfoData As SP_DEVINFO_DATA, ByVal Scope As Long, _
 ByVal HwProfile As Long, ByVal KeyType As Long, ByVal InfHandle As Long, _
 ByVal InfSectionName As String) As Long
 
Public Declare Function SetupDiDestroyDeviceInfoList Lib "setupapi.dll" _
 (ByVal DeviceInfoSet As Long) As Boolean
Public Declare Function SetupDiGetDeviceInstallParams _
 Lib "setupapi.dll" Alias "SetupDiGetDeviceInstallParamsA" _
 (ByVal DeviceInfoSet As Long, _
 ByRef DeviceInfoData As SP_DEVINFO_DATA, _
 ByRef DeviceInstallParams As SP_DEVINSTALL_PARAMS) As Boolean
Public Declare Function SetupDiGetINFClass Lib "setupapi.dll" Alias "SetupDiGetINFClassA" _
 (ByVal InfName As String, ByRef ClassGuid As GUID, _
 ByVal ClassName As String, ByVal ClassNameSize As Long, _
 Optional ByRef RequiredSize As Long) As Boolean
Public Declare Function SetupDiGetSelectedDriver _
 Lib "setupapi.dll" Alias "SetupDiGetSelectedDriverA" _
 (ByVal DeviceInfoSet As Long, _
 ByRef DeviceInfoData As SP_DEVINFO_DATA, ByRef DriverInfoData As SP_DRVINFO_DATA) As Boolean
Public Declare Function SetupDiOpenDevRegKey Lib "setupapi.dll" _
 (ByVal DeviceInfoSet As Long, _
 ByRef DeviceInfoData As SP_DEVINFO_DATA, ByVal Scope As Long, _
 ByVal HwProfile As Long, ByVal KeyType As Long, ByVal samDesired As Long) As Long
Public Declare Function SetupDiRegisterDeviceInfo Lib "setupapi.dll" _
 (ByVal DeviceInfoSet As Long, _
 ByRef DeviceInfoData As SP_DEVINFO_DATA, ByVal Flags As Long, _
 ByVal CompareProc As Long, ByVal CompareContext As Long, ByRef DupDeviceInfoData As Long) As Boolean 'Optional параметры опускаем
Public Declare Function SetupDiSetDeviceInstallParams _
 Lib "setupapi.dll" Alias "SetupDiSetDeviceInstallParamsA" _
 (ByVal DeviceInfoSet As Long, _
 ByRef DeviceInfoData As SP_DEVINFO_DATA, _
 ByRef DeviceInstallParams As SP_DEVINSTALL_PARAMS) As Boolean
 
'Property - identifies the property to be set
Public Const SPDRP_HARDWAREID = 1 'REG_MULTI_SZ string that contains the list of hardware IDs for a device
 
Public Declare Function SetupDiSetDeviceRegistryProperty _
 Lib "setupapi.dll" Alias "SetupDiSetDeviceRegistryPropertyA" _
 (ByVal DeviceInfoSet As Long, _
 ByRef DeviceInfoData As SP_DEVINFO_DATA, ByVal Property As Long, _
 ByVal PropertyBuffer As Long, ByVal PropertyBufferSize As Long) As Boolean
Public Declare Function SetupDiSetSelectedDevice Lib "setupapi.dll" _
 (ByVal DeviceInfoSet As Long, _
 ByRef DeviceInfoData As SP_DEVINFO_DATA) As Boolean
 
'InstallFlags -A caller-supplied value
Public Const INSTALLFLAG_FORCE = &H1

Public Declare Function UpdateDriverForPlugAndPlayDevices _
 Lib "newdev.dll" Alias "UpdateDriverForPlugAndPlayDevicesA" _
 (ByVal hWndParent As Long, ByVal HardwareId As String, _
 ByVal FullInfPath As String, ByVal InstallFlags As Long, _
 Optional ByRef bRebootRequired As Boolean) As Boolean

Public Function InstallModem(ByVal INF_File As String, _
 ByVal COM_Port As String, ByVal Hardware_ID As String, _
 Optional ByRef RebootRequired As Boolean) As Boolean
  'INF_File -путь к inf-файлу (напр. C:\111\mdmgen.inf)
  'COM_Port -порт, на кот. устанавливаем (напр. COM35)
  'Hardware_ID -напр. mdmgen144
  'RebootRequired-возвращается true если нужна перезагрузка
  
  Dim bResult As Boolean
  Dim m_ClassGUID As GUID
  Dim m_ClassName As String
  Dim ReqSize As Long
  Dim hDeviceInfoSet As Long
  Dim m_DeviceInfoData As SP_DEVINFO_DATA
  Dim bRemove As Boolean
  Dim hKeyDev As Long
  Dim dwRet As Long
  Dim m_DriverInfoData As SP_DRVINFO_DATA
  Dim m_DeviceInstallParams As SP_DEVINSTALL_PARAMS
  
  ' Use the INF File to extract the Class GUID
  bResult = SetupDiGetINFClass(INF_File, m_ClassGUID, m_ClassName, 0, ReqSize)
  If (bResult = False) And (Err.LastDllError = ERROR_INSUFFICIENT_BUFFER) Then
    m_ClassName = String(ReqSize, 0)
    bResult = SetupDiGetINFClass(INF_File, m_ClassGUID, m_ClassName, ReqSize)
    If bResult = False Then
      Debug.Print "SetupDiGetINFClass Error " & RaiseAPIErrorByNumber(Err.LastDllError)
      Exit Function
    Else
      m_ClassName = Left(m_ClassName, InStr(m_ClassName, Chr(0)) - 1)
      Debug.Print "m_ClassName=" & m_ClassName
    End If
  Else
    Debug.Print "SetupDiGetINFClass Error " & RaiseAPIErrorByNumber(Err.LastDllError)
    Exit Function
  End If
  
  ' Create the container for the to-be-created Device Information Element
  hDeviceInfoSet = SetupDiCreateDeviceInfoList(m_ClassGUID)
  If hDeviceInfoSet = INVALID_HANDLE_VALUE Then
    Debug.Print "SetupDiCreateDeviceInfoList Error " & RaiseAPIErrorByNumber(Err.LastDllError)
    Exit Function
  End If
  Debug.Print "hDeviceInfoSet=" & hDeviceInfoSet
  
  ' Now create the element. Use the Class GUID and Name from the INF file.
  m_DeviceInfoData.cbSize = LenB(m_DeviceInfoData)
  bResult = SetupDiCreateDeviceInfo(hDeviceInfoSet, m_ClassName, m_ClassGUID, _
   vbNullString, 0&, DICD_GENERATE_ID, m_DeviceInfoData)
  If bResult = False Then
    Debug.Print "SetupDiCreateDeviceInfo Error " & RaiseAPIErrorByNumber(Err.LastDllError)
    GoTo Cleanup
  End If
  
  ' Add the HardwareID to the Device's HardwareID property.
  bResult = SetupDiSetDeviceRegistryProperty(hDeviceInfoSet, m_DeviceInfoData, SPDRP_HARDWAREID, _
   StrPtr(StrConv(Hardware_ID, vbFromUnicode)), Len(Hardware_ID) + 2)
  If bResult = False Then
    Debug.Print "SetupDiSetDeviceRegistryProperty Error " & RaiseAPIErrorByNumber(Err.LastDllError)
    GoTo Cleanup
  End If
  
  bResult = SetupDiRegisterDeviceInfo(hDeviceInfoSet, m_DeviceInfoData, 0&, 0&, 0&, 0&)
  If bResult = False Then
    Debug.Print "SetupDiRegisterDeviceInfo 1 Error " & RaiseAPIErrorByNumber(Err.LastDllError)
    bRemove = True
    GoTo Cleanup
  End If
  
  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)
    If hKeyDev = INVALID_HANDLE_VALUE Then
      Debug.Print "SetupDiCreateDeviceInfoList Error " & RaiseAPIErrorByNumber(Err.LastDllError)
      bRemove = True
      GoTo Cleanup
    End If
  End If
  Debug.Print "hKeyDev=" & hKeyDev
  
  dwRet = RegSetValueEx(hKeyDev, "AttachedTo", 0&, REG_SZ, COM_Port, CLng(Len(COM_Port) + 1))
  RegCloseKey hKeyDev
  If dwRet <> ERROR_SUCCESS Then
    Debug.Print "RegSetValueEx Error " & RaiseAPIErrorByNumber(dwRet)
    bRemove = True
    GoTo Cleanup
  End If
  
  bResult = SetupDiRegisterDeviceInfo(hDeviceInfoSet, m_DeviceInfoData, 0&, 0&, 0&, 0&)
  If bResult = False Then
    Debug.Print "SetupDiRegisterDeviceInfo 2 Error " & RaiseAPIErrorByNumber(Err.LastDllError)
    bRemove = True
    GoTo Cleanup
  End If
  
  ' Install the Driver
  ' http://support.microsoft.com/kb/889763/ru
  ' первая попытка (InstallSelectedDriver) - устанавливаем драйвер только для данного девайса
  ' в m_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.
  bResult = SetupDiSetSelectedDevice(hDeviceInfoSet, m_DeviceInfoData)
  If bResult = False Then
    Debug.Print "SetupDiSetSelectedDevice Error " & RaiseAPIErrorByNumber(Err.LastDllError)
    GoTo ForceInstall
  End If
  
  '==================================================
  ' You now have a SP_DEVINFO_DATA structure
  ' representing your device.  Next, get a SP_DRVINFO_DATA
  ' structure to install on that device.
  m_DeviceInstallParams.cbSize = LenB(m_DeviceInstallParams)
  bResult = SetupDiGetDeviceInstallParams(hDeviceInfoSet, _
                                       m_DeviceInfoData, _
                                       m_DeviceInstallParams)
  If bResult = False Then
    Debug.Print "SetupDiGetDeviceInstallParams Error " & RaiseAPIErrorByNumber(Err.LastDllError)
    GoTo ForceInstall
  End If

  ' 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.
  m_DeviceInstallParams.Flags = m_DeviceInstallParams.Flags Or DI_ENUMSINGLEINF
  Dim i As Long
  For i = 0 To Len(INF_File) - 1
    m_DeviceInstallParams.DriverPath(i) = Asc(Mid(INF_File, i + 1, 1))
  Next i
  
  ' 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.
  m_DeviceInstallParams.FlagsEx = m_DeviceInstallParams.FlagsEx Or DI_FLAGSEX_ALLOWEXCLUDEDDRVS
  bResult = SetupDiSetDeviceInstallParams(hDeviceInfoSet, _
                                       m_DeviceInfoData, _
                                       m_DeviceInstallParams)
  If bResult = False Then
    Debug.Print "SetupDiSetDeviceInstallParams 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) Or (dwRebootRequired = DI_NEEDRESTART) 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
    
Cleanup:
  If bRemove Then
    ' Delete Device Instance that was registered using SetupDiRegisterDeviceInfo
    ' May through an error if Device not registered -- who cares??
    SetupDiCallClassInstaller DIF_REMOVE, hDeviceInfoSet, m_DeviceInfoData
  End If
  
  SetupDiDestroyDeviceInfoList hDeviceInfoSet
  
End Function

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

7   голосов , оценка 4 из 5
Похожие ответы