Как сделать чтобы запущеный exe сам себя удалил? (45827)

Посмотреть архив целиком

Укрощение строптивого… CD-ROM

Алексей Фоминов

Кто не мечтает о быстром CD-ROM? Быстрый CD-ROM – это хорошо… с одной стороны. А если на компакт-диске появилась трещина? Быстрый CD-ROM – это уже нехорошо. На скорости 52х такой компакт-диск читать просто опасно. А если на этом диске жизненно важные данные? Выход есть. Просто снизить скорость привода. Если вы знакомы с языком программирования Object Pascal, тогда читайте далее.

Использование интерфейса SCSI

SCSI (Small Computer System Interface - интерфейс малой компьютерной системы) – шина ввода/вывода, которая разрабатывалась как метод соединения нескольких классов периферийных устройств в главную систему, не требующий внесения модификации в общие аппаратные средства и программное обеспечение.

Поскольку цель данной статьи рассказать читателю о том, как программно управлять устройствами, которые подключаются к SCSI-шине, а не о том, как написать драйвер SCSI-устройства, описывать технические особенности шины SCSI и её отличие от IDE я не буду.

Каким же образом операционная система Windows общается со SCSI-устройствами?

Это зависит от версии операционной системы. В системах семейства Windows 9х (95, 98, 98SE, Me) применяется ASPI (Advanced SCSI Programmer Interface – улучшенный интерфейс программирования SCSI). В стандартную поставку этих операционных систем входят ASPI-драйвер и библиотека для работы с ним, разработанные фирмой Adaptec. В системах семейства Windows NT (NT 4.0, 2000, XP, Server) используется SPTI (SCSI Pass Through Interface – интерфейс передачи через SCSI). То есть, в NT-системах компания Майкрософт полностью отказалась от продукта фирмы Adaptec и создала свой интерфейс общения со SCSI-устройствами. Принесло ли это пользу пользователям? Вряд ли. На мой субъективный взгляд, рядовому пользователю всё равно, как происходит доступ к SCSI, ему важно, чтобы всё работало правильно. Принесло ли это пользу разработчикам программного обеспечения? Однозначно нет. Теперь, разрабатывая приложения для управления SCSI-устройствами, разработчик должен либо создавать две версии своего продукта (одну для Win9x, другую для WinNT), либо включать поддержку двух интерфейсов в свой продукт, что вряд ли является целесообразным с точки зрения размера программы.

Какой из двух интерфейсов лучше, мне сказать трудно. Отмечу лишь то, что программа Nero использует ASPI-драйвер, специально разработанный для неё фирмой Adaptec.

Рассмотрим сначала программирование с помощью интерфейса ASPI, на примере управления приводом CD-ROM/R/RW.

Предполагается, что читатель умеет работать с динамически компонуемыми библиотеками (dll). Как вы будете подключать библиотеку для работы с ASPI-драйвером wnaspi32.dll (статически или динамически) – дело ваше, главное, чтобы ваше приложение правильно импортировало из этой библиотеки необходимые нам функции.

Я подключал эту библиотеку статически и импорт нужных нам функций у меня выглядел так:

function GetASPI32SupportInfo:DWORD; external 'wnaspi32.dll'

name 'GetASPI32SupportInfo';

function SendASPI32Command(LPSRB:Pointer):DWORD; external 'wnaspi32.dll'

name 'SendASPI32Command'.

Функция GetASPI32SupportInfo инициализирует ASPI и возвращает информацию об основной конфигурации. При успешном выполнении она возвращает двойное слово (DWORD), в котором старший байт младшего слова содержит статус ASPI, а младший байт – количество устройств (адаптеров), поддерживающих ASPI. Байт статуса может содержать следующие значения:

$01 – выполнено без ошибок;

$E8 – нет адаптеров;

$E2 – не может быть выполнено под управлением Windows 3.1;

$E3 – неправильная установка ASPI, или имеются конфликты ресурсов;

$E7 – установка ASPI нарушена (требуется повторная установка);

$E9 – недостаточно системных ресурсов для инициализации ASPI;

$E4 – общий внутренний сбой ASPI.

Количество возвращенных адаптеров представляет собой количество логических шин, а не физических адаптеров. Для адаптеров с единственной шиной количество адаптеров и количество логических шин идентичны.

Функция SendASPI32Command оперирует со всеми SCSI-запросами ввода/вывода. Каждый SCSI-запрос использует SCSI Request Block (SRB – Блока Запроса SCSI), определяющий операцию ASPI, которую нужно выполнить.

Параметр, передаваемый функции SendASPI32Command – указатель на определённую структуру. Описание этих структур приведено ниже.

type

SRB_HAInquiry = packed record

SRB_Cmd: Byte; // код команды ASPI (константа SC_HA_INQUIRY = $00)

SRB_Status, // байт статуса ASPI команды

SRB_HaId, // номер адаптера ASPI

SRB_Flags: Byte; // зарезервировано, должно быть 0

SRB_Hdr_Rsvd: Dword; // зарезервировано, должно быть 0

HA_Count: Byte; // количество адаптеров

HA_SCSI_ID: Byte; // ID SCSI-адаптера

HA_ManagerId: array [0..15] of Byte; // строка, описывающая менеджер

HA_Identifier: array [0..15] of Byte; // строка, описывающая адаптер

HA_Unique: array [0..15] of Byte; // уникальные параметры адаптера

HA_Rsvd1: Word; // зарезервировано, должно быть 0

end;


PSRB_HAInquiry = ^SRB_HAInquiry;

TSRB_HAInquiry = SRB_HAInquiry;

Структура TSRB_HAInquiry используется для получения информации о физических SCSI-адаптерах.

type

SRB_GDEVBlock = packed record

SRB_Cmd, // код команды ASPI (константа SC_GET_DEV_TYPE = $01);

SRB_Status, // байт статуса ASPI команды;

SRB_HaId, // номер адаптера ASPI;

SRB_Flags: Byte; // зарезервировано, должно быть 0;

SRB_Hdr_Rsvd: Dword; // зарезервировано, должно быть 0;

SRB_Target, // ID объекта SCSI;

SRB_Lun, // Logical Unit Number (LUN - логический номер устройства);

SRB_DeviceType, // тип периферийного устройства;

SRB_Rsvd1: Byte; // зарезервировано, должно быть 0;

end;


TSRB_GDEVBlock = SRB_GDEVBlock;

PSRB_GDEVBlock = ^SRB_GDEVBlock;

Структура TSRB_GDEVBlock используется для идентификации устройств на шине SCSI.

type

SRB_ExecSCSICmd = packed record

SRB_Cmd, // код команды ASPI (константа SC_EXEC_SCSI_CMD = $02)

SRB_Status, // байт статуса ASPI команды

SRB_HaId, // номер адаптера ASPI

SRB_Flags: Byte; // флаги запроса ASPI

SRB_Hdr_Rsvd: Dword; // зарезервировано, должно быть 0

SRB_Target, // ID объекта SCSI

SRB_Lun: Byte; // Logical Unit Number (LUN - логический номер устройства)

SRB_Rsvd1: Word; // зарезервировано для выравнивания

SRB_BufLen: Dword; // длина буфера

SRB_BufPointer: Pointer; // указатель на буфер данных

SRB_SenseLen, // длина значения;

SRB_CDBLen, // длина Command Descriptor Block – блока дескриптора команды

SRB_HaStat, // статус адаптера

SRB_TargStat: Byte; // статус объекта

SRB_PostProc, // указатель на функцию постинга (см.ниже)

SRB_Rsvd2: Pointer; // зарезервировано, должно быть 0;

SRB_Rsvd3, // зарезервировано для выравнивания

CDBByte: array [0..15] of byte; // SCSI Command Descriptor Block

// буфер значения для SCSI-запроса

SenseArea: array [0..SENSE_LEN + 1] of byte;

end;


TSRB_ExecSCSICmd = SRB_ExecSCSICmd;

PSRB_ExecSCSICmd = ^SRB_ExecSCSICmd;

Структура TSRB_ExecSCSICmd используется для выполнения команд ввода/вывода. Константа SENSE_LEN (длина буфера значения) по умолчанию равна 14.

На мой взгляд, теории пока достаточно. Перейду к практике.

Для начала инициализируем ASPI.

function GetASPI: Integer;

var

dwSupportInfo: DWORD;

byASPIStatus,byHACount: Byte;

begin

Result := 0;

dwSupportInfo := GetASPI32SupportInfo;

byASPIStatus := HIBYTE(LOWORD(dwSupportInfo)); // статус ASPI

byHACount := LOBYTE(LOWORD(dwSupportInfo)); // количество адаптеров

case byASPIStatus of

SS_COMP: Result := Integer(byHACount);

SS_NO_ADAPTERS: ShowMessage('ASPI-контроллеры не обнаружены!');

SS_ILLEGAL_MODE: ShowMessage(

'ASPI не может быть выполнен под управлением Windows 3.1!');

SS_NO_ASPI: ShowMessage(

'Неправильная установка ASPI, или имеются конфликты ресурсов!');

SS_MISMATCHED_COMPONENTS: ShowMessage(

'Установка ASPI нарушена! Установите повторно, пожалуйста!');

SS_INSUFFICIENT_RESOURCES: ShowMessage(

'Недостаточно системных ресурсов для инициализации ASPI!');

SS_FAILED_INIT: ShowMessage('Общий внутренний сбой ASPI!');

end;

end;

Итак, мы получили информацию об имеющихся SCSI-адаптерах. Теперь выделим из их числа (если их несколько) устройства CD-ROM/R/RW. Для этого создадим вспомогательные структуры: TCDROM и TCDROMs.

type

TCDROM=record

HaID, // номер адаптера ASPI

Target, // ID объекта SCSI

Lun: Byte; // логический номер устройства

DriveLetter: string; // буквенное обозначение диска

VendorID, // идентификатор производителя

ProductID, // идентификатор продукта

Revision, // изменение

VendorSpec, // спецификация производителя

Description: string; // описание

end;


Случайные файлы

Файл
19318.rtf
~$писка ДЗ2.doc
73267-1.rtf
129748.rtf
44550.doc




Чтобы не видеть здесь видео-рекламу достаточно стать зарегистрированным пользователем.
Чтобы не видеть никакую рекламу на сайте, нужно стать VIP-пользователем.
Это можно сделать совершенно бесплатно. Читайте подробности тут.