lab4 / lab4
.docxФЕДЕРАЛЬНОЕ АГЕНТСТВО СВЯЗИ
Федеральное государственное образовательное бюджетное учреждение
высшего профессионального образования
Московский технический университет связи и информатики
----------------------------------------------------------------------------------------------------
Кафедра Математической кибернетики и информационных технологий
ЛАБОРАТОРНАЯ РАБОТА № 4
по дисциплине
ОПЕРАЦИОННЫЕ СИСТЕМЫ
на тему:
«Процессы и потоки»
Выполнил:
Проверил:
Королькова Т.В.
ст.пр. кафедры МКиИТ
Москва 2017
Цель работы: получение практических навыков по использованию Win32 API для исследования памяти Windows
Задание: Разработать программное обеспечение, которое:
выдает информацию, получаемую при использовании API GlobalMemoryStatus. При выводе информации использовать диаграммы.
Составляет карту виртуальной памяти для любого процесса.
В данной программе были использованы функции:
void WINAPI GlobalMemoryStatus(
_Out_ LPMEMORYSTATUS lpBuffer
);
которая принимает параметром структуру:
struct_MEMORYSTATUS {
DWORD dwLength; // Размер структуры MEMORYSTATUS.
DWORD dwMernoryLoad; // Процент используемой памяти.
DWORD dwTotalPhys; // Количество байтов физической памяти.
DWORD dwАvailPhys; // Количество свободных байтов физической памяти.
DWORD dwTotalPageFile; // Размер в байтах файла подкачки.
DWORD dwAvailPageFile; // Количество свободных байтов файла подкачки.
DWORD dwTotalVirtual; // Количество байтов адресного пространства, доступного пользователю.
DWORD dwAvailvirtual; // Количество свободных байтов памяти, доступных пользователю.
}
Также была использована функция:
DWORD VirtualQueryEx(
HANDLE hProcess // Дескриптор процесса LPCVOID IpAddress, // Адрес области MEMORY_BASIC_INFORMATION IpBuffer, // Адрес информационного буфера DWORD dwLength // Размер буфера
);
которая принимает параметром структуру:
Struct MEMORY_BASlC_INFORMATION {
PVOID BaseAdciress; // Базовый адрес области
PVOID AllocationBase; // Базовый адрес выделенной области
DWORD AllocationProtect; // Первоначальная защита от доступа
DWORD RegionSize; // Размер области в байтах
DWORD State; // Передана зарезервирована, свободна
DWORD Protect; // Текущая защита от доступа
DWORD Type; // Тип страниц
}
Код программы:
Form1.cs:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Windows.Forms.DataVisualization.Charting;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.Security;
namespace OSLab_4
{
public partial class MainForm : Form
{
public MainForm()
{
InitializeComponent();
FillForm();
FillGV();
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public class MemoryStatus
{
[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
internal static extern bool GlobalMemoryStatusEx([In, Out] MemoryStatus lpBuffer);
private uint dwLength;
public uint MemoryLoad;
public ulong TotalPhys;
public ulong AvailPhys;
public ulong TotalPageFile;
public ulong AvailPageFile;
public ulong TotalVirtual;
public ulong AvailVirtual;
public ulong AvailExtendedVirtual;
private static volatile MemoryStatus singleton;
private static readonly object syncroot = new object();
public static MemoryStatus CreateInstance()
{
if (singleton == null)
lock (syncroot)
if (singleton == null)
singleton = new MemoryStatus();
return singleton;
}
[SecurityCritical]
private MemoryStatus()
{
dwLength = (uint)Marshal.SizeOf(typeof(MemoryStatus));
GlobalMemoryStatusEx(this);
}
}
private void FillForm()
{
MemoryStatus memeStat = MemoryStatus.CreateInstance();
memoryChartPhys.Series.Clear();
ulong totalPhys = memeStat.TotalPhys/1024/1024;
ulong totalPage = memeStat.TotalPageFile / 1024 / 1024;
ulong totalVirtual = memeStat.TotalVirtual / 1024 / 1024;
memoryChartPhys.Titles.Add("Physical memory distribution (" + totalPhys.ToString() + " MB total)");
memoryChartPhys.Series.Add(new Series("ColumnSeries1") { ChartType = SeriesChartType.Pie });
memoryChartPage.Series.Clear();
memoryChartPage.Titles.Add("Page memory distribution (" + totalPage.ToString() + " MB total)");
memoryChartPage.Series.Add(new Series("ColumnSeries2") { ChartType = SeriesChartType.Pie });
memoryChartVirtual.Series.Clear();
memoryChartVirtual.Titles.Add("Virtual memory distribution (" + totalVirtual.ToString() + " MB total)");
memoryChartVirtual.Series.Add(new Series("ColumnSeries3") { ChartType = SeriesChartType.Pie });
ulong[] yValues = { (memeStat.TotalPhys - memeStat.AvailPhys)/1024/1024, memeStat.AvailPhys/1024/1024 };
string[] xValues = { "Ocuupied", "Available" };
memoryChartPhys.Series["ColumnSeries1"].Points.DataBindXY(xValues, yValues);
yValues[0] = (memeStat.TotalPageFile - memeStat.AvailPageFile)/1024/1024;
yValues[1] = memeStat.AvailPageFile/1024/1024;
memoryChartPage.Series["ColumnSeries2"].Points.DataBindXY(xValues, yValues);
yValues[0] = (memeStat.TotalVirtual - memeStat.AvailVirtual)/1024/1024;
yValues[1] = memeStat.AvailVirtual/1024/1024;
memoryChartVirtual.Series["ColumnSeries3"].Points.DataBindXY(xValues, yValues);
}
private void FillGV()
{
processGV.Columns.Add("Id", "id");
processGV.Columns.Add("Name", "name");
processGV.Columns.Add("Bit", "bit");
processGV.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;
foreach (Process process in Process.GetProcesses())
{
try { string check = process.Handle. ToString(); processGV.Rows.Add(process.Id.ToString(), process.ProcessName, "64"); }
catch { processGV.Rows.Add(process.Id.ToString(), process.ProcessName, "32"); }
}
}
private void mapButton_Click(object sender, EventArgs e)
{
int id = Convert.ToInt32(processGV[0, processGV.CurrentRow.Index].Value.ToString());
Process selectedProcess = findSelected(id);
try
{
MapForm mapForm = new MapForm(selectedProcess);
mapForm.Show();
}
catch(Win32Exception)
{
MessageBox.Show("Cannot retrieve information about modules of this process!", "Exception", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
}
Process findSelected(int id)
{
foreach (Process process in Process.GetProcesses())
if (id == process.Id)
return process;
return null;
}
}
}
MapForm:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.Security;
namespace OSLab_4
{
public partial class MapForm : Form
{
public MapForm(Process selectedProcess)
{
InitializeComponent();
dgvSetup();
getMemoryMap(selectedProcess);
}
[DllImport("kernel32.dll")]
static extern int VirtualQueryEx(IntPtr hProcess, IntPtr lpAddress, out MEMORY_BASIC_INFORMATION lpBuffer, uint dwLength);
[StructLayout(LayoutKind.Sequential)]
public struct MEMORY_BASIC_INFORMATION
{
public IntPtr BaseAddress;
public IntPtr AllocationBase;
public uint AllocationProtect;
public IntPtr RegionSize;
public uint State;
public uint Protect;
public uint Type;
}
void getMemoryMap(Process selectedProcess)
{
long MaxAddress = 0x7FFEFFFF;
long address = 0;
do
{
MEMORY_BASIC_INFORMATION memBase;
int result = VirtualQueryEx(selectedProcess.Handle, (IntPtr)address, out memBase, (uint)Marshal.SizeOf(typeof(MEMORY_BASIC_INFORMATION)));
switch(memBase.State)
{
case 4096:
memoryMapDGV.Rows.Add(memBase.BaseAddress, (uint)memBase.BaseAddress + (uint)memBase.RegionSize - 1, memBase.RegionSize, result, "Commited");
break;
case 65536:
memoryMapDGV.Rows.Add(memBase.BaseAddress, (uint)memBase.BaseAddress + (uint)memBase.RegionSize - 1, memBase.RegionSize, result,"Free");
break;
case 8192:
memoryMapDGV.Rows.Add(memBase.BaseAddress, (uint)memBase.BaseAddress + (uint)memBase.RegionSize - 1, memBase.RegionSize, result, "Reserved");
break;
}
if (address == (long)memBase.BaseAddress + (long)memBase.RegionSize)
break;
address = (long)memBase.BaseAddress + (long)memBase.RegionSize;
}
while (address<=MaxAddress);
}
void dgvSetup()
{
memoryMapDGV.Columns.Add("Start address", "start address");
memoryMapDGV.Columns.Add("End address", "end address");
memoryMapDGV.Columns.Add("Region size", "region size");
memoryMapDGV.Columns.Add("Bytes result", "bytes result");
memoryMapDGV.Columns.Add("State", "state");
memoryMapDGV.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;
}
}
}
Результаты выполнения программы: