/*++ Copyright (c) 1998-2001 Klaus P. Gerlicher Module Name: util.c Abstract: Environment: Kernel mode only Author: Klaus P. Gerlicher Revision History: 19-Aug-1998: created 15-Nov-2000: general cleanup of source files Copyright notice: This file may be distributed under the terms of the GNU Public License. --*/ //////////////////////////////////////////////////// // INCLUDES //// #include "remods.h" #include "precomp.h" #include //////////////////////////////////////////////////// // GLOBALS //// // output string char tempUtil[1024]; char tempFlowChanges[256]; //PMADDRESS_SPACE my_init_mm=NULL; ULONG TwoPagesForPhysMem[2*_PAGE_SIZE]; // scancode to ASCII table SCANTOASCII ucScanToAscii_DE[]= { // German keyboard {16,'q'},{17,'w'},{18,'e'},{19,'r'},{20,'t'}, {21,'z'},{22,'u'},{23,'i'},{24,'o'},{25,'p'}, {30,'a'},{31,'s'},{32,'d'},{33,'f'},{34,'g'}, {35,'h'},{36,'j'},{37,'k'},{38,'l'}, {44,'y'},{45,'x'},{46,'c'},{47,'v'},{48,'b'}, {49,'n'},{50,'m'}, {2,'1'},{3,'2'},{4,'3'},{ 5,'4'},{ 6,'5'}, {7,'6'},{8,'7'},{9,'8'},{10,'9'},{11,'0'}, {12,'ß'}, // 239 = ß {0x39,' '},{0x35,'-'},{0x34,'.'},{0x1b,'+'}, {0,0} }; SCANTOASCII ucShiftScanToAscii_DE[]= { // German keyboard SHIFTED {16,'Q'},{17,'W'},{18,'E'},{19,'R'},{20,'T'}, {21,'Z'},{22,'U'},{23,'I'},{24,'O'},{25,'P'}, {30,'A'},{31,'S'},{32,'D'},{33,'F'},{34,'G'}, {35,'H'},{36,'J'},{37,'K'},{38,'L'}, {44,'Y'},{45,'X'},{46,'C'},{47,'V'},{48,'B'}, {49,'N'},{50,'M'}, {2,'!'},{3,'\"'}, // " // (fixes mc syntax highlighting) {4,'@'}, // is pragraph sign on keyboard { 5,'$'},{ 6,'%'}, {7,'&'},{8,'/'},{9,'('},{10,')'},{11,'='}, {12,'?'}, {0x39,' '},{0x35,'_'},{0x34,':'},{0x1b,'*'}, {0,0} }; SCANTOASCII ucScanToAscii_US[]= { // US keyboard {16,'q'},{17,'w'},{18,'e'},{19,'r'}, {20,'t'},{21,'y'},{22,'u'},{23,'i'}, {24,'o'},{25,'p'},{30,'a'},{31,'s'}, {32,'d'},{33,'f'},{34,'g'},{35,'h'}, {36,'j'},{37,'k'},{38,'l'},{44,'z'}, {45,'x'},{46,'c'},{47,'v'},{48,'b'}, {49,'n'},{50,'m'},{2,'1'},{3,'2'}, {4,'3'},{5,'4'},{6,'5'},{7,'6'}, {8,'7'},{9,'8'},{10,'9'},{11,'0'},{12,'-'}, {0x39,' '},{0x35,'/'},{0x34,'.'},{0x1b,']'}, {0x1a,'['},{0x33,','},{0x27,';'},{0x0d,'='}, {0x2b,'\\'},{0x28,'\''},{0x29,'`'}, {0,0} }; SCANTOASCII ucShiftScanToAscii_US[]= { // US keyboard SHIFTED {16,'Q'},{17,'W'},{18,'E'},{19,'R'}, {20,'T'},{21,'Y'},{22,'U'},{23,'I'}, {24,'O'},{25,'P'},{30,'A'},{31,'S'}, {32,'D'},{33,'F'},{34,'G'},{35,'H'}, {36,'J'},{37,'K'},{38,'L'},{44,'Z'}, {45,'X'},{46,'C'},{47,'V'},{48,'B'}, {49,'N'},{50,'M'},{2,'!'},{3,'@'}, {4,'#'},{5,'$'},{6,'%'},{7,'^'}, {8,'&'},{9,'*'},{10,'('},{11,')'},{12,'_'}, {0x39,' '},{0x35,'?'},{0x34,'>'},{0x1b,'}'}, {0x1a,'{'},{0x33,'<'},{0x27,':'},{0x0d,'+'}, {0x2b,'|'},{0x28,'\"'},{0x29,'~'}, {0,0} }; SCANTOASCII ucScanToAscii_DK[]= { // Danish keyboard {16,'q'},{17,'w'},{18,'e'},{19,'r'}, {20,'t'},{21,'y'},{22,'u'},{23,'i'}, {24,'o'},{25,'p'},{30,'a'},{31,'s'}, {32,'d'},{33,'f'},{34,'g'},{35,'h'}, {36,'j'},{37,'k'},{38,'l'},{44,'z'}, {45,'x'},{46,'c'},{47,'v'},{48,'b'}, {49,'n'},{50,'m'},{2,'1'},{3,'2'}, {4,'3'},{5,'4'},{6,'5'},{7,'6'}, {8,'7'},{9,'8'},{10,'9'},{11,'0'},{12,'+'}, {0x39,' '},{0x35,'-'},{0x34,'.'},{0x1b,'¨'}, {0x1a,'å'},{0x33,','},{0x27,'æ'},{0x0d,'´'}, {0x2b,'\''},{0x28,'ø'},{0x29,' '}, {0,0} }; SCANTOASCII ucShiftScanToAscii_DK[]= { // Danish keyboard SHIFTED {16,'Q'},{17,'W'},{18,'E'},{19,'R'}, {20,'T'},{21,'Y'},{22,'U'},{23,'I'}, {24,'O'},{25,'P'},{30,'A'},{31,'S'}, {32,'D'},{33,'F'},{34,'G'},{35,'H'}, {36,'J'},{37,'K'},{38,'L'},{44,'Z'}, {45,'X'},{46,'C'},{47,'V'},{48,'B'}, {49,'N'},{50,'M'},{2,'!'},{3,'"'}, {4,'#'},{5,'¤'},{6,'%'},{7,'&'}, {8,'/'},{9,'('},{10,')'},{11,'='},{12,'?'}, {0x39,' '},{0x35,'_'},{0x34,':'},{0x1b,'^'}, {0x1a,'Å'},{0x33,';'},{0x27,'Æ'},{0x0d,'`'}, {0x2b,'*'},{0x28,'Ø'},{0x29,'§'}, {0,0} }; SCANTOASCII ucAltScanToAscii_DK[]= { // Danish keyboard ALTED {16,' '},{17,' '},{18,' '},{19,' '}, {20,' '},{21,' '},{22,' '},{23,' '}, {24,' '},{25,' '},{30,' '},{31,' '}, {32,' '},{33,' '},{34,' '},{35,' '}, {36,' '},{37,' '},{38,' '},{44,' '}, {45,' '},{46,' '},{47,' '},{48,' '}, {49,' '},{50,' '},{2,' '},{3,'@'}, {4,'£'},{5,'$'},{6,'€'},{7,' '}, {8,'{'},{9,'['},{10,']'},{11,'}'},{12,' '}, {0x39,' '},{0x35,' '},{0x34,' '},{0x1b,'~'}, {0x1a,' '},{0x33,' '},{0x27,' '},{0x0d,'|'}, {0x2b,' '},{0x28,' '},{0x29,' '}, {0,0} }; KEYBOARD_LAYOUT ucKeyboard[]= { {"de", ucScanToAscii_DE, ucShiftScanToAscii_DE, NULL}, {"us", ucScanToAscii_US, ucShiftScanToAscii_US, NULL}, {"dk", ucScanToAscii_DK, ucShiftScanToAscii_DK, ucAltScanToAscii_DK}, {NULL, NULL, NULL, NULL} }; PKEYBOARD_LAYOUT CurrentKeyboard = NULL; //////////////////////////////////////////////////// // FUNCTIONS //// //************************************************************************* // GetKeyboardLayout() // //************************************************************************* PKEYBOARD_LAYOUT GetKeyboardLayout() { if (CurrentKeyboard == NULL) { CurrentKeyboard = &ucKeyboard[kbUS]; } return CurrentKeyboard; } //************************************************************************* // SetKeyboardLayoutByName() // //************************************************************************* PKEYBOARD_LAYOUT SetKeyboardLayoutByName(LPSTR Name) { CHAR tempCmd[256]; ULONG i; for(i=0;ucKeyboard[i].name != NULL;i++) { if(PICE_strcmpi(ucKeyboard[i].name, Name) == 0) { CurrentKeyboard = &ucKeyboard[i]; return CurrentKeyboard; } } return GetKeyboardLayout(); } //************************************************************************* // PICE_memset() // //************************************************************************* void PICE_memset(void* p,unsigned char c,int sz) { unsigned char *p2 = (unsigned char *)p; while(sz--) *p2++ = c; } //************************************************************************* // PICE_memcpy() // //************************************************************************* void PICE_memcpy(void* t,void* s,int sz) { memcpy(t,s,sz); } //************************************************************************* // PICE_isprint() // //************************************************************************* BOOLEAN PICE_isprint(char c) { BOOLEAN bResult = FALSE; if((ULONG)c>=0x20 && (ULONG)c<=0x7f) bResult = TRUE; return bResult; } //************************************************************************* // PICE_strchr() // //************************************************************************* char* PICE_strchr(char* s,char c) { while(IsAddressValid((ULONG)s) && *s) { if(*s == c) return s; s++; } #ifdef DEBUG if(!IsAddressValid((ULONG)s) ) { DPRINT((0,"PICE_strchr(): ********************\n")); DPRINT((0,"PICE_strchr(): EXCEPTION @ %.8X\n",(ULONG)s)); DPRINT((0,"PICE_strchr(): ********************\n")); } #endif return NULL; } //************************************************************************* // PICE_strncpy() // //************************************************************************* char* PICE_strncpy(char* s1,char* s2,int len) { ULONG len2 = PICE_strlen(s2); if(len='a' && c<='z') c = (c-'a')+'A'; return c; } int PICE_isdigit( int c ) { return ((c>=0x30) && (c<=0x39)); } int PICE_isxdigit( int c ) { return (PICE_isdigit(c) || ((c>=0x41) && (c<=0x46)) || ((c>=0x61) && (c<=0x66))); } int PICE_islower( int c ) { return ((c>=0x61) && (c<=0x7a)); } int PICE_isalpha( int c ) { return ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')); } //************************************************************************* // PICE_strncmpi() // // my version of strncmpi() //************************************************************************* ULONG PICE_strncmpi(char* s1,char* s2,ULONG len) { ULONG result=1; while(len && IsAddressValid((ULONG)s1) && *s1 && // not end of string IsAddressValid((ULONG)s2) && *s2 && // not end of string PICE_toupper(*s1)==PICE_toupper(*s2) ) // char are the same except case { s1++; s2++; len--; } // strings same length if(len==0) result=0; return result; } //************************************************************************* // PICE_strcmpi() // // my version of strcmp() //************************************************************************* ULONG PICE_strcmpi(char* s1,char* s2) { ULONG result=1; while(IsAddressValid((ULONG)s1) && *s1 && // not end of string IsAddressValid((ULONG)s2) && *s2 && // not end of string PICE_toupper(*s1)==PICE_toupper(*s2) ) // char are the same except case { s1++; s2++; } // strings same length if(*s1==0 && *s2==0) result=0; return result; } //************************************************************************* // PICE_strcmp() // // my version of strcmp() //************************************************************************* ULONG PICE_strcmp(char* s1,char* s2) { ULONG result=1; while(IsAddressValid((ULONG)s1) && *s1 && // not end of string IsAddressValid((ULONG)s2) && *s2 && // not end of string (*s1)==(*s2) ) { s1++; s2++; } // strings same length if(*s1==0 && *s2==0) result=0; return result; } //************************************************************************* // PICE_fncmp() // // compare function names ignoring decorations: // leading '_' or '@" and trailing "@xx" //************************************************************************* ULONG PICE_fncmp(char* s1,char* s2) { ULONG result=1; if( IsAddressValid((ULONG)s1) && (*s1 == '_' || *s1 == '@')) s1++; if( IsAddressValid((ULONG)s2) && (*s2 == '_' || *s2 == '@')) s2++; while(IsAddressValid((ULONG)s1) && *s1 && // not end of string IsAddressValid((ULONG)s2) && *s2 ) { if( (*s1 != *s2) || *s1=='@' || *s2=='@' ) break; s1++; s2++; } // strings same length if((*s1==0 || *s1=='@') && (*s2==0 || *s2 =='@')){ result=0; } return result; } //************************************************************************* // PICE_fnncmp() // // compare function names ignoring decorations: // leading '_' or '@" and trailing "@xx" . Decorations are included in total length. //************************************************************************* ULONG PICE_fnncmp(char* s1,char* s2, ULONG len) { ULONG result=1; ULONG len1 = len, len2 = len; if( IsAddressValid((ULONG)s1) && (*s1 == '_' || *s1 == '@')){ s1++; len1--; } if( IsAddressValid((ULONG)s2) && (*s2 == '_' || *s2 == '@')){ s2++; len2--; } while(len1 && len2 && IsAddressValid((ULONG)s1) && *s1 && // not end of string IsAddressValid((ULONG)s2) && *s2 ) { if( (*s1 != *s2) || *s1=='@' || *s2=='@' ) break; s1++; s2++; len1--; len2--; } // strings are the same length if((*s1=='\0' || *s1=='@') && (*s2=='\0' || *s2 =='@')){ result=0; } return result; } wchar_t PICE_towlower(wchar_t c) { if ( c>=L'A' && c<=L'Z' ) return (c - (L'A' - L'a')); return(c); } ULONG PICE_wcsicmp(WCHAR* s1, WCHAR* s2) { ULONG result=1; while(IsAddressValid((ULONG)s1) && *s1 && // not end of string IsAddressValid((ULONG)s2) && *s2 && // not end of string PICE_towlower(*s1)==PICE_towlower(*s2) ) // char are the same except case { s1++; s2++; } // strings same length if(*s1==0 && *s2==0) result=0; return result; } //************************************************************************* // PICE_strrev() // // my version of strrev() //************************************************************************* char* PICE_strrev(char* s) { ULONG i,j,len=PICE_strlen(s)-1; char c; for(i=0,j=len;i>8)==0) pAnsi[j]=(char)(pWide[j]); else pAnsi[j]=0x20; } pAnsi[j]=0; } #endif // LINUX //************************************************************************* // IsAddressValid() // //************************************************************************* BOOLEAN IsAddressValid(ULONG address) { PULONG pPGD; PULONG pPTE; BOOLEAN bResult = FALSE; address &= (~(_PAGE_SIZE-1)); pPGD = ADDR_TO_PDE(address); if(pPGD && ((*pPGD)&_PAGE_PRESENT)) { // not large page if(!((*pPGD)&_PAGE_4M)) { pPTE = ADDR_TO_PTE(address); if(pPTE) { bResult = (*pPTE)&(_PAGE_PRESENT | _PAGE_PSE); } } // large page else { bResult = TRUE; } } return bResult; } //************************************************************************* // IsAddressWriteable() // // returns: // TRUE if adress/page is writeable // FALSE if adress/page is not writeable // //************************************************************************* BOOLEAN IsAddressWriteable(ULONG address) { PULONG pPGD; PULONG pPTE; //address &= (~(_PAGE_SIZE-1)); pPGD = ADDR_TO_PDE(address); if(pPGD && ((*pPGD)&_PAGE_PRESENT)) { // not large page if(!((*pPGD)&_PAGE_4M)) { if(!((*pPGD) & _PAGE_RW)) return FALSE; pPTE = ADDR_TO_PTE(address); if(pPTE) { if( ((*pPTE)&(_PAGE_PRESENT | _PAGE_PSE)) && ((*pPTE) & _PAGE_RW)) return TRUE; else return FALSE; } } // large page else return ((*pPGD) & _PAGE_RW); } return FALSE; } //************************************************************************* // SetAddressWriteable() // //************************************************************************* BOOLEAN SetAddressWriteable(ULONG address,BOOLEAN bSet) { PULONG pPGD; PULONG pPTE; //address &= (~(_PAGE_SIZE-1)); pPGD = ADDR_TO_PDE(address); if(pPGD && ((*pPGD)&_PAGE_PRESENT)) { // not large page if(!((*pPGD)&_PAGE_4M)) { pPTE = ADDR_TO_PTE(address); if(pPTE) { if( (*pPTE)&(_PAGE_PRESENT | _PAGE_PSE) ) { if( bSet ){ *pPTE |= _PAGE_RW; } else{ *pPTE &= ~_PAGE_RW; } FLUSH_TLB; return TRUE; } } } // large page else { if( bSet ) *pPGD |= _PAGE_RW; else *pPGD &= ~_PAGE_RW; FLUSH_TLB; return TRUE; } } return FALSE; } //************************************************************************* // IsRangeValid() // // scan range for page present //************************************************************************* BOOLEAN IsRangeValid(ULONG Addr,ULONG Length) { ULONG i,NumPages,PageNum; // need to only touch one byte per page // calculate PICE_number of pages to touch NumPages=(Length+(_PAGE_SIZE-1))>>12; // calculate PICE_number of page PageNum=Addr>>PAGE_SHIFT; // touch all pages containing range for(i=0;i>16))); LEAVE_FUNC(); return pGdt; } //************************************************************************* // GetLinearAddress() // // return flat address for SEGMENT:OFFSET //************************************************************************* ULONG GetLinearAddress(USHORT Segment,ULONG Offset) { PGDT pGdt; ULONG result=0; PDESCRIPTOR pSel; USHORT OriginalSegment=Segment; ENTER_FUNC(); pSel=(struct tagDESCRIPTOR*)&Segment; // get GDT pointer pGdt=GetGDTPtr(); DPRINT((0,"GetLinearAddress(): pGDT = %.8X\n",pGdt)); DPRINT((0,"GetLinearAddress(): original Segment:Offset = %.4X:%.8X\n",Segment,Offset)); // see if segment selector is in LDT if(pSel->Ti) { DPRINT((0,"GetLinearAddress(): Segment is in LDT\n")); // get LDT selector __asm__("\n\t \ sldt %%ax\n\t \ mov %%ax,%0" :"=m" (Segment)); if(Segment) { DPRINT((0,"GetLinearAddress(): no LDT\n")); // get LDT selector pGdt=(PGDT)((pGdt[pSel->Val].Base_31_24<<24)| (pGdt[pSel->Val].Base_23_16<<16)| (pGdt[pSel->Val].Base_15_0)); if(!IsRangeValid((ULONG)pGdt,0x8) ) pGdt=0; } else { pGdt=0; } } if(pGdt && Segment) { DPRINT((0,"GetLinearAddress(): Segment:Offset = %.4X:%.8X\n",Segment,Offset)); result=pGdt[OriginalSegment>>3].Base_15_0| (pGdt[OriginalSegment>>3].Base_23_16<<16)| (pGdt[OriginalSegment>>3].Base_31_24<<24); result+=Offset; } DPRINT((0,"GetLinearAddress(%.4X:%.8X)=%.8X\n",OriginalSegment,Offset,result)); LEAVE_FUNC(); return result; } //************************************************************************* // ShowRunningMsg() // // place RUNNING message //************************************************************************* void ShowRunningMsg(void) { ENTER_FUNC(); SetForegroundColor(COLOR_TEXT); SetBackgroundColor(COLOR_CAPTION); ClrLine(wWindow[OUTPUT_WINDOW].y+wWindow[OUTPUT_WINDOW].cy); PutChar(" Reactos is running... (Press CTRL-D to stop) ",1,wWindow[OUTPUT_WINDOW].y+wWindow[OUTPUT_WINDOW].cy); ResetColor(); LEAVE_FUNC(); } //************************************************************************* // ShowStoppedMsg() // // place STOPPED message //************************************************************************* void ShowStoppedMsg(void) { ENTER_FUNC(); SetForegroundColor(COLOR_TEXT); SetBackgroundColor(COLOR_CAPTION); ClrLine(wWindow[OUTPUT_WINDOW].y+wWindow[OUTPUT_WINDOW].cy); PutChar(" Stopped... (Type 'x' to continue) ",1,wWindow[OUTPUT_WINDOW].y+wWindow[OUTPUT_WINDOW].cy); ResetColor(); LEAVE_FUNC(); } //************************************************************************* // SetHardwareBreakPoint() // //************************************************************************* void SetHardwareBreakPoint(ULONG ulAddress,ULONG ulReg) { ULONG mask = 0x300; ULONG enable_mask = 0x3; DPRINT((0,"SetHardwareBreakPoint(%x,DR%x)\n",ulAddress,ulReg)); enable_mask <<= (ulReg*2); mask |= enable_mask; DPRINT((0,"mask = %x\n",mask)); __asm__ __volatile__ ("\n\t \ xorl %%eax,%%eax\n\t \ mov %%eax,%%dr6\n\t \ mov %%dr7,%%eax\n\t \ orl %0,%%eax\n\t \ mov %%eax,%%dr7\n\t \ " : :"m" (mask) :"eax"); switch(ulReg) { case 0: __asm__ __volatile__ ("\n\t \ mov %0,%%eax\n\t \ mov %%eax,%%dr0\n\t \ " : :"m" (ulAddress) :"eax"); break; case 1: __asm__ __volatile__ ("\n\t \ mov %0,%%eax\n\t \ mov %%eax,%%dr1\n\t \ " : :"m" (ulAddress) :"eax"); break; case 2: __asm__ __volatile__ ("\n\t \ mov %0,%%eax\n\t \ mov %%eax,%%dr2\n\t \ " : :"m" (ulAddress) :"eax"); break; case 3: __asm__ __volatile__ ("\n\t \ mov %0,%%eax\n\t \ mov %%eax,%%dr3\n\t \ " : :"m" (ulAddress) :"eax"); break; } } //************************************************************************* // SetHardwareBreakPoints() // // install HW breakpoints //************************************************************************* void SetHardwareBreakPoints(void) { ULONG i; ULONG mask; ULONG LinAddr0,LinAddr1,LinAddr2,LinAddr3; PULONG LinAddr[4]={&LinAddr0,&LinAddr1,&LinAddr2,&LinAddr3}; ENTER_FUNC(); // cancel all debug activity __asm__("\n\t \ pushl %eax\n\t \ xorl %eax,%eax\n\t \ mov %eax,%dr6\n\t \ mov %eax,%dr7\n\t \ popl %eax"); // build DR7 mask for(mask=0,i=0;i<4;i++) { mask<<=2; if(Bp[i].Active && Bp[i].Used && !Bp[i].Virtual) { mask|=0x03; *LinAddr[3-i]=Bp[i].LinearAddress; DPRINT((0,"breakpoint %u at %.8X\n",i,Bp[i].LinearAddress)); } } if(mask) { __asm__("\n\t \ pushl %%eax\n\t \ movl %0,%%eax\n\t \ andl $0x000000FF,%%eax\n\t \ orl $0x300,%%eax\n\t \ mov %%eax,%%dr7\n\t \ mov %1,%%eax\n\t \ mov %%eax,%%dr0\n\t \ mov %2,%%eax\n\t \ mov %%eax,%%dr1\n\t \ mov %3,%%eax\n\t \ mov %%eax,%%dr2\n\t \ mov %4,%%eax\n\t \ mov %%eax,%%dr3\n\t \ popl %%eax" : :"m" (mask),"m" (LinAddr0),"m" (LinAddr1),"m" (LinAddr2),"m" (LinAddr3)); } LEAVE_FUNC(); } //************************************************************************* // IsCallInstrAtEIP() // // check if instruction at CS:EIP changes program flow //************************************************************************* BOOLEAN IsCallInstrAtEIP(void) { PUCHAR linear; BOOLEAN result=FALSE; ENTER_FUNC(); DPRINT((0,"IsCallInstrAtEIP()\n")); linear=(PUCHAR)GetLinearAddress(CurrentCS,CurrentEIP); if(IsRangeValid((ULONG)linear,2)) { if(*linear== 0xE8 || // call (*linear== 0xFF && ( ((*(linear+1)>>3)&0x7)==0x2 || ((*(linear+1)>>3)&0x7)==0x3) ) || // call *linear== 0x9A || // call *linear== 0xF2 || // REP *linear== 0xF3) // REP result=TRUE; } LEAVE_FUNC(); return result; } //************************************************************************* // IsRetAtEIP() // // check if instruction at CS:EIP is a return instruction //************************************************************************* BOOLEAN IsRetAtEIP(void) { PUCHAR linear; BOOLEAN bResult = FALSE; ENTER_FUNC(); DPRINT((0,"IsRetAtEIP()\n")); linear=(PUCHAR)GetLinearAddress(CurrentCS,CurrentEIP); switch(*linear) { case 0xc2: case 0xc3: case 0xca: case 0xcb: case 0xcf: // IRET/IRETD bResult = TRUE; break; } LEAVE_FUNC(); return bResult; } //************************************************************************* // VisualizeFlags() // // display CPU EFLAGS as string //************************************************************************* LPSTR VisualizeFlags(ULONG EFlags) { static UCHAR FlagNames[]={'c',0,'p',0,'a',0,'z','s','t','i','d','o'}; ULONG i,j; static char temp[32]; for(j=0,i=0;i>=1; } temp[j]=0; PICE_strrev(temp); return temp; } //************************************************************************* // DisplayRegs() // // display CPU registers //************************************************************************* void DisplayRegs(void) { char tempDisplayRegs[48]; ENTER_FUNC(); // Clear(REGISTER_WINDOW); Home(REGISTER_WINDOW); // EAX Print(REGISTER_WINDOW,"EAX="); PICE_sprintf(tempDisplayRegs,"%.8X",CurrentEAX); if(OldEAX!=CurrentEAX) { SetForegroundColor(WHITE); } Print(REGISTER_WINDOW,tempDisplayRegs); if(OldEAX!=CurrentEAX) { ResetColor(); } // EBX Print(REGISTER_WINDOW," EBX="); PICE_sprintf(tempDisplayRegs,"%.8X",CurrentEBX); if(OldEBX!=CurrentEBX) { SetForegroundColor(WHITE); } Print(REGISTER_WINDOW,tempDisplayRegs); if(OldEBX!=CurrentEBX) { ResetColor(); } // ECX Print(REGISTER_WINDOW," ECX="); PICE_sprintf(tempDisplayRegs,"%.8X",CurrentECX); if(OldECX!=CurrentECX) { SetForegroundColor(WHITE); } Print(REGISTER_WINDOW,tempDisplayRegs); if(OldECX!=CurrentECX) { ResetColor(); } // EDX Print(REGISTER_WINDOW," EDX="); PICE_sprintf(tempDisplayRegs,"%.8X",CurrentEDX); if(OldEDX!=CurrentEDX) { SetForegroundColor(COLOR_HILITE); } Print(REGISTER_WINDOW,tempDisplayRegs); if(OldEDX!=CurrentEDX) { ResetColor(); } // ESI Print(REGISTER_WINDOW," ESI="); PICE_sprintf(tempDisplayRegs,"%.8X",CurrentESI); if(OldESI!=CurrentESI) { SetForegroundColor(COLOR_HILITE); } Print(REGISTER_WINDOW,tempDisplayRegs); if(OldESI!=CurrentESI) { ResetColor(); } // EDI Print(REGISTER_WINDOW," EDI="); PICE_sprintf(tempDisplayRegs,"%.8X\n",CurrentEDI); if(OldEDI!=CurrentEDI) { SetForegroundColor(COLOR_HILITE); } Print(REGISTER_WINDOW,tempDisplayRegs); if(OldEDI!=CurrentEDI) { ResetColor(); } // EBP Print(REGISTER_WINDOW,"EBP="); PICE_sprintf(tempDisplayRegs,"%.8X",CurrentEBP); if(OldEBP!=CurrentEBP) { SetForegroundColor(COLOR_HILITE); } Print(REGISTER_WINDOW,tempDisplayRegs); if(OldEBP!=CurrentEBP) { ResetColor(); } // ESP Print(REGISTER_WINDOW," ESP="); PICE_sprintf(tempDisplayRegs,"%.8X",CurrentESP); if(OldESP!=CurrentESP) { SetForegroundColor(COLOR_HILITE); } Print(REGISTER_WINDOW,tempDisplayRegs); if(OldESP!=CurrentESP) { ResetColor(); } // EIP Print(REGISTER_WINDOW," EIP="); PICE_sprintf(tempDisplayRegs,"%.8X",CurrentEIP); if(OldEIP!=CurrentEIP) { SetForegroundColor(COLOR_HILITE); } Print(REGISTER_WINDOW,tempDisplayRegs); if(OldEIP!=CurrentEIP) { ResetColor(); } // EFL Print(REGISTER_WINDOW," EFLAGS="); PICE_sprintf(tempDisplayRegs,"%.8X",CurrentEFL); if(OldEFL!=CurrentEFL) { SetForegroundColor(COLOR_HILITE); } Print(REGISTER_WINDOW,tempDisplayRegs); if(OldEFL!=CurrentEFL) { ResetColor(); } // visual flags PICE_sprintf(tempDisplayRegs," %s\n",VisualizeFlags(CurrentEFL)); Print(REGISTER_WINDOW,tempDisplayRegs); // CS Print(REGISTER_WINDOW,"CS="); PICE_sprintf(tempDisplayRegs,"%.4X",CurrentCS); if(OldCS!=CurrentCS) { SetForegroundColor(COLOR_HILITE); } Print(REGISTER_WINDOW,tempDisplayRegs); if(OldCS!=CurrentCS) { ResetColor(); } // DS Print(REGISTER_WINDOW," DS="); PICE_sprintf(tempDisplayRegs,"%.4X",CurrentDS); if(OldDS!=CurrentDS) { SetForegroundColor(COLOR_HILITE); } Print(REGISTER_WINDOW,tempDisplayRegs); if(OldDS!=CurrentDS) { ResetColor(); } // ES Print(REGISTER_WINDOW," ES="); PICE_sprintf(tempDisplayRegs,"%.4X",CurrentES); if(OldES!=CurrentES) { SetForegroundColor(COLOR_HILITE); } Print(REGISTER_WINDOW,tempDisplayRegs); if(OldES!=CurrentES) { ResetColor(); } // FS Print(REGISTER_WINDOW," FS="); PICE_sprintf(tempDisplayRegs,"%.4X",CurrentFS); if(OldFS!=CurrentFS) { SetForegroundColor(COLOR_HILITE); } Print(REGISTER_WINDOW,tempDisplayRegs); if(OldFS!=CurrentFS) { ResetColor(); } // GS Print(REGISTER_WINDOW," GS="); PICE_sprintf(tempDisplayRegs,"%.4X",CurrentGS); if(OldGS!=CurrentGS) { ResetColor(); } Print(REGISTER_WINDOW,tempDisplayRegs); if(OldGS!=CurrentGS) { ResetColor(); } // SS Print(REGISTER_WINDOW," SS="); PICE_sprintf(tempDisplayRegs,"%.4X",CurrentSS); if(OldSS!=CurrentSS) { SetForegroundColor(COLOR_HILITE); } Print(REGISTER_WINDOW,tempDisplayRegs); if(OldSS!=CurrentSS) { ResetColor(); } LEAVE_FUNC(); } //************************************************************************* // SaveOldRegs() // //************************************************************************* void SaveOldRegs(void) { ENTER_FUNC(); OldEAX=CurrentEAX; OldEBX=CurrentEBX; OldECX=CurrentECX; OldEDX=CurrentEDX; OldESI=CurrentESI; OldEDI=CurrentEDI; OldEBP=CurrentEBP; OldESP=CurrentESP; OldEIP=CurrentEIP; OldEFL=CurrentEFL; OldCS=CurrentCS; OldDS=CurrentDS; OldES=CurrentES; OldFS=CurrentFS; OldGS=CurrentGS; OldSS=CurrentSS; LEAVE_FUNC(); } //************************************************************************* // GetKeyStatus() // //************************************************************************* UCHAR GetKeyStatus(void) { UCHAR ucRet; ucRet = inb_p((PUCHAR)(I8042_PHYSICAL_BASE + I8042_STATUS_REGISTER_OFFSET)); return ucRet; } //************************************************************************* // GetKeyData() // //************************************************************************* UCHAR GetKeyData(void) { UCHAR ucRet; ucRet = inb_p((PUCHAR)(I8042_PHYSICAL_BASE + I8042_DATA_REGISTER_OFFSET)); return ucRet; } //************************************************************************* // GetKeyPolled // //************************************************************************* UCHAR KeyboardGetKeyPolled(void) { UCHAR ucKey; UCHAR ucStatus; static BOOLEAN bExtended = FALSE; while(ucKey=0,(ucStatus=GetKeyStatus())&OUTPUT_BUFFER_FULL) { ucKey = 0; ucKey = GetKeyData(); if(ucStatus&MOUSE_OUTPUT_BUFFER_FULL) continue; DPRINT((1,"GetKeyPolled(): key = %x bExtended=%s\n",ucKey,bExtended?"TRUE":"FALSE")); if(SCANCODE_EXTENDED == ucKey) { DPRINT((1,"extended switched ON\n")); bExtended = TRUE; continue; } else { if(!(ucKey&0x80)) // keypress { switch(ucKey&0x7f) { case SCANCODE_L_CTRL: case SCANCODE_R_CTRL: if(!bExtended) bControl=TRUE; break; case SCANCODE_L_SHIFT: case SCANCODE_R_SHIFT: if(!bExtended) bShift=TRUE; break; case SCANCODE_L_ALT: case SCANCODE_R_ALT: if(!bExtended) bAlt=TRUE; break; default: DPRINT((0,"GetKeyPolled(): control = %u shift = %u alt = %u\n",bControl,bShift,bAlt)); return ucKey; } } else { switch(ucKey&0x7f) { case SCANCODE_L_CTRL: case SCANCODE_R_CTRL: if(!bExtended) bControl=FALSE; break; case SCANCODE_L_SHIFT: case SCANCODE_R_SHIFT: if(!bExtended) bShift=FALSE; break; case SCANCODE_L_ALT: case SCANCODE_R_ALT: if(!bExtended) bAlt=FALSE; break; } } } bExtended=FALSE; } return ucKey; } //************************************************************************* // KeyboardFlushKeyboardQueue() // //************************************************************************* void KeyboardFlushKeyboardQueue(void) { //__udelay(10); KeStallExecutionProcessor(10); while(GetKeyStatus()&OUTPUT_BUFFER_FULL) { GetKeyData(); //__udelay(10); KeStallExecutionProcessor(10); } } //************************************************************************* // CheckLoadAbort() // //************************************************************************* BOOLEAN CheckLoadAbort(void) { ULONG i; UCHAR ucKey; MaskIrqs(); SaveGraphicsState(); FlushKeyboardQueue(); PrintLogo(TRUE); for(i=0;i<5000;i++) { if(!(i%1000) ) { PICE_sprintf(tempUtil,"\n LOAD WILL CONTINUE IN %u SEC (HIT 'C' TO CONTINUE OR ANY OTHER KEY TO ABORT)\n",5-i/1000); Clear(REGISTER_WINDOW); Print(REGISTER_WINDOW,tempUtil); PrintLogo(TRUE); } ucKey = GetKeyPolled(); if(ucKey) { if((ucKey&0x7f)!=46) { RestoreGraphicsState(); UnmaskIrqs(); return FALSE; } else goto load; } KeStallExecutionProcessor(1000); } load: Clear(REGISTER_WINDOW); PrintLogo(TRUE); tempUtil[0] = 0; FlushKeyboardQueue(); RestoreGraphicsState(); UnmaskIrqs(); return TRUE; } //************************************************************************* // IntelStackWalk() // //************************************************************************* void IntelStackWalk(ULONG pc,ULONG ebp,ULONG esp) { PULONG pFrame, pPrevFrame; LPSTR pSymbolName; DPRINT((0,"IntelStackWalk(): pc = %X ebp = %X esp = %X\n",pc,ebp,esp)); pFrame = pPrevFrame = (PULONG)ebp; PutStatusText("EIP FRAME NAME\n"); while(1) { DPRINT((0,"IntelStackWalk(): pFrame = %X pPrevFrame = %X pc =%X\n",(ULONG)pFrame,(ULONG)pPrevFrame,pc)); if ( ( (ULONG)pFrame & 3 ) || ( (pFrame <= pPrevFrame) ) ) { DPRINT((0,"IntelStackWalk(): pFrame is either unaligned or not less than previous\n")); if( !IsRangeValid((ULONG)pFrame, sizeof(PVOID)*2) ) { DPRINT((0,"IntelStackWalk(): pFrame not valid pointer!\n")); break; } } if((pSymbolName = FindFunctionByAddress(pc,NULL,NULL)) ) PICE_sprintf(tempUtil,"%08X %08X %s\n",pc, (ULONG)pFrame,pSymbolName); else PICE_sprintf(tempUtil,"%08X %08X\n",pc, (ULONG)pFrame); Print(OUTPUT_WINDOW,tempUtil); if(WaitForKey()==FALSE)break; pc = pFrame[1]; pPrevFrame = pFrame; pFrame = (PULONG)pFrame[0]; // proceed to next higher frame on stack } } //************************************************************************* // FindPteForLinearAddress() // //************************************************************************* PULONG FindPteForLinearAddress(ULONG address) { PULONG pPGD; PULONG pPTE; BOOLEAN bResult = FALSE; PEPROCESS my_current = IoGetCurrentProcess(); ENTER_FUNC(); address &= (~(_PAGE_SIZE-1)); if(my_current) { pPGD = ADDR_TO_PDE(address); if(pPGD && ((*pPGD)&_PAGE_PRESENT)) { // not large page if(!((*pPGD)&_PAGE_4M)) { pPTE = ADDR_TO_PTE(address); if(pPTE) { LEAVE_FUNC(); return pPTE; } } // large page else { LEAVE_FUNC(); return NULL; } } } LEAVE_FUNC(); return NULL; } //************************************************************************* // InvalidateLB() // //************************************************************************* void InvalidateLB(void) { ENTER_FUNC(); __asm__ __volatile__ ( "wbinvd\n\t \ mov %%cr3,%%ecx\n\t \ mov %%ecx,%%cr3" :::"ecx" ); LEAVE_FUNC(); } //************************************************************************* // ReadPhysMem() // //************************************************************************* ULONG ReadPhysMem(ULONG Address,ULONG ulSize) { ULONG Page = ((ULONG)TwoPagesForPhysMem+_PAGE_SIZE)&~(_PAGE_SIZE-1); PULONG pPTE; ULONG temp = 0; ULONG oldPTE; ENTER_FUNC(); DPRINT((0,"ReadPhysMem(%.8X,%u)\n",Address,ulSize)); DPRINT((0,"ReadPhysMem(): Page = %.8X\n",Page)); pPTE = (PULONG)FindPteForLinearAddress(Page); DPRINT((0,"ReadPhysMem(): pPTE = %.8X\n",pPTE)); if(pPTE) { oldPTE = *pPTE; DPRINT((0,"ReadPhysMem(): oldPTE = %.8X\n",oldPTE)); temp = (Address & ~(_PAGE_SIZE-1)); DPRINT((0,"ReadPhysMem(): page-aligned Address = %.8X\n",temp)); *pPTE = temp|0x1; DPRINT((0,"ReadPhysMem(): new PTE = %.8X\n",*pPTE)); InvalidateLB(); switch(ulSize) { case sizeof(UCHAR): // BYTE temp = *(PUCHAR)(Page + (Address & (_PAGE_SIZE-1))); temp = (UCHAR)temp; break; case sizeof(USHORT): // WORD temp = *(PUSHORT)(Page + (Address & (_PAGE_SIZE-1))); temp = (USHORT)temp; break; case sizeof(ULONG): // DWORD temp = *(PULONG)(Page + (Address & (_PAGE_SIZE-1))); break; } *pPTE = oldPTE; InvalidateLB(); } LEAVE_FUNC(); return temp; } //************************************************************************* // WritePhysMem() // //************************************************************************* void WritePhysMem(ULONG Address,ULONG Datum,ULONG ulSize) { ULONG Page = ((ULONG)TwoPagesForPhysMem+_PAGE_SIZE)&~(_PAGE_SIZE-1); PULONG pPTE; ULONG temp; ULONG oldPTE; pPTE = (PULONG)FindPteForLinearAddress(Page); if(pPTE) { oldPTE = *pPTE; temp = (Address & ~(_PAGE_SIZE-1)); *pPTE = temp | 0x3; // present and writable InvalidateLB(); switch(ulSize) { case sizeof(UCHAR): // BYTE *(PUCHAR)(Page + (Address & (_PAGE_SIZE-1))) = (UCHAR)Datum; break; case sizeof(USHORT): // WORD *(PUSHORT)(Page + (Address & (_PAGE_SIZE-1))) = (USHORT)Datum; break; case sizeof(ULONG): // DWORD *(PULONG)(Page + (Address & (_PAGE_SIZE-1))) = Datum; break; } *pPTE = oldPTE; InvalidateLB(); } } ///////////////////////////////////////////////////////////////////////////// unsigned long simple_strtoul(const char *cp,char **endp,unsigned int base) { unsigned long result = 0,value; if (!base) { base = 10; if (*cp == '0') { base = 8; cp++; if ((*cp == 'x') && PICE_isxdigit(cp[1])) { cp++; base = 16; } } } while (PICE_isxdigit(*cp) && (value = PICE_isdigit(*cp) ? *cp-'0' : (PICE_islower(*cp) ? PICE_toupper(*cp) : *cp)-'A'+10) < base) { result = result*base + value; cp++; } if (endp) *endp = (char *)cp; return result; } long simple_strtol(const char *cp,char **endp,unsigned int base) { if(*cp=='-') return -simple_strtoul(cp+1,endp,base); return simple_strtoul(cp,endp,base); } /* we use this so that we can do without the ctype library */ #define is_digit(c) ((c) >= '0' && (c) <= '9') static int skip_atoi(const char **s) { int i=0; while (is_digit(**s)) i = i*10 + *((*s)++) - '0'; return i; } size_t PICE_strnlen(const char * s, size_t count) { const char *sc; for (sc = s; count-- && IsAddressValid((ULONG)sc) && *sc != '\0'; ++sc) /* nothing */; return sc - s; } #define NUM_ZEROPAD 1 /* pad with zero */ #define NUM_SIGN 2 /* unsigned/signed long */ #define NUM_PLUS 4 /* show plus */ #define NUM_SPACE 8 /* space if plus */ #define NUM_LEFT 16 /* left justified */ #define NUM_SPECIAL 32 /* 0x */ #define NUM_LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */ #define do_div(n,base) ({ \ int __res; \ __res = ((unsigned long) n) % (unsigned) base; \ n = ((unsigned long) n) / (unsigned) base; \ __res; }) static char * PICE_number(char * str, long num, int base, int size, int precision ,int type) { char c,sign,tmp[66]; const char *digits="0123456789abcdefghijklmnopqrstuvwxyz"; int i; if (type & NUM_LARGE) digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; if (type & NUM_LEFT) type &= ~NUM_ZEROPAD; if (base < 2 || base > 36) return 0; c = (type & NUM_ZEROPAD) ? '0' : ' '; sign = 0; if (type & NUM_SIGN) { if (num < 0) { sign = '-'; num = -num; size--; } else if (type & NUM_PLUS) { sign = '+'; size--; } else if (type & NUM_SPACE) { sign = ' '; size--; } } if (type & NUM_SPECIAL) { if (base == 16) size -= 2; else if (base == 8) size--; } i = 0; if (num == 0) tmp[i++]='0'; else while (num != 0) tmp[i++] = digits[do_div(num,base)]; if (i > precision) precision = i; size -= precision; if (!(type&(NUM_ZEROPAD+NUM_LEFT))) while(size-->0) *str++ = ' '; if (sign) *str++ = sign; if (type & NUM_SPECIAL) { if (base==8) *str++ = '0'; else if (base==16) { *str++ = '0'; *str++ = digits[33]; } } if (!(type & NUM_LEFT)) while (size-- > 0) *str++ = c; while (i < precision--) *str++ = '0'; while (i-- > 0) *str++ = tmp[i]; while (size-- > 0) *str++ = ' '; return str; } /* Forward decl. needed for IP address printing stuff... */ int PICE_sprintf(char * buf, const char *fmt, ...); int PICE_vsprintf(char *buf, const char *fmt, va_list args) { int len; unsigned long num; int i, base; char * str; const char *s; const wchar_t *sw; int flags; /* flags to PICE_number() */ int field_width; /* width of output field */ int precision; /* min. # of digits for integers; max PICE_number of chars for from string */ int qualifier; /* 'h', 'l', or 'L' for integer fields */ for (str=buf ; *fmt ; ++fmt) { if (*fmt != '%') { *str++ = *fmt; continue; } /* process flags */ flags = 0; repeat: ++fmt; /* this also skips first '%' */ switch (*fmt) { case '-': flags |= NUM_LEFT; goto repeat; case '+': flags |= NUM_PLUS; goto repeat; case ' ': flags |= NUM_SPACE; goto repeat; case '#': flags |= NUM_SPECIAL; goto repeat; case '0': flags |= NUM_ZEROPAD; goto repeat; } /* get field width */ field_width = -1; if (is_digit(*fmt)) field_width = skip_atoi(&fmt); else if (*fmt == '*') { ++fmt; /* it's the next argument */ field_width = va_arg(args, int); if (field_width < 0) { field_width = -field_width; flags |= NUM_LEFT; } } /* get the precision */ precision = -1; if (*fmt == '.') { ++fmt; if (is_digit(*fmt)) precision = skip_atoi(&fmt); else if (*fmt == '*') { ++fmt; /* it's the next argument */ precision = va_arg(args, int); } if (precision < 0) precision = 0; } /* get the conversion qualifier */ qualifier = -1; if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L') { qualifier = *fmt; ++fmt; } /* default base */ base = 10; switch (*fmt) { case 'c': if (!(flags & NUM_LEFT)) while (--field_width > 0) *str++ = ' '; *str++ = (unsigned char) va_arg(args, int); while (--field_width > 0) *str++ = ' '; continue; case 's': s = va_arg(args, char *); if (!s) s = ""; len = PICE_strnlen(s, precision); if (!(flags & NUM_LEFT)) while (len < field_width--) *str++ = ' '; for (i = 0; i < len; ++i) *str++ = *s++; while (len < field_width--) *str++ = ' '; continue; case 'S': if (qualifier == 'h') { /* print ascii string */ s = va_arg(args, char *); if (s == NULL) s = ""; len = PICE_strlen (s); if ((unsigned int)len > (unsigned int)precision) len = precision; if (!(flags & NUM_LEFT)) while (len < field_width--) *str++ = ' '; for (i = 0; i < len; ++i) *str++ = *s++; while (len < field_width--) *str++ = ' '; } else { /* print unicode string */ sw = va_arg(args, wchar_t *); if (sw == NULL) sw = L""; len = wcslen (sw); if ((unsigned int)len > (unsigned int)precision) len = precision; if (!(flags & NUM_LEFT)) while (len < field_width--) *str++ = ' '; for (i = 0; i < len; ++i) *str++ = (unsigned char)(*sw++); while (len < field_width--) *str++ = ' '; } continue; case 'p': if (field_width == -1) { field_width = 2*sizeof(void *); flags |= NUM_ZEROPAD; } str = PICE_number(str, (unsigned long) va_arg(args, void *), 16, field_width, precision, flags); continue; case 'n': if (qualifier == 'l') { long * ip = va_arg(args, long *); *ip = (str - buf); } else { int * ip = va_arg(args, int *); *ip = (str - buf); } continue; case '%': *str++ = '%'; continue; /* integer PICE_number formats - set up the flags and "break" */ case 'o': base = 8; break; case 'X': flags |= NUM_LARGE; case 'x': base = 16; break; case 'd': case 'i': flags |= NUM_SIGN; case 'u': break; default: *str++ = '%'; if (*fmt) *str++ = *fmt; else --fmt; continue; } if (qualifier == 'l') num = va_arg(args, unsigned long); else if (qualifier == 'h') { num = (unsigned short) va_arg(args, int); if (flags & NUM_SIGN) num = (short) num; } else if (flags & NUM_SIGN) num = va_arg(args, int); else num = va_arg(args, unsigned int); str = PICE_number(str, num, base, field_width, precision, flags); } *str = '\0'; return str-buf; } int PICE_sprintf(char * buf, const char *fmt, ...) { va_list args; int i; va_start(args, fmt); i = PICE_vsprintf(buf,fmt,args); va_end(args); return i; } //************************************************************************* // AsciiFromScan() // // Convert Scancode to ASCII //************************************************************************* UCHAR AsciiFromScan(UCHAR s) { PSCANTOASCII table; ULONG i; ENTER_FUNC(); if (bShift) { table = GetKeyboardLayout()->shifted; } else if(bAlt) { table = GetKeyboardLayout()->alted; } else { table = GetKeyboardLayout()->normal; } if (table) { for(i=0;table[i].s != 0;i++) { if(table[i].s==s) { LEAVE_FUNC(); return table[i].a; } } } DPRINT((0,"AsciiFromScan(): no translation for key\n")); LEAVE_FUNC(); return 0; } //************************************************************************* // AsciiToScan() // // Convert Scancode to ASCII //************************************************************************* UCHAR AsciiToScan(UCHAR s) { PSCANTOASCII table; ULONG i; ENTER_FUNC(); if (bShift) { table = GetKeyboardLayout()->shifted; } else if(bAlt) { table = GetKeyboardLayout()->alted; } else { table = GetKeyboardLayout()->normal; } if (table) { for(i=0;table[i].s != 0;i++) { if(table[i].a==s) { LEAVE_FUNC(); return table[i].s; } } } DPRINT((0,"AsciiToScan(): no translation for ASCII code\n")); LEAVE_FUNC(); return 0; } //************************************************************************ // outportb() // //************************************************************************ void outportb(PUCHAR port,UCHAR data) { WRITE_PORT_UCHAR((PUCHAR)port, data); } void outb_p(UCHAR data, PUCHAR port) { WRITE_PORT_UCHAR((PUCHAR)port, data); } VOID outl(ULONG data, PULONG port) { WRITE_PORT_ULONG(port, data); } //************************************************************************ // inportb() // //************************************************************************ UCHAR inportb(PUCHAR port) { return READ_PORT_UCHAR((PUCHAR)port); } UCHAR inb_p(PUCHAR port) { return READ_PORT_UCHAR((PUCHAR)port); } ULONG inl(PULONG port) { return READ_PORT_ULONG(port); } //************************************************************************* // EnablePassThrough() // // enable MDA passthrough on AGP chipset //************************************************************************* void EnablePassThrough(void) { ULONG oldCF8,flags; save_flags(flags); cli(); oldCF8 = inl((PULONG)0xcf8); outl(0x80000050,(PULONG)0xcf8); outl(inl((PULONG)0xcfc)|0x00000020,(PULONG)0xcfc); outl(oldCF8,(PULONG)0xcf8); restore_flags(flags); } //*********************************************************************************** // Pice_malloc - allocate memory from paged or non-paged pool //*********************************************************************************** void * PICE_malloc( size_t numBytes, BOOLEAN fromPaged ) { void* res = ExAllocatePool( (fromPaged)?PagedPool:NonPagedPool, numBytes ); ASSERT(res); return res; } //*********************************************************************************** // PICE_free - free memory allocated by PICE_malloc //*********************************************************************************** void PICE_free( void* p ) { ASSERT( p ); ExFreePool( p ); } long PICE_read(HANDLE hFile, LPVOID lpBuffer, long lBytes) { DWORD NumberOfBytesRead; IO_STATUS_BLOCK iosb; ASSERT( lpBuffer ); if (!NT_SUCCESS(NtReadFile( (HANDLE) hFile, NULL, NULL, NULL, &iosb, (LPVOID) lpBuffer, (DWORD) lBytes, NULL, NULL ))) { return -1; } NumberOfBytesRead = iosb.Information; return NumberOfBytesRead; } HANDLE PICE_open (LPCWSTR lpPathName, int iReadWrite) { DWORD dwAccessMask = 0; DWORD dwShareMode = 0; UNICODE_STRING TmpFileName; OBJECT_ATTRIBUTES ObjectAttributes; HANDLE hfile; NTSTATUS status; DPRINT((0,"PICE_open: %S\n", lpPathName)); if ( (iReadWrite & OF_READWRITE ) == OF_READWRITE ) dwAccessMask = GENERIC_READ | GENERIC_WRITE; else if ( (iReadWrite & OF_READ ) == OF_READ ) dwAccessMask = GENERIC_READ; else if ( (iReadWrite & OF_WRITE ) == OF_WRITE ) dwAccessMask = GENERIC_WRITE; if ((iReadWrite & OF_SHARE_COMPAT) == OF_SHARE_COMPAT ) dwShareMode = FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE; else if ((iReadWrite & OF_SHARE_DENY_NONE) == OF_SHARE_DENY_NONE) dwShareMode = FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE; else if ((iReadWrite & OF_SHARE_DENY_READ) == OF_SHARE_DENY_READ) dwShareMode = FILE_SHARE_WRITE | FILE_SHARE_DELETE; else if ((iReadWrite & OF_SHARE_DENY_WRITE) == OF_SHARE_DENY_WRITE ) dwShareMode = FILE_SHARE_READ | FILE_SHARE_DELETE; else if ((iReadWrite & OF_SHARE_EXCLUSIVE) == OF_SHARE_EXCLUSIVE) dwShareMode = 0; RtlInitUnicodeString (&TmpFileName, lpPathName); InitializeObjectAttributes(&ObjectAttributes, &TmpFileName, 0, NULL, NULL); status = NtOpenFile( &hfile, dwAccessMask, &ObjectAttributes, NULL, dwShareMode, FILE_NO_INTERMEDIATE_BUFFERING); //BUG BUG check status!!! if( !NT_SUCCESS( status ) ){ DPRINT((0,"PICE_open: NtOpenFile error: %x\n", status)); return 0; } return hfile; } int PICE_close (HANDLE hFile) { if (NT_SUCCESS( ZwClose((HANDLE)hFile))) { return 0; } DPRINT((0,"ZwClose failed:\n")); return -1; } size_t PICE_len( HANDLE hFile ) { FILE_STANDARD_INFORMATION fs; IO_STATUS_BLOCK iosb; NTSTATUS status; status = ZwQueryInformationFile( hFile, &iosb, &fs, sizeof fs, FileStandardInformation ); if( !NT_SUCCESS( status ) ){ DPRINT((0,"PICE_len: ZwQueryInformationFile error: %x\n", status)); return 0; } //ASSERT(fs.EndOfFile.u.HighPart == 0); return (size_t)fs.EndOfFile.u.LowPart; } /* From kernel32 * NOTE * A raw converter for now. It assumes lpMultiByteStr is * NEVER multi-byte (that is each input character is * 8-bit ASCII) and is ALWAYS NULL terminated. * FIXME-FIXME-FIXME-FIXME */ INT STDCALL PICE_MultiByteToWideChar ( UINT CodePage, DWORD dwFlags, LPCSTR lpMultiByteStr, int cchMultiByte, LPWSTR lpWideCharStr, int cchWideChar ) { int InStringLength = 0; BOOL InIsNullTerminated = TRUE; PCHAR r; PWCHAR w; int cchConverted; /* * Check the parameters. */ if ( /* --- CODE PAGE --- */ ( (CP_ACP != CodePage) && (CP_MACCP != CodePage) && (CP_OEMCP != CodePage)) /* --- FLAGS --- */ /*|| (dwFlags ^ ( MB_PRECOMPOSED | MB_COMPOSITE | MB_ERR_INVALID_CHARS | MB_USEGLYPHCHARS ) )*/ /* --- INPUT BUFFER --- */ || (NULL == lpMultiByteStr) ) { DPRINT((0,"ERROR_INVALID_PARAMETER\n")); return 0; } /* * Compute the input buffer length. */ if (-1 == cchMultiByte) { InStringLength = PICE_strlen(lpMultiByteStr); } else { InIsNullTerminated = FALSE; InStringLength = cchMultiByte; } /* * Does caller query for output * buffer size? */ if (0 == cchWideChar) { DPRINT((0,"ERROR_SUCCESS\n")); return InStringLength; } /* * Is space provided for the translated * string enough? */ if (cchWideChar < InStringLength) { DPRINT((0,"ERROR_INSUFFICIENT_BUFFER: cchWideChar: %d, InStringLength: %d\n", cchWideChar, InStringLength)); return 0; } /* * Raw 8- to 16-bit conversion. */ for ( cchConverted = 0, r = (PCHAR) lpMultiByteStr, w = (PWCHAR) lpWideCharStr; ((*r) && (cchConverted < cchWideChar)); r++, w++, cchConverted++ ) { *w = (WCHAR) *r; } /* * Is the input string NULL terminated? */ if (TRUE == InIsNullTerminated) { *w = L'\0'; ++cchConverted; } /* * Return how many characters we * wrote in the output buffer. */ return cchConverted; }