Index: reactos/drivers/storage/floppy/floppy.c =================================================================== --- reactos/drivers/storage/floppy/floppy.c (revision 74444) +++ reactos/drivers/storage/floppy/floppy.c (working copy) @@ -832,6 +832,91 @@ UCHAR i; UCHAR j; +/* Start of km VPC Detection Routine */ + int vpc = 1; // Initially say we are in a VPC machine + +/* Code idea from: http://phrack.org/issues/59/4.html */ + + struct idt_descrip + { + unsigned short lo_offset,segment_value; + unsigned char unknown,flags; + unsigned short hi_offset; + }; + + unsigned long get_idt_value (void) + { + unsigned char idtr_char[6]; + unsigned long idt_val; + __asm__ volatile ("sidt %0": "=m" (idtr_char)); + idt_val = *((unsigned long *) &idtr_char[2]); + return(idt_val); + } + + void * get_vect_from_idt (int n) + { + struct idt_descrip *idt_desc = &((struct idt_descrip *) get_idt_value()) [n]; + return ((void *) ((idt_desc->hi_offset << 16 ) + idt_desc->lo_offset)); + } + + void hook_idt(int n,void *new_vect,unsigned long *old_vect) + + { + unsigned long new_ptr=(unsigned long)new_vect; + struct idt_descrip *idt_struct=(struct idt_descrip *)get_idt_value(); + /*save old vector*/ + if(old_vect) *old_vect=(unsigned long)get_vect_from_idt(n); + /*assign new stub*/ + idt_struct[n].hi_offset = (unsigned short) (new_ptr >> 0x10); + idt_struct[n].lo_offset = (unsigned short) (new_ptr & 0xFFFF); + return; + } + +/* + End of code from: http://phrack.org/issues/59/4.html +*/ + + void unhook_stub(int n, unsigned long old_vect) + { + unsigned long new_ptr=(unsigned long)old_vect; + struct idt_descrip *idt_struct=(struct idt_descrip *)get_idt_value(); + /*assign original stub back*/ + idt_struct[n].hi_offset = (unsigned short) (new_ptr >> 16); + idt_struct[n].lo_offset = (unsigned short) (new_ptr & 0x0000FFFF); + return; + } + + unsigned long old_vect; // used by hook routine to store the original vector value + + void stub_new(void) + { + __asm__( // decrement vpc from 1 to 0 which means we are NOT in VPC + "sub $1, %0" + : "=r" (vpc) + : "r" (vpc) + ); + __asm__ __volatile__ ("addl $4,0x4(%esp)"); // adjust return value on stack to skip 4 bytes of invalid opcode + __asm__ __volatile__ ("POP %ebp"); // reset the stack point back to original + __asm__ __volatile__ ("IRET"); // IRET to continue because we are here on INT6 + } + + hook_idt(6, &stub_new, &old_vect); // Replace INT6 with our new stub + + /* execute 4 byte normally invalid opcode but good on VPC */ + __asm__ __volatile__ (".byte 0x0F"); + __asm__ __volatile__ (".byte 0x3F"); + __asm__ __volatile__ (".byte 0x07"); + __asm__ __volatile__ (".byte 0x0B"); + + unhook_stub(6, old_vect); + +/* End of km VPC Detection Routine */ + + if (vpc) + DPRINT1("FLOPPY.C: Is VPC\n"); + else + DPRINT1("FLOPPY.C: Not VPC\n"); + PAGED_CODE(); /* Find our controllers on all ISA buses */ @@ -990,7 +1075,12 @@ /* 3l: Attempt to get drive info - if a floppy is already present */ StartMotor(&gControllerInfo[i].DriveInfo[j]); - RWDetermineMediaType(&gControllerInfo[i].DriveInfo[j], TRUE); + + if (!vpc) + RWDetermineMediaType(&gControllerInfo[i].DriveInfo[j], TRUE); + else + DPRINT1("RWDetermineMediaType was skipped here since we are running VPC!\n"); + StopMotor(gControllerInfo[i].DriveInfo[j].ControllerInfo); } }