reactos/rosapps/applications/sysutils/utils/pice/module/utils.c

2431 lines
53 KiB
C
Raw Normal View History

/*++
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 <defines.h>
////////////////////////////////////////////////////
// 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,'<EFBFBD>'}, // 239 = &szlig;
{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,'<EFBFBD>'},
{0x1a,'<EFBFBD>'},{0x33,','},{0x27,'<EFBFBD>'},{0x0d,'<EFBFBD>'},
{0x2b,'\''},{0x28,'<EFBFBD>'},{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,'<EFBFBD>'},{6,'%'},{7,'&'},
{8,'/'},{9,'('},{10,')'},{11,'='},{12,'?'},
{0x39,' '},{0x35,'_'},{0x34,':'},{0x1b,'^'},
{0x1a,'<EFBFBD>'},{0x33,';'},{0x27,'<EFBFBD>'},{0x0d,'`'},
{0x2b,'*'},{0x28,'<EFBFBD>'},{0x29,'<EFBFBD>'},
{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,'<EFBFBD>'},{5,'$'},{6,'<EFBFBD>'},{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<len2)
PICE_memcpy(s1,s2,len2+1);
else
PICE_memcpy(s1,s2,len);
return s1;
}
//*************************************************************************
// PICE_strcpy()
//
//*************************************************************************
char* PICE_strcpy(char* s1,char* s2)
{
ULONG len2 = PICE_strlen(s2);
PICE_memcpy(s1,s2,len2+1);
return s1;
}
//*************************************************************************
// PICE_strcat()
//
//*************************************************************************
char* PICE_strcat(char* s1,char* s2)
{
ULONG len1 = PICE_strlen(s1);
ULONG len2 = PICE_strlen(s2);
PICE_memcpy(&s1[len1],s2,len2+1);
return s1;
}
//*************************************************************************
// PICE_toupper()
//
//*************************************************************************
char PICE_toupper(char c)
{
if(c>='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<j;i++,j--)
{
c=s[i]; s[i]=s[j]; s[j]=c;
}
return s;
}
//*************************************************************************
// PICE_strlen()
//
// my version of strlen()
//
// does a page validity check on every character in th string
//*************************************************************************
USHORT PICE_strlen(const char* s)
{
USHORT i;
for(i=0;IsAddressValid((ULONG)&s[i]) && s[i]!=0 && i<_PAGE_SIZE;i++);
if(IsAddressValid((ULONG)&s[i]) && s[i]==0)
return i;
return 0;
}
WCHAR * PICE_wcscpy(WCHAR * str1,const WCHAR * str2)
{
WCHAR *save = str1;
for (; (*str1 = *str2); ++str2, ++str1);
return save;
}
#ifndef LINUX
//*************************************************************************
// GetShortName()
//
// separates module name from path
//*************************************************************************
LPSTR GetShortName(LPSTR p)
{
ULONG i;
// scan backwards till backslash or start
for(i=PICE_strlen(p);p[i]!='\\' && &p[i]!=p;i--);
// it's not start, inc. counter
if(&p[i]!=p)i++;
// return section of string containing mod name
return &p[i];
}
//*************************************************************************
// CopyWideToAnsi()
//
// copy wide string to ANSI string
//*************************************************************************
void CopyWideToAnsi(LPSTR pAnsi,PWSTR pWide)
{
ULONG j;
for(j=0;pWide[j]!=0;j++)
{
if((char)(pWide[j]>>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<NumPages;i++)
{
// if any one page is invalid range is invalid
if(!IsAddressValid((ULONG)((PageNum+i)*_PAGE_SIZE)) )
return FALSE;
}
return TRUE;
}
//*************************************************************************
// GetGDTPtr()
//
// return flat address of GDT
//*************************************************************************
PGDT GetGDTPtr(void)
{
ULONG gdtr[2];
PGDT pGdt;
ENTER_FUNC();
__asm__("sgdt %0;":"=m" (gdtr));
pGdt=(PGDT)(((ULONG)(gdtr[1]<<16))|((ULONG)(gdtr[0]>>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<sizeof(FlagNames);i++)
{
if(FlagNames[i]!=0)
{
if(EFlags&1)
temp[j++] = PICE_toupper(FlagNames[i]);
else
temp[j++] = FlagNames[i];
temp[j++]=' ';
}
EFlags>>=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 = "<NULL>";
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 = "<NULL>";
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"<NULL>";
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;
IO_STATUS_BLOCK StatusBlock;
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,
&StatusBlock, 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;
}