ZEVSIK Код (Text): #include <stdio.h> #include <stdlib.h> void main(void) { system("mem /p"); puts("Press Enter to exit"); getchar(); }
ZEVSIK Можно пройти по цепочке mcb (memory control block), определяя программу-владельца каждого блока.
Можно пройти по цепочке mcb (memory control block), определяя программу-владельца каждого блока. Как начать? Какова структура? Где почитать? спсб.
ZEVSIK > Как начать? Воспользоваться какой-нибудь (ya, google, rambler etc.) поисковой системой, указав в строке поиска: "memory control block".
Код (Text): #include<dos.h> #include<stdio.h> #include<conio.h> #include<stdlib.h> #pragma pack(1) typedef struct _CVT_ { unsigned mcb_seg; void far *dev_cb; void far *file_tab; void far *clock_dr; void far *con_dr; unsigned max_btbl; void far *disk_buf; void far *drv_info; void far *fcb_tabl; unsigned fcb_size; unsigned char num_bdev; unsigned char lastdriv; } CVT; typedef struct _MCB_ { unsigned char type; unsigned owner; unsigned size; char reserve[ 11 ]; char pgmname[ 8 ]; // ? ? } MCB; #pragma pack() #define FP_MAKE(seg,off) ((void far *) \ ((((unsigned long) (unsigned)(seg)) << 16L) | \ ((unsigned long) (unsigned) (off)))) CVT far *get_mcvt(void) { union REGS inregs, outregs; struct SREGS segregs; inregs.h.ah = 0x52; intdosx( &inregs, &outregs, &segregs ); return( (CVT far*)FP_MAKE(segregs.es,outregs.x.bx-2) ); } MCB far *get_fmcb(CVT far *cvt) { return( (MCB far *) FP_MAKE (cvt->mcb_seg, 0) ); } MCB far *get_nmcb( MCB far *mcb ) { unsigned seg, off; if( mcb->type == 'M' ) { seg = FP_SEG( mcb ) + mcb->size + 1; off = FP_OFF( mcb ); return( (MCB far *) FP_MAKE (seg,off) ); } else return( (MCB far *)0 ); } void main( void ) { CVT far *cvt; MCB far *mcb; int i; cvt = get_mcvt(); mcb = get_fmcb(cvt); for(;;) { if(mcb == (MCB far *)0) break; printf("%Fp %c %04X %04X\n", mcb, mcb->type, mcb->owner, mcb->size); printf( "%s\n", mcb->size ); for( i=0; i<8; i++ ) printf( "%c", mcb->pgmname[ i ] ); printf( "\n" ); getch(); mcb = get_nmcb( mcb ); } exit(0); } Подскажите, кто знает, почему вместо имен программ лезет всякая муть. mcb->pgmname должен содержать "имя программы, находящейся в данном блоке" но что-то не получается.
ZEVSIK 1) ошибка в определении структуры mcb Код (Text): typedef struct _MCB_ { unsigned char type; unsigned owner; unsigned size; char reserve[ 3 ]; // !!! не 11, а 3 char pgmname[ 8 ]; // ? ? } MCB; 2) выводить надо до первого нуль-символа Код (Text): for( i=0; i<8 && mcb->pgmname[ i ]; i++ ) printf( "%c", mcb->pgmname[ i ] ); printf( "\n" ); 3) имя программы есть не у каждого mcb: 3.1) для mcb->owner == 0, т.е. у свободного mcb, нет имени программы; 3.2) afaik для mcb->owner == 8 тоже нет имени; 3.3.) если mcb->owner очередного mcb "похож" на psp, то надо проверять не является этот mcb средой/окружением/environment'омесли да, то, скорее всего, имя программы надо искать через родителя, либо псоле переменных окружения есть полный пусть запущенной программы.
q_q Я извиняюсь что туплю, но не мог бы ты примерчик подкинуть, а то непонятно: и что значит ... Я пример с Delphi переводил и совсем запутался напр вот это: Код (Text): psp = ( ProgramSegmentPrefix * ) MK_FP ( MCB->BlockOwner, 0 ); //possible PSP //Almost all programs have a tag of 0x20CD; DOS MODE is one that uses 0x27CD in some versions. } if( (psp->PSPtag != 0x20CD) && (psp->PSPtag != 0x27CD) ) { //printf( "System <DOS %d.%d>", DosVerNum, DOSVersion ); // not valid PSP } else { MCBenv = ( MemoryControlBlock * ) MK_FP ( psp->Environment-1, 0 ); // MCB of environment
ZEVSIK > непонятно 3.2) afaik для mcb->owner == 8 В поле mcb->owner содержится сегментный адрес psp владельца, если он равен нулю, то владельцем mcb является он сам, т.е. mcb свободен. Если mcb->owner окажется меньше чем адрес первого mcb, то блок принадлежит ОС, скорее всего он будет один, самый первый. Я не встречал в mcb->owner чисел меньших адреса первого mcb отличных от нуля или восьми, поэтому написал восемь, а вообще можно сравнивать с адресом первого mcb. > пример с Delphi переводил С этого "Show Memory Control Blocks" by JOSE ANTONIO NODA? > напр вот это Да, это проверка "похожести". Если выполняется условие, что psp->PSPtag == 0x20CD, то MCB->BlockOwner очень похож на psp, если еще окажется, что psp->Environment == FP_SEG(mcb), то MCB->BlockOwner очень-очень похож на psp, а mcb от его окружения. Про psp->PSPtag == 0x27CD ничего сказать не могу.
Какие еще запущеные программы в досе? Дос же однозадачный - там только прерывания есть. Почему не просканировать область 0:0 -> 0:400 и не посмотреть куда векторы кажут?
_DEN_ в ДОСе может быть (и обычно так и есть) много программ запущено из них выполняется только одна, однозадачность типа, как ты правильно заметил
На сколько я помню, соответствующая функция 21-го прерывания называлась "передать управление и остаться резидентной"
это 31 функция а я про 4b я просто придрался к твоему слову - "запускать" можно было много программ, ну тысячу, лишь бы памяти хватило выполняться - да, только одна, текущая
_DEN_ > просканировать область 0:0 -> 0:400 и ... посмотреть куда векторы кажут Imho цепочка перехватчиков нормальное состояние для DOS, поэтому "список запущенных программ" тут не получить.
Не получается найти в psp. Подскажите. Код (Text): #include<dos.h> #include<stdio.h> #include<conio.h> #include<stdlib.h> #include<string.h> typedef unsigned char BYTE; typedef unsigned int WORD; typedef unsigned long DWORD; enum bool{ false, true }; #pragma pack(1) typedef struct _CVT_ { unsigned mcb_seg; void far *dev_cb; void far *file_tab; void far *clock_dr; void far *con_dr; unsigned max_btbl; void far *disk_buf; void far *drv_info; void far *fcb_tabl; unsigned fcb_size; unsigned char num_bdev; unsigned char lastdriv; } CVT; typedef struct _MCB_ { unsigned char type; unsigned owner; unsigned size; char reserve[ 3 ]; char pgmname[ 8 ]; } MCB; typedef struct _PSP_ // PSP -- only needed fields are shown { unsigned int tag; // 0x20CD or 0x27CD if PSP} { 00 0x00 } unsigned int misc[ 21 ]; // 02 0x02 unsigned int environment; // 44 0x2C } PSP; #pragma pack() #define FP_MAKE(seg,off) ((void far *) \ ((((unsigned long) (unsigned)(seg)) << 16L) | \ ((unsigned long) (unsigned) (off)))) CVT far *get_mcvt(void) { union REGS inregs, outregs; struct SREGS segregs; inregs.h.ah = 0x52; intdosx( &inregs, &outregs, &segregs ); return( (CVT far*)FP_MAKE(segregs.es,outregs.x.bx-2) ); } MCB far *get_fmcb(CVT far *cvt) { return( (MCB far *) FP_MAKE (cvt->mcb_seg, 0) ); } MCB far *get_nmcb( MCB far *mcb ) { unsigned seg, off; if( mcb->type == 'M' ) { seg = FP_SEG( mcb ) + mcb->size + 1; off = FP_OFF( mcb ); return( (MCB far *) FP_MAKE (seg,off) ); } else return( (MCB far *)0 ); } // получает номер версии DOS void get_DOS_ver_h( BYTE *dos ) { union REGS r; r.h.ah = 0x30; intdos( &r, &r ); *dos = r.h.al; } void main( void ) { CVT far *cvt; MCB far *cmcb, far *mcb_owner, far *mcb_env; PSP *psp; char BlockType[ 10 ]; WORD othersegm, fathersegm, csegm, envsize; BYTE *envstr, dos; int i, envlen; get_DOS_ver_h( &dos ); cvt = get_mcvt(); cmcb = get_fmcb(cvt); csegm = ( WORD )cmcb; for(;;) { if(cmcb == (MCB far *)0) break; if( cmcb->owner == 0 ) { printf( "Free Space <unallocated>\n" ); } else { psp = ( PSP * ) FP_MAKE ( cmcb->owner, 0 ); // possible PSP // Almost all programs have a tag of $20CD; DOS MODE is one that uses $27CD in some versions. if( (psp->tag == 0x20CD) || (psp->tag == 0x27CD) ) { printf( "Not valid PSP\n" ); // not valid PSP } else { mcb_env = ( MCB * ) MK_FP ( psp->environment-1, 0 ); // MCB of environment if( cmcb->owner == (csegm+1) ) { strcpy( BlockType, "Program " ); } else if( psp->environment == (csegm+1) ) { strcpy( BlockType, "Environment " ); if( cmcb->owner != mcb_env->owner ) { if( dos != 4 ) { printf( "<unknown>" ); // different owner; unknown in 3.X } else { // in DOS 4.0 short name is in MCB mcb_owner = ( MCB * ) MK_FP ( cmcb->owner-1, 0 ); // MCB of owner block for( i=0; mcb_owner->pgmname[ i ]!='\0' && i<8; i++ ) { printf( "%c", mcb_owner->pgmname[ i ] ); } printf( "\n" ); } } } else { // environment must have same owner as MCB if( dos < 3 ) { printf( "<unknown>" ); // DOS 1.X or 2.X } else { // Здесь не знвю что делать. /* for( i=0; (i < 100); i++ ) { printf( "%c", psp->environment[ i ] ); } getch(); printf( "%X", envsize ); getch(); */ } } } if( cmcb->owner == fathersegm ) { printf( "COMMAND.COM\n" ); } else { } } cmcb = get_nmcb( cmcb ); } exit(0); } Как прояснить?
ZEVSIK Если выполняется if( (psp->tag == 0x20CD) || (psp->tag == 0x27CD) ), то это означает, что cmcb->owner "похож" на psp, а не наоборот как у тебя.