Понедельник, 29.04.2024
Королевство Delphi
Главное меню
Статьи
Наш опрос
Нравится раздел статьи?
Всего ответов: 68
Статистика
Онлайн всего: 1
Гостей: 1
Пользователей: 0
Форма входа
Главная » Статьи » Система » CORBA и COM

Создание COM-сервера

Всем привет!

Чем отличается программист от другого типа человека разумного?
Я думаю, постоянным желанием подшутить над братом меньшим - Человеком нормальным, благо способов для этого - великое множество. В реестре Windows неограниченное количество мест для автоматического запуска программ - сейчас нас интересует расширение оболочки - контекстное меню Эксплорера. Займемся созданием +СОМ-сервера который будет запускаться при вызове контекстного меню.
Сразу оговорюсь - на компе потенциального испытуемого должна стоять звуковая карта и, желательно, антивирус Касперского, чтобы испытуемому был хорошо известен вопль AVP при обнаружении вируса.

Для начала, создадим файл ресурса содержащего нужный нам вопль.
Создаем текстовый файл, пишем в нем на одной строке:

MYWAVE RCData C:\Temp\Infected.wav

(вместо C:\Temp\Infected.wav пишете реальный путь к *.wav файлу)
Сохраняем файл с именем WAVE.RC. Далее выполняем команду:

brcc32.exe C:\Temp\Wave.rc

(вместо C:\Temp\Wave.rc пишете реальный путь к Wave.rc файлу)
У нас получился файл ресурсов Wave.res который мы будем использовать дальше.

В примерах Delphi есть почти все, что нам нужно:

..:\Program Files\Borland\Delphi7\Demos\ActiveX\ShellExt\ContextM.pas

Немножко редактируем этот файл (в смысле выбрасываем ненужное - добавляем нужное) и получаем примерно это:

unit Unit1;

interface

uses
 Windows, ActiveX, ComObj, Classes,
 Dialogs, StdCtrls,
 ShlObj;

type
 TInitWormHook = class(TComObject, IShellExtInit, IContextMenu)
 protected
 { IShellExtInit }
 function IShellExtInit.Initialize = SEIInitialize;
 function SEIInitialize(pidlFolder: PItemIDList; lpdobj: IDataObject;
 hKeyProgID: HKEY): HResult; stdcall;
 { IContextMenu }
 function QueryContextMenu(Menu: HMENU; indexMenu, idCmdFirst, idCmdLast,
 uFlags: UINT): HResult; stdcall;
 function InvokeCommand(var lpici: TCMInvokeCommandInfo): HResult; stdcall;
 function GetCommandString(idCmd, uType: UINT; pwReserved: PUINT;
 pszName: LPSTR; cchMax: UINT): HResult; stdcall;
 end;

 function DllGetClassObject(const CLSID, IID: TGUID; var Obj): HResult; stdcall;
 function DllCanUnloadNow: HResult; stdcall;

const
 Class_ContextMenu: TGUID = '{1A39ADB3-5ED9-44F4-B6BA-5B3D41255033}';

implementation

uses ComServ, SysUtils, ShellApi, Registry, Graphics, mmSystem;

//Цепляем наш ресурс
{$R wave.res}

function TInitWormHook.SEIInitialize(pidlFolder: PItemIDList; lpdobj: IDataObject;
 hKeyProgID: HKEY): HResult;
begin
 Result := NOERROR;
end;

function TInitWormHook.QueryContextMenu(Menu: HMENU; indexMenu, idCmdFirst,
 idCmdLast, uFlags: UINT): HResult;
begin
 Result := 0;
end;

function TInitWormHook.InvokeCommand(var lpici: TCMInvokeCommandInfo): HResult;
begin
 Result := NOERROR;
end;

function TInitWormHook.GetCommandString(idCmd, uType: UINT; pwReserved: PUINT;
 pszName: LPSTR; cchMax: UINT): HRESULT;
begin
 Result := NOERROR;
end;

type
 TInitWormHookFactory = class(TComObjectFactory)
 public
 procedure UpdateRegistry(Register: Boolean); override;
 end;
 
//А это - наша процедура по извлечению звука из файла ресурса
procedure RUNWAV;
var
WaveHandle: THandle;
 WavePointer: pointer;
 begin
 WaveHandle:= FindResource(hInstance, 'MYWAVE', RT_RCDATA);
 if WaveHandle <> 0 then
 begin
 WaveHandle := LoadResource(hInstance, WaveHandle);
 if WaveHandle <> 0 then
 begin;
 WavePointer:= LockResource(WaveHandle);
 sndPlaySound(WavePointer, snd_Memory or SND_ASYNC);
 UnlockResource(WaveHandle);
 FreeResource(WaveHandle);
 end;
 end;
end;

procedure TInitWormHookFactory.UpdateRegistry(Register: Boolean);
var
 ClassID: string;
begin
 if Register then begin
 inherited UpdateRegistry(Register);
 ClassID := GUIDToString(Class_ContextMenu);
 CreateRegKey('Directory\shellex\ContextMenuHandlers\WAV', '', ClassID);
 if (Win32Platform = VER_PLATFORM_WIN32_NT) then
 with TRegistry.Create do
 try
 RootKey := HKEY_LOCAL_MACHINE;
 OpenKey('SOFTWARE\Microsoft\Windows\CurrentVersion\Shell Extensions', True);
 OpenKey('Approved', True);
 WriteString(ClassID, 'FTP simple client');
 finally
 Free;
 end;
 end
 else begin
 DeleteRegKey('Directory\shellex\ContextMenuHandlers\WAV');
 inherited UpdateRegistry(Register);
 end;
end;

function DllGetClassObject(const CLSID, IID: TGUID; var Obj): HResult;
begin
 Result:=ComServ.DllGetClassObject(CLSID, IID, Obj);
 if Result = S_OK then begin
 try
 RUNWAV;
 except
 end;
 end;
end;

function DllCanUnloadNow: HResult;
begin
 Result := ComServ.DllCanUnloadNow;
 if Result = S_OK then begin
 try
 RUNWAV;
 except
 end;
 end;
end;

initialization
 TInitWormHookFactory.Create(ComServer, TInitWormHook, Class_ContextMenu,
 '', 'FTP simple client', ciMultiInstance,
 tmApartment);
end.

Теперь нам нужно скомпилировать из этого модуля DLL-ку. Пишем проект ShWave.dpr:

library ShWave;

uses
 ComServ,
 Unit1 in 'Unit1.pas';

exports
 DllGetClassObject,
 DllCanUnloadNow,
 DllRegisterServer,
 DllUnregisterServer;
begin
end.

После компиляции получаем ShWave.dll

Мы получили +СОМ-сервер, теперь осталось его подключить к контекстному меню. Пишем файл реестра Install.reg:

REGEDIT4

[HKEY_CLASSES_ROOT\CLSID\{1A39ADB3-5ED9-44F4-B6BA-5B3D41255033}\InprocServer32]
@="ShWave.dll"
"ThreadingModel"="Apartment"

[HKEY_CLASSES_ROOT\*\shellex\ContextMenuHandlers\WAV]
@="{1A39ADB3-5ED9-44F4-B6BA-5B3D41255033}"

[HKEY_CLASSES_ROOT\Directory\shellex\ContextMenuHandlers\WAV]
@="{1A39ADB3-5ED9-44F4-B6BA-5B3D41255033}"

Закидываем файл ShWave.dll в %SystemRoot%\System32, запускаем Install.reg и при попытке использования контекстного меню будет звучать вопль AVP или тот, который вы сами зашили в ресурс.

Вместо \*\ можно использовать любое расширение файлов и СОМ-сервер будет активизироваться только при щелчке правой кнопкой мыши на файлах выбранного типа.

Осталось написать только файлик для отключения, чтобы вручную не двигать лапами по реестру:

REGEDIT4
[-HKEY_CLASSES_ROOT\CLSID\{1A39ADB3-5ED9-44F4-B6BA-5B3D41255033}\InprocServer32]
[-HKEY_CLASSES_ROOT\CLSID\{1A39ADB3-5ED9-44F4-B6BA-5B3D41255033}]
[-HKEY_CLASSES_ROOT\*\shellex\ContextMenuHandlers\WAV]
[-HKEY_CLASSES_ROOT\Directory\shellex\ContextMenuHandlers\WAV]

Вот и все.

Получить ссылку на материал

Категория: CORBA и COM | Добавил: Барон (20.12.2011)
Просмотров: 1005 | Теги: СCOM, сервер | Рейтинг: 0.0/0
[ Пожертвования для сайта ] [ Пожаловаться на материал ]

Если вам помог материал сайта кликните по оплаченной рекламе размещенной в центре

Поиск
Категории раздела
ActiveX [10]
CORBA и COM [16]
Kol и MCK [23]
WinAPI [28]
Компоненты [27]
Работа с Bluetooth [4]
Железо [8]
Текст [18]
Разное [98]
Королевство Delphi © 2010-2024
Яндекс цитирования