38220

Розширення оболонки Windows

Лабораторная работа

Информатика, кибернетика и программирование

В даній роботі розглядаються засоби для розширення стандартних можливостей ОС Windows. Для виконання даної роботи потрібно чітке розуміння основ об’єктно-орієнтованого програмування (ООП)

Украинкский

2014-11-30

59 KB

4 чел.

Лабораторна робота №4

Тема: Розширення оболонки Windows

Теоретична частина

В даній роботі розглядаються засоби для розширення стандартних можливостей ОС Windows. Для виконання даної роботи потрібно чітке розуміння основ об’єктно-орієнтованого програмування (ООП). Що таке клас та об’єкт класу, я думаю розповідати вам не потрібно. В роботі будуть використане поняття інтерфейсу. В даному контексті, інтерфейс – це певна сутність ООП, яка описує тільки назви методів класу. Реалізація цих методів покладається виключно на об’єкт нащадок інтерфейсу. Тобто можна сказати, що інтерфейс – це певний абстрактний клас в якому тільки оголошуються методи (процедури та функції). Для чого це потрібно ??? Для розширення оболонки ОС ваша програма повинна буде реалізовувати інтерфейси, через які система буде взаємодіяти з вашим кодом. Тобто, вам потрібно буде описати певний клас, який буде  унаслідуватись від інтерфейсу і в якому будуть реалізовуватись методи, що оголошені в ньому.

Реалізація перехоплення процесу копіювання.

Ще деякий нюанс. Для розширення оболонки ваш клас повинен не тільки унаслідуватись від інтерфейсу, а ще від базового класу, що реалізує основні методи реалізації технології COM. Я не буду описувати, що це за технологія, так як це дуже громіздка тема. Скажу лише одне – дана технологія дозволяє взаємодіяти між об’єктами, що вже є відкомпільованими шляхом реалізації певних інтерфейсів.

 Багато рутинної роботи можна покласти на саме середовище Delphi. Перед початком потрібно створити ActiveX бібліотеку (ActiveX – це технологія, що базується на технології СОМ. Дозволяє використовувати відкомпільовані об’єкти в інших програмах.). Для цього треба зайти File/New і у вкладці ActiveX натиснути на ActiveX Library. Буде створена бібліотека, яка в принципі мало чим відрізняється від звичайної DLL (по своїй суті це і є динамічна бібліотека, в якій буде описані СОМ-об’єкти). Зберігаєм гарненько цю бібліотеку з нормальним ім’ям. Далі створюємо СОМ-об’єкт, який буде реалізовувати методи певних інтерфейсів. Так само заходимо File/New і у вкладці ActiveX потрібно вибрати COM Object. Наприклад CopyHook. З радістю на обличчі тиснемо «ОК».

Система щось там вам наплодила до дідька… Все це допоміжні файли, для реалізації роботи. Нас цікавить файл з назвою Unit1.pas. Вибираємо його і звісно перейменовуємо на нормальну зрозумілу  назву. В цьому фалі описаний клас, який ви вказали при створенні об’єкта. З ним ми і працюємо. Цей клас має унаслідувати інтерфейс ICopyHook, що описаний в бібліотеці ShlObj(я думаю зрозуміли, що цей модуль потрібно додати до розділу uses). Даний інтерфейс оголошений наступним чином:

 ICopyHookA = interface(IUnknown)

   

   function CopyCallback(Wnd: HWND; wFunc, wFlags: UINT; pszSrcFile: PAnsiChar;

     dwSrcAttribs: DWORD; pszDestFile: PAnsiChar; dwDestAttribs: DWORD): UINT; stdcall;

 end;

В даному випадку interfaceце ключове слово, яке вказує, що дана сутність таки є інтерфейсом (типу як слово class при оголошенні класу). Як видно даний інтерфейс має тільки один метод   CopyCallback, який ви і повинні реалізувати у своєму класі.

Отже додаємо даний інтерфейс до класів від яких унаслідується наш СОМ-об’єкт. Іншими словами потрібно назву цього інтерфейсу додати в дужках, які йдуть після службового слова class. Слід зауважити, що мова Object Pascal не підтримує множинне наслідування, але це обмеження не стосується інтерфейсів. Клас може унаслідувати їх скільки завгодно, але клас – тільки один. В нашому прикладі вийшло

 TTCopyHook = class(TTypedComObject, ITCopyHook, ICopyHook)

 protected

   {Тут оголошуються методи та властивості класу}

 end;   

В даному класі ми і повинні реалізувати функцію CopyCallback, яка буде викликаєтись ОС кожного разу, якщо відбуваються певні маніпуляції з папками (даний інтерфейс забезпечує роботу тільки з папками).

Отже оголошуємо метод класу, що відповідає прототипу функції CopyCallback з інтерфейсу.      

 TTCopyHook = class(TTypedComObject, ITCopyHook, ICopyHook)

 protected

       function CopyCallback(Wnd: HWND; wFunc, wFlags: UINT; pszSrcFile: PAnsiChar;

     dwSrcAttribs: DWORD; pszDestFile: PAnsiChar; dwDestAttribs: DWORD): UINT; stdcall;

 end;   

 А в розділі implementation реалізуємо дану функцію (реалізація функції означає додати туди якийсь код, тоді як оголошення функції -  це просто запис назви функції та її формальних параметрів).

function TTCopyHook.CopyCallback(Wnd: HWND; wFunc, wFlags: UINT;

 pszSrcFile: PAnsiChar; dwSrcAttribs: DWORD; pszDestFile: PAnsiChar;

 dwDestAttribs: DWORD): UINT;

begin

end;

При реалізації потрібно знати, що визначають формальні параметри даної функції.

 Wndдескриптор вікна, в якому відбувається подія

 wFuncвказує на дію, яка відбувається над папкою. Може приймати наступні значення : FO_COPY – відбувається копіювання файлу, що заданий параметром pszSrcFile в файл, що заданий pszDestFile; FO_DELETE – відбувається видалення файлу, що описаний в параметрі pszSrcFile; FO_MOVE – відбувається переміщення файлу; FO_RENAME – переіменування.

 wFlags – додаткові флаги операції. Їх значення дивись в описі функцій системи.

Призначення решти параметрів я думаю для вас зрозуміле. Функція може повертати два значення IDOKпідтвердження операції, IDNOвідміна.

Отже підсумок. Ви оголосили функції і її реалізували. При будь якій операції з папками буде викликатись саме ваша функція і ви зможете керувати процесом роботи. І це одне застереження – під’єднайте бібліотеку ShellAPI, для коректної роботи з параметрами.

Після реалізації методу -  компілюйте проект. На виході у вас бібліотека динамічного підключення, в якій міститься ваш СОМ-об’єкт. Тепер потрібно зареєструвати його в системі.

 Реєстрація бібліотеки в системі є досить складною задачею. Середовище Delphi бере на себе велику частину цієї роботи, але все ж таки певні дій нам потрібно описати самим.

В модулі, де описаний вам СОМ-об’єкт в розділі initialization ви побачете щось подібне наступному:

 TTypedComObjectFactory.Create(ComServer, TTCopyHook, Class_TCopyHook,

   ciMultiInstance, tmApartment)

 

Що це таке ??? Цікаве запитання… Це оголошений клас, що називається фабрикою класів. Його завдання – це створення СОМ-об’єкта при роботі в системі і він викликається автоматично, якщо тільки буде викликана ваша динамічна бібліотека. І все б нічого, але є одне але – при роботі з перехопленням потрібно деяким чином змінити системний реєстр ОС Windows (реєстр – це деревовидна база даних, в якій зберігаються ключові настройки системи, дані про неї та інша додаткова інформація). Отже нам потрібно зробити так, щоб при реєстрації нашої бібліотеки відбувались автоматично зміни в реєстрі. Я повністю наведу приклад як це робити і по можливості спробую описати всі дії. Якщо вас цікавить більш ширше висвітлення цієї теми – звертайтесь до викладача. А поки що спочатку – заремарюйте цей рядок…

Для автоматизації процесу реєстрації потрібно  перезавантажити деякі методи фабрики класів. Отже в інтерфейсній частині оголошуємо наш клас, що буде нащадком класу фабрики

TCopyHookFactory=class(TComObjectFactory)

protected

     procedure ApproveShellEx(Register:boolean; CLsid:string);

public

  procedure UpdateRegistry(Register:boolean); override;

end;

Як видно з прикладу, перезавантажено один метод – це UpdateRegistry. Ця функція викликається тоді, коли фабрика класу записує дані в реєстр. Нам потрібно додати до неї деяку функціональність. Процедура ApproveShellEx призначена для ще однієї зміни в реєстрі, а саме в гілці:

 HKEY_LOCAL_MASHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Shell Extensions\Approved)      

 Дана процедура буде викликатись з функції UpdateRegistry. Це одне доповнення –кожен СОМ-об’єкт ідентифікується власним глобальним ідентифікатором. Глобальний означає, те що гарантується повна унікальність даного ключа в глобальному масштабі, тобто той код, що згенерувався на вашій машині гарантовано на іншим машинах світу згенерований не буде. Цей код за вас також генерує середовище Delphi. Цей ідентифікатор має назву GUID і ось його приклад:

        {8762883B-9019-4B71-9746-5C9911E8BB16}

 

 Це 16-байтне число, яке представляють у HEX-форматі. GUID вашого СОМ-об’єкта зберігається у змінній CLASS_назва_вашого_об’єкта і описана ця змінна в модулю, що <НазваБібліотеки>_TLB.PAS.

Отже тепер в розділі implementation описуємо реалізацію наших методів. Так як у мене клас-фабрики називався TCopyHookFactory то і їх реалізація буде наступною:

procedure TCopyHookFactory.ApproveShellEx(Register: boolean; CLsid: string);

const

 SApproveKey='SOFTWARE\Microsoft\Windows\CurrentVersion\Shell Extensions\Approved';

        //Шлях до вітки реєстру, в яку буде вводитись зміни

var

  Reg:TRegistry;// Об’єкт для роботи з реєстром

begin

 Reg:=TRegistry.Create;// Створення об’єкта для роботи з реєстром

 Reg.RootKey:=HKEY_LOCAL_MACHINE;// Виставляємо йому корінь реєстра

 if not Reg.OpenKey(SApproveKey,true)  then exit; // Перехід на відповідну гілку

 if Register then  Reg.WriteString(CLsID,Description) // Запис у реєстр

              else Reg.DeleteValue(CLsID);// Якщо відбувається знищення СОМ-об’єкта, знищується і запис

end;

 

procedure TCopyHookFactory.UpdateRegistry(Register: boolean);

var

ClsID:string;

begin

  ClsID:=GUIDToString(ClassID); // Перетворення Ідентифікатора в рядок

 inherited UpdateRegistry(Register);// Виклик метода з предка

 ApproveShellEx(Register,ClsID); // Виклик вищеописаної процедури  

 if Register then // Якщо об’єкт реєструється,то додаємо запис в реєстр

    CreateRegKey('Directory\shellex\CopyHookHandlers\'+ClassName,'',ClsID)

   Else // в противному випадку – знищуємо запис

     DeleteRegKey('Directory\shellex\CopyHookHandlers\'+ClassName);

end;

Функція UpdateRegistry також додає запис в гілку реєстра HKEY_CLASSES_ROOT/Directiry/Shellex/CopyHookHandlers. Реалізація цих функцій є повноцінною в даному описі, тобто можете його сміливо брати. Тільки уважно бути, якщо у вас фабрика називається іншим ім’ям, тоді я думаю ви розумієте, де треба внести зміни.

Ну що ж, тепер треба тільки заставити системи, щоб при реєстрації нашого СОМ-об’єкта використовувалась наша фабрика класів. Для цього в розділі initialize замість згенерованої команди прописати свою власну типу:

TCopyHookFactor.Create(ComServer,<НАЗВА КЛАСУ, В ЯКОМУ ОПИСУВАВСЯ ОБ’ЄКТ>,<GUID об’єкта>,<НАЗВА_ОБ’ЄКТА_В_СИСТЕМІ>,<ОПИС>, ciMultiInstance, tmApartment).

<НАЗВА КЛАСУ, В ЯКОМУ ОПИСУВАВСЯ ОБ’ЄКТ> - назва Delphi-ого класу в якому ви описували процедуру перехоплення

 <GUID об’єкта> - можете взяти прямо з *_TLB.PAS, а можете вказати змінну (CLASS_назва_об’єкта).

 <НАЗВА_ОБ’ЄКТА_В_СИСТЕМІ> - строкова змінна, що визначає назву об’єкта в ОС вцілому. Не допускаються пробіли.

 <ОПИС> - строкова змінна. Опис об’єкта.

Всі решта параметрів такі і залишаються, що і у прикладі.

Компілюєте проект. На виході DLL бібліотека. Ця бібліотека має чотири експортні функції(їх прототип - function:HResult;stdcall), з яких нас цікавлять дві:

 DLLRegisterServer – реєстрація об’єктів, що в бібліотеці в системі

 DLLUnRegisterServerвідміна реєстрації.

Можна написати окрему програму, що буде викликати ці функції для реєстрації. Після реєстрації потрібно перезавантажити систему. Звичайно після того як ви продемонструєте викладачу вашу роботу – ви повинні відмінити реєстрацію.

Завдання на 4 бали: Створити СОМ-об’єкт, що буде відслідковувати всі операції копіювання і записувати в окремий файл, що коли і куди було скопійовано.

Завдання на 5 балів: Створити СОМ-об’єкт, що буде відслідковувати всі операції над папками  і записувати в окремий файл, що, коли відбувалося та з якою папкою, а також час події.

Завдання на 6 балів: Те саме, що і попередня задача, але при натиску на кнопку F7виникає вікно в якому має виводитись увесь файл, в якому записувались дані.

P.S. Так лабораторна складна, але і ви вчитесь на програмістів, а не на простих спеціалістів по набору тексту в MS WORD. Так що зберіться і вперед

БАЖАЄМО УСПІХУ.


 

А также другие работы, которые могут Вас заинтересовать

71937. Смысловая организация сложного предложения в английском языке 105 KB
  Основным признаком сложного предложения лингвисты издавна считают объединение в нем нескольких предикативных сочетаний подлежащего и сказуемого. Причем на протяжении всей истории развития учения о сложном предложении наблюдаются разногласия в трактовке...
71938. Организация отношений между данными: иерархическая, сетевая, реляционная 896.09 KB
  Основные идеи современной информационной технологии базируются на концепции баз данных (БД). Согласно данной концепции основой информационной технологии являются данные, организованные в БД, адекватно отражающие реалии действительности в той или иной предметной области...
71939. Декабризм, и его значение в истории России 365 KB
  Движение декабристов является событием, длительное время приковывающим внимание историков. Это связано с тем, что события более чем 170-летней давности оказали значительное влияние на последующее развитие России; декабристы были первыми русскими революционерами, которые организовали открытое восстание против царизма.
71940. ЗАКОНОДАТЕЛЬНЫЕ И ИНЫЕ НОРМАТИВНЫЕ ПРАВОВЫЕ АКТЫ, УСТАНАВЛИВАЮЩИЕ ПОРЯДОК РАССЛЕДОВАНИЯ И УЧЕТА НЕСЧАСТНЫХ СЛУЧАЕВ НА ПРОИЗВОДСТВЕ 91 KB
  Формы документов необходимых для расследования и учета несчастных случаев на производстве утвержденные Минтрудом России следующие: извещение о групповом несчастном случае тяжелом несчастном случае несчастном случае со смертельным исходом; акт о несчастном случае...
71941. Пыль. Средства индивидуальной защиты от пыли 179.5 KB
  Для этой цели используется классификация пыли по ее дисперсности и способу образования. Характер действия пыли на организм зависит от физико-химических свойств пылевых частиц. Ядовитые пыли свинца ртути мышьяка и т. растворяясь в биологических средах действуют как введенный в организм...
71942. Пенсии по случаю потери кормильца 24.33 KB
  Пенсии по случаю потери кормильца –- это ежемесячные денежные выплаты алиментарного характера из фонда социальной защиты населения или государственного бюджета назначаемые нетрудоспособным членам семьи умершего кормильца состоявшим на его иждивении в размерах соизмеримых с заработком кормильца.