Легенда:
новое сообщение
закрытая нитка
новое сообщение
в закрытой нитке
старое сообщение
|
- Напоминаю, что масса вопросов по функционированию форума снимается после прочтения его описания.
- Новичкам также крайне полезно ознакомиться с данным документом.
| |
Ага. DHCP у меня действительно выключен :-) 08.01.04 13:31 Число просмотров: 1390
Автор: amirul <Serge> Статус: The Elderman
|
|
<programming>
|
Тем кто юзает XP/2k3 - нужно проверить кое что... 05.01.04 13:17
Автор: Killer{R} <Dmitry> Статус: Elderman Отредактировано 05.01.04 13:33 Количество правок: 2
|
А именно понадобилось мне прогу написать которая меняет основной ИП адрес сетевухи. Через пару часов ползания по мсдн и iphlpapi.dll нашел в длл нигде недокументированную функцию SetAdapterIpAddress. Поисковики ниче не сказали по ее поводу, пришлось заюзать дизасм. Оказалось что прототип у нее такой:
DWORD WINAPI SetAdapterIpAddress(char *ID, DWORD dhcp, DWORD ip, DWORD subnet, DWORD netmask);
ID - GUID интерфейса типа "{FCC9086D-3608-416C-ADC8-D97EE9D2A197}". Один из тех что находятся в HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces.
dhcp - если 0 то DHCP не юзается. Иначе юзается. Короче никакой это не DWORD а BOOL Ж)
ip, subnet, netmask - по названию ясно что такое, получаются после inet_addr
Вобщем дело в том что у меня ща под рукой тока винда 2000 а надо чтоб прога юзащая эту функцию точно работала еще под ХР и 2к3. И может эту фишку в FAQ стоит включить, раз про нее нигде ниче нету (чтож я просто так 2 часа "бался...Ж)) - мот кому еще понадобится . Короче надо откомпилять (заменив GUI на тот который у вашей сетевухи и поставив адреса по вкусу) и запустить это :
#include "windows.h"
#include "winsock.h"
#pragma comment (lib,"ws2_32.lib")
int APIENTRY WinMain(HINSTANCE,HINSTANCE,LPSTR,int)
{
typedef DWORD (WINAPI *SetAdapterIpAddressx)(char *,DWORD,DWORD,DWORD,DWORD);
WSADATA wd;
WSAStartup(257,&wd);
HINSTANCE lib=(HINSTANCE)LoadLibrary("iphlpapi.dll");
SetAdapterIpAddressx SetAdapterIpAddress=(SetAdapterIpAddressx)GetProcAddress(lib,"SetAdapterIpAddress");
if(SetAdapterIpAddress)
{
DWORD ret=SetAdapterIpAddress("{FCC9086D-3608-416C-ADC8-D97EE9D2A197}",0,inet_addr("192.168.4.1"),inet_addr("192.168.4.2"),inet_addr("192.168.4.3"));
if(ret)MessageBox(0,"Error","zz",0);else MessageBox(0,"Ok","zz",0);
}else MessageBox(0,"SetAdapterIpAddress not found","zz",0);
return 0;
}
|
|
Дополнение... 07.01.04 02:43
Автор: Killer{R} <Dmitry> Статус: Elderman Отредактировано 07.01.04 04:25 Количество правок: 4
|
И возможно объяснение глюка у амирула. Чтоб оно работало (если оно не работает) надо сделать так:
net start dhcp
А если после такого сервис DHCP клиента не поднимается надо ему помочь )
Иначе драйвер не воспринимает новые настройки. И ошибка 2 понятно откуда - трубу не смог открыть.
Причем работает первый способ (через SetAdapterIpAddress из iphlpapi.dll) и второй (DhcpNotifyConfigChange из dhcpcsvc.dll). Различие №1- первый способ сохраняет настройки перманентно, второй - до ребута машины. Прототип DhcpNotifyConfigChange (его я в инете нашел):
/*
BOOL DhcpNotifyConfigChange(
LPWSTR lpwszServerName, // NULL for local machine
LPWSTR lpwszAdapterName, // это все тот же GUID сетевой карточки
BOOL fNewIpAddress, // TRUE if IP address modified
DWORD dwIpIndex, // IP address index (0 based)
DWORD dwIpAddress, // IP address to set (network order)
DWORD dwSubNetMask, // Associated subnet mask (network order)
int nDhcpAction ); // 0:don't modify/1:enable/2:disable DHCP
*/
Как видно этот метод хоть и не сохраняет настройки в реестр, зато позволяет менять все адреса закрепленные за интерфейсом компа, + к тому им вроде как можно насильно менять ИПшники на других компах с сервере. Вот это уже интересно и может оказаться весьма полезным Ж). Вот тока инфы по этой функции - ноль, кое как нашел сам прототип. Когда ее можно юзать - непонятно. Толи когда имеются права админа на том компе, толи когда ты - DHCP сервер, толи всегда (маловероятно, зато какой прикол бы был Ж))), толи параметр lpwszServerName вообще на будущее зарезервирован - непонятно, надо на практике проверять.
|
| |
Ага. DHCP у меня действительно выключен :-) 08.01.04 13:31
Автор: amirul <Serge> Статус: The Elderman
|
|
|
У меня, собственно, работает. 05.01.04 17:40
Автор: IgorR <Igor Razin> Статус: Member
|
Это работает на ура:
typedef DWORD (WINAPI *SetAdapterIpAddressx )( char *szAdapterGUID,
DWORD dwDHCP, // Не проверял
DWORD dwNewIP, // Новый ИП
DWORD dwMask, // Маска
DWORD dwGateway // Гетвей
);
HINSTANCE lib = (HINSTANCE) LoadLibrary( T("iphlpapi.dll") );
SetAdapterIpAddressx SetAdapterIpAddress=(SetAdapterIpAddressx) GetProcAddress( lib,"SetAdapterIpAddress" );
CRegistry Reg;
PTSTR pszGUID = NULL;
char szGUID[64] = {0};
DWORD dwSize = 0;
// Отсюда удобней было выцеплять
Reg.Read( T("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\NetworkCards\\1"),
T("ServiceName"),
(PVOID&) pszGUID,
&dwSize );
WideCharToMultiByte( CP_ACP, 0, pszGUID, -1, szGUID, sizeof( szGUID ), NULL, NULL );
SetAdapterIpAddress( szGUID, 0,
inet_addr("192.168.1.5"),
inet_addr("255.255.255.1"),
inet_addr("192.168.1.2") );
Пробовал под w2k и XP. Меняет на лету, без всяких передергиваний.
Спасибо за рульную инфу :)
|
| |
Хм... Под ХР оно у тебя точно работает? 05.01.04 17:45
Автор: Killer{R} <Dmitry> Статус: Elderman
|
Вон амирул тоже думал что работает..
|
| | |
Проверил еще. 05.01.04 18:08
Автор: IgorR <Igor Razin> Статус: Member
|
Как часы. ХР правда без SP. Может в карточках дело? Я на 2-х машинах проверил, на обеих 3Com EtherLink XL 10/100 PCI For Complete PC Management NIC (3C905C-TX).
|
|
Продолжение (вернее обновление) эпопеи... 05.01.04 17:18
Автор: Killer{R} <Dmitry> Статус: Elderman
|
#include "windows.h"
#include "winsock.h"
#pragma comment (lib,"ws2_32.lib")
typedef DWORD (WINAPI *SetAdapterIpAddressx)(char *,DWORD,DWORD,DWORD,DWORD);
typedef DWORD (WINAPIDhcpNotifyConfigChangex)(wchar_t*,wchar_tBOOL,DWORD,DWORD,DWORD,int);
SetAdapterIpAddressx SetAdapterIpAddress;
DhcpNotifyConfigChangex DhcpNotifyConfigChange;
void __fastcall ChangeIPAddr(char *id,DWORD ip,DWORD mask, DWORD gway)
{
SetAdapterIpAddress(id,0,ip,mask,gway);
wchar_t uid[256]={0};
MultiByteToWideChar(CP_ACP,0,id,-1,uid,127);
DhcpNotifyConfigChange(0,uid,1,0,ip,mask,2);
}
int APIENTRY WinMain(HINSTANCE,HINSTANCE,LPSTR,int)
{
WSADATA wd;
WSAStartup(257,&wd);
HINSTANCE lib=(HINSTANCE)LoadLibrary("iphlpapi.dll");
SetAdapterIpAddress=(SetAdapterIpAddressx)GetProcAddress(lib,"SetAdapterIpAddress");
lib=(HINSTANCE)LoadLibrary("dhcpcsvc.dll");
DhcpNotifyConfigChange=(DhcpNotifyConfigChangex)GetProcAddress(lib,"DhcpNotifyConfigChange");
ChangeIPAddr("{FCC9086D-3608-416C-ADC8-D97EE9D2A197}",inet_addr("192.168.4.9"),inet_addr("255.255.255.0"),inet_addr("192.168.4.9"));
MessageBox(0,"Changing finished!","zz",0);
return 0;
}
|
|
XP SP1 - работает 05.01.04 14:23
Автор: amirul <Serge> Статус: The Elderman
|
Только возращается наверное не DWORD, а все таки BOOL. TRUE - все хорошо, FALSE - все плохо. Потому как настройки TCP/IP меняются, но выдается сообщение об ошибке. У меня возвращается 2. Error Lookup говорит, что это означает "Не удается найти указанный файл".
А факу написать - эт правильно.
-------------------
Поторопился я. Настройки конечно меняются. Только они то ли в дривер не уходят, то ли еще что. Но после такого изврата надо передернуть карточку (отключить/включить), иначе она даже свою подсетку не хочет пинговать. Поищи может NDIS-овские OID-ы какие помогут. В частности OID_GEN_NETWORK_LAYER_ADDRESSES выдает минипорту именно эту инфу. Хотя с другой стороны проще действительно просто передернуть карточку через SetupAPI
|
| |
А скинь мне плз iphlpapi.dll от ХР [UPD] 05.01.04 14:27
Автор: Killer{R} <Dmitry> Статус: Elderman Отредактировано 06.01.04 10:36 Количество правок: 3
|
на killer_r +другчеловека+ tut.by
Драйвер как раз у меня под 2000й передергивается - с этим все в порядке. А оно не падает при выходе из проги? (может там параметр какой добавлен еще)
--
А может ты случайно пытался поменять ипшник на такой как есть в сетке или на какой нельзя изза чего-нить поставить? Или может файрволл твой мог прикрыть это дело? И если вручную ИП менять в настройках оно там ничего не ругается, ребута например не просит?
|
| | |
Не не просит. Я менял сначала на то, что у тебя в примере,... 05.01.04 14:45
Автор: amirul <Serge> Статус: The Elderman
|
> на killer_r +собака+ tut.by > Драйвер как раз у меня под 2000й передергивается - с этим > все в порядке. А оно не падает при выходе из проги? (может > там параметр какой добавлен еще) > -- > А может ты случайно пытался поменять ипшник на такой как > есть в сетке или на какой нельзя изза чего-нить поставить? > Или может файрволл твой мог прикрыть это дело? И если > вручную ИП менять в настройках оно там ничего не ругается, > ребута например не просит? Не не просит. Я менял сначала на то, что у тебя в примере, а потом обратно на свой. Оба раза поменялось, выдало ошибку 2 и перестало видеть сеть (ребутов не просила, крахов не было). После этого даже из свойств IP менялся, но карточка не видела сети. То, что параметры были указаны правильно следует из того, что карточка начала работать правильно сразу после того, как я ее передернул.
|
| | | |
Вот ведь.. 05.01.04 14:57
Автор: Killer{R} <Dmitry> Статус: Elderman Отредактировано 05.01.04 15:01 Количество правок: 1
|
Я ведь эту функцию специально ковырял чтоб обойтись без перзапуска карточки - иначе можно не морочить голову, поправить в реестре параметры и перезапустить ее. С другой стороны Error 2 - file not found наводит на мысли о том что оно почемуто не смогло открыть tcp/ip драйвер для ресета сетевухи (там есть вызовы DeviceIOControl). Может там надо еще чего инициализировать перед этой функцией... Кстати а как ее можно выключить\включить через SetupAPI?
ЗЫ 2ALL а у остальных как? (т.ч. w2k3)
ЗЗЫ А в той длл что ты мне прислал имхо все тоже самое что в моей. Тока я сильно много не сравнивал но начало функции и параметры - один в один тока наверно в разных версиях компилятора скомпилено.
|
| | | | |
Мож у меня система какая то кривая 05.01.04 17:55
Автор: amirul <Serge> Статус: The Elderman
|
Девелоперская машина в конце концов. Тут столько всего поставлено/снесено, (и оставлено тоже) что я уже подумываю над переустановкой.
> как ее можно выключить\включить через SetupAPI? Через PnP Config Manager нашел - CM_Disable_Devnode/CM_Disable_Devnode_Ex и CM_Enable_Devnode/CM_Enable_Devnode_Ex
Но MSDN говорит, что это устаревшие функции и надо пользоваться "device installation functions"-ами, что и есть тот самый SetupAPI. Я там сильно не копался, но с первой попытки не нашел.
> ЗЫ 2ALL а у остальных как? (т.ч. w2k3) > ЗЗЫ А в той длл что ты мне прислал имхо все тоже самое что > в моей. Тока я сильно много не сравнивал но начало функции > и параметры - один в один тока наверно в разных версиях > компилятора скомпилено.
|
|
|