Сегодня 15 июня 2024
18+
MWC 2018 2018 Computex IFA 2018
реклама
Программное обеспечение

Как получить список открытых файлов на Win9x

Автор: Ашот Оганесян

Как известно, Win32 API не содержит функцию, которая может помочь извлечь из системы список всех файлов, открытых в данный момент на локальной машине. К сожалению, документация (MSDN) содержит очень туманную и расплывчатую информацию, но одно ясно - такой список хранится в системе и мы можем его получить из User Mode, т.е. не прибегая к написанию драйвера!

Хитрость в том, что нам надо вызвать старое доброе прерывание INT21h, для этого воспользуемся законной (документированной) API-шной ф-цией DeviceIoControl. Ф-ция DeviceIoControl посылает управляющие команды напрямую указанному драйверу, тем-самым заставляя драйвер выполнять соответствующие действия. Вот прототип DeviceIoControl:

BOOL DeviceIoControl(
HANDLE hDevice,
DWORD dwIoControlCode,
LPVOID lpInBuffer,
DWORD nInBufferSize,
LPVOID lpOutBuffer,
DWORD nOutBufferSize,
LPDWORD lpBytesReturned,
LPOVERLAPPED lpOverlapped
);

Первый параметр это описатель (hDevice) устройства, файла или директории, так что получим этот описатель. Система Windows9x содержит специальный драйвер - VWIN32.VXD, он предоставляет доступ к управляющим ф-циям, за которые в MS-DOS отвечало прерывание 21h. Теперь нам надо как-то получить описатель этого драйвера что бы передать его в DeviceIoControl:

HANDLE WINAPI OpenVWin32 (void)
{

return CreateFile (TEXT("\.vwin32"), 0, 0, NULL, 0,
FILE_FLAG_DELETE_ON_CLOSE, NULL);
}

Второй параметр это управляющий код операции, которую необходимо выполнить (dwIoControlCode). Мы передадим константу VWIN32_DIOC_DOS_IOCTL, равняющуюся 1: #define VWIN32_DIOC_DOS_IOCTL 0x01

Третий параметр - указатель на буфер для входных данных (lpInBuffer). Для системы Windows 95/98 надо определить следующую структуру:

typedef struct _DIOC_REGISTERS {
DWORD reg_EBX;
DWORD reg_EDX;
DWORD reg_ECX;
DWORD reg_EAX;
DWORD reg_EDI;
DWORD reg_ESI;
DWORD reg_Flags;
}
DIOC_REGISTERS, *PDIOC_REGISTERS;

Указатель на буффер (lpInBuffer) должен указывать на адрес структуры, описаной выше, инициализированной следующими значениями:

regs.reg_EBX = 0;// Устройство на котором перечисляются файлы (0-Текущее,A-1,B-2,C-3,...)
regs.reg_EDX = (DWORD)buf;// Адрес буффера, куда записывается имя файла
regs.reg_ECX = 0x486D;// Перечислять открытые файлы
regs.reg_EAX = 0x440D;// Управляющий код для блочных устройств
regs.reg_EDI = 0;// Тип файлов для перечисления (0-все,1-не перемещаемые)
regs.reg_ESI = i++;// Индекс (начиная с 0) файла для перечисления

Каждый вызов будет возвращать информацию только об одном файле. Что бы перечислить все открытые файлы, необходимо вызывать ф-цию в цикле:

#define CARRY_FLAG 0x01

DWORD cb;
DIOC_REGISTERS regs;
char buf[MAX_PATH];
int i = 0;
while (1)
{
ZeroMemory(®s,sizeof(regs));
regs.reg_EBX = 0;
regs.reg_EDX = (DWORD)buf;
regs.reg_ECX = 0x486D;
regs.reg_EAX = 0x440D;
regs.reg_EDI = 0;
regs.reg_ESI = i++;

DeviceIoControl (hVWin32, VWIN32_DIOC_DOS_IOCTL,
®s, sizeof(regs), ®s, sizeof(regs),
&cb, 0);
if (regs.reg_Flags & CARRY_FLAG)
break;

// Ух ты, получилось!
}

Ну что же, теперь мы все можем и все умеем, осталось только написать маленький работающий пример: openfiles.zip (15Kb)

Оригинал этой статьи на английском языке лежит здесь: Trick 1

Не документированные ф-ции WindowsNT и Windows95/98 и описания на английском языке: www.codepile.com

 
 
Если Вы заметили ошибку — выделите ее мышью и нажмите CTRL+ENTER.
Вечерний 3DNews
Каждый будний вечер мы рассылаем сводку новостей без белиберды и рекламы. Две минуты на чтение — и вы в курсе главных событий.

window-new
Soft
Hard
Тренды 🔥
Disney внедрил «рекламные игры» в стриминговые сервисы Hulu и ESPN 11 ч.
Meta перестала обучать ИИ на данных пользователей, но только из ЕС 11 ч.
Новая статья: XDefiant — зов долга, но не тот. Рецензия 11 ч.
В Сети нашли намёк на сроки выхода крупного эксклюзива Xbox — ролевой игры Clockwork Revolution, похожей на BioShock Infinite 12 ч.
The Talos Principle 2 получила «грандиозное» дополнение Road to Elysium со счастливой концовкой и сложнейшими загадками 12 ч.
Ubisoft превращается в «Абстерго»: платформу Assassin’s Creed Infinity переименовали в «Анимус» 14 ч.
Статистика назвала самые желанные игры с летних презентаций — Doom: The Dark Ages на втором месте 15 ч.
Bandai Namco анонсировала первый за несколько месяцев патч для Elden Ring и раскрыла системные требования Shadow of the Erdtree 16 ч.
«Базальт СПО» представила открытую библиотеку libdomain для управления службами каталогов 17 ч.
Президента Microsoft допросили в Конгрессе США после «каскада ошибок» в системе безопасности 18 ч.
Китайские учёные создали основу для идеальной энергонезависимой памяти без износа 18 мин.
На всех парах: Google запитает от геотермальной энергии ЦОД в Неваде 49 мин.
Intel поймала AMD на подтасовке результатов в ИИ-тестах EPYC против Xeon 11 ч.
Южнокорейские ИИ-стартапы Sapeon и Rebellions объединятся, чтобы вместе противостоять NVIDIA 12 ч.
Lian Li представила корпус O11 EVO RGB Automobili Lamborghini в стиле итальянских суперкаров 13 ч.
«Джеймс Уэбб» разглядел пару звёзд с газовыми шлейфами там, где учёные 50 лет видели лишь одну звезду 16 ч.
Марсоход Perseverance наткнулся на опасное поле валунов, но смог обогнуть его по руслу древней реки 17 ч.
Samsung Galaxy Z Fold6 показался на видео в форме макета — его сравнили с предшественником 17 ч.
Учёные облачили ДНК в искусственный янтарь — получилось сверхплотное и долговечное хранилище данных 18 ч.
Спрос на ЦОД в Азиатско-Тихоокеанском регионе значительно превышает предложение 19 ч.