Поделиться через


Руководство по совместному использованию подключения к Интернету (выпуск за ноябрь 2015 г.)

В этом документе описаны действия по включению общего доступа к подключению к Интернету (ICS) на устройстве под управлением Windows 10 IoT Базовая выпуске за ноябрь 2015 г. Целью является совместное подключение к Интернету между точкой доступа программного обеспечения Wi-Fi (SoftAP) и адаптером Ethernet. Если вы используете юбилейный выпуск Windows 10 IoT Базовая, ознакомьтесь с руководством по совместному использованию подключений к Интернету.

Предварительные требования

  • Устройство под управлением Windows 10 IoT Базовая выпуске за ноябрь 2015 г.
  • Wi-Fi USB-устройство, которое может запускать SoftAP. Сведения о поддерживаемых Wi-Fi USB-устройствах см. в списке совместимости оборудования .
  • Ethernet-подключение с доступом к Интернету.

Настройка

Шаг 1. Сбор сведений о сети

  1. Загрузите устройство с подключенным аппаратным ключом Wi-Fi, подключенным кабелем Ethernet.

  2. Запустите SoftAP с устройства IoT Core.

    По умолчанию предоставленные корпорацией Майкрософт образы запускают приложение для подключения Интернета вещей, которое настраивает SoftAP, если Wi-Fi радио поддерживается и профиль WLAN не добавлен. Чтобы запустить SoftAP, приложения UWP могут использовать API Windows.Devices.WiFiDirect.WiFiDirectAdvertisementPublisher. Исходный код приложения для подключения Интернета вещей может находиться в GitHub IoTOnboarding.

    Запишите SSID сети SoftAP. Он понадобится позже для подключения к устройству IoT Core через Wi-Fi. Для приложения для подключения Интернета вещей SSID будет начинаться с "AJ_SoftAPSsid_" и может быть изменен в файле конфигурации приложения.

  3. Удаленно подключитесь к устройству IoT Core по протоколу SSH.

  4. Сбор сведений о сетях устройств путем поиска индексов и описаний сетевых устройств. Это необходимо для объявления сетей для моста.

    На устройстве запустите печать маршрута и соберите следующие данные:

    • Запишите индекс сети общедоступного интерфейса для Ethernet.
    • Запишите индекс сети интерфейса PRIVATE для SoftAP (например, Microsoft Wi-Fi Direct Virtual Adapter #2).

    Например, SoftAP предоставляется через индекс интерфейса 5, описание адаптера Microsoft Wi-Fi Direct Virtual Adapter #2.

    печать маршрута

    На устройстве выполните команду ipconfig /all и соберите следующие данные:

    • Запись имени сетевого адаптера интерфейса PRIVATE для SoftAP

    Например, при выполнении команды ipconfig /all выполняется поиск определенного адаптера с именем Local Area Connection* 3 с описанием Microsoft Wi-Fi Direct Virtual Adapter #2. Используйте этот метод, чтобы вручную найти имя адаптера из описания, возвращаемого при печати маршрута.

    ipconfig all

Шаг 2. Создание скриптов триггера общего доступа к подключению к Интернету

Чтобы начать совместное использование подключений к Интернету между двумя сетями, необходимо выполнить следующие действия.

  • Настройте разделы реестра, чтобы настроить частные сетевые интерфейсы (SoftAP) и общедоступные сетевые интерфейсы (Ethernet) для моста.
  • Задайте соответствующие правила брандмауэра.
  • Отключает DHCP для частного интерфейса.
  • Задает статический IP-адрес в частном интерфейсе.
  • Запускает службу SharedAccess.
  • Отправляет код команды "129" в службу SharedAccess.

Создание скрипта для автоматизации параметров ICS

Ниже приведен пример скриптов и кода для автоматизации перечисленных выше шагов, которые можно интегрировать в последовательность запуска устройства. Создайте файл скрипта (например , ConfigureICS.cmd) со следующим содержимым:

echo off

set START_OR_STOP=%1
set PUBLIC_INDEX=%2
set PRIVATE_INDEX=%3
set PRIVATE_INTERFACE_NAME=%4

if not defined PRIVATE_INTERFACE_NAME (
  goto usage
)

if "%START_OR_STOP%"=="start" (

  REM Set the public and private interface registry keys
  reg add HKEY_LOCAL_MACHINE\System\SA /f /v private /t REG_DWORD /d %PRIVATE_INDEX%
  reg add HKEY_LOCAL_MACHINE\System\SA /f /v public /t REG_DWORD /d %PUBLIC_INDEX%

  REM Set the firewall rules to allow DHCP to work
  netsh advfirewall firewall add rule name=\"AllowPort67In\" protocol=UDP dir=in localport=67 action=allow
  netsh advfirewall firewall add rule name=\"AllowPort68In\" protocol=UDP dir=in localport=68 action=allow
  netsh advfirewall firewall add rule name=\"AllowPort67Out\" protocol=UDP dir=out localport=67 action=allow
  netsh advfirewall firewall add rule name=\"AllowPort68Out\" protocol=UDP dir=out localport=68 action=allow
  netsh advfirewall firewall add rule name=\"AllowPort53Out\" protocol=UDP dir=out localport=53 action=allow
  netsh advfirewall firewall add rule name=\"AllowPort53In\" protocol=UDP dir=in localport=53 action=allow

  REM Turn off DHCP and set static IP for private interface
  netsh interface ip set address %4 static 192.168.137.1

  REM Start sharing
  call SharedAccessUtility.exe start

) else if "%START_OR_STOP%"=="stop" (

  REM Stop sharing
  call SharedAccessUtility.exe stop

  REM Set the public and private interface registry keys
  reg add HKEY_LOCAL_MACHINE\System\SA /f /v private /t REG_DWORD /d 0
  reg add HKEY_LOCAL_MACHINE\System\SA /f /v public /t REG_DWORD /d 0

  REM Clear the firewall rules
  netsh advfirewall firewall delete rule name="AllowPort67In"
  netsh advfirewall firewall delete rule name="AllowPort68In"
  netsh advfirewall firewall delete rule name="AllowPort67Out"
  netsh advfirewall firewall delete rule name="AllowPort68Out"
  netsh advfirewall firewall delete rule name="AllowPort53Out"
  netsh advfirewall firewall delete rule name="AllowPort53In"

  REM Reenable DHCP for private interface
  netsh interface ip set address %4 dhcp

) else (
  goto usage
)

goto eof

:usage
ECHO USAGE: %0 [start ^| stop] [public interface index] [private interface index] [private interface name]
ECHO e.g. %0 start 1 2 "Ethernet"

:eof

Этот скрипт выполняет все действия, кроме запуска или остановки службы SharedAccess, и не отправляет команду службы. Для этих задач он вызывает SharedAccessUtility.exe, который необходимо создать.

Создание приложения SharedAccessUtility

В Visual Studio с установленными расширениями шаблонов проектов Windows IoT Core создайте проект Visual C++ "Пустое консольное приложение Windows IoT Core" с именем SharedAccessUtility.

Новый проект VS

Замените содержимое ConsoleApplication.cpp следующим кодом:

#include "pch.h"
#include <ws2tcpip.h>
#include <iphlpapi.h>
#include <mstcpip.h>
#include <stdio.h>

#define SHARED_ACCESS_NAME L"SharedAccess"
#define START_SHARING_CONTROL 129

DWORD StartSharedAccessService(SC_HANDLE *phScm, SC_HANDLE *phSvc)
{
    DWORD dwError = ERROR_SUCCESS;
    SERVICE_STATUS svcStatus = { 0 };

    // open a handle to SCM
    *phScm = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
    if (*phScm == NULL)
    {
        dwError = GetLastError();
        printf("\nOpenSCManager failed; error = %d", dwError);
    }
    else
    {
        // open a handle to the service
        *phSvc = OpenService(*phScm, SHARED_ACCESS_NAME, SERVICE_START | SERVICE_QUERY_STATUS | SERVICE_QUERY_CONFIG | SERVICE_STOP | SERVICE_USER_DEFINED_CONTROL);
        if (*phSvc == NULL)
        {
            dwError = GetLastError();
            printf("\nOpenService failed; error = %d", dwError);
        }
        else
        {
            if (!StartService(*phSvc, 0, NULL))
            {
                dwError = GetLastError();
                if (dwError != ERROR_SERVICE_ALREADY_RUNNING)
                {
                    printf("\nStartService failed; error = %d", dwError);
                }
                else
                {
                    dwError = ERROR_SUCCESS;
                    printf("\nService already running.");
                }
            }

            if (dwError == ERROR_SUCCESS)
            {
                if (QueryServiceStatus(*phSvc, &svcStatus) && svcStatus.dwCurrentState != SERVICE_RUNNING)
                {
                    for (int i = 0; i < 10; i++)
                    {
                        printf("\nWaiting 1 second for service to start.");
                        Sleep(1000);
                        if (QueryServiceStatus(*phSvc, &svcStatus))
                        {
                            if (svcStatus.dwCurrentState == SERVICE_RUNNING)
                            {
                                printf("\nService is running.");
                                // it is, so break out
                                dwError = ERROR_SUCCESS;
                                break;
                            }
                            else
                            {
                                if (svcStatus.dwCurrentState == SERVICE_STOPPED)
                                {
                                    printf("\nService could not run.");
                                    // it is, so break out
                                    dwError = ERROR_SERVICE_NOT_ACTIVE;
                                    break;
                                }
                            }
                        }
                        else
                        {
                            printf("\nWaiting more time.");
                        }
                    }
                }
            }
        }
    }

    if (dwError == ERROR_SUCCESS) //service is running
    {
        if (!ControlService(*phSvc, START_SHARING_CONTROL, &svcStatus))
        {
            dwError = GetLastError();
            printf("\nControl service for start sharing failure, %d", dwError);
        }
        else
        {
            printf("\nSharing started");
        }
    }

    // Service cleanup done at the main.
    return dwError;
}


DWORD StopSharedAccessService(SC_HANDLE *phSvc)
{
    DWORD dwError = ERROR_SUCCESS;
    SERVICE_STATUS svcStatus = { 0 };

    if (!QueryServiceStatus(*phSvc, &svcStatus))
    {
        dwError = GetLastError();
        printf("\nFailed to query sharedaccess, %d", dwError);
    }
    else
    {
        if (svcStatus.dwCurrentState != SERVICE_STOPPED)
        {
            if (ControlService(*phSvc, SERVICE_CONTROL_STOP, &svcStatus))
            {
                if (QueryServiceStatus(*phSvc, &svcStatus) && svcStatus.dwCurrentState != SERVICE_STOPPED)
                {
                    for (int i = 0; i < 10; i++)
                    {
                        printf("\nWaiting 1 second for service to stop.");
                        Sleep(1000);
                        if (QueryServiceStatus(*phSvc, &svcStatus))
                        {
                            if (svcStatus.dwCurrentState == SERVICE_STOPPED)
                            {
                                printf("\nService stopped.");
                                // it is, so break out
                                dwError = ERROR_SUCCESS;
                                break;
                            }
                            else
                            {
                                printf("\nWaiting more time.");
                            }
                        }
                    }
                }
            }
        }
    }
    return dwError;
}

void ShowUsage()
{
    printf("Usage: SharedAccessUtility.exe start | stop\n"
        "Setup: Make sure the public and private interfaces are up and running and that the SharedAccess registry keys are set.");
}

int __cdecl
main(
    __in int argc,
    __in_ecount(argc) LPSTR argv[]
    )
{
    SC_HANDLE hScm = NULL;
    SC_HANDLE hSvc = NULL;
    DWORD dwError = NO_ERROR;
    bool startSharing = true;

    if (argc < 2)
    {
        ShowUsage();
        return -1;
    }
    else
    {
        if (strcmp(argv[1], "start") == 0 || strcmp(argv[1], "/start") == 0)
        {
            startSharing = true;
        }
        else if (strcmp(argv[1], "stop") == 0 || strcmp(argv[1], "/stop") == 0)
        {
            startSharing = false;
        }
        else
        {
            ShowUsage();
            return -1;
        }
    }

    dwError = startSharing ? StartSharedAccessService(&hScm, &hSvc) : StopSharedAccessService(&hSvc);

    // Cleanup
    if (hSvc != NULL)
    {
        CloseServiceHandle(hSvc);
        hSvc = NULL;
    }
    if (hScm != NULL)
    {
        CloseServiceHandle(hScm);
        hScm = NULL;
    }
    return 0;
}

Выполните сборку для целевой архитектуры, например выпуск x86, и найдите выходные SharedAccessUtility.exe

Шаг 3. Запуск общего доступа к подключению к Интернету

  1. Скопируйте скрипт ConfigICS.cmd , созданный на шаге 2, на устройство в определенном расположении, например в C:\test\
  2. Скопируйте SharedAccessUtility.exe , созданные на шаге 2, на устройство в том же расположении, например C:\test\
  3. На устройстве выполните команду C:\test\ConfigureICS.cmd start [общедоступный индекс] [частный индекс] [имя частного адаптера] В этом примере это будет означать C:\test\ConfigureICS.cmd start 4 5 "Local Area Connection 3"*

На этом этапе устройство включило общий доступ к подключению к Интернету для любого клиента, подключенного к объявленной SSID устройства.