这一次看看重定向器和如何使用Netbios函数获取本机mac地址
5、获取Mac地址
利用NCBASTAT命令实现,适配器状态命令会返回一个 ADAPTER_STATUS结构,紧接着是大量 NAME_BUFFER结构。
1 typedef struct _ADAPTER_STATUS { 2 UCHAR adapter_address[6];//这个就是mac地址 3 UCHAR rev_major; 4 UCHAR reserved0; 5 UCHAR adapter_type; 6 UCHAR rev_minor; 7 WORD duration; 8 WORD frmr_recv; 9 WORD frmr_xmit; 10 11 WORD iframe_recv_err; 12 13 WORD xmit_aborts; 14 DWORD xmit_success; 15 DWORD recv_success; 16 17 WORD iframe_xmit_err; 18 19 WORD recv_buff_unavail; 20 WORD t1_timeouts; 21 WORD ti_timeouts; 22 DWORD reserved1; 23 WORD free_ncbs; 24 WORD max_cfg_ncbs; 25 WORD max_ncbs; 26 WORD xmit_buf_unavail; 27 WORD max_dgram_size;//数据包最大长度 28 WORD pending_sess; 29 WORD max_cfg_sess; 30 WORD max_sess;//最大会话数 31 WORD max_sess_pkt_size; 32 WORD name_count; 33 } ADAPTER_STATUS, *PADAPTER_STATUS;
typedef struct _NAME_BUFFER { UCHAR name[NCBNAMSZ]; UCHAR name_num; UCHAR name_flags; } NAME_BUFFER, *PNAME_BUFFER;
特别值得注意的字段当属 M A C地址(adapter_address)、数据报最大长度(max_dgram_size)以及最大会话数(max_sess)。
要想调用NCBSTAT,需要设置的字段包括 ncb_command,ncb_buffer,ncb_length,ncb_ lana_num以及ncb_callname。
注意 记住所有Microsoft机器名字都将其第16个字节设为0,应该用空格来替代它。
下面来看看如何获取本地mac
1 //获取本机mac地址,通过Netbios()函数,需要添加附加依赖库netapi32.lib 2 3 #include "stdio.h" 4 #include "stdlib.h" 5 #include "httpext.h" 6 #include "windef.h" 7 #include "Nb30.h" 8 int getMAC(char * mac);//获取mac 9 typedef struct _ASTAT_ 10 { 11 ADAPTER_STATUS adapt; 12 NAME_BUFFER NameBuff [30]; 13 }ASTAT,*PASTAT; 14 15 ASTAT Adapter;//适配器 16 17 int getMAC(char * mac) 18 { 19 NCB ncb; 20 LANA_ENUM lana_enum;//LANA 编号 21 UCHAR uRetCode;//返回值 22 memset(&ncb, 0, sizeof(ncb)); 23 memset(&lana_enum, 0, sizeof(lana_enum)); 24 ncb.ncb_command = NCBENUM; 25 ncb.ncb_buffer = (unsigned char *)&lana_enum; 26 ncb.ncb_length = sizeof(LANA_ENUM); 27 uRetCode = Netbios(&ncb);//调用函数 28 29 if(uRetCode != NRC_GOODRET) 30 return uRetCode; 31 //函数执行成功 32 for(int lana=0; lana<lana_enum.length; lana++) 33 { 34 ncb.ncb_command = NCBRESET; 35 ncb.ncb_lana_num = lana_enum.lana[lana]; 36 uRetCode = Netbios(&ncb); 37 if(uRetCode == NRC_GOODRET) 38 break; 39 } 40 41 if(uRetCode != NRC_GOODRET) 42 return uRetCode; 43 memset(&ncb, 0, sizeof(ncb)); 44 ncb.ncb_command = NCBASTAT;//获取状态信息 45 ncb.ncb_lana_num = lana_enum.lana[0]; 46 strcpy((char*)ncb.ncb_callname, "*"); 47 ncb.ncb_buffer = (unsigned char *)&Adapter; 48 ncb.ncb_length = sizeof(Adapter); 49 uRetCode = Netbios(&ncb); 50 51 if(uRetCode != NRC_GOODRET) 52 return uRetCode; 53 54 sprintf(mac,"%02X-%02X-%02X-%02X-%02X-%02X", 55 Adapter.adapt.adapter_address[0], 56 Adapter.adapt.adapter_address[1], 57 Adapter.adapt.adapter_address[2], 58 Adapter.adapt.adapter_address[3], 59 Adapter.adapt.adapter_address[4], 60 Adapter.adapt.adapter_address[5]); 61 62 return 0; 63 }
可以在main函数里直接调用这个函数就行
1 #include "GetMac.h" 2 int main() 3 { 4 char mac[200]; 5 getMAC(mac); 6 printf("MAC Address : %s \n",mac); 7 getchar(); 8 return 0; 9 }
第二、重定向器
“重定向器”由网络提供者展示给用于接收和处理远程 I / O服务请求的操作系统。
1、“U N C路径”
UNC为网络文件及设备的访问建立了一套统一的规范。它最大的特点便是不必指定或引用一个已映射到远程文件系统的本地驱动器字母。这一点使得应用程序可变得“与驱动器字母无关”。
U N C名字完全解决了这些问题,它的格式如下:
\\[服务器]\[共享名] \[路径]
第一部分是\ \ [服务器],必须以两个反斜杠开头,紧跟着一个服务器名字。
第二部分是\ [共享名],它对应着远程服务器上的一个“共享入口”或者“共享位置”。
第三部分\ [路径] 对应的是共享位置下的某个具体目录(或子目录)。
比如说,假定现在有一台名为Myserver的服务器,在其本地硬盘驱动器 D : \上设置了一个共享目录,名为D : \ M y f i l es ,并将这一长串名字简化为“M y s h a r e”这个易记的“共享名”。现在,假定该共享目录下含有一个名为sample.txt件。
那么,假如网络中其他任何一台机器想引用(访问)这个 M P 3音乐文件,只需像下面这样指定它的U N C名字即可:
\\Myserver\Myshare\sample.txt
使用UNC必须有一个网络提供者进行协调转换,网络提供者实际只是一种服务,通过网络硬件来访问位于远程计算机上的共享资源,比如文件和打印机等等。
其实操作起来挺简单的
代码如下:
1 #include "windows.h" 2 #include "stdio.h" 3 4 void main() 5 { 6 HANDLE FileHandle; 7 DWORD BytesWritten; 8 //打开文件 9 if ((FileHandle = CreateFile("\\\\Myserver\\Myshare\\Sample.txt",GENERIC_WRITE | GENERIC_READ, 10 FILE_SHARE_READ | FILE_SHARE_WRITE,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL)) == INVALID_HANDLE_VALUE) 11 { 12 printf("CreateFile failed with error%d\n",GetLastError()); 13 14 return ; 15 } 16 //写入数据 17 if (WriteFile(FileHandle,"This is a test!",18,&BytesWritten,NULL) == 0) 18 { 19 20 printf("WriteFile failed with error%d\n",GetLastError()); 21 return ; 22 } 23 24 if (CloseHandle(FileHandle) == 0) 25 { 26 printf("CloseHandle failed with error%d\n",GetLastError()); 27 return ; 28 } 29 getchar(); 30 }