Приветствую. Необходимо создать постоянный маршрут в системах Vista / 7. Под 2000 и XP все прекрасно создается, а тут загвоздка. Впринципе в таблицу маршрутизации маршрут добавляется, что подтверждается демо примером iphlpapi для Delphi, идущим с заголовочными модулями, но если в командной строке выполнить команду route print, список постоянных маршрутов пуст.
| Код | function CreatePersistentRoute(network, netmask, gateway: AnsiString): Boolean; var pRoute : MIB_IPFORWARDROW; dwError: DWORD; ifIndex: DWORD; fMetric: DWORD; szRoute: AnsiString; lResult: Integer; begin
// WriteLn('Enter your gateway IP...'); // ReadLn(gateway);
Result := FALSE;
// первоначально выставляем индекс интерфейса чтобы после определить, нужно // ли выполнять последующие действия.
ifIndex := DWORD(-1);
// пытаемся узнать индекс интерфейса, котоырй имеет оптимальный маршрут до // указанного адреса IPv4.
try dwError := GetBestInterface(inet_addr(@gateway[1]), ifIndex); case dwError of ERROR_SUCCESS: WriteLn('GetBestInterface: ERROR_SUCCESS'); ERROR_NOT_SUPPORTED: WriteLn('GetBestInterface: ERROR_NOT_SUPPORTED'); ERROR_CAN_NOT_COMPLETE: WriteLn('GetBestInterface: ERROR_CAN_NOT_COMPLETE'); else WriteLn('GetBestInterface: Unknown ERROR - ' + IntToStr(dwError)); end; except WriteLn('GetBestInterface: EXCEPT'); end;
// если индекс интерфейса не удалось узнать, то дальше ничего не выполняем.
if (ifIndex = DWORD(-1)) then Exit;
// проверяем адрес маски подсети и если он пуст, то автоматически его // указываем.
try if (netmask = '') then netmask := '255.255.255.255';
dwError := GetBestRoute(inet_addr(@network[1]), 0, pRoute); case dwError of NO_ERROR: WriteLn('GetBestRoute: NO_ERROR'); else WriteLn('GetBestRoute: Unknown ERROR - ' + IntToStr(dwError)); end;
fMetric := pRoute.dwForwardMetric1;
// MessageBox(0, PAnsiChar(gateway), nil, MB_OK); // Exit;
// заполняем структуру MIB_IPFORWARDROW нужной информацией и создаем // маршрут в таблице маршрутов.
ZeroMemory(@pRoute, SizeOf(MIB_IPFORWARDROW));
pRoute.dwForwardDest := inet_addr(@network[1]); pRoute.dwForwardMask := inet_addr(@netmask[1]); pRoute.dwForwardPolicy := 0; pRoute.dwForwardNextHop := inet_addr(@gateway[1]); pRoute.dwForwardIfIndex := ifIndex; pRoute.dwForwardType := MIB_IPROUTE_TYPE_DIRECT; pRoute.dwForwardProto := PROTO_IP_NETMGMT; pRoute.dwForwardAge := 0; pRoute.dwForwardNextHopAS := 0; pRoute.dwForwardMetric1 := fMetric; pRoute.dwForwardMetric2 := DWORD(-1); pRoute.dwForwardMetric3 := DWORD(-1); pRoute.dwForwardMetric4 := DWORD(-1); pRoute.dwForwardMetric5 := DWORD(-1);
dwError := CreateIpForwardEntry(@pRoute); lResult := GetLastError; case dwError of NO_ERROR: begin
WriteLn('CreateIpForwardEntry: NO_ERROR'); WriteLn('GetLastError: ' + IntToStr(lResult)); // нам необходимо создать постоянный маршрут, поэтому нужно добавить // сведения о нем в соответствующий раздел реестра, а также заодно и // проверим возвращаемый результат от функции.
szRoute := Format('%s,%s,%s,1', [network, netmask, gateway]); // запись в ключи ControlSet001 и ControlSet002 необходимо выполнять // только в системах Vista и 7. в предыдущих системах достаточно ключа // CurrentControlSet.
if RegWriteString(HKEY_LOCAL_MACHINE, 'SYSTEM\ControlSet001\services\Tcpip\Parameters\PersistentRoutes', szRoute, '') then WriteLn('RegWriteString (1) - OK'); if RegWriteString(HKEY_LOCAL_MACHINE, 'SYSTEM\ControlSet002\services\Tcpip\Parameters\PersistentRoutes', szRoute, '') then WriteLn('RegWriteString (2) - OK'); if RegWriteString(HKEY_LOCAL_MACHINE, 'SYSTEM\CurrentControlSet\services\Tcpip\Parameters\PersistentRoutes', szRoute, '') then WriteLn('RegWriteString (3) - OK');
Result := TRUE;
end; ERROR_ACCESS_DENIED: WriteLn('CreateIpForwardEntry: ERROR_ACCESS_DENIED'); ERROR_INVALID_PARAMETER: WriteLn('CreateIpForwardEntry: ERROR_INVALID_PARAMETER'); ERROR_NOT_SUPPORTED: WriteLn('CreateIpForwardEntry: ERROR_NOT_SUPPORTED'); else WriteLn('CreateIpForwardEntry: Unknown ERROR - ' + IntToStr(dwError)); end; except WriteLn('CreateIpForwardEntry: EXCEPT'); end;
//route ADD 77.88.0.0 MASK 255.255.224.0 192.168.75.2 -P // if CreatePersistentRoute('77.88.0.0', '255.255.224.0', '192.168.75.2') then // MessageBox(0, 'Route success create!', nil, MB_OK); end;
|
Есть несколько вопросов:
1. Если не вызывать GetBestRoute для сохранения метрики интерфейса из заполненной структуры, почему-то CreateIpForwardEntry выдает ошибку 160, хотя GetLastError выдает при этом 0. До этого указывал метрику равную 1. Под XP и 2000 все прекрасно работает, а тут вообще непонятно какое значение подставить. Просто случайно обнаружил данный способ. Работает конечно, но как-то уж криво реализованный он, да и сомнение есть по этому поводу.
2. Проверяю код на виртуальнйо машине так как просто не хочу устанавливать Vista и 7. Может быть оно и работает как надо и только на виртуальной машине проявляется этот глюк. Просмотрел снимки реестра до и после работы системной программы route с целью получения информации чтоже она доабвляет-то в реестр раз после ее манипуляций она показывает постоянный маршрут.
| Код | Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\Nsi\{eb004a00-9b1a-11d4-9123-0050047759bc}\16] "000000004d5800001300000000000000000000000000000000000000000000000000000000000000c0a84b0200000000"=hex:ff,\ ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,01,00,00,00,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,\ ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,\ ff,ff,ff,ff,ff
[HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\services\Tcpip\Parameters\PersistentRoutes] "77.88.10.0,255.255.224.0,192.168.75.2,21"=""
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Nsi\{eb004a00-9b1a-11d4-9123-0050047759bc}\16] "000000004d5800001300000000000000000000000000000000000000000000000000000000000000c0a84b0200000000"=hex:ff,\ ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,01,00,00,00,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,\ ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,\ ff,ff,ff,ff,ff
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\Tcpip\Parameters\PersistentRoutes] "77.88.10.0,255.255.224.0,192.168.75.2,21"=""
|
Если поудалять ключи {eb004a00-9b1a-11d4-9123-0050047759bc}, постоянных маршрутов не будет. что это за идентификатор или GUID или что вообще? От чего зависит сохранение постоянного маршрута в этих системах? Смотрел на различных форумах, но вообще глухо по этой теме. |