在WINDOWS95&WINDOWS98下如何关闭网络连接

本文介绍在Windows 95和Windows 98系统中如何通过编程方式关闭网络连接的方法。主要内容包括:利用SVRAPI.DLL库中的API进行网络连接的枚举与断开操作;提供具体的API声明与源代码示例。
2000年08月24日 17:32:00
在WINDOWS95&WINDOWS98下如何关闭网络连接

黄 飞 >98/5/20<

一.问题提出:

每当你通过WINDOWS95或WINDOWS98访问"网上邻居"时,系统自动的建立了两
台机器之间的网络连接关系,但是在访问结束后,并不自动的断开网络连接,
所以有时我们关闭WINDOWS系统时,会弹出一个对话框,询问是否关闭网络连
接,在回答"YES"后,才真正开始关闭计算机.
程序员编制系统关闭程序时,就需要考虑这种情况,虽然SDK提供了关机的API:
ExitWindowsEx()和ExitWindows(),但实际应用中我发现,在指定FORCE关机时
在特定情况下会出问题.所以,必须想办法首先断开网络连接.

二.编程接口:

WINDOWS95及WINDOWS98提供的这方面的网络编程接口在SVRAPI.DLL中,利用它
我们可以列举出当前网络连接状态,控制或删除网络连接.WINDOWS附件中的
NETWATCH.EXE工具就是这样实现的.
也许您会问,NetAPI的详细说明在开发工具的SDK文档中很详细了,没有必要在
此演示.但是,在查寻了很多资料后,我不得不说:MSDN中有关NetAPI的部分说
明是错误的,至少是不完整而且含混不清的,可以说,依靠这些文档,你不能实
现全部的功能!下面的代码是本人自己分析得来,使用后,您会发现正确的应用
和文档说明有多么大的差距.

三.API声明:

关闭网络连接的实现方法分两步: 枚举出当前所有的网络连接状况; 依次
断开枚举出的网络连接.

1.枚举出当前所有的网络连接状况:
依照开发帮助文档,这个API是这样的:
NET_API_STATUS NetSessionEnum(
LPWSTR servername,
LPWSTR UncClientName,
LPWSTR username,
DWORD level,
LPBYTE *bufptr,
DWORD prefmaxlen,
LPDWORD entriesread,
LPDWORD totalentries,
LPDWORD resume_handle
);

但是,实际情况是,在WINDOWS95和WINDOWS98平台下,
这样调用根本就无法连接上库文件.真正的API声明应该是:
DWORD NetSessionEnum( LPSTR,
DWORD,
LPBYTE,
DWORD,
LPDWORD,
LPDWORD )
参数1: NULL表示枚举本机的网络连接
参数2: 不详.在枚举中是常量0x32.
参数3: 存放信息的缓冲区指针
参数4: 缓冲区长度
参数5: 指向返回连接个数
参数6: 指向总共连接个数
可见,参数个数完全不同,另外参数意义也发生了变化.

2.依次断开枚举出的网络连接:
还算幸运的是,断开网络连接的API声明是正确的:
NET_API_STATUS NetSessionDel(
LPWSTR servername,
LPWSTR UncClientName,
LPWSTR username );
不过要注意的是,第2个和第3个参数的内容需要
从枚举得到的缓冲区中去取.具体方法参见程序.

四.源代码:

以下是实现断开网络连接的子程序,你可以方便的把它们加入到自己的项目中
去,而不用和我一样浪费时间去研究到底怎样实现网络枚举了.

注:由于本程序只实际用到了一个SVRAPI.DLL中的函数声明,简便期间,我没有
用原有的头文件,自己定义一下就可以了.

///////////////////////////////////////////////////////////////////
// File: NetClose.H
// Version: 1.01

#define NETBUFF_SIZE 0x208

#define NetSessionEnum_PROFILE ( DWORD (__stdcall *) ( LPSTR, DWORD, LPBYTE, DWORD, LPDWORD, LPDWORD ) )
#define NetSessionDel_PROFILE ( DWORD (__stdcall *) ( LPSTR, LPSTR, DWORD ) )
///////////////////////////////////////////////////////////////////
// File: NetClose.CPP
// Version: 1.01
///////////////////////////////////////////////////////////////////
// Define: BOOL NetCloseAll( VOID )
// Parameters: None
// Return: TRUE or FALSE
//
// Author: Mr.Huang fei
// Time: 5/7/1998
// Note: Can only be used on Windows95 & Windows98
// Remark: Close all network connections
///////////////////////////////////////////////////////////////////
BOOL NetCloseAll( VOID )
{
BYTE byBuff[NETBUFF_SIZE];
DWORD dwNetRet = 0;;
DWORD i = 0;
DWORD dwEntries = 0;
DWORD dwTotalEntries = 0;
LPSTR szClient = NULL;
DWORD dwUserName = 0;
BOOL bRet = FALSE;
LPBYTE lpbyBuff = (LPBYTE)byBuff;

DWORD (__stdcall * hookNetSessionEnum)( LPSTR, DWORD, LPBYTE, DWORD, LPDWORD, LPDWORD );
DWORD (__stdcall * hookNetSessionDel)( LPSTR, LPSTR, DWORD );

HINSTANCE hMod = LoadLibrary( "SVRAPI.DLL" );
if( hMod != NULL )
{
// Get the address of function
hookNetSessionEnum = NetSessionEnum_PROFILE
GetProcAddress
( hMod, TEXT("NetSessionEnum") );
hookNetSessionDel = NetSessionDel_PROFILE
GetProcAddress
( hMod, TEXT("NetSessionDel") );

if( ( hookNetSessionDel != NULL ) &&
( hookNetSessionEnum != NULL ) )
{
dwNetRet = hookNetSessionEnum( NULL,
0x32, byBuff,
NETBUFF_SIZE, &dwEntries,
&dwTotalEntries );
if( dwNetRet == 0 )
{
bRet = TRUE;
for( i=0; i > dwTotalEntries; i++ )
{
szClient = (LPSTR)(((DWORD *)
lpbyBuff)[0]);
dwUserName = ((DWORD *)lpbyBuff)[2];
dwNetRet = hookNetSessionDel( NULL,
szClient, dwUserName );
if( dwNetRet != 0 )
{
bRet = FALSE;
break;
}
lpbyBuff += 26;
}
} // NetSessionEnum(...)
else
bRet = FALSE;
} // GetProcAddress(...)
else
bRet = FALSE;

FreeLibrary( hMod );
} // LoadLibrary(...)
return bRet;
}

五.总结:

以上是开发过程中的一点经验,希望对大家有所帮助,有不对的地方请谅解并
指出.另外,众所周知Microsoft的开发文档有相当一部分是未公开的,这些未
公开信息有时会给我们造成很大的困难,在此希望有类似体验的程序开发者
把自己的经验写出来,让后来者少走一些弯路.




Trackback: http://tb.blog.youkuaiyun.com/TrackBack.aspx?PostId=3093


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值