PDA

View Full Version : سوال: تشخیص وصل شدن سیستم به اینترنت بصورت اتوماتیک با استفاده از Hook



hamid-nic
یک شنبه 04 تیر 1391, 12:23 عصر
سلام دوستان ، وقتتان بخیر
همانطور که از عنوان مشخصه می خواهیم وقتی برنامه در حال عادی داره کار می کنه و سیستم به اینترنت وصل نیست اما مثلا پس از مدتی سیستم کاربر به اینترنت وصل میشه بدون اینکه بخواهیم بطور مداوم با توابع موجود چک کنیم که اینترنت وصل است یا نه ، برنامه متوجه وصل شدن به اینترنت بشه . برای این کار جایی خوندم که باید از hook کردن پیغام های سیستمی در سطح پایین استفاده کنیم اما برای انجام این کار نیاز به راهنمایی دارم ؟؟ (در سایت هم تاپیک با این موضوع بود ولی به نتیجه نرسیده بود .)

hamid-nic
دوشنبه 05 تیر 1391, 09:43 صبح
دوستان در این زمینه اطلاعاتی ندارید ؟

Mask
دوشنبه 05 تیر 1391, 14:12 عصر
شما باید تابع InternetGetConnectedState مربوط به wininet.dll رو هوک کنید.

function InternetGetConnectedState(lpdwFlags: LPDWORD;
dwReserved: DWORD): BOOL; stdcall; external 'wininet.dll' name 'InternetGetConnectedState';

SayeyeZohor
دوشنبه 05 تیر 1391, 15:48 عصر
Use WinInet;

FUNCTION InternetConnected: Boolean;
const
INTERNET_CONNECTION_MODEM = 1;
INTERNET_CONNECTION_LAN = 2;
INTERNET_CONNECTION_PROXY = 4;
INTERNET_CONNECTION_MODEM_BUSY = 8;
var
dwConnectionTypes: DWORD;
begin
dwConnectionTypes :=
INTERNET_CONNECTION_MODEM +
INTERNET_CONNECTION_LAN +
INTERNET_CONNECTION_PROXY;
Result := InternetGetConnectedState(@dwConnectionTypes, 0);
end;

SayeyeZohor
دوشنبه 05 تیر 1391, 15:51 عصر
function InternetGetConnectedState(lpdwFlags: LPDWORD;
dwReserved: DWORD): BOOL;
begin
if WinInetLoad() and Assigned(_InternetGetConnectedState) then
Result := _InternetGetConnectedState(lpdwFlags,
dwReserved)
else
Result := False;
end;

SayeyeZohor
دوشنبه 05 تیر 1391, 15:52 عصر
ببشخيد
يك سوال داشتم:خجالت:
شمرنده
Hook چيه؟
سوالم آماتوريه

Mask
دوشنبه 05 تیر 1391, 16:22 عصر
ببشخيد
يك سوال داشتم:خجالت:
شمرنده
Hook چيه؟
سوالم آماتوريه
اون 2 تا پستی که گزاشتی رو خودت تست کردی ؟
قبل از گزاشتن پست ، کد رو تست کن.
اون 2 تا تابع اولا جواب این دوستمون نیست. چون برای بدست آوردن وضعیت فعلی کانکت ، باید این توابع در یک تایمر ، گزاشته بشه و چند ثانیه یکبار ، این وضعیت چک بشه.
پس ایونتی وجود نداره ، که با تحریک شدنش ، این وضعیت به کاربر نمایش داده بشه.(البته یه چیزایی یادم میاد ، که : یه روزی دنبال این مورد بودم ، و انگار یه مسیجی پیدا کردم ، که وضعیت رو اعلام میکرد ، که با هندل کردنش ، میشد ، بدون تایمر وضعیت ارتباط رو بدست آورد . اما حیف یادم نیست چی بود.)
در مورد این 2 تا تابع : این 2 تا تابع در مورد همه ارتباطات جواب درست رو بر نمیگردونه . مثلا ارتباطات بریج رو نمیتونه تشخیص بدهد.
در مورد هوک هم در لینک زیر یه توضیحات کمی دادم. میتونید واسه شروع بخونیدش.
البته اگه روال : فقط تشخیص باشه ، کد زیر تمام حالات رو در خودش داره ، و جواب درست رو بر میگردونه.

const
INTERNET_CONNECTION_MODEM = 1;
INTERNET_CONNECTION_LAN = 2;
INTERNET_CONNECTION_PROXY = 4;

function InternetGetConnectedState(lpdwFlags: LPDWORD;
dwReserved: DWORD): BOOL; stdcall; external 'wininet.dll' name 'InternetGetConnectedState';

function IsOnline: Boolean;
var
dlvFlag : DWord;
begin
Result:=False;
dlvFlag := Internet_Connection_Modem + Internet_Connection_Lan + Internet_Connection_Proxy;
If InternetGetConnectedState ( @dlvFlag, 0 ) = True Then
Result:=dlvFlag = 81;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
if IsOnline then
showmessage('Online')
else
showmessage('Offline');
end;
http://barnamenevis.org/showthread.php?337110-%D9%87%D9%88%DA%A9&p=1493520&viewfull=1#post1493520

SayeyeZohor
دوشنبه 05 تیر 1391, 16:25 عصر
بله تست كردم بابا:گریه:
اونا رو خواب آلو بودم
اين dll رو داريد؟
'wininet.dll'

فانكشن من :

Use WinInet;

FUNCTION InternetConnected: Boolean;
const
INTERNET_CONNECTION_MODEM = 1;
INTERNET_CONNECTION_LAN = 2;
INTERNET_CONNECTION_PROXY = 4;
INTERNET_CONNECTION_MODEM_BUSY = 8;
var
dwConnectionTypes: DWORD;
begin
dwConnectionTypes :=
INTERNET_CONNECTION_MODEM +
INTERNET_CONNECTION_LAN +
INTERNET_CONNECTION_PROXY;
Result := InternetGetConnectedState(@dwConnectionTypes, 0);
end;



فانكشن شما :
const
INTERNET_CONNECTION_MODEM = 1;
INTERNET_CONNECTION_LAN = 2;
INTERNET_CONNECTION_PROXY = 4;

function InternetGetConnectedState(lpdwFlags: LPDWORD;
dwReserved: DWORD): BOOL; stdcall; external 'wininet.dll' name 'InternetGetConnectedState';

function IsOnline: Boolean;
var
dlvFlag : DWord;
begin
Result:=False;
dlvFlag := Internet_Connection_Modem + Internet_Connection_Lan + Internet_Connection_Proxy;
If InternetGetConnectedState ( @dlvFlag, 0 ) = True Then
Result:=dlvFlag = 81;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
if IsOnline then
showmessage('Online')
else
showmessage('Offline');
end;

فرقشون چيه؟

Mask
دوشنبه 05 تیر 1391, 16:37 عصر
ين dll رو داريد؟
'wininet.dll'
ماله خوده ویندوزه.

فرقشون چيه؟
فرقش تو تفاوتشه:لبخند:
خروجیاشو نیگا :

Result:=dlvFlag = 81;

Result := InternetGetConnectedState(@dwConnectionTypes, 0);

hamid-nic
سه شنبه 06 تیر 1391, 01:00 صبح
سلام
ممنون از محبتتون دوستان
اما GOLD جان اولا بابت این کدتون ممنون که جواب درست را بر می گرداند (یه چندتایی امتحان کرده بودم که جواب درست را نمی داد) و ثانیا اینکه حالا باید به چه شکلی عمل hook را انجام بدهیم که نیاز نباشه مداوم این عمل را چک کنیم ؟؟ :متفکر:

بهروز عباسی
سه شنبه 06 تیر 1391, 08:24 صبح
درود و خسته نباشید
برای آشنایی بیشتر با هوک مقاله زیر رو بخون.

seyed_farid
پنج شنبه 08 تیر 1391, 00:35 صبح
با سلام
ميخواستم ببينم من اگه بخوام اتصال يك كامپيوتر با IP مشخص به شبكه داخلي را داشته باشم راهي براش هست؟
مثلا چند كامپيوتر تو يك شبكه داخلي بهم وصلند و من بايد بدونم به كدوم كامپيوتر وصلم؟

Mask
پنج شنبه 08 تیر 1391, 13:25 عصر
با سلام
ميخواستم ببينم من اگه بخوام اتصال يك كامپيوتر با IP مشخص به شبكه داخلي را داشته باشم راهي براش هست؟
مثلا چند كامپيوتر تو يك شبكه داخلي بهم وصلند و من بايد بدونم به كدوم كامپيوتر وصلم؟
میتونید در فواصلی، سیستمها رو پینگ کنید.

seyed_farid
پنج شنبه 08 تیر 1391, 18:41 عصر
با پینگ کردن در صورت نیافتن سیستم مورد نظر، برنامه حالت هنگ پیدا میکند(من با اکو فعلا چک میکنم و تو xpخیلی بد نبود ولی تو سون که اجراش میکنم کف میکنه) و من این رو نمیپسندم. تو این برنامه دیدم سریع لیست شبکه را آورد. خواستم ببینم میتونم از این بخشش استفاده کنم و هرچند لحظه این لیست را بگیرم و بفهمم سیستم موردنظر من موجوداست یانه.

Mask
پنج شنبه 08 تیر 1391, 19:58 عصر
برنامه حالت هنگ پیدا میکند(
اگه تو یه ترد دیگه این عملیات رو انجام بدید ، مشکلی پیش نمیاد.

تو این برنامه دیدم سریع لیست شبکه را آورد
کدوم برنامه؟

seyed_farid
جمعه 09 تیر 1391, 14:21 عصر
برنامه حالت هنگ پیدا میکند(
اگه تو یه ترد دیگه این عملیات رو انجام بدید ، مشکلی پیش نمیاد.


ممنون از پاسختون.
من به روش زیر چک میکنم و تو xp زیاد گیر نمیکنه ولی تو 7 درصورت عدم اتصال به شبکه موردنظر حدود 5 ثانیه کف میکنه.

unit MyARP;

interface

uses
Windows, Classes, SysUtils, WinSock;

function SendARP(DestIp: DWORD; srcIP: DWORD; pMacAddr: pointer; PhyAddrLen: Pointer): DWORD;stdcall; external 'iphlpapi.dll';
function MySendARP(const IPAddress: String): String;
function MyCheckIP(const IPAddress: String): Boolean;

implementation

function MySendARP(const IPAddress: String): String;
var
DestIP: ULONG;
MacAddr: Array [0..5] of Byte;
MacAddrLen: ULONG;
SendArpResult: Cardinal;
begin
DestIP := inet_addr(PAnsiChar(AnsiString(IPAddress)));
MacAddrLen := Length(MacAddr);
SendArpResult := SendARP(DestIP, 0, @MacAddr, @MacAddrLen);

if SendArpResult = NO_ERROR then
Result := Format('Connected, MAC: %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X',
[MacAddr[0], MacAddr[1], MacAddr[2],
MacAddr[3], MacAddr[4], MacAddr[5]])
else
Result := 'Disconnected';
end;

function MyCheckIP(const IPAddress: String): Boolean;
var
DestIP: ULONG;
MacAddr: Array [0..5] of Byte;
MacAddrLen: ULONG;
SendArpResult: Cardinal;
begin
DestIP := inet_addr(PAnsiChar(AnsiString(IPAddress)));
MacAddrLen := Length(MacAddr);
SendArpResult := SendARP(DestIP, 0, @MacAddr, @MacAddrLen);
Result := SendArpResult = NO_ERROR;
end;

end.

میشه درمورد قرار دادن مثلاً این دستور تو یه ترد دیگه و راهش توضیح و مثالی بدید؟:تشویق:

SayeyeZohor
جمعه 09 تیر 1391, 23:19 عصر
FUNCTION InternetGetConnectedState(lpdwFlags: LPDWORD; dwReserved:DWORD):BOOL; stdcall; external 'wininet.dll' name 'InternetGetConnectedState';

FUNCTION InternetConnected: Boolean;
//-- 4 --
const
INTERNET_CONNECTION_MODEM = 1;
INTERNET_CONNECTION_LAN = 2;
INTERNET_CONNECTION_PROXY = 4;
INTERNET_CONNECTION_MODEM_BUSY = 8;

dwConnectionTypes: DWORD =
INTERNET_CONNECTION_MODEM +
INTERNET_CONNECTION_LAN +
INTERNET_CONNECTION_PROXY;
begin
Result := False;
// Result := InternetGetConnectedState(@dwConnectionTypes, 0);
If InternetGetConnectedState(@dwConnectionTypes, 0) = True Then
Result := dwConnectionTypes = 81;
end;



اما GOLD جان اولا بابت این کدتون ممنون که جواب درست را بر می گرداند (یه چندتایی امتحان کرده بودم که جواب درست را نمی داد)
dwConnectionTypes = 18 , Result = False
اين خروجي فانكشن منه
كه يعني اتصال اينترنتي برقرار نيست
در صورتي كه هست من با Lan به اينترنت متصل هستم :گریه:
چيكار كنم ؟

اين كد رو پيدا كردم ، فكر كنم اين درسته چك مي كنين درسته يا نه ؟

if InternetGetConnectedState(@dwFlags, 0) then
begin
if (dwFlags and INTERNET_CONNECTION_MODEM) = INTERNET_CONNECTION_MODEM then
ShowMessage('Modem Connection')
else
if (dwFlags and INTERNET_CONNECTION_LAN) = INTERNET_CONNECTION_LAN then
ShowMessage('LAN Connection')
else
if (dwFlags and INTERNET_CONNECTION_PROXY) = INTERNET_CONNECTION_PROXY then
ShowMessage('Connection thru Proxy')
else
if (dwFlags and INTERNET_CONNECTION_OFFLINE) = INTERNET_CONNECTION_OFFLINE then
ShowMessage('Local system in offline mode')
else
if (dwFlags and INTERNET_CONNECTION_CONFIGURED) = INTERNET_CONNECTION_CONFIGURED then
ShowMessage('Valid connection exists, but might or might not be connected')
end
else
ShowMessage('Not Connected. Try to connect and risk of being prompted to dial into another Internet Service Provider.');

AmirSky
شنبه 07 مرداد 1391, 12:52 عصر
من از این کد ها استفاده میکنم. ولی یه اشکال توی ویندوز سون دارم. البته روی ویندوز های دیگه چک نکردم.
وقتی سیستم روشن میشه و اینترنت کانکت نیست پیام disconnect صادر میشه و درسته.
وقتی اینترنت رو کانکت میکنم پیام connect صادر میشه و درسته.
اما وقتی دوباره اینترنت رو دیسکانکت میکنم باز پیام connect صادر میشه و اشتباهه. و دیگه پیام disconnect صادر نمیشه. باید مشکل از پیام های ویندوز باشه. راه حلی وجود نداره؟



procedure TForm1.Button1Click(Sender: TObject);
begin
If InternetConnected Then
Begin
ShowMessage('connect');
End
Else
Begin
ShowMessage('disconnect');
End;
end;

function TForm1.InternetConnected: Boolean;
CONST
// local system uses a modem to connect to the INTERNET.
INTERNET_CONNECTION_MODEM = 1;
// local system uses a local area network to connect to the INTERNET.
INTERNET_CONNECTION_LAN = 2;
// local system uses a proxy server to connect to the INTERNET.
INTERNET_CONNECTION_PROXY = 4;
// local system's modem is busy with a non-INTERNET connection.
INTERNET_CONNECTION_MODEM_BUSY = 8;
VAR
dwConnectionTypes : DWORD;
BEGIN
dwConnectionTypes :=
INTERNET_CONNECTION_MODEM +
INTERNET_CONNECTION_LAN +
INTERNET_CONNECTION_PROXY;
Result := INTERNETGetCONNECTEDState(@dwConnectionTypes,0);
END;

AmirSky
شنبه 07 مرداد 1391, 13:23 عصر
با این تغییرات مشکلم حل شد

function TForm1.InternetConnected: Boolean;
const
// local system uses a modem to connect to the INTERNET.
INTERNET_CONNECTION_MODEM = 1;
// local system uses a local area network to connect to the INTERNET.
INTERNET_CONNECTION_LAN = 2;
// local system uses a proxy server to connect to the INTERNET.
INTERNET_CONNECTION_PROXY = 4;
// local system's modem is busy with a non-INTERNET connection.
INTERNET_CONNECTION_MODEM_BUSY = 8;
var
dwConnectionTypes : DWORD;
begin
dwConnectionTypes :=
INTERNET_CONNECTION_MODEM +
INTERNET_CONNECTION_LAN +
INTERNET_CONNECTION_PROXY;
Result := False;
If InternetGetConnectedState(@dwConnectionTypes, 0) = True Then
Result := dwConnectionTypes = 81;
end;

Sal_64
جمعه 06 بهمن 1391, 20:33 عصر
سلام به متخصصین بخش دلفی- آیا اطلاع دارید که net. هم شبیه این کد داره ؟؟

بهروز عباسی
جمعه 06 بهمن 1391, 20:47 عصر
سلام به متخصصین بخش دلفی- آیا اطلاع دارید که net. هم شبیه این کد داره ؟؟
درود
این الان خبره ! یا سوال !

اگه سواله آره چون از Windows API درش استفاده شده میتونی توی زبان های دیگه هم این کد رو پیاده سازی کنی.
موفق باشید.

Sal_64
یک شنبه 08 بهمن 1391, 11:52 صبح
سلام- عنوان تاپیک تشخیص اتوماتیک بود - اما من هر بار باید دستی تابع فراخوانی کنم که وضعیت چک کنه ! یعنی پس از هر اتصال یا قطع اینترنت برنامه عکس العملی نشون نمیده! دوستان میشه بیشتر راهنمایی کن؟ تشکر