简述WINDOWS进程管理工具的原理和实现_第1页
简述WINDOWS进程管理工具的原理和实现_第2页
简述WINDOWS进程管理工具的原理和实现_第3页
简述WINDOWS进程管理工具的原理和实现_第4页
简述WINDOWS进程管理工具的原理和实现_第5页
已阅读5页,还剩26页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

(企业管理工具)简述WINDOWS进程管理工具的原理和实现591论文网www.591LW.com简述WINDOWS进程管理工具的原理和实现摘要Windows自带的任务管理器存在功能上的缺陷,比如不能查看进程的模块及线程信息。课题设计就是模拟Windows任务管理器,开发一个功能更完善的WindowsVC++程管理的基本功能。在程序的设计过程中,通过调用WindowsAPI函数而获得任WindowsXP系统上况提供了很好的参考。关键词:任务管理器;线程;进程;API591论文网www.591LW.comTheDesignandImplementationoftheProcessesManagementToolforWindowsAbstractTherearesomedefectsintheTaskManagerbuilt-inWindows.Forexample,itdoesn'tshowustheinformationofprocessmodulesandthreads.TheworkofmydesignistofollowtheWindowsTaskManageranddevelopthesoftwarewhichhasimprovedfunctionformanagingprocess.ThissoftwareisdesignedtobeaprogrambasedonadialogwriteintheVC++.Thereisalabelcontrolinthemaindialogbox,andtherearethreepagesfortask,processandsysteminformation.Thelabelcontrolisusedtoselectthepageandtoshowit.Thethreepagesareusedrespectivelytodisplaytheinformationoftaskrunsatcurrent,processandprocessmodules,theutilizationofsystemresources.Thissoftwarealsorealizedsomebasicfunctionformanagingprocess,suchasendingthetask,switchingthetask,terminatingtheprocessandsoon.Duringtheprocessofmyprogram,theinformationfortasks,process,threadmodulesandtheutilizationofsystemresourceisgotbycallingtheWindowsAPIfunctions.FinallyItestitontheWindowsXPsystem.Anditachievesthebasicfunctionformanagingprocess.Itprovidesagoodreferenceforuserstoviewtheprocessatcurrentandtheutilizationofsystemresources.Keywords:TaskManager;Threads;Process;API591论文网www.591LW.com目录论文总页数:25页1引言11.1课题背景11.2国内外研究现状11.3课题研究的意义11.4课题的研究方法11.5进程与线程简介11.5.1进程简介11.5.2线程简介31.5.3进程与线程的关系31.5.4Windows自带的任务管理器分析42主要功能及设计思路42.1主要功能42.2设计思路53详细设计53.1主框架的实现53.1.1子对话框的显示63.1.2实现菜单73.1.3提升程序权限83.2任务列表页面设计83.2.1显示任务信息83.2.2结束任务93.2.3切换任务103.3进程列表页面设计103.3.1显示进程信息113.3.2显示模块及线程信息133.3.3结束进程153.3.4删除文件163.3.5保存进程信息到文件173.4系统性能页面设计173.4.1绘制CPU使用率图173.4.2绘制内存使用率图193.4.3其他性能显示193.4.4系统信息显示204测试结果214.1测试环境214.2测试方法214.3测试结果21结论23参考文献23591论文网www.591LW.com1引言1.1课题背景的一些关于计算机操作系统、进程、计算机安全、编程等知识)的能力,模拟Windows任务管理器,开发一个功能更完善的Windows进程管理软件,对任务、进程进行查看、结束等操作。1.2国内外研究现状从现状看来,Windows技术都相当成熟。微软Windows操作系统系列(98和ME除外)都自带有进程管理器,但功能不是很完善,不能查看进程模块及线程信息,而许多其他版本的Windows进程管理软件都具有完善的功能。1.3课题研究的意义Windows第1页共25页591论文网www.591LW.com次模拟实际产品的开发,对于自己以后工作能力的培养具有重要的意义。1.4课题的研究方法系统使用VC++6.0Windows的任务管理器进行设计与开发。的开发工具进行开发;同时,在开发设计与实现中,要保存好相关的设计文挡。1.5进程与线程简介1.5.1进程简介DLL模块的代码和数据。它还包含动态内存分配的空间。如线程堆栈和堆分配空间。址空间。述。进程的静态描述由三部份组成:进程控件块PCB,有关程序段和该程序段对PCB感知进程的存在和通过PCB中所包含的各项变量的变化,掌握进程所处的状态以及达到控制进程活动的PCB第2页共25页591论文网www.591LW.com作系统中,一个进程的PCB结构都是全部或部分常驻内存的。多道操作系统中,这两部分内容存放在外存中,直到该进程执行时再调入内存。根据PCB结构中的状态值控制进程。已经得到除CPU之外的其它资源,只要由调度得到处理机,便可立即投入执行。进入就绪状态,如图1。图1进程状态转换1.5.2线程简介用户程序控制。它用于维护线程在执行代码时需要的所有函数参数和局部变量TCB组成。寄存器可被用来存储线程内的局部变量,但不能存储其它线程的相关变量。第3页共25页591论文网www.591LW.com基本状态,存在五种基本操作来转换线程的状态。这五种基本操作是:1、派生:线程在进程内派生出来,它既可由进程派生,也可由线程派生。2、阻塞:如果一个线程在执行过程中需要等待某个事件发生,则被阻塞。3、激活:如果阻塞线程的事件发生,则该线程被激活并进入就绪队列。4、调度:选择一个就绪线程进入执行状态。5、结束:如果一个线程执行结束,它的寄存器上下文以及堆栈内容等将被释放。1.5.3进程与线程的关系程可能包含若干个线程,所有这些线程都“同时”执行进程地址空间中的代码。CPU寄由了,系统就将自动撤消该进程和它的地址空间。CPU时3显示了在单个CPU的计算机上是如何实现这种运行方式的。如果计算机拥有多个CPU,那么操作系统就要使用复杂得多的第4页共25页591论文网www.591LW.com算法来实现CPU上线程负载的平衡。当创建一个进程时,系统会自动创建它的第一个线程,称为主线程。然后,该线程可以创建其他的线程,而这些线程又能创建更多的线程。1.5.4Windows自带的任务管理器分析Windows任务管理器由性能、进程、应用程序三大部分组成。其实这三大部CPU余的数据都是由进程模块顺便取得的。Windows2000/XP的任务管理器通过NtQuerySystemInformation的调用来获CPU在任务管理器中的几乎所有信息都是来自该函数。NtQuerySystemInformation函数隶属,是一个未公开的函数。其调用方式为:NTSTATUSNtQuerySystemInformation(SYSTEM_INFORMATION_CLASSSystemInformationClass,PVOIDSystemInformation,ULONGSystemInformationLength,PULONGReturnLength);SystemInformationClass:在SYSTEM_INFORMATION_CLASS中的枚举值之一,声明返回信息的种类;SystemInformation:指到一个要求返回信息的缓冲区,这个系统信息变量的尺寸和结构依赖于SystemInformationClass参数的值;SystemInformationLength:SystemInformation参数指定的缓冲区尺寸;ReturnLength:返回值尺寸。Windows2000和WindowsXP在Windows98和WindowsMe第5页共25页591论文网www.591LW.com用复杂。因此,在此次进程管理器的开发中,将使用其它方法来获取各类信息。2主要功能及设计思路2.1主要功能设计要求实现的主要功能——进程管理功能,具体包括以下内容:(1)任务管理:列出所有当前运行的窗口程序名、运行状态等信息;对它们进行终止、切换等操作。(2)进程管理:列出所有的Windows进程,以及进程所在的磁盘绝对路径,(3)CPU和用户名等。2.2设计思路在VisualC++6.0环境设计一个基于对话框的应用程序,类似于Windows自带的任务管理器,主窗口上添加一个标签控件,加入三个页面,分别是:任务、进程和系统性能信息。(可见且有窗口标题)进行显示,并能够对任务进行操作,如:添加新任务,结束任务,切换任务等。进行显示,并能够实行终止进程、进程列表保存到文件等操作。第6页共25页591论文网www.591LW.com系统性能页面显示物理内存、虚拟内存和页文件等详细使用情况,CPU、内CPU使用率和内存使用率的图形,并用列表控件显示系统当前信息(系统名、计算机名和当前用户等)。3详细设计程序主界面如图2。窗口程序、进程及进程模块、系统资源使用情况。图2主界面3.1主框架的实现所设计的程序是基于对话框的程序。首先创建一个基于对话框的应用程序,在主对话框类PcsMgrDlg三个页面,如图3。3.每一项时,分别显示对应页面的相关信息。Style属性设为ChildBoard设为NoneCTaskCProcess,CChart,并定义这三个类的变量:CTaskm_Task;//任务第7页共25页591论文网www.591LW.comCProcessm_Process;//进程CChartm_Chart;//图表并定义一个图像列表变量用于存放标签图标:CImageListm_ImageList;接下来就创建子窗口:m_(IDD_TASK,m_());m_(IDD_PROCESS,m_());m_(IDD_CHART,m_());当用户选择标签中的一项是,为了将对应的对话框在标签控件中显示出来,需要在OnShowWindow(BOOLbShow,UINTnStatus)中添加代码相关代码。这样便可示不同页面还需在OnSelchangeMaintab(NMHDR*pNMHDR,LRESULT*pResult)和OnSelchangingMaintab(NMHDR*pNMHDR,LRESULT*pResult)两函数中添加显示代码。voidCPcsMgrDlg::OnSelchangeMaintab(NMHDR*pNMHDR,LRESULT*pResult){switch(m_()){case0:m_(SW_SHOW);//任务页面被选中,则显示任务页面m_();break;case1:m_(SW_SHOW);//任务页面被选中,则显示进程页面m_();break;第8页共25页591论文网www.591LW.comcase2:m_(SW_SHOW);//任务页面被选中,则显示系统信息页面m_();break;}}3.1.2实现菜单WindowsAPI函数ExitWindowsEx()完成的。但在Windows98和Windows2000实现稍有不同。ExitWindowsEx()函数定义格式:BOOLExitWindowsEx(UINTuFlags//操作DWORDdwReason//原因);在Windows98/重启/关机功能将直接调用ExitWindiwsExExitWindowsEx(EWX_LOGOFF,0);//注销ExitWindowsEx(EWX_REBOOT,0);//重启ExitWindowsEx(EWX_SHUTDOWN,0);//关机在Windows2000实现“注销/重启/关机”功能须取得高级权限:LookupPrivilegeValue(NULL,SE_SHUTDOWN_NAME,&[0].Luid);=1;[0].Attributes=SE_PRIVILEGE_ENABLED;AdjustTokenPrivileges(hToken,FALSE,&tkp,0,(PTOKEN_PRIVILEGES)NULL,0第9页共25页591论文网www.591LW.com);ExitWindowsEx(FFlag,0);新建菜单直接调用系统运行对话框:RUNRunFileDlg;RunFileDlg=(RUN)GetProcAddress(hShell32,MAKEINTRESOURCE(61));开机自动运行可在注册表的主键”HKEY_LOCAL_MACHINE”下的运行子键”Software\Microsoft\Windows\CurrentVersion\Run”下写入和删除一个键值的方法实现。3.1.3提升程序权限为了能够终止所有进程,需要提升本进程的权限:1、先调用GetCurrentProcess函数取得当前进程的句柄;2、然后调用OpenProcessToken打开当前进程的访问令牌;3、接着调用LookupPrivilegeValue函数取得你想提升的权限的值;4AdjustTokenPrivileges函数给当前进程的访问令牌增加权限。相关代码是在CPcsMgrApp类的InitInstance()函数中添加。3.2任务列表页面设计添加新任务,结束任务,切换任务等。3.2.1显示任务信息列表页面中添加一个列表控件,用于将任务信息显示出来,如图4。第10页共25页591论文网www.591LW.com要的相关信息:t{CStringstrTaskName;//窗口标题DWORDdwProcessID;//进程IDDWORDdwThreadID;//线程IDCStringstrRunState;//运行状态DWORDdwWndHandle;//窗口句柄}TASK_IFNO,*PTASK_INFO;获取窗口标题,使用API标准函数GetWindowText():chartemp[MAX_PATH];GetWindowText(hwnd,temp,sizeof(temp))获取进程及线程ID:TID=GetWindowThreadProcessId(hwnd,&PID);确定运行状态是利用SendMessageTimeout向窗口发送消息而取得:if(SendMessageTimeout(hwnd,WM_SYSCOMMAND,NULL,NULL,SMTO_ABORTIFHUNG,1000,NULL))strRunState="正在运行";elsestrRunState="没有响应";第11页共25页591论文网www.591LW.com然后添加任务信息到数组:TASK_IFNOti;=temp;=PID;=TID;=(DWORD)hwnd;=strRunState;pTaskThis->m_(ti);最后把任务信息的每一行在任务列表中显示出来:for(inti=0;i<newCount;i++){m_(i,,i);//任务名("%d",);m_(i,1,str);//进程ID("%d",);m_(i,2,str);//线程IDm_(i,3,);//运行状态}3.2.2结束任务结束任务操作将调用SendMessageTimeout函数向要关闭的窗口发送关闭消息,如果没有响应则用TerminateProcess函数强行终止该窗口进程。if(!SendMessageTimeout(hwnd,WM_SYSCOMMAND,SC_CLOSE,NULL,SMTO_BLOC第12页共25页591论文网www.591LW.comK|SMTO_ABORTIFHUNG,1000,NULL)){HANDLEhProcess=OpenProcess(PROCESS_ALL_ACCESS,FALSE,);//打开进程TerminateProcess(hProcess,1);//强制终止该窗口进程CloseHandle(hProcess);}3.2.3切换任务我们知道,Windows9x/2000中SetForegroundWindow函数当用户正在操作其他窗口时是不能强制某个窗口为前景窗口的,而是激活窗口并调用FlashWindowEx函数来通知用户。但是很多实际情况要求将激活窗口的同时将创建这个窗口的线程置为前景状态。碰到这种情况我们可以使用USER32.DLL中的几个未公开API函数。voidSwitchToThisWindow(HWNDhWnd,//被激活的窗口句柄BOOLbRestore//如果被极小化,则恢复窗口);typedefvoid(WINAPI*PROCSWITCHTOTHISWINDOW)(HWND,BOOL);PROCSWITCHTOTHISWINDOWSwitchToThisWindow;HMODULEhUser32=GetModuleHandle("user32");SwitchToThisWindow=(PROCSWITCHTOTHISWINDOW)GetProcAddress(hUser32,"SwitchToThisWindow");接下来只要用任何现存窗口的句柄调用这个函数即可,参数bRestore指定第13页共25页591论文网www.591LW.com如果窗口极小化,是否恢复其原状态。SwitchToThisWindow(hWnd,TRUE);3.3进程列表页面设计当前选择的进程的所以模块信息,如图5。第14页共25页591论文网www.591LW.com图5进程列表页面3.3.1显示进程信息IDCPU级、线程数、父进程ID和进程路径等,如图6。It1、hProcessSnap=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);该函数用于创建一个系统进程快照,取得系统中的所有进程的信息。2Process32First(hProcessSnap,&pe32);该函数取得快照中第一个进程信息,pe32参数是一个PROCESSENTRY32结构类型,该函数将取得的进程信息填充到pe32中。PROCESSENTRY32的定义如下:typedefstructtagPROCESSENTRY32{DWORDdwSize;//结构大小DWORDcntUsage;DWORDth32ProcessID;//进程IDULONG_PTRth32DefaultHeapID;DWORDth32ModuleID;DWORDcntThreads;//线程计数DWORDth32ParentProcessID;//父进程ID第15页共25页591论文网www.591LW.comLONGpcPriClassBase;//优先级DWORDdwFlags;TCHARszExeFile[MAX_PATH];//进程路径}PROCESSENTRY32ID线程数、父进程ID和进程路径等信息。3、BOOLWINAPIProcess32Next(HANDLEhSnapshot,LPPROCESSENTRY32lppe);该函数取得快照中下一个进程信息,参数同Process32First函数。进程基本信息的获取过程如图7。取得。Windows性能头文件(即pdh开给用户的。部分hCounter,PDH_FMT_LONG,&dwctrType,&fmtValue);//得到格式化数据,fmtValue即是我们需要得到的CPU使用率数据。Windows9X系统上不能通过以上方法获得CPU使用率,因此设计的该进程管理软件不能获取9X系统上进程的CPU使用率。要得到进程的内存使用率要用到的函数GetProcessMemoryInfo,首先在第16页共25页591论文网www.591LW.comProcess.h中定义WINAPI函数类型:GETPROCESSMEMORYINFOGetProcessMemoryInfo;,再取得内存使用数:PROCESS_MEMORY_COUNTERSpmc;GetProcessMemoryInfo(hProcess,&pmc,sizeof(pmc));dwMemoryUse=;//内存使用大小pmc返回进程的内存使用信息,它是定义的一个PROCESS_MEMORY_COUNTERS结构,定义如下:typedefstruct_PROCESS_MEMORY_COUNTERS{DWORDcb;DWORDPageFaultCount;//结构尺寸SIZE_TPeakWorkingSetSize;//缺页数SIZE_TWorkingSetSize;//当前工作集尺寸SIZE_TQuotaPeakPagedPoolUsage;//最高页池使用数SIZE_TQuotaPagedPoolUsage;//当前页池使用数SIZE_TQuotaPeakNonPagedPoolUsage;//最高无页池使用数SIZE_TQuotaNonPagedPoolUsage;//当前无页池使用数SIZE_TPagefileUsage;//当前分配页文件空间SIZE_TPeakPagefileUsage;//最高分配页文件空间}PROCESS_MEMORY_COUNTERS,*PPROCESS_MEMORY_COUNTERS;3.3.2显示模块及线程信息ToolHelpAPI函数便可实现。主要用到的函数有:第17页共25页591论文网www.591LW.com1hModuleSnap=CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,dwPID)该函数用于创建指定进程的模块快照。2Module32First(hModuleSnap,&me32);该函数获取指定进程的第一个模块信息,将取得的信息填充到me32中。me32是一个MODULEENTRY32结构类型,对它的定义如下:TypedefstructtagMODULEENTRY32{DWORDdwSize;DWORDth32ModuleID;DWORDth32ProcessID;DWORDGlblcntUsage;DWORDProccntUsage;BYTE*modBaseAddr;DWORDmodBaseSize;HMODULEhModule;charszModule[MAX_MODULE_NAME32+1];charszExePath[MAX_PATH];}MODULEENTRY32;3Module32Next(hModuleSnap,&me32)该函数获取指定进程的下一个模块信息。线程信息包括线程ID和线程优先级,也是通过ToolHelpAPI函数取得。1、hThreadSnap=CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD,0);该函数创建指定进程的线程快照,取得所有线程信息。第18页共25页591论文网www.591LW.com2Thread32First(hThreadSnap,&te32);//取得指定进程的第一个线程信息将取得的信息填充到te32中。te32也是一个数据结构,它的定义和存放进程信息或存放模块信息的数据结构类似。typedefstructtagTHREADENTRY32{DWORDdwSize;//结构体尺寸,必须在调用前指定DWORDcntUsage;DWORDth32ThreadID;//线程IDDWORDth32OwnerProcessID;//创建该线程的进程IDLONGtpBasePri;//基本优先级LONGtpDeltaPri;DWORDdwFlags;}THREADENTRY32,*PTHREADENTRY32;3Thread32Next(hThreadSnap,&te32)//取得指定进程的下一个模块信息。获取进程模块的过程如图8。图8模块信息的获取3.3.3结束进程的终止方式是进程的正常退出,进程中的所有线程资源都能够得到正确的清除。第19页共25页591论文网www.591LW.com程或其他进程的运行。ExitProcess()函数即可在进程中的某个线程中使用,并将立即终止本进程的运行。ExitProcess()函数原型为:VOIDExitProcess(UINTuExitCode);其参数uExitCode为进程设置了退出代代码将不能被执行。虽然ExitProcess()函数可以在结束进程的同时通知与其相关联的动态链接库,但是由于它的这种执行的强制性,使得ExitProcess()函数在使用上将存在有安全隐患。例如,如果在程序调用ExitProcess()函数之前曾用new操作符申请过一段内存,那么将会由于ExitProcess()函数的强制性而无法通过deleteExitProcess()函数的强制性和不安全性,在使用时一定要引起注意。ExitProcess()只能强制执行本进程的退出,如果要在一个进程中强制结束其他的进程就要用TerminateProcess()来实现。与ExitProcess()不同,TerminateProcess的。所以,通常只有在其他任何方法都无法迫使进程退出时才会考虑使用TerminateProcessTerminateProcess数原型:BOOLTerminateProcess(HANDLEhProcess,UINTuExitCode);参数hProcess和uExitCodeuExitCode0时,在调用TerminateProcess()杀死进程后,Windows1时,杀死进程后,Windows不会再唤醒该进程。本程序中的结束进程,是指强制结束其他应用程序运行的进程,应采用第20页共25页591论文网www.591LW.comTerminateProcessOpenProcess函数将进程打开,然后用TerminateProcess函数结束进程。HANDLEhProcess=OpenProcess(PROCESS_TERMINATE,FALSE,m_(m_iCurSel));TerminateProcess(hProcess,1);//终止进程终止进程的流程如图9。图9终止进程3.3.4删除文件OpenProcess函数将进程打开,用FindFirstFile找到文件,然后用TerminateProcess函数结束进程,再删除该进程对应的文件。HANDLEhProcess=OpenProcess(PROCESS_TERMINATE,FALSE,m_(m_iCurSel));HANDLEh=::FindFirstFile(filename,&fData);//查找文件TerminateProcess(hProcess,1);//终止进程::DeleteFile();//删除文件3.3.5保存进程信息到文件件中。第21页共25页591论文网www.591LW.com3.4系统性能页面设计该页面主要显示CPU前用户名等。3.4.1绘制CPU使用率图3.4.2绘制内存使用率图取得内存使用率可通过一个全局内存函数GlobalMemoryStatus实现,该函数原型为:MEMORYSTATUSMemStat;=sizeof(MEMORYSTATUS);GlobalMemoryStatus(&MemStat);m_ulNewUsges=;绘制图形也是通过位图绘制函数进行绘制,方法和绘制CPU使用率图一样。内存使用率图如图11。图11内存使用率3.4.3其他性能显示GlobalMemoryStatus函数得到的。MEMORYSTATUSMemStat;=sizeof(MEMORYSTATUS);GlobalMemoryStatus(&MemStat);//物理内存总大小第22页共25页591论文网www.591LW.com//物理内存可用数//页文件总大小//页文件可用数//虚拟内存总大小//虚拟内存可用数3.4.4系统信息显示系统信息包括当前操作系统名、用户名、计算机名等。1、获取操作系统名需要用到微软标准函数GetVersionEx()。在windows.h中定义了OSVERSIONINFO结构,OSVERSIONINFO结构包含了操作系统的版本信息,包括操作系统的主版本号、副版本号、创建号、以及操作系统平台ID号和关于操作系统的其他信息。typedefstruct_OSVERSIONINFO{DWORDdwOSVersionInfoSize;//指定该数据结构的字节大小DWORDdwMajorVersion;//操作系统的主版本号DWORDdwMinorVersion;//操作系统的副版本号DWORDdwBuildNumber;//操作系统的创建号DWORDdwPlatformId;//操作系统ID号TCHARszCSDVersion[128];//关于操作系统的一些附加信息}OSVERSIONINFO;其中dwPlatformId可为以下值:VER_PLATFORM_WIN32s:标识为Windows3.1;VER_PLATFORM_W

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论