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

    技术2022-05-11  106

    在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的开发文档有相当一部分是未公开的,这些未 公开信息有时会给我们造成很大的困难,在此希望有类似体验的程序开发者 把自己的经验写出来,让后来者少走一些弯路.

    最新回复(0)