Установите Microsoft loopback адаптер программно из VBS (или C # / VB) - PullRequest
3 голосов
/ 17 января 2011

Я бы хотел программно установить петлевой адаптер MS для автоматизации туннелирования SMB через SSH .

Весь код, который я нашел в сети, использует утилиту MS devcon, котораяне подлежит распространению (см. http://support.microsoft.com/kb/311272/en-us). Пример использования (больше примеров):

devcon -r install %WINDIR%\Inf\Netloop.inf *MSLOOP

Помимо проблемы распространяемости, в идеале я хотел бы иметь некоторый контроль над получающимся именем устройства, хотя этоможно исправить перечислением сетевых адаптеров до и после и поиском нового устройства MS loopback. Это немного странно, хотя я думаю, что смогу с этим смириться. Моя идея состоит в том, чтобы адаптировать некоторые из этого кода .

В настоящее время я изучаю исходный код devcon из WDK, чтобы добавить адаптер обратной связи через SetupAPI / CfgMgr32, как показано в статье MS KB, указанной выше. Есть ли какой-нибудь более простой / пригодный для сценариев способ?

Если его нет, есть ли у кого-нибудь сравнительно простой пример кода для этого маршрута SetupAPI / CfgMgr32?

Ответы [ 3 ]

4 голосов
/ 18 октября 2012

Я хотел добиться того же самого, не написав для этого нового exe-файла, и обнаружил, что это можно сделать с помощью cscript и инструментов devcon и netsh. кажется, что создание адаптера не дает никакого контроля над тем, как он будет называться, поэтому вам нужно перечислить его с помощью интерфейса WMI после того, как вы его создали. К сожалению, поведение netsh зависит от того, на какой версии Windows вы работаете, но добавьте следующее в файл с именем create-loopback.vbs, и оно будет работать на серверах XP и 2008.

  Dim strLastLoopbackAdapterName, loopbackAdapterName 

  If wscript.arguments.count < 3 then
    WScript.Echo "usage: create-loopback.vbs loopbackAdapterName loopbackIpAddress loopbackSubNetMask "
    WScript.Quit
  end If
  loopbackAdapterName = wscript.arguments(0)
  loopbackIpAddress = wscript.arguments(1)
  loopbackSubNetMask = wscript.arguments(2)

  Wscript.Echo "Creating loopback called " &loopbackAdapterName &" on " &loopbackIpAddress &" with mask " &loopbackSubNetMask

  Set objShell = CreateObject("WScript.Shell") 
  Wscript.Echo "Installing loopback adapter..."

  objShell.Run "cmd /c devcon install %windir%\inf\netloop.inf *MSLOOP", 0, True 

  Wscript.Echo "Waiting for drivers to update..."
  Wscript.sleep 10000 'Allow 10s for install' 

  strComputer = "."
  Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\CIMV2")
  Set colItems = objWMIService.ExecQuery("SELECT NetConnectionID FROM Win32_NetworkAdapter WHERE Name='Microsoft Loopback Adapter'", "WQL", 48)
  For Each objItem In colItems
     strLastLoopbackAdapterName = objItem.NetConnectionID
  Next

  Wscript.Echo "Last Loopback Connection is " & strLastLoopbackAdapterName  

  Wscript.Echo "Renaming new loopback..."
  objShell.Run "netsh interface set interface name = " &Chr(34) &strLastLoopbackAdapterName &Chr(34) &" newname = " &Chr(34) &loopbackAdapterName &Chr(34), 0, True 
  Wscript.Echo "Configuring loopback..."
  objShell.run "netsh interface ip set address name=" &Chr(34) &loopbackAdapterName &Chr(34) &" source=static " &loopbackIpAddress &" " &loopbackSubNetMask, 0, True 
  Wscript.Echo "Done"
  WScript.Quit(0)
2 голосов
/ 26 июня 2016

Надеюсь, я еще не опоздал на вечеринку - это возможно без devcon / vbs (хотя для этого требуется много родных вызовов pinvoke):

Чтобы установить адаптер обратной связи, вызовите следующий методс параметрами "C:\Windows\Inf\netloop.inf", *MSLOOP:

class Devcon
{
    //https://msdn.microsoft.com/en-us/magazine/dd419661.aspx?f=255&MSPPError=-2147217396#id0070035
    [HandleProcessCorruptedStateExceptions]
    static bool InstallDriver(string inf, string hwid)
    {
        StringBuilder className = new StringBuilder(MAX_CLASS_NAME_LEN);
        Guid ClassGUID = Guid.Empty;

        if (!SetupDiGetINFClass(inf, ref ClassGUID, className, MAX_CLASS_NAME_LEN, 0))
            return false;

        IntPtr DeviceInfoSet = SetupDiCreateDeviceInfoList(ref ClassGUID, IntPtr.Zero);
        SP_DEVINFO_DATA DeviceInfoData = new SP_DEVINFO_DATA();
        if (!SetupDiCreateDeviceInfo(DeviceInfoSet, className.ToString(), ref ClassGUID, null, IntPtr.Zero, DICD_GENERATE_ID, DeviceInfoData))
            return false;

        if (!SetupDiSetDeviceRegistryProperty(DeviceInfoSet, DeviceInfoData, SPDRP_HARDWAREID, hwid, hwid.Length))
        {
            SetupDiDestroyDeviceInfoList(DeviceInfoSet);
            return false;
        }

        if (!SetupDiCallClassInstaller(DIF_REGISTERDEVICE, DeviceInfoSet, DeviceInfoData))
        {
            SetupDiDestroyDeviceInfoList(DeviceInfoSet);
            return false;
        }

        // http://stackoverflow.com/questions/11474317/updatedriverforplugandplaydevices-error-is-telling-me-im-not-doing-something
        try
        {
            bool reboot = false;
            if (!UpdateDriverForPlugAndPlayDevices(IntPtr.Zero, hwid, inf, 0, reboot))
            {
                SetupDiCallClassInstaller(DIF_REMOVE, DeviceInfoSet, DeviceInfoData);
                return false;
            }
        }
        catch (AccessViolationException) { }
        return true;
    }

    // Consts
    const int MAX_CLASS_NAME_LEN = 32;
    const int SPDRP_HARDWAREID = 0x00000001;
    const int DICD_GENERATE_ID = 0x00000001;
    const int DIF_REGISTERDEVICE = 0x00000019;
    const int DIF_REMOVE = 0x00000005;

    // Pinvokes
    [DllImport("setupapi.dll", SetLastError = true)]
    static extern bool SetupDiGetINFClass(string infName, ref Guid ClassGuid, [MarshalAs(UnmanagedType.LPStr)] StringBuilder ClassName, int ClassNameSize, int RequiredSize);

    [DllImport("setupapi.dll", SetLastError = true)]
    static extern IntPtr SetupDiCreateDeviceInfoList(ref Guid ClassGuid, IntPtr hwndParent);

    [DllImport("Setupapi.dll", SetLastError = true)]
    static extern bool SetupDiCreateDeviceInfo(IntPtr DeviceInfoSet, String DeviceName, ref Guid ClassGuid, string DeviceDescription, IntPtr hwndParent, Int32 CreationFlags, SP_DEVINFO_DATA DeviceInfoData);

    [DllImport("setupapi.dll", SetLastError = true)]
    static extern bool SetupDiSetDeviceRegistryProperty(IntPtr DeviceInfoSet, SP_DEVINFO_DATA DeviceInfoData, uint Property, string PropertyBuffer, int PropertyBufferSize);

    [DllImport("setupapi.dll", SetLastError = true)]
    static extern bool SetupDiDestroyDeviceInfoList(IntPtr DeviceInfoSet);

    [DllImport("setupapi.dll", SetLastError = true)]
    static extern bool SetupDiCallClassInstaller(UInt32 InstallFunction, IntPtr DeviceInfoSet, SP_DEVINFO_DATA DeviceInfoData);

    [DllImport("newdev.dll", SetLastError = true)]
    static extern bool UpdateDriverForPlugAndPlayDevices(IntPtr hwndParent, string HardwareId, string FullInfPath, int InstallFlags, bool bRebootRequired);

    // Structs
    [StructLayout(LayoutKind.Sequential, Pack = 8)]
    class SP_DEVINFO_DATA
    {
        internal int cbSize = Marshal.SizeOf(typeof(SP_DEVINFO_DATA));
        [MarshalAs(UnmanagedType.Struct)]
        internal Guid classGuid = Guid.Empty; // temp
        internal int devInst = 0; // dumy
        internal long reserved = 0;
    }
}

Вышеописанное будет работать на 64-разрядных ОС.чтобы он работал на x86 OS, измените Pack = 8 на Pack = 1 в SP_DEVINFO_DATA struct

2 голосов
/ 04 февраля 2011

Пожалуйста, проверьте следующую ветку:

Как установить аппаратный драйвер с помощью C на Win32

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...