Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Перехват 0x21 прерывания под досом, а именно чтение размера файла 
:(
    Опции темы
merge
Дата 16.6.2007, 09:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 84
Регистрация: 20.3.2007

Репутация: нет
Всего: 1



Вобщем над этой проблемой уже бьюсь неделю.
Необходимо изменить отображаемое в досе размер файла. Для этого перехватываю 0x21 прерывание, 0x23 функцию.
В листинге ниже сделал проверку на занятость доса и, пока, изменение первой буквы файла на 1. с размером пока ничего дне делал. но. Не работает! 
Загружаю досбокс, гружу там NC, затем из него свою прогу. В NC у меня уже не возвращается ) делаю dir. Все как было. все имена нормальные :( На экране признак вхождения в if в обработчике не появляется. Если меняю прерывание - и в NC возвращается после запуска проги и ничо не зависает =)
Код

#include <dos.h>
#include <stdlib.h>
#include <string.h>

#define INT 0x21
#define ATTR 0x7900

extern unsigned _heaplen = 1024;
extern unsigned _stklen  = 512;

void interrupt (*oldhandler)(...);
void interrupt newhandler(...);

union REGS inregs, outregs;
struct SREGS segregs;

char far *PDOSBUSY;

//вывод строки на экран
void putstr(char *s, int x, int y)
{
    char (far *p)[25][80][2]=(char (far*)[25][80][2])0xB8000000;
    while(*s !='\0')
    {
        (*p)[y][x ][0] = *s++;
        (*p)[y][x++][1] = 0x71;
    }
    sleep(1);
}

#pragma argsused
int main(int argc, char *argv[])
{
    inregs.h.ah = 0x34;
    intdosx( &inregs, &outregs, &segregs );
//проверяем на занятость дос
    PDOSBUSY = (char far*)FP_MAKE(segregs.es,outregs.x.bx);
    if (!(*PDOSBUSY))
    {
        putstr("DOSFREE ",0,1);
        oldhandler = getvect(INT);
        setvect(INT, newhandler);
    }

    keep(0, _SS + (_SP/16) - _psp);
    return 0;
}

void interrupt newhandler(...)
{
    (*oldhandler)();
    if (_AH == 0x23)
    {
        putstr("ah=0x23",0,1);
        fcb *item = (fcb*)MK_FP(_DS,_DX);
        item->fcb_name[0] = '1';
    }
}

помогите пожалуйста, совсем мало времени осталось (
или подскажите - куда запостить, чтоб помогли

Это сообщение отредактировал(а) merge - 16.6.2007, 09:05
PM MAIL   Вверх
bsa
Дата 16.6.2007, 09:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



Если я не ошибаюсь, у тебя проблема с передачей значений регистров в старый обработчик. Обработчик прерывания немного по-другому надо оформлять, чтобы этого не было. Но как - уже не помню.
PM   Вверх
Sartorius
Дата 16.6.2007, 09:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1568
Регистрация: 18.7.2006
Где: Ivory tower

Репутация: 8
Всего: 37



 уверен, что старый обработчик AH не меняет?

PS Попробуй без дос бокса в чистом досе запуситть?
PM MAIL ICQ   Вверх
merge
Дата 16.6.2007, 18:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 84
Регистрация: 20.3.2007

Репутация: нет
Всего: 1



даже так не хочет (

Код
#include <dos.h>
#include <stdlib.h>

#define INT 0x21

extern unsigned _heaplen = 1024;
extern unsigned _stklen  = 512;

void interrupt (*oldhandler)(...);
void interrupt newhandler(...);

union REGS inregs, outregs;
struct SREGS segregs;

char far *PDOSBUSY;

#pragma argsused
int main(int argc, char *argv[])
{
    inregs.h.ah = 0x34;
    intdosx( &inregs, &outregs, &segregs );
//проверяем на занятость дос
    PDOSBUSY = (char far*)FP_MAKE(segregs.es,outregs.x.bx);
    if (!(*PDOSBUSY))
    {
        oldhandler = getvect(INT);
        setvect(INT, newhandler);
    }

    keep(0, _SS + (_SP/16) - _psp);
    return 0;
}

void interrupt newhandler(...)
{
    (*oldhandler)();
}



Добавлено через 48 секунд
Цитата(Sartorius @  16.6.2007,  09:41 Найти цитируемый пост)
Попробуй без дос бокса в чистом досе запуситть?

запускал на вирт машине. результат тот-же

Добавлено через 1 минуту и 33 секунды
Цитата(bsa @  16.6.2007,  09:31 Найти цитируемый пост)
Обработчик прерывания немного по-другому надо оформлять, чтобы этого не было. Но как - уже не помню.

ну намекни хоть как поискать.. какие слова повводить. ато я уже пол инета перерыл (
PM MAIL   Вверх
merge
Дата 16.6.2007, 19:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 84
Регистрация: 20.3.2007

Репутация: нет
Всего: 1



ВСЕ! проблема решена!
юзайте функцию _chain_intr для вызова старого обработчика! е-мае. неделя прошла до того, как в инете увидел эту фунцию. :(
PM MAIL   Вверх
merge
Дата 16.6.2007, 21:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 84
Регистрация: 20.3.2007

Репутация: нет
Всего: 1



тогда вопрос по немного другой стороны проблемы.

При вызове старого обработчика, у меня больше не возвращается в мой обработчик. В хелпе написано, что так может быть. Но как перебороть это?
Код
void interrupt newhandler(...)
{
  _chain_intr(oldhandler);
  if (_AH == 0x42 && _AL == 2 &&
      _CX == 0 && _DX == 0)
  {
    putstr("0x42",0,1);
    delay(100);
    _DX = 0;
    _AX = 0x0001;
    //_FLAGS
  }
}


Это сообщение отредактировал(а) merge - 16.6.2007, 21:25
PM MAIL   Вверх
bsa
Дата 16.6.2007, 21:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



Вызывай его после для тех случаев, когда не возвращается.
PM   Вверх
merge
Дата 17.6.2007, 07:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 84
Регистрация: 20.3.2007

Репутация: нет
Всего: 1



Цитата(bsa @  16.6.2007,  21:32 Найти цитируемый пост)
Вызывай его после для тех случаев, когда не возвращается.

всмысле?
при вызове старого обработчика он всегда НЕ передает управление обратно моему обработчику. Быть может можно сделать каку-нибудь мутку со стеком? чтоб потом в моу прогу возвратился?
PM MAIL   Вверх
bsa
Дата 17.6.2007, 14:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



Ты не понял.
Я думаю, он не возвращается в случае завершения программ. Если я не ошибаюсь, при завершении программа вызывает какую-то функцию DOS. Более того, тот же keep, если память не изменяет не возвращает управление.
Поэтому, если ты видишь, что программа хочет выполнить какой-то из этих вызовов, то просто либо сначала выполняй свой код, либо сразу передавай управление обработчику ДОС, понимая, что из него не вернешься.
PM   Вверх
merge
Дата 17.6.2007, 16:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 84
Регистрация: 20.3.2007

Репутация: нет
Всего: 1



а если мне нужно узнать дискриптор открытого файла функцией 3d ?
PM MAIL   Вверх
bsa
Дата 17.6.2007, 22:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



Ты не понял. Сначала проверяй функцию дос. Если она та, что тебе нужна, делай какие-либо действия. Иначе вызывай сразу обработчик DOS:
Код
void interrupt newhandler(...)
{
  if (_AH == 0x42 && _AL == 2 &&
      _CX == 0 && _DX == 0)
  {
    _chain_intr(oldhandler);
    putstr("0x42",0,1);
    delay(100);
    _DX = 0;
    _AX = 0x0001;
    //_FLAGS
  } else
       _chain_intr(oldhandler);
}
Примерно так. Только надо убедиться в сохранности регистров.
PM   Вверх
dumb
Дата 18.6.2007, 04:33 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


sceloglauxalbifacies
****


Профиль
Группа: Экс. модератор
Сообщений: 2929
Регистрация: 16.6.2006

Репутация: 8
Всего: 158



вставлю свои "пять копеек":
1. флаг занятости доса проверяется в обработчиках аппаратных прерываний для исключения повторного входа в функции доса. его проверка в вышеприведенном куске совершенно бессмысленна.
2. _chain_intr - это по сути jmp на указанный обработчик с восстановлением состояния регистров на момент входа в текущий обработчик. возврата не будет.
3. размер файлов получают, как правило, при их перечислении функциями 4e/4f.
4. C вообще весьма посредственно заточен под написание такого рода обработчиков - эти вещи лучше делать на асме и прилиньковывать obj. поясню мыслю: чтобы выполнить вызов(call) "старого" обработчика с состоянием регистров таким, какое оно было на входе в наш обработчик, нужно неплохо попрыгать с бубном на костылях(выглядеть это будет крайне убого - как прыжки, так и получившийся код smile ). первые попадающиеся на глаза проблемы(для примера): при использовании модификатора interrupt, компилер помещает в начало процедуры сохранение всех(почти) регистров, перенастройку регистра ds(для доступа к данным нашей проги), ну и bp до кучи. т.е. вызов старого обработчика идет уже с измененными регистрами(а ds, к слову, довольно часто используется в качестве входного параметра функций доса). а в конце нашего обработчика компилер заботливо восстанавливает все сохраненные на входе регистры, так что чтобы вернуть результаты работы "старого" обработчика, надо менять значения в стеке... итд. итп.
5. а для реализации такой мелочи, как описанная выше задача, лучше воспользоваться асмом в чистом виде - получится гораздо меньше букв. smile сильно меньше, чем я тут написал... smile
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0563 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.