Перехват сообщений об изменении конфигурации аппаратных средств



    При изменении в конфигурации операционная система посылает следующие сообщения:

· WM_DEVICECHANGE – изменение аппаратных средств:

· DBT_DEVICEARRIVAL – добавление нового устройства;

· DBT_DEVICEREMOVECOMPLETE – удаление устройства.

    Для обработки данных сообщений требуется создать оконную процедуру WndProc. Сообщения (в виде структурных переменных MSG) попадают в данную функцию в виде параметров: описатель окна, идентификатор сообщения и два параметра. Внутри оконной процедуры расположено ветвление switch, в котором идёт проверка идентификатора сообщения.

    Каждый раз, когда в очереди сообщений появляется новое сообщение, ОС выбирает его из очереди и запускает оконную процедуру, того приложения, которому адресовано данное сообщение.

    Подробнее работа приложения по отслеживанию аппаратных изменений приведена в подразделе 2.2.3.

    Кроме того, при компиляции приложения  необходимо установить признак «опасного режима работы» -«Allow unsafe code». Для этого в пункте главного меню «Project» выбирается подпункт «Имя проекта Properties» в появившемся диалоговом окне выбирается закладка «Build» и устанавливается режим «Allow unsafe code» (см. рисунок 2.2).

 

 


Приложение для отслеживания аппаратных изменений

       В качестве примера рассмотрим приложение, изображенное на рисунке 2.3. В таблице 2.4  приведено описание используемых в приложении элементов управления.

 

 

 


Таблица  2.4 – Элементы управления приложения для отслеживания изменений файловой системы

Элемент управления Класс Описание
button1 Button Командная кнопка «Обновить список аппаратных средств»
HardWareTreeView TreeView Дерево для вывода списка установленного оборудования
listBox1 ListBox Окно для вывода информации об изменении аппаратных средств
groupBox1 GroupBox Контейнер служит для размещения списка listBox1

 

       Последовательность программирования приложения:

1. Для работы с журналами событий необходимо подключить пространство имен System.Runtime.InteropServices:

using System.Runtime.InteropServices;

2. Для работы программы необходимо импортировать ряд функций и зарезервированных констант из библиотеки SetupApi32.dll. Для этих целей создается специальный класс SetupAPI.cs:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Runtime.InteropServices;

 

namespace СписокАппаратуры

{

class SetupAPI

{

[DllImport("hid.dll", SetLastError = true)]

public static extern unsafe void HidD_GetHidGuid(

           ref Guid lpHidGuid

);

[DllImport("setupapi.dll", SetLastError = true)]

public static extern unsafe int          SetupDiGetClassDevs(

           ref Guid lpGuid,

           int* Enumerator,

           int* hwndParent,

           ClassDevsFlags Flags

           );

[DllImport("setupapi.dll", SetLastError = true)]

public static extern unsafe int           SetupDiGetClassDevs(

           int* guid,

           int* Enumerator,

           int* hwndParent,

           ClassDevsFlags Flags

           );

[StructLayout(LayoutKind.Sequential)]

public struct SP_DEVINFO_DATA

{

     public int cbSize;

     public Guid ClassGuid;

     public int DevInst;

     public int Reserved;

}

[DllImport("setupapi.dll", SetLastError = true)]

public static extern unsafe int       SetupDiEnumDeviceInfo(

          int DeviceInfoSet,

           int Index,

           ref SP_DEVINFO_DATA DeviceInfoData

           );

  [Flags]

  public enum ClassDevsFlags

  {

       DIGCF_DEFAULT = 0x00000001,

       DIGCF_PRESENT = 0x00000002,

       DIGCF_ALLCLASSES = 0x00000004,

       DIGCF_PROFILE = 0x00000008,

       DIGCF_DEVICEINTERFACE = 0x00000010,

  }

  // Device interface data

  [StructLayout(LayoutKind.Sequential)]

  public unsafe struct SP_DEVICE_INTERFACE_DATA

  {

    public int cbSize;

    public Guid InterfaceClassGuid;

    public int Flags;

    public int Reserved;

  }

  // Device interface detail data

[StructLayout(LayoutKind.Sequential, CharSet =   CharSet.Ansi)]

public unsafe struct       PSP_DEVICE_INTERFACE_DETAIL_DATA

  {

     public int cbSize;

     [MarshalAs(UnmanagedType.ByValTStr, SizeConst    = 256)]

     public string DevicePath;

  }

 

[DllImport("setupapi.dll", SetLastError = true)]

public static extern unsafe int SetupDiEnumDeviceInterfaces(

           int DeviceInfoSet,

           int DeviceInfoData,

           ref Guid lpHidGuid,

           int MemberIndex,

           ref SP_DEVICE_INTERFACE_DATA                  lpDeviceInterfaceData);

 

 [DllImport("setupapi.dll", SetLastError = true)]

public static extern unsafe int SetupDiGetDeviceInterfaceDetail(

        int DeviceInfoSet,

           ref SP_DEVICE_INTERFACE_DATA                         lpDeviceInterfaceData,

           int* aPtr,

           int detailSize,

           ref int requiredSize,

           int* bPtr);

 

[DllImport("setupapi.dll", SetLastError = true)]

public static extern unsafe int SetupDiGetDeviceInterfaceDetail(

   int DeviceInfoSet,

   ref SP_DEVICE_INTERFACE_DATA                  lpDeviceInterfaceData,

   ref PSP_DEVICE_INTERFACE_DETAIL_DATA     myPSP_DEVICE_INTERFACE_DETAIL_DATA,

  int detailSize,

   ref int requiredSize,

   int* bPtr);

 

   public enum RegPropertyType

   {

        // DeviceDesc (R/W)           

        SPDRP_DEVICEDESC = 0x00000000,

        // HardwareID (R/W)

        SPDRP_HARDWAREID = 0x00000001,

        // CompatibleIDs (R/W)

        SPDRP_COMPATIBLEIDS = 0x00000002,

        SPDRP_UNUSED0 = 0x00000003, // unused

        // Service (R/W)

        SPDRP_SERVICE = 0x00000004,

        SPDRP_UNUSED1 = 0x00000005, // unused

        SPDRP_UNUSED2 = 0x00000006, // unused

        // Class (R--tied to ClassGUID)

        SPDRP_CLASS = 0x00000007,

        // ClassGUID (R/W)

        SPDRP_CLASSGUID = 0x00000008,

        SPDRP_DRIVER = 0x00000009, // Driver (R/W)

        // ConfigFlags (R/W)

        SPDRP_CONFIGFLAGS = 0x0000000A,

        SPDRP_MFG = 0x0000000B, // Mfg (R/W)

        // FriendlyName (R/W)

        SPDRP_FRIENDLYNAME = 0x0000000C,

        // LocationInformation (R/W)

    SPDRP_LOCATION_INFORMATION = 0x0000000D,

        // PhysicalDeviceObjectName (R)

        SPDRP_PHYSICAL_DEVICE_OBJECT_NAME =           0x0000000E,

        // Capabilities (R)

        SPDRP_CAPABILITIES = 0x0000000F,

        // UiNumber (R)

        SPDRP_UI_NUMBER = 0x00000010,

        // UpperFilters (R/W)

       SPDRP_UPPERFILTERS = 0x00000011,

        // LowerFilters (R/W)        

        SPDRP_LOWERFILTERS = 0x00000012,

        // BusTypeGUID (R)

       SPDRP_BUSTYPEGUID = 0x00000013,

        // LegacyBusType (R)

        SPDRP_LEGACYBUSTYPE = 0x00000014,

        // BusNumber (R)

        SPDRP_BUSNUMBER = 0x00000015,

        // Enumerator Name (R)

        SPDRP_ENUMERATOR_NAME = 0x00000016,

        // Security (R/W, binary form)

        SPDRP_SECURITY = 0x00000017,

        // Security (W, SDS form)

        SPDRP_SECURITY_SDS = 0x00000018,

        // Device Type (R/W)

        SPDRP_DEVTYPE = 0x00000019,

        // Device is exclusive-access (R/W)

        SPDRP_EXCLUSIVE = 0x0000001A,

        // Device Characteristics (R/W)

        SPDRP_CHARACTERISTICS = 0x0000001B,

        // Device Address (R)

        SPDRP_ADDRESS = 0x0000001C,

        // UiNumberDescFormat (R/W)

        SPDRP_UI_NUMBER_DESC_FORMAT = 0x0000001E,

        // Upper bound on ordinals

        SPDRP_MAXIMUM_PROPERTY = 0x0000001F 

}

[DllImport("setupapi.dll", SetLastError = true)]

public static extern unsafe int SetupDiGetDeviceRegistryProperty(

           int DeviceInfoSet,

           ref SP_DEVINFO_DATA DeviceInfoData,

           RegPropertyType Property,

           int* PropertyRegDataType,

           int* PropertyBuffer,

           int PropertyBufferSize,

           ref int RequiredSize

       );

 

// Device interface detail data

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]

public unsafe struct DATA_BUFFER

{

  [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 1024)]

  public string Buffer;

}

 

[DllImport("setupapi.dll", SetLastError = true)]

public static extern unsafe int SetupDiGetDeviceRegistryProperty(

           int DeviceInfoSet,

           ref SP_DEVINFO_DATA DeviceInfoData,

           RegPropertyType Property,

           int* PropertyRegDataType,

           ref DATA_BUFFER PropertyBuffer,

           int PropertyBufferSize,

           ref int RequiredSize

       );

}

}

3. В основной программе объявляются глобальные переменные и константы:

const int WM_DEVICECHANGE = 0x0219;

   const int DBT_DEVICEARRIVAL = 0x8000;

   const int DBT_DEVICEREMOVECOMPLETE = 0x8004;

 

   [StructLayout(LayoutKind.Sequential)]

  public struct DEV_BROADCAST_HDR

   {

       public int dbch_size;

       public int dbch_devicetype;

       public int dbch_reserved;

   }

4. Оконная процедура для обработки событий имеет вид:

protected override void WndProc(ref Message m)

{

if (m.Msg == WM_DEVICECHANGE)

{

   int EventCode = m.WParam.ToInt32();

   Log(string.Format("WM_DEVICECHANGE. Код={0}",      EventCode));

   switch (EventCode)

   {

       case DBT_DEVICEARRIVAL:

       {

             Log("Добавление устройства");

        break;

     }

     case DBT_DEVICEREMOVECOMPLETE:

     {

        Log("Удаление устройства");

        break;

     }

}

}

base.WndProc(ref m);

}

5. Функция Log для вывода на экран сообщений об аппаратных изменениях имеет вид:

private void Log(string s)

 {

listBox1.Items.Add(s);

listBox1.SelectedIndex = listBox1.Items.Count - 1;

 }

6. Функция GetRegistryProperty для получения информации о найденном оборудовании имеет вид:

private unsafe static string GetRegistryProperty(int PnPHandle, ref SetupAPI.SP_DEVINFO_DATA DeviceInfoData, SetupAPI.RegPropertyType Property)

{

int RequiredSize = 0;

SetupAPI.DATA_BUFFER Buffer = new SetupAPI.DATA_BUFFER();

int result = SetupAPI.SetupDiGetDeviceRegistryProperty(

           PnPHandle,

           ref DeviceInfoData,

           Property,

           null,

           ref Buffer,

           1024,

           ref RequiredSize

          );

return Buffer.Buffer;

}

7. Для события Click кнопки button1 (Обновить список аппаратных средств) пишем следующий программный код:

private unsafe void button1_Click(object sender, EventArgs e)

{

Guid guid = new Guid("{36FC9E60-C465-11CF-8056-444553540000}");

 

int PnPHandle = SetupAPI.SetupDiGetClassDevs(

    ref guid,

    null,

    null,

    SetupAPI.ClassDevsFlags.DIGCF_ALLCLASSES

);

 

int result  = -1;

int DeviceIndex = 0;

int u = 0;

HardWareTreeView.Nodes.Clear();

HardWareTreeView.BeginUpdate();

HardWareTreeView.Nodes.Add("Список оборудования");

while (result != 0)

{

SetupAPI.SP_DEVINFO_DATA DeviceInfoData = new SetupAPI.SP_DEVINFO_DATA();

    DeviceInfoData.cbSize = Marshal.SizeOf(DeviceInfoData);

    result = SetupAPI.SetupDiEnumDeviceInfo(PnPHandle, DeviceIndex, ref DeviceInfoData);

 

if (result == 1)

{

                   HardWareTreeView.Nodes[u].Nodes.Add( GetRegistryProp erty(PnPHandle, ref DeviceInfoData, SetupAPI.RegPropertyType.SPDRP_DEVICEDESC));

              HardWareTreeView.Nodes[u].Nodes[DeviceIndex].Nodes. Add( GetRegistryProperty(PnPHandle, ref DeviceInfoData, SetupAPI.RegPropertyType.SPDRP_CLASS));

               HardWareTreeView.Nodes[u].Nodes[DeviceIndex].Nodes. Add(GetRegistryProperty(PnPHandle, ref DeviceInfoData, SetupAPI.RegPropertyType.SPDRP_CLASSGUID));

               HardWareTreeView.Nodes[u].Nodes[DeviceIndex].Nodes. Add(GetRegistryProperty(PnPHandle, ref DeviceInfoData, SetupAPI.RegPropertyType.SPDRP_DRIVER));

               HardWareTreeView.Nodes[u].Nodes[DeviceIndex].Nodes. Add(GetRegistryProperty(PnPHandle, ref DeviceInfoData, SetupAPI.RegPropertyType.SPDRP_MFG));

}

DeviceIndex++;

}

HardWareTreeView.EndUpdate();

}

 

2.3 Задания для самостоятельной работы

Вариант 1

1. Отслеживать события создания папок в любом выбранном каталоге или списке каталогов  и заносить информацию об изменениях в специально созданный журнал событий. Выполнять обработку созданного журнала (очистка, фильтрация по любому признаку и т.д.)

2. Отслеживать изменения аппаратуры и заносить информацию об изменениях в специально созданный журнал событий. Выполнять обработку созданного журнала (очистка, фильтрация по любому признаку и т.д.)

 


Вариант 2

1. Отслеживать события создания папок в любом выбранном каталоге или списке каталогов и заносить информацию об изменениях в базу данных. Выполнять обработку базы данных (очистка, фильтрация по любому признаку и т.д.)

2. Выводить информацию об аппаратных средствах компьютера с помощью функции SetupDiGetClassDevs  с флагом DIGCF_PRESENT. Отслеживать события, связанные с удалением устройств. Результат работы заносить в таблицу БД.

Вариант 3

1. Отслеживать события создания файлов и папок в любом выбранном каталоге или списке каталогов и заносить информацию об изменениях INI-файл. Выполнять обработку созданного файла (очистка, фильтрация по любому признаку и т.д.).

2. Выводить информацию об аппаратных средствах компьютера с помощью функции SetupDiGetClassDevs  с флагом DIGCF_ALLCLASSES. Отслеживать события, связанные с добавлением новых устройств. Результат работы заносить в INI-файл.

Вариант 4

1. Отслеживать события создания файлов и папок в любом выбранном каталоге или списке каталогов и заносить информацию об изменениях INI-файл. Выполнять обработку созданного файла (очистка, фильтрация по любому признаку и т.д.)

2. Выводить информацию об аппаратных средствах компьютера с помощью функции SetupDiGetClassDevs  с флагом DIGCF_DEFAULT. Отслеживать события, связанные с добавлением новых устройств. Результат работы заносить в INI-файл.

Вариант 5

1. Отслеживать события удаления файлов и папок в любом выбранном каталоге и заносить информацию об изменениях в специально созданный журнал событий. Выполнять обработку созданного журнала (очистка, фильтрация по любому признаку и т.д.)

2. Выводить информацию об аппаратных средствах компьютера с помощью функции SetupDiGetClassDevs  с флагом DIGCF_PROFILE. Отслеживать события, связанные с добавлением и удалением устройств. Результат работы заносить в специально созданный журнал событий

Вариант 6

1. Отслеживать события переименования папок в любом выбранном каталоге и заносить информацию об изменениях в специально созданный журнал событий. Выполнять обработку созданного журнала (очистка, фильтрация по любому признаку и т.д.).

2. Отслеживать изменения аппаратуры и заносить информацию об изменениях в специально созданный журнал событий. Выполнять обработку созданного журнала (очистка, фильтрация по любому признаку и т.д.)

Вариант 7

1. Отслеживать события любых изменений файлов и папок в любом выбранном каталоге и заносить информацию об изменениях в специально созданный журнал событий. Выполнять обработку созданного журнала (очистка, фильтрация по любому признаку и т.д.)

2. Выводить информацию об аппаратных средствах компьютера с помощью функции SetupDiGetClassDevs  с флагом DIGCF_PRESENT. Отслеживать события, связанные с удалением устройств. Результат работы заносить в таблицу БД.

Вариант 8

1. Отслеживать события любых изменений исполняемых файлов в любом выбранном каталоге и заносить информацию об изменениях в специально созданный журнал событий. Выполнять обработку созданного журнала (очистка, фильтрация по любому признаку и т.д.)

2. Выводить информацию об аппаратных средствах компьютера с помощью функции SetupDiGetClassDevs  с флагом DIGCF_ALLCLASSES. Отслеживать события, связанные с добавлением новых устройств. Результат работы заносить в INI-файл

Вариант 9

1. Отслеживать события любых изменений файлов библиотек в любом выбранном каталоге и заносить информацию об изменениях в специально созданный журнал событий. Выполнять обработку созданного журнала (очистка, фильтрация по любому признаку и т.д.)

2. Выводить информацию об аппаратных средствах компьютера с помощью функции SetupDiGetClassDevs  с флагом DIGCF_DEFAULT. Отслеживать события, связанные с добавлением новых устройств. Результат работы заносить в INI-файл.

Вариант 10

1. Отслеживать события любых изменений текстовых файлов в любом выбранном каталоге и заносить информацию об изменениях в специально созданный журнал событий. Выполнять обработку созданного журнала (очистка, фильтрация по любому признаку и т.д.)

2. Выводить информацию об аппаратных средствах компьютера с помощью функции SetupDiGetClassDevs  с флагом DIGCF_PROFILE. Отслеживать события, связанные с добавлением и удалением устройств. Результат работы заносить в специально созданный журнал событий

Вариант 11

1. Отслеживать любые изменения файлов в любом выбранном каталоге и получить информацию, с файлами каких типов чаще всего работает пользователь. Заносить полученные статистические данные в базу данных.

2. Отслеживать изменения аппаратуры и заносить информацию об изменениях в специально созданный журнал событий. Выполнять обработку созданного журнала (очистка, фильтрация по любому признаку и т.д.)

Вариант 12

1. Отслеживать события переименования файлов и каталогов в любом выбранном каталоге и  заносить в базу данных информацию о переименованных файлах и каталогах (новое имя, старое имя, дата переименования, время переименования). Обеспечить возможность поиска и фильтрации записей БД по любому из перечисленных полей.

2. Выводить информацию об аппаратных средствах компьютера с помощью функции SetupDiGetClassDevs  с флагом DIGCF_PRESENT. Отслеживать события, связанные с удалением устройств. Результат работы заносить в таблицу БД

Вариант 13

1. Отслеживать события удаления файлов и каталогов в любом выбранном каталоге и  заносить в базу данных информацию об удаленных файлах и каталогах (полное имя файла или каталога, дата удаления, время удаления). Обеспечить возможность поиска и фильтрации записей БД по любому из перечисленных полей.

2. Выводить информацию об аппаратных средствах компьютера с помощью функции SetupDiGetClassDevs  с флагом DIGCF_ALLCLASSES. Отслеживать события, связанные с добавлением новых устройств. Результат работы заносить в INI-файл

Вариант 14

1. Составить список файлов, содержимое которых не должно изменяться. Отслеживать любые изменения файловой системы. При попытке изменения файлов из выбранного списка выводить на экран предупреждающее сообщение. Заносить в журнал аудита информации о попытках изменения защищаемых файлов.

2. Выводить информацию об аппаратных средствах компьютера с помощью функции SetupDiGetClassDevs  с флагом DIGCF_DEFAULT. Отслеживать события, связанные с добавлением новых устройств. Результат работы заносить в INI-файл

Вариант 15

1. Составить список каталогов, содержимое которых не должно изменяться. Отслеживать любые изменения файловой системы. При попытке изменения содержимого каталогов из выбранного списка (добавление, удаление или изменение файлов в выбранном каталоге) выводить на экран предупреждающее сообщение. Заносить в журнал аудита информации о попытках изменения содержимого защищаемых каталогов.

2. Выводить информацию об аппаратных средствах компьютера с помощью функции SetupDiGetClassDevs  с флагом DIGCF_PROFILE. Отслеживать события, связанные с добавлением и удалением устройств. Результат работы заносить в специально созданный журнал событий

Вариант 16

1. Отслеживать события создания файлов и каталогов в любом выбранном каталоге и  заносить в базу данных информацию о созданных файлах и каталогах (имя файла или каталога, дата создания, время создания). Обеспечить возможность поиска и фильтрации записей БД по любому из перечисленных полей.

2. Отслеживать изменения аппаратуры и заносить информацию об изменениях в специально созданный журнал событий. Выполнять обработку созданного журнала (очистка, фильтрация по любому признаку и т.д.)

Вариант 17

1. Отслеживать любые изменения файловой системы в любом выбранном каталоге и  заносить в базу данных информацию обо всех изменениях файловой системы. Обеспечить возможность поиска и фильтрации записей БД по видам изменений (создание, удаление, переименование и т.п.), по дате и времени изменений.

2. Выводить информацию об аппаратных средствах компьютера с помощью функции SetupDiGetClassDevs  с флагом DIGCF_PRESENT. Отслеживать события, связанные с удалением устройств. Результат работы заносить в таблицу БД

Вариант 18

1. Отслеживать события любых изменений графических файлов в любом выбранном каталоге и заносить информацию об изменениях в специально созданный журнал событий. Выполнять обработку созданного журнала (очистка, фильтрация по любому признаку и т.д.)

2. Выводить информацию об аппаратных средствах компьютера с помощью функции SetupDiGetClassDevs  с флагом DIGCF_ALLCLASSES. Отслеживать события, связанные с добавлением новых устройств. Результат работы заносить в INI-файл

Вариант 19

1. Отслеживать события переименования, создания или изменения исполняемых файлов. При появлении указанных событий выводить на экран предупреждающее сообщение и заносить информацию о данных событиях в БД. Предусмотреть возможность фильтрации записей в БД по дате и времени изменения, а также по типу исполняемого файла (*.exe, *.bat, *.cmd  и т.п.)

2. Выводить информацию об аппаратных средствах компьютера с помощью функции SetupDiGetClassDevs  с флагом DIGCF_DEFAULT. Отслеживать события, связанные с добавлением новых устройств. Результат работы заносить в INI-файл

 

Вариант 20

1. Отслеживать любые изменения графических и аудио-файлов. При появлении указанных событий выводить на экран предупреждающее сообщение и заносить информацию о данных событиях в БД. Предусмотреть возможность фильтрации записей в БД по дате и времени изменения, а также по типу файла (*.bmp, *.jpg, *.mp3  и т.п.)

2. Выводить информацию об аппаратных средствах компьютера с помощью функции SetupDiGetClassDevs  с флагом DIGCF_PROFILE. Отслеживать события, связанные с добавлением и удалением устройств. Результат работы заносить в специально созданный журнал событий

 

Контрольные вопросы

1. Опишите основные события класса FileSystemWatcher

2. Опишите основные свойства класса FileSystemWatcher

3. Как выполняется подключение нового обработчика событий?

4. Как настроить приложение на отслеживание событий в текущем и во всех вложенных каталогах?

5. Опишите основные функции библиотеки SetupAPI.dll

6. Какие сообщения посылает операционная система при изменении конфигурации оборудования?

7. Для каких целей используется функция WndProc?

 


Дата добавления: 2018-08-06; просмотров: 345; Мы поможем в написании вашей работы!

Поделиться с друзьями:






Мы поможем в написании ваших работ!