网络扫描技术揭秘读书笔记2--扫描器中公用编程示例(1)
2013-10-30 21:31
218 查看
编程环境:工具 VS2010 MFC 使用字符集:Unicode
1.
CTreeCtrl控件的应用
在对话框中,放置一个CTreeCtrl树型控件,属性Has Buttons、HasLines和Lines At Root都设为True,调整到合适的位置和大小,同时要声明一个CTreeCtrl的变量与此控件绑定:
CTreeCtrlm_ctlTreeResult;
在VC++里,所有的节点都是一个HTREEITEM的数据结构。
生成树状结构,只需要用到一个主要的函数InsertItem即可,该函数有如下几种调用方式:
HTREEITEMInsertItem( LPTVINSERTSTRUCT lpInsertStruct );
HTREEITEMInsertItem(UINT nMask, LPCTSTR lpszItem, int nImage, int nSelectedImage, UINTnState, UINT nStateMask, LPARAM lParam, HTREEITEM hParent, HTREEITEMhInsertAfter );
HTREEITEMInsertItem( LPCTSTR lpszItem, HTREEITEM hParent = TVI_ROOT, HTREEITEMhInsertAfter = TVI_LAST );
HTREEITEMInsertItem( LPCTSTR lpszItem, int nImage, int nSelectedImage, HTREEITEM hParent= TVI_ROOT, HTREEITEM hInsertAfter = TVI_LAST);
返回值:无论哪一个调用,如果调用成功,返回的都是一个HTREEITEM变量(该变量实际就是一个句柄);如果调用失败,返回的是一个NULL。在平时使用中,如果要插入的项是叶子节点,可以不考虑返回值,如果是根节点或分支节点,则需要保存返回的值,因为下一步在该节点下面再加入新的节点时,要用到这个返回值。
在第3项调用中,参数lpszItem即插入节点的描述字符串。hParent表示将当前哪个节点作为父节点,插入到该节点下面,默认的值是TVI_ROOT,表示直接插入到根节点下,否则就可以用前面调用InsertItem之后保存的返回值作为父节点,将当前节点插入到该节点的下面。hInsertAfter表示当要插入的父节点已有子节点时,当前插入的节点放置到什么位置,可取值分别为:
运行结果:
2. CListCtrl控件的应用
要创建这样的一个结构,首先需要在对话框中,放置一个CListCtrl列表控件,调整到合适的位置和大小,同时要声明一个CListCtrl的变量与此控件绑定。
注意不要忘了将View属性设为Report,即为报表风格。
CListCtrlm_ctlListResult;
与树型控件CTreeCtrl不同的是,CListCtrl的创建要分两步,第一步是设置控件的表头部分,第二步才是增、修、删其数据项。
运行结果:
3.IP地址互换
一个IP地址通常描述为以点分隔的字符串,例如“192.168.1.100”,这种方式很方便于人识别,但在计算机处理中并不方便,原因在于这样表示的IP地址存在以下不足:(1)整个字符串的长度不定长,给传输、存储带来麻烦。(2)给编程时的程序判断带来麻烦,例如想知道某一个IP之后的一个IP是什么,再如某一个IP是不是在某两个IP所组成的IP网段里?
计算机所处理的IP地址是用一种UINT无符号整型表示的(当然,在使用中用int或DWORD也都可以),这样做可以避免字符串表示方式中难以处理的问题,但却具有可读性差的缺点,因此一个程序中,应该同时具有两种表现形式,又可以相互转换。
要实现其中几种类型的转换,可以使用系统提供的API函数,也可以自己编写。使用API的优点是直接使用,缺点是不够灵活,有些API当输入出错时,会自动按默认数据处理,而自己编写的转换函数可以按自己要求处理。
1.Win32 Console版
2.MFC版
4.Windows操作系统类型的判断
通过GetVersion和GetVersionEx函数读取操作系统的版本
该函数返回一个DWORD类型,其中数据高位是主版本号,数据低位是次版本号。
1.
CTreeCtrl控件的应用
在对话框中,放置一个CTreeCtrl树型控件,属性Has Buttons、HasLines和Lines At Root都设为True,调整到合适的位置和大小,同时要声明一个CTreeCtrl的变量与此控件绑定:
CTreeCtrlm_ctlTreeResult;
在VC++里,所有的节点都是一个HTREEITEM的数据结构。
生成树状结构,只需要用到一个主要的函数InsertItem即可,该函数有如下几种调用方式:
HTREEITEMInsertItem( LPTVINSERTSTRUCT lpInsertStruct );
HTREEITEMInsertItem(UINT nMask, LPCTSTR lpszItem, int nImage, int nSelectedImage, UINTnState, UINT nStateMask, LPARAM lParam, HTREEITEM hParent, HTREEITEMhInsertAfter );
HTREEITEMInsertItem( LPCTSTR lpszItem, HTREEITEM hParent = TVI_ROOT, HTREEITEMhInsertAfter = TVI_LAST );
HTREEITEMInsertItem( LPCTSTR lpszItem, int nImage, int nSelectedImage, HTREEITEM hParent= TVI_ROOT, HTREEITEM hInsertAfter = TVI_LAST);
返回值:无论哪一个调用,如果调用成功,返回的都是一个HTREEITEM变量(该变量实际就是一个句柄);如果调用失败,返回的是一个NULL。在平时使用中,如果要插入的项是叶子节点,可以不考虑返回值,如果是根节点或分支节点,则需要保存返回的值,因为下一步在该节点下面再加入新的节点时,要用到这个返回值。
在第3项调用中,参数lpszItem即插入节点的描述字符串。hParent表示将当前哪个节点作为父节点,插入到该节点下面,默认的值是TVI_ROOT,表示直接插入到根节点下,否则就可以用前面调用InsertItem之后保存的返回值作为父节点,将当前节点插入到该节点的下面。hInsertAfter表示当要插入的父节点已有子节点时,当前插入的节点放置到什么位置,可取值分别为:
BOOL CCTreeCtrlEGDlg::OnInitDialog() { CString strItem;//用于生成各项的值。 strItem.Format(_T("NetBIOS扫描[127.0.0.1]")); //将根节点插入,并记下该节点的位置到root变量中,以备后面再插入节点时使用 HTREEITEM root=m_ctlTreeResult.InsertItem(strItem); strItem.Format(_T("主机名:localhost")); //插入“主机名”的叶子节点到root根节点上 m_ctlTreeResult.InsertItem(strItem,root); strItem.Format(_T("共享文件夹")); //插入“共享文件夹”的分支节点到root根节点上 HTREEITEM curr=m_ctlTreeResult.InsertItem(strItem,root); //插入在root根节点下 int iItemDir=3; char *ShareFolers[3]={"E$[]","IPC$[]","D$[]"}; TCHAR *TcharTempItem; int i,byteLen,Charlen; for (i=0;i<iItemDir;i++) { //依次生成各个共享的文件夹名 //char *-->CString(TCHAR) byteLen=strlen(ShareFolers[i]); //1.先计算多字节字符的大小 Charlen=MultiByteToWideChar(CP_ACP,0,ShareFolers[i],byteLen,NULL,0); //2.为宽字节字符数组申请空间 TcharTempItem=new TCHAR[Charlen+1]; //3.多字节编码转换成宽字节编码(In Unicode: TCHAR/CString) MultiByteToWideChar(CP_ACP,0,ShareFolers[i],byteLen,TcharTempItem,Charlen); TcharTempItem[Charlen]='\0';//添加字符串结尾标示符 m_ctlTreeResult.InsertItem(TcharTempItem,curr); //插入在curr结点下作为子节点 } strItem.Format(_T("当前时间:2013-10-27"));//当前时间 //插入“当前时间”的叶子节点到root根节点上 m_ctlTreeResult.InsertItem(strItem,root); strItem.Format(_T("用户名")); //插入“用户名”的分支节点到root根节点上 curr=m_ctlTreeResult.InsertItem(strItem,root); char *Users[3]={"Wang","Zhou","Li"}; for (i=0;i<iItemDir;i++) { byteLen=strlen(Users[i]); Charlen=MultiByteToWideChar(CP_ACP,0,Users[i],byteLen,NULL,0); TcharTempItem=new TCHAR[Charlen+1]; MultiByteToWideChar(CP_ACP,0,Users[i],byteLen,TcharTempItem,Charlen); TcharTempItem[Charlen]='\0'; m_ctlTreeResult.InsertItem(TcharTempItem,curr); } }
运行结果:
2. CListCtrl控件的应用
要创建这样的一个结构,首先需要在对话框中,放置一个CListCtrl列表控件,调整到合适的位置和大小,同时要声明一个CListCtrl的变量与此控件绑定。
注意不要忘了将View属性设为Report,即为报表风格。
CListCtrlm_ctlListResult;
与树型控件CTreeCtrl不同的是,CListCtrl的创建要分两步,第一步是设置控件的表头部分,第二步才是增、修、删其数据项。
/*预定义一些字段顺序的宏定义,之后如果想调整字段的顺序,只需要修改此宏定义的 顺序即可。注意:下面宏定义由0起,并且顺序号必须相连,不得间断。*/ #define LIST_RESULT_INDEX 0 #define LIST_RESULT_IP 1 #define LIST_RESULT_STATUS 2 #define LIST_RESULT_MAC 3 #define LIST_RESULT_NAME 4 #define LIST_RESULT_COMMENT 5 BOOL ScanListDlg::OnInitDialog() { CoInitialize(NULL); //初始化COM库 CDialogEx::OnInitDialog();//必须先初始化对话框 CRect rect; // 获取列表视图控件的位置和大小 m_ctlListResult.GetClientRect(&rect); //设定列表的风格是有网格线,并且在选择的时候是选中一行,而不是首字段 m_ctlListResult.SetExtendedStyle(m_ctlListResult.GetExtendedStyle()|LVS_EX_FULLROWSELECT| LVS_EX_GRIDLINES); //创建表头部分 //m_ctlListResult.InsertColumn(LIST_RESULT_INDEX,_T("序号"),LVCFMT_CENTER,rect.Width()/6,0); m_ctlListResult.InsertColumn(LIST_RESULT_INDEX,_T("序号"),LVCFMT_CENTER,40); m_ctlListResult.InsertColumn(LIST_RESULT_IP,_T("IP"),LVCFMT_LEFT,110); m_ctlListResult.InsertColumn(LIST_RESULT_STATUS,_T("状态"),LVCFMT_LEFT,80); m_ctlListResult.InsertColumn(LIST_RESULT_MAC,_T("MAC"),LVCFMT_LEFT,115); m_ctlListResult.InsertColumn(LIST_RESULT_NAME,_T("主机名"),LVCFMT_LEFT,100); m_ctlListResult.InsertColumn(LIST_RESULT_COMMENT,_T("注释"),LVCFMT_LEFT,100); CString strItem;//用于生成各项的值 int iNum=10; for (int i=0;i<iNum;i++) { strItem.Format(_T("%d"),i+1); m_ctlListResult.InsertItem(i,strItem); //插入列表项(即每行第一个元素) strItem.Format(_T("192.168.1.%d"),i+1); //设置列表子项文本 m_ctlListResult.SetItemText(i,LIST_RESULT_IP,strItem); m_ctlListResult.SetItemText(i,LIST_RESULT_STATUS,_T("扫描中...")); m_ctlListResult.SetItemText(i,LIST_RESULT_MAC,_T("FF-FF-FF-FF-FF-FF")); m_ctlListResult.SetItemText(i,LIST_RESULT_NAME,_T("localhost")); m_ctlListResult.SetItemText(i,LIST_RESULT_COMMENT,_T("No")); } return TRUE; }
运行结果:
3.IP地址互换
一个IP地址通常描述为以点分隔的字符串,例如“192.168.1.100”,这种方式很方便于人识别,但在计算机处理中并不方便,原因在于这样表示的IP地址存在以下不足:(1)整个字符串的长度不定长,给传输、存储带来麻烦。(2)给编程时的程序判断带来麻烦,例如想知道某一个IP之后的一个IP是什么,再如某一个IP是不是在某两个IP所组成的IP网段里?
计算机所处理的IP地址是用一种UINT无符号整型表示的(当然,在使用中用int或DWORD也都可以),这样做可以避免字符串表示方式中难以处理的问题,但却具有可读性差的缺点,因此一个程序中,应该同时具有两种表现形式,又可以相互转换。
要实现其中几种类型的转换,可以使用系统提供的API函数,也可以自己编写。使用API的优点是直接使用,缺点是不够灵活,有些API当输入出错时,会自动按默认数据处理,而自己编写的转换函数可以按自己要求处理。
1.Win32 Console版
char *iptos(UINT in) { char *output=new char[16]; u_char *p=(u_char *)in; sprintf(output, "%d.%d.%d.%d", p[0], p[1], p[2], p[3]); return output; } UINT StringIptoUint(const char *IpString)//Convert IP Address(String Format to Long) {//eg:172.22.145.128 UINT IpUint=0; char *temp=new char[4]; int i,t=1; int dot_len=0; memset(temp,0,4); for(i=0;i<(int)strlen(IpString);i++) { /* >>> 172+22*256+145*256*256+128*256*256*256 */ if(IpString[i]=='.') { memcpy(temp,IpString+i-dot_len,dot_len); IpUint+=StringNumToUint(temp)*t;//********* t*=256; memset(temp,0,sizeof(temp)); dot_len=0; } else dot_len++; } //最后一个点分十进制 即UINT的最高字节 memcpy(temp,IpString+i-dot_len,dot_len); IpUint+=StringNumToUint(temp)*t; printf("IpUint=%u\n",IpUint); return IpUint; }
2.MFC版
typedef union MultiByteStruct {//IP地址联合体 int iInt; //int有符号整型 float fFloat; //浮点数 UINT uInt; //无符号整数 ULONG uLong; //ULONG无符号整型 DWORD dwDword; //DWORD有符号整型 WORD wWord[2]; //WORD无符号整型数组 UCHAR ucByte[4]; //无符号字符数组 char cByte[4]; //字符数组 }UNIONIP,*PUNIONIP; CString IPConvert::IPIntToStr(UINT IPInt) { CString IPStr; UNIONIP IP; IP.uInt=IPInt; IPStr.Format(_T("%d.%d.%d.%d"),IP.ucByte[0],IP.ucByte[1],IP.ucByte[2],IP.ucByte[3]); return IPStr; } UINT IPConvert::IPStrToInt(CString IPStr,BOOL bShowMsgBox) { UNIONIP IP; int i,j=0; IPStr.TrimLeft(_T(" ")); IPStr.TrimRight(_T(" ")); for (i=0;i<IPStr.GetLength();i++) { if (IPStr.GetAt(i) <'0' || IPStr.GetAt(i)>'9') if (IPStr.GetAt(i) == '.') j++; else { if (bShowMsgBox) MessageBox(_T("IP串中有非法字符,合适的字符为“0~9”和“.”!")); return 0; } } if (j!=3) { if (bShowMsgBox) MessageBox(_T("IP串格式不对!")); return 0; } i=0; IPStr+="."; CString temp; char *charstr_temp;// for (int m=0;m<4;m++) { temp=""; while (IPStr.GetAt(i) != '.') { temp+=IPStr.GetAt(i); i++; } i++; CStringToCharStr(temp,&charstr_temp); if (temp=="" || atoi(charstr_temp) > 0xFF) { if (bShowMsgBox) MessageBox(_T("IP串格式不对!")); return 0; } else { CStringToCharStr(temp,&charstr_temp); IP.ucByte[m]=atoi(charstr_temp); } } return IP.uInt; } void IPConvert::CStringToCharStr(CString str,char **char_str) { int charlen=str.GetLength();//字符长度 int Bytelen = WideCharToMultiByte(CP_ACP,0,str,charlen,NULL,0,NULL,NULL);//字节长度 *char_str = new char[Bytelen+1]; //以字节为单位 WideCharToMultiByte(CP_ACP,0,str,charlen,*char_str,Bytelen,NULL,NULL); (*char_str)[Bytelen] = '\0'; //多字节字符以'\0'停止 }
4.Windows操作系统类型的判断
通过GetVersion和GetVersionEx函数读取操作系统的版本
该函数返回一个DWORD类型,其中数据高位是主版本号,数据低位是次版本号。
#ifndef _GETOSTYPE_H_ #define _GETOSTYPE_H_ enum Win32Type{Win32s,WinNT3,Win95,Win98,WinME,WinNT4,Win2000,WinXP,Win7}; Win32Type IsShellType(); static Win32Type g_Shell=IsShellType(); Win32Type IsShellType() { Win32Type ShellType; DWORD winVer; OSVERSIONINFO *osvi; //通过GetVersion和GetVersionEx函数读取操作系统的版本 //该函数返回一个DWORD类型,其中数据高位是主版本号,数据低位是次版本号。 winVer=GetVersion(); if(winVer<0x80000000)//最高位 {/*NT架构系列*/ ShellType=WinNT3; osvi= (OSVERSIONINFO *)malloc(sizeof(OSVERSIONINFO)); if (osvi!=NULL) { memset(osvi,0,sizeof(OSVERSIONINFO)); osvi->dwOSVersionInfoSize=sizeof(OSVERSIONINFO); GetVersionEx(osvi); //主版本等于4,表示是Windows NT4.0系列 if(osvi->dwMajorVersion==4L) ShellType=WinNT4; //主版本等于5,次版本是0,表示是Windows 2000系列 else if(osvi->dwMajorVersion==5L && osvi->dwMinorVersion==0L) ShellType=Win2000; //主版本等于5,次版本是1,表示是Windows XP系列 else if(osvi->dwMajorVersion==5L && osvi->dwMinorVersion==1L) ShellType=WinXP; //Windows NT6.1 --Windows 7 else if(osvi->dwMajorVersion==5L && osvi->dwMinorVersion==1L) ShellType=Win7; free(osvi); } } else { if (LOBYTE(LOWORD(winVer))<4) ShellType=Win32s; else { ShellType=Win95; osvi= (OSVERSIONINFO *)malloc(sizeof(OSVERSIONINFO)); if (osvi!=NULL) { memset(osvi,0,sizeof(OSVERSIONINFO)); osvi->dwOSVersionInfoSize=sizeof(OSVERSIONINFO); GetVersionEx(osvi); //主版本等于4,次版本是10,表示是Windows 98系列 //主版本等于4,次版本是90,表示是Windows ME系列 if(osvi->dwMajorVersion==4L && osvi->dwMinorVersion==10L) ShellType=Win98; else { if(osvi->dwMajorVersion==4L && osvi->dwMinorVersion==90L) ShellType=WinME; } free(osvi); } } } return ShellType; } #endif
相关文章推荐
- 网络扫描技术揭秘读书笔记2--扫描器中公用编程示例(2)
- php应该遵循什么样的编码规范?PHP符合PSR编程规范示例
- linux下应用oci编程示例
- C# .NET编程基础-throw异常处理-Email格式检测示例
- Java socket编程服务器端/客户端代码编写示例
- cuda编程入门示例3---数组求和
- cuda编程入门示例15
- C#编程获取客户端计算机硬件及系统信息功能示例
- Hadoop编程基于MR程序实现倒排索引示例
- Java UDP网络编程 - 最简单示例
- python原始套接字编程示例分享
- Android 编程之第三方开发 MaoZhuaWeiBo微博开发示例-1
- C++ 并发编程,std::unique_lock与std::lock_guard区别示例
- JavaSE经典编程示例
- 多线程Java Socket编程示例
- Python UDP编程小示例
- Socket编程指南及示例程序
- Muduo 网络编程示例之七:“串并转换”连接服务器及其自动化测试
- 网络编程 Socket编程指南及示例程序
- [IE编程] 多页面基于IE内核浏览器的代码示例