:pserver:cvsanon@mok.lvcm.com:/CVS/ReactOS reactos
[reactos.git] / apps / utils / pice / module / utils.c
1 /*++
2
3 Copyright (c) 1998-2001 Klaus P. Gerlicher
4
5 Module Name:
6
7     util.c
8
9 Abstract:
10
11 Environment:
12
13     Kernel mode only
14
15 Author:
16
17     Klaus P. Gerlicher
18
19 Revision History:
20
21     19-Aug-1998:        created
22     15-Nov-2000:    general cleanup of source files
23
24 Copyright notice:
25
26   This file may be distributed under the terms of the GNU Public License.
27
28 --*/
29
30 ////////////////////////////////////////////////////
31 // INCLUDES
32 ////
33 #include "remods.h"
34 #include "precomp.h"
35 #include <defines.h>
36
37
38 ////////////////////////////////////////////////////
39 // GLOBALS
40 ////
41 // output string
42 char tempUtil[1024];
43 char tempFlowChanges[256];
44
45 //PMADDRESS_SPACE my_init_mm=NULL;
46
47 ULONG TwoPagesForPhysMem[2*_PAGE_SIZE];
48
49 // scancode to ASCII table
50 SCANTOASCII ucScanToAscii_DE[]=
51 {
52 // German keyboard
53         {16,'q'},{17,'w'},{18,'e'},{19,'r'},{20,'t'},
54         {21,'z'},{22,'u'},{23,'i'},{24,'o'},{25,'p'},
55         {30,'a'},{31,'s'},{32,'d'},{33,'f'},{34,'g'},
56         {35,'h'},{36,'j'},{37,'k'},{38,'l'},
57         {44,'y'},{45,'x'},{46,'c'},{47,'v'},{48,'b'},
58         {49,'n'},{50,'m'},
59         {2,'1'},{3,'2'},{4,'3'},{ 5,'4'},{ 6,'5'},
60         {7,'6'},{8,'7'},{9,'8'},{10,'9'},{11,'0'},
61         {12,'ß'}, // 239 = &szlig;
62         {0x39,' '},{0x35,'-'},{0x34,'.'},{0x1b,'+'},
63   {0,0}
64 };
65
66 SCANTOASCII ucShiftScanToAscii_DE[]=
67 {
68 // German keyboard SHIFTED
69         {16,'Q'},{17,'W'},{18,'E'},{19,'R'},{20,'T'},
70         {21,'Z'},{22,'U'},{23,'I'},{24,'O'},{25,'P'},
71         {30,'A'},{31,'S'},{32,'D'},{33,'F'},{34,'G'},
72         {35,'H'},{36,'J'},{37,'K'},{38,'L'},
73         {44,'Y'},{45,'X'},{46,'C'},{47,'V'},{48,'B'},
74         {49,'N'},{50,'M'},
75         {2,'!'},{3,'\"'}, // " // (fixes mc syntax highlighting)
76                         {4,'@'}, // is pragraph sign on keyboard
77                                                 { 5,'$'},{ 6,'%'},
78         {7,'&'},{8,'/'},{9,'('},{10,')'},{11,'='},
79         {12,'?'},
80         {0x39,' '},{0x35,'_'},{0x34,':'},{0x1b,'*'},
81   {0,0}
82 };
83
84 SCANTOASCII ucScanToAscii_US[]=
85 {
86 // US keyboard
87     {16,'q'},{17,'w'},{18,'e'},{19,'r'},
88     {20,'t'},{21,'y'},{22,'u'},{23,'i'},
89     {24,'o'},{25,'p'},{30,'a'},{31,'s'},
90     {32,'d'},{33,'f'},{34,'g'},{35,'h'},
91     {36,'j'},{37,'k'},{38,'l'},{44,'z'},
92     {45,'x'},{46,'c'},{47,'v'},{48,'b'},
93     {49,'n'},{50,'m'},{2,'1'},{3,'2'},
94     {4,'3'},{5,'4'},{6,'5'},{7,'6'},
95     {8,'7'},{9,'8'},{10,'9'},{11,'0'},{12,'-'},
96     {0x39,' '},{0x35,'/'},{0x34,'.'},{0x1b,']'},
97     {0x1a,'['},{0x33,','},{0x27,';'},{0x0d,'='},
98     {0x2b,'\\'},{0x28,'\''},{0x29,'`'},
99     {0,0}
100 };
101
102 SCANTOASCII ucShiftScanToAscii_US[]=
103 {
104 // US keyboard SHIFTED
105         {16,'Q'},{17,'W'},{18,'E'},{19,'R'},
106         {20,'T'},{21,'Y'},{22,'U'},{23,'I'},
107         {24,'O'},{25,'P'},{30,'A'},{31,'S'},
108         {32,'D'},{33,'F'},{34,'G'},{35,'H'},
109         {36,'J'},{37,'K'},{38,'L'},{44,'Z'},
110         {45,'X'},{46,'C'},{47,'V'},{48,'B'},
111         {49,'N'},{50,'M'},{2,'!'},{3,'@'},
112         {4,'#'},{5,'$'},{6,'%'},{7,'^'},
113         {8,'&'},{9,'*'},{10,'('},{11,')'},{12,'_'},
114         {0x39,' '},{0x35,'?'},{0x34,'>'},{0x1b,'}'},
115         {0x1a,'{'},{0x33,'<'},{0x27,':'},{0x0d,'+'},
116         {0x2b,'|'},{0x28,'\"'},{0x29,'~'},
117   {0,0}
118 };
119
120
121 SCANTOASCII ucScanToAscii_DK[]=
122 {
123 // Danish keyboard
124     {16,'q'},{17,'w'},{18,'e'},{19,'r'},
125     {20,'t'},{21,'y'},{22,'u'},{23,'i'},
126     {24,'o'},{25,'p'},{30,'a'},{31,'s'},
127     {32,'d'},{33,'f'},{34,'g'},{35,'h'},
128     {36,'j'},{37,'k'},{38,'l'},{44,'z'},
129     {45,'x'},{46,'c'},{47,'v'},{48,'b'},
130     {49,'n'},{50,'m'},{2,'1'},{3,'2'},
131     {4,'3'},{5,'4'},{6,'5'},{7,'6'},
132     {8,'7'},{9,'8'},{10,'9'},{11,'0'},{12,'+'},
133     {0x39,' '},{0x35,'-'},{0x34,'.'},{0x1b,'¨'},
134     {0x1a,'å'},{0x33,','},{0x27,'æ'},{0x0d,'´'},
135     {0x2b,'\''},{0x28,'ø'},{0x29,' '},
136     {0,0}
137 };
138
139 SCANTOASCII ucShiftScanToAscii_DK[]=
140 {
141 // Danish keyboard SHIFTED
142         {16,'Q'},{17,'W'},{18,'E'},{19,'R'},
143         {20,'T'},{21,'Y'},{22,'U'},{23,'I'},
144         {24,'O'},{25,'P'},{30,'A'},{31,'S'},
145         {32,'D'},{33,'F'},{34,'G'},{35,'H'},
146         {36,'J'},{37,'K'},{38,'L'},{44,'Z'},
147         {45,'X'},{46,'C'},{47,'V'},{48,'B'},
148         {49,'N'},{50,'M'},{2,'!'},{3,'"'},
149         {4,'#'},{5,'¤'},{6,'%'},{7,'&'},
150         {8,'/'},{9,'('},{10,')'},{11,'='},{12,'?'},
151         {0x39,' '},{0x35,'_'},{0x34,':'},{0x1b,'^'},
152         {0x1a,'Å'},{0x33,';'},{0x27,'Æ'},{0x0d,'`'},
153         {0x2b,'*'},{0x28,'Ø'},{0x29,'§'},
154   {0,0}
155 };
156
157 SCANTOASCII ucAltScanToAscii_DK[]=
158 {
159 // Danish keyboard ALTED
160         {16,' '},{17,' '},{18,' '},{19,' '},
161         {20,' '},{21,' '},{22,' '},{23,' '},
162         {24,' '},{25,' '},{30,' '},{31,' '},
163         {32,' '},{33,' '},{34,' '},{35,' '},
164         {36,' '},{37,' '},{38,' '},{44,' '},
165         {45,' '},{46,' '},{47,' '},{48,' '},
166         {49,' '},{50,' '},{2,' '},{3,'@'},
167         {4,'£'},{5,'$'},{6,'\80'},{7,' '},
168         {8,'{'},{9,'['},{10,']'},{11,'}'},{12,' '},
169         {0x39,' '},{0x35,' '},{0x34,' '},{0x1b,'~'},
170         {0x1a,' '},{0x33,' '},{0x27,' '},{0x0d,'|'},
171         {0x2b,' '},{0x28,' '},{0x29,' '},
172   {0,0}
173 };
174
175 KEYBOARD_LAYOUT ucKeyboard[]=
176 {
177   {"de", ucScanToAscii_DE, ucShiftScanToAscii_DE, NULL},
178   {"us", ucScanToAscii_US, ucShiftScanToAscii_US, NULL},
179   {"dk", ucScanToAscii_DK, ucShiftScanToAscii_DK, ucAltScanToAscii_DK},
180   {NULL, NULL, NULL, NULL}
181 };
182
183 PKEYBOARD_LAYOUT CurrentKeyboard = NULL;
184
185
186 ////////////////////////////////////////////////////
187 // FUNCTIONS
188 ////
189
190 //*************************************************************************
191 // GetKeyboardLayout()
192 //
193 //*************************************************************************
194 PKEYBOARD_LAYOUT GetKeyboardLayout()
195 {
196   if (CurrentKeyboard == NULL)
197     {
198       CurrentKeyboard = &ucKeyboard[kbUS];
199     }
200
201   return CurrentKeyboard;
202 }
203
204 //*************************************************************************
205 // SetKeyboardLayoutByName()
206 //
207 //*************************************************************************
208 PKEYBOARD_LAYOUT SetKeyboardLayoutByName(LPSTR Name)
209 {
210   CHAR tempCmd[256];
211   ULONG i;
212
213         for(i=0;ucKeyboard[i].name != NULL;i++)
214           {
215             if(PICE_strcmpi(ucKeyboard[i].name, Name) == 0)
216               {
217       CurrentKeyboard = &ucKeyboard[i];
218                   return CurrentKeyboard;
219               }
220           }
221   return GetKeyboardLayout();
222 }
223
224 //*************************************************************************
225 // PICE_memset()
226 //
227 //*************************************************************************
228 void PICE_memset(void* p,unsigned char c,int sz)
229 {
230     unsigned char *p2 = (unsigned char *)p;
231     while(sz--)
232         *p2++ = c;
233 }
234
235 //*************************************************************************
236 // PICE_memcpy()
237 //
238 //*************************************************************************
239 void PICE_memcpy(void* t,void* s,int sz)
240 {
241     memcpy(t,s,sz);
242 }
243
244 //*************************************************************************
245 // PICE_isprint()
246 //
247 //*************************************************************************
248 BOOLEAN PICE_isprint(char c)
249 {
250         BOOLEAN bResult = FALSE;
251
252         if((ULONG)c>=0x20 && (ULONG)c<=0x7f)
253                 bResult = TRUE;
254
255         return bResult;
256 }
257
258 //*************************************************************************
259 // PICE_strchr()
260 //
261 //*************************************************************************
262 char* PICE_strchr(char* s,char c)
263 {
264     while(IsAddressValid((ULONG)s) && *s)
265     {
266         if(*s == c)
267             return s;
268         s++;
269     }
270 #ifdef DEBUG
271     if(!IsAddressValid((ULONG)s) )
272     {
273         DPRINT((0,"PICE_strchr(): ********************\n"));
274         DPRINT((0,"PICE_strchr(): EXCEPTION @ %.8X\n",(ULONG)s));
275         DPRINT((0,"PICE_strchr(): ********************\n"));
276     }
277 #endif
278
279     return NULL;
280 }
281
282 //*************************************************************************
283 // PICE_strncpy()
284 //
285 //*************************************************************************
286 char* PICE_strncpy(char* s1,char* s2,int len)
287 {
288         ULONG len2 =  PICE_strlen(s2);
289
290         if(len<len2)
291                 PICE_memcpy(s1,s2,len2+1);
292         else
293                 PICE_memcpy(s1,s2,len);
294
295         return s1;
296 }
297
298 //*************************************************************************
299 // PICE_strcpy()
300 //
301 //*************************************************************************
302 char* PICE_strcpy(char* s1,char* s2)
303 {
304         ULONG len2 =  PICE_strlen(s2);
305
306         PICE_memcpy(s1,s2,len2+1);
307
308         return s1;
309 }
310
311 //*************************************************************************
312 // PICE_strcat()
313 //
314 //*************************************************************************
315 char* PICE_strcat(char* s1,char* s2)
316 {
317         ULONG len1 = PICE_strlen(s1);
318         ULONG len2 = PICE_strlen(s2);
319
320         PICE_memcpy(&s1[len1],s2,len2+1);
321
322         return s1;
323 }
324
325 //*************************************************************************
326 // PICE_toupper()
327 //
328 //*************************************************************************
329 char PICE_toupper(char c)
330 {
331         if(c>='a' && c<='z')
332                 c = (c-'a')+'A';
333
334         return c;
335 }
336
337 int PICE_isdigit( int c )
338 {
339         return ((c>=0x30) && (c<=0x39));
340 }
341
342 int PICE_isxdigit( int c )
343 {
344         return (PICE_isdigit(c) || ((c>=0x41) && (c<=0x46)) || ((c>=0x61) && (c<=0x66)));
345 }
346
347 int PICE_islower( int c )
348 {
349         return ((c>=0x61) && (c<=0x7a));
350 }
351
352 int PICE_isalpha( int c )
353 {
354         return ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'));
355 }
356
357 //*************************************************************************
358 // PICE_strncmpi()
359 //
360 // my version of strncmpi()
361 //*************************************************************************
362 ULONG PICE_strncmpi(char* s1,char* s2,ULONG len)
363 {
364 ULONG result=1;
365
366     while(len &&
367                   IsAddressValid((ULONG)s1) && *s1 && // not end of string
368           IsAddressValid((ULONG)s2) && *s2 && // not end of string
369           PICE_toupper(*s1)==PICE_toupper(*s2) ) // char are the same except case
370     {
371         s1++;
372         s2++;
373                 len--;
374     }
375         // strings same length
376     if(len==0)
377         result=0;
378
379     return result;
380 }
381
382 //*************************************************************************
383 // PICE_strcmpi()
384 //
385 // my version of strcmp()
386 //*************************************************************************
387 ULONG PICE_strcmpi(char* s1,char* s2)
388 {
389 ULONG result=1;
390
391     while(IsAddressValid((ULONG)s1) && *s1 && // not end of string
392           IsAddressValid((ULONG)s2) && *s2 && // not end of string
393           PICE_toupper(*s1)==PICE_toupper(*s2) ) // char are the same except case
394     {
395         s1++;
396         s2++;
397     }
398         // strings same length
399     if(*s1==0 && *s2==0)
400         result=0;
401
402     return result;
403 }
404
405 //*************************************************************************
406 // PICE_strcmp()
407 //
408 // my version of strcmp()
409 //*************************************************************************
410 ULONG PICE_strcmp(char* s1,char* s2)
411 {
412     ULONG result=1;
413
414     while(IsAddressValid((ULONG)s1) && *s1 && // not end of string
415           IsAddressValid((ULONG)s2) && *s2 && // not end of string
416           (*s1)==(*s2) )
417     {
418         s1++;
419         s2++;
420     }
421         // strings same length
422     if(*s1==0 && *s2==0)
423         result=0;
424
425     return result;
426 }
427
428 //*************************************************************************
429 // PICE_fncmp()
430 //
431 // compare function names ignoring decorations:
432 // leading '_' or '@" and trailing "@xx"
433 //*************************************************************************
434 ULONG PICE_fncmp(char* s1,char* s2)
435 {
436         ULONG result=1;
437
438         if( IsAddressValid((ULONG)s1) && (*s1 == '_' || *s1 == '@'))
439                         s1++;
440
441         if( IsAddressValid((ULONG)s2) && (*s2 == '_' || *s2 == '@'))
442                         s2++;
443
444         while(IsAddressValid((ULONG)s1) && *s1 && // not end of string
445           IsAddressValid((ULONG)s2) && *s2 )
446     {
447                 if( (*s1 != *s2) || *s1=='@' || *s2=='@' )
448                                 break;
449         s1++;
450         s2++;
451     }
452         // strings same length
453         if((*s1==0 || *s1=='@') && (*s2==0 || *s2 =='@')){
454         result=0;
455         }
456         return result;
457 }
458
459 //*************************************************************************
460 // PICE_fnncmp()
461 //
462 // compare function names ignoring decorations:
463 // leading '_' or '@" and trailing "@xx" . Decorations are included in total length.
464 //*************************************************************************
465 ULONG PICE_fnncmp(char* s1,char* s2, ULONG len)
466 {
467         ULONG result=1;
468         ULONG len1 = len, len2 = len;
469
470         if( IsAddressValid((ULONG)s1) && (*s1 == '_' || *s1 == '@')){
471                         s1++;
472                         len1--;
473         }
474
475         if( IsAddressValid((ULONG)s2) && (*s2 == '_' || *s2 == '@')){
476                         s2++;
477                         len2--;
478         }
479
480         while(len1 && len2 && IsAddressValid((ULONG)s1) && *s1 && // not end of string
481           IsAddressValid((ULONG)s2) && *s2 )
482     {
483                 if( (*s1 != *s2) || *s1=='@' || *s2=='@' )
484                                 break;
485         s1++;
486         s2++;
487                 len1--;
488                 len2--;
489     }
490         // strings are the same length
491         if((*s1=='\0' || *s1=='@') && (*s2=='\0' || *s2 =='@')){
492         result=0;
493         }
494         return result;
495 }
496
497 wchar_t PICE_towlower(wchar_t c)
498 {
499    if ( c>=L'A' && c<=L'Z' )
500        return (c - (L'A' - L'a'));
501    return(c);
502 }
503
504 ULONG PICE_wcsicmp(WCHAR* s1, WCHAR* s2)
505 {
506     ULONG result=1;
507
508     while(IsAddressValid((ULONG)s1) && *s1 && // not end of string
509           IsAddressValid((ULONG)s2) && *s2 && // not end of string
510           PICE_towlower(*s1)==PICE_towlower(*s2) ) // char are the same except case
511     {
512         s1++;
513         s2++;
514     }
515         // strings same length
516     if(*s1==0 && *s2==0)
517         result=0;
518
519     return result;
520 }
521
522 //*************************************************************************
523 // PICE_strrev()
524 //
525 // my version of strrev()
526 //*************************************************************************
527 char* PICE_strrev(char* s)
528 {
529 ULONG i,j,len=PICE_strlen(s)-1;
530 char c;
531
532         for(i=0,j=len;i<j;i++,j--)
533         {
534                 c=s[i]; s[i]=s[j]; s[j]=c;
535         }
536
537         return s;
538 }
539
540 //*************************************************************************
541 // PICE_strlen()
542 //
543 // my version of strlen()
544 //
545 // does a page validity check on every character in th string
546 //*************************************************************************
547 USHORT PICE_strlen(const char* s)
548 {
549         USHORT i;
550
551         for(i=0;IsAddressValid((ULONG)&s[i]) && s[i]!=0 && i<_PAGE_SIZE;i++);
552
553     if(IsAddressValid((ULONG)&s[i]) && s[i]==0)
554         return i;
555
556     return 0;
557 }
558
559 WCHAR * PICE_wcscpy(WCHAR * str1,const WCHAR * str2)
560 {
561   WCHAR *save = str1;
562
563   for (; (*str1 = *str2); ++str2, ++str1);
564   return save;
565 }
566
567 #ifndef LINUX
568 //*************************************************************************
569 // GetShortName()
570 //
571 // separates module name from path
572 //*************************************************************************
573 LPSTR GetShortName(LPSTR p)
574 {
575 ULONG i;
576
577         // scan backwards till backslash or start
578         for(i=PICE_strlen(p);p[i]!='\\' && &p[i]!=p;i--);
579         // it's not start, inc. counter
580         if(&p[i]!=p)i++;
581
582         // return section of string containing mod name
583         return &p[i];
584 }
585
586 //*************************************************************************
587 // CopyWideToAnsi()
588 //
589 // copy wide string to ANSI string
590 //*************************************************************************
591 void CopyWideToAnsi(LPSTR pAnsi,PWSTR pWide)
592 {
593 ULONG j;
594
595         for(j=0;pWide[j]!=0;j++)
596         {
597         if((char)(pWide[j]>>8)==0)
598                     pAnsi[j]=(char)(pWide[j]);
599         else
600             pAnsi[j]=0x20;
601         }
602         pAnsi[j]=0;
603
604 }
605 #endif // LINUX
606
607 //*************************************************************************
608 // IsAddressValid()
609 //
610 //*************************************************************************
611 BOOLEAN IsAddressValid(ULONG address)
612 {
613         PULONG pPGD;
614         PULONG pPTE;
615         BOOLEAN bResult = FALSE;
616
617         address &= (~(_PAGE_SIZE-1));
618
619         pPGD = ADDR_TO_PDE(address);
620     if(pPGD && ((*pPGD)&_PAGE_PRESENT))
621     {
622         // not large page
623         if(!((*pPGD)&_PAGE_4M))
624                 {
625                         pPTE = ADDR_TO_PTE(address);
626                         if(pPTE)
627                         {
628                                 bResult = (*pPTE)&(_PAGE_PRESENT | _PAGE_PSE);
629                         }
630                 }
631                 // large page
632                 else
633                 {
634                         bResult = TRUE;
635                 }
636         }
637
638         return bResult;
639 }
640
641
642 //*************************************************************************
643 // IsAddressWriteable()
644 //
645 // returns:
646 //  TRUE    if adress/page is writeable
647 //  FALSE   if adress/page is not writeable
648 //
649 //*************************************************************************
650 BOOLEAN IsAddressWriteable(ULONG address)
651 {
652         PULONG pPGD;
653         PULONG pPTE;
654
655         //address &= (~(_PAGE_SIZE-1));
656         pPGD = ADDR_TO_PDE(address);
657     if(pPGD && ((*pPGD)&_PAGE_PRESENT))
658     {
659         // not large page
660         if(!((*pPGD)&_PAGE_4M))
661                 {
662                     if(!((*pPGD) & _PAGE_RW))
663                                         return FALSE;
664
665                         pPTE = ADDR_TO_PTE(address);
666                         if(pPTE)
667                         {
668                                 if( ((*pPTE)&(_PAGE_PRESENT | _PAGE_PSE)) &&
669                                                          ((*pPTE) & _PAGE_RW))
670                                         return TRUE;
671                                 else
672                                         return FALSE;
673                         }
674                 }
675                 // large page
676                 else
677                         return ((*pPGD) & _PAGE_RW);
678         }
679
680         return FALSE;
681 }
682
683
684 //*************************************************************************
685 // SetAddressWriteable()
686 //
687 //*************************************************************************
688 BOOLEAN SetAddressWriteable(ULONG address,BOOLEAN bSet)
689 {
690         PULONG pPGD;
691         PULONG pPTE;
692
693         //address &= (~(_PAGE_SIZE-1));
694
695         pPGD = ADDR_TO_PDE(address);
696     if(pPGD && ((*pPGD)&_PAGE_PRESENT))
697     {
698         // not large page
699         if(!((*pPGD)&_PAGE_4M))
700                 {
701                         pPTE = ADDR_TO_PTE(address);
702                         if(pPTE)
703                         {
704                                 if( (*pPTE)&(_PAGE_PRESENT | _PAGE_PSE) )
705                                 {
706                     if( bSet ){
707                                                 *pPTE |= _PAGE_RW;
708                                         }
709                     else{
710                                                 *pPTE &= ~_PAGE_RW;
711                                         }
712                                         FLUSH_TLB;
713                                         return TRUE;
714                 }
715                         }
716                 }
717                 // large page
718                 else
719                 {
720             if( bSet )
721                 *pPGD |= _PAGE_RW;
722             else
723                 *pPGD &= ~_PAGE_RW;
724                         FLUSH_TLB;
725             return TRUE;
726                 }
727         }
728         return FALSE;
729 }
730 //*************************************************************************
731 // IsRangeValid()
732 //
733 // scan range for page present
734 //*************************************************************************
735 BOOLEAN IsRangeValid(ULONG Addr,ULONG Length)
736 {
737 ULONG i,NumPages,PageNum;
738
739         // need to only touch one byte per page
740         // calculate PICE_number of pages to touch
741         NumPages=(Length+(_PAGE_SIZE-1))>>12;
742
743         // calculate PICE_number of page
744         PageNum=Addr>>PAGE_SHIFT;
745
746         // touch all pages containing range
747         for(i=0;i<NumPages;i++)
748         {
749                 // if any one page is invalid range is invalid
750                 if(!IsAddressValid((ULONG)((PageNum+i)*_PAGE_SIZE)) )
751                         return FALSE;
752         }
753
754         return TRUE;
755 }
756
757 //*************************************************************************
758 // GetGDTPtr()
759 //
760 // return flat address of GDT
761 //*************************************************************************
762 PGDT GetGDTPtr(void)
763 {
764 ULONG gdtr[2];
765 PGDT pGdt;
766
767     ENTER_FUNC();
768
769         __asm__("sgdt %0;":"=m" (gdtr));
770         pGdt=(PGDT)(((ULONG)(gdtr[1]<<16))|((ULONG)(gdtr[0]>>16)));
771
772     LEAVE_FUNC();
773
774         return pGdt;
775 }
776
777 //*************************************************************************
778 // GetLinearAddress()
779 //
780 // return flat address for SEGMENT:OFFSET
781 //*************************************************************************
782 ULONG GetLinearAddress(USHORT Segment,ULONG Offset)
783 {
784     PGDT pGdt;
785     ULONG result=0;
786     PDESCRIPTOR pSel;
787     USHORT OriginalSegment=Segment;
788
789     ENTER_FUNC();
790
791         pSel=(struct tagDESCRIPTOR*)&Segment;
792
793         // get GDT pointer
794         pGdt=GetGDTPtr();
795     DPRINT((0,"GetLinearAddress(): pGDT = %.8X\n",pGdt));
796     DPRINT((0,"GetLinearAddress(): original Segment:Offset = %.4X:%.8X\n",Segment,Offset));
797
798         // see if segment selector is in LDT
799         if(pSel->Ti)
800         {
801                 DPRINT((0,"GetLinearAddress(): Segment is in LDT\n"));
802                 // get LDT selector
803                 __asm__("\n\t \
804                         sldt %%ax\n\t \
805                         mov %%ax,%0"
806                         :"=m" (Segment));
807                 if(Segment)
808                 {
809                         DPRINT((0,"GetLinearAddress(): no LDT\n"));
810                         // get LDT selector
811                         pGdt=(PGDT)((pGdt[pSel->Val].Base_31_24<<24)|
812                                            (pGdt[pSel->Val].Base_23_16<<16)|
813                                        (pGdt[pSel->Val].Base_15_0));
814                         if(!IsRangeValid((ULONG)pGdt,0x8) )
815                                 pGdt=0;
816                 }
817                 else
818                 {
819                         pGdt=0;
820                 }
821         }
822
823         if(pGdt && Segment)
824         {
825         DPRINT((0,"GetLinearAddress(): Segment:Offset = %.4X:%.8X\n",Segment,Offset));
826                 result=pGdt[OriginalSegment>>3].Base_15_0|
827                            (pGdt[OriginalSegment>>3].Base_23_16<<16)|
828                            (pGdt[OriginalSegment>>3].Base_31_24<<24);
829                 result+=Offset;
830         }
831         DPRINT((0,"GetLinearAddress(%.4X:%.8X)=%.8X\n",OriginalSegment,Offset,result));
832
833     LEAVE_FUNC();
834
835         return result;
836 }
837
838 //*************************************************************************
839 // ShowRunningMsg()
840 //
841 // place RUNNING message
842 //*************************************************************************
843 void ShowRunningMsg(void)
844 {
845     ENTER_FUNC();
846
847     SetForegroundColor(COLOR_TEXT);
848         SetBackgroundColor(COLOR_CAPTION);
849         ClrLine(wWindow[OUTPUT_WINDOW].y+wWindow[OUTPUT_WINDOW].cy);
850         PutChar(" Reactos is running... (Press CTRL-D to stop) ",1,wWindow[OUTPUT_WINDOW].y+wWindow[OUTPUT_WINDOW].cy);
851     ResetColor();
852
853     LEAVE_FUNC();
854 }
855
856 //*************************************************************************
857 // ShowStoppedMsg()
858 //
859 // place STOPPED message
860 //*************************************************************************
861 void ShowStoppedMsg(void)
862 {
863     ENTER_FUNC();
864
865     SetForegroundColor(COLOR_TEXT);
866         SetBackgroundColor(COLOR_CAPTION);
867         ClrLine(wWindow[OUTPUT_WINDOW].y+wWindow[OUTPUT_WINDOW].cy);
868         PutChar(" Stopped... (Type 'x' to continue) ",1,wWindow[OUTPUT_WINDOW].y+wWindow[OUTPUT_WINDOW].cy);
869     ResetColor();
870
871     LEAVE_FUNC();
872 }
873
874 //*************************************************************************
875 // SetHardwareBreakPoint()
876 //
877 //*************************************************************************
878 void SetHardwareBreakPoint(ULONG ulAddress,ULONG ulReg)
879 {
880     ULONG mask = 0x300;
881     ULONG enable_mask = 0x3;
882
883     DPRINT((0,"SetHardwareBreakPoint(%x,DR%x)\n",ulAddress,ulReg));
884
885     enable_mask <<= (ulReg*2);
886     mask |= enable_mask;
887
888     DPRINT((0,"mask = %x\n",mask));
889
890         __asm__ __volatile__
891         ("\n\t \
892                 xorl %%eax,%%eax\n\t \
893                 mov %%eax,%%dr6\n\t \
894         mov %%dr7,%%eax\n\t \
895         orl %0,%%eax\n\t \
896                 mov %%eax,%%dr7\n\t \
897         "
898         :
899         :"m" (mask)
900         :"eax");
901
902     switch(ulReg)
903     {
904         case 0:
905             __asm__ __volatile__
906             ("\n\t \
907                         mov %0,%%eax\n\t \
908                         mov %%eax,%%dr0\n\t \
909              "
910              :
911              :"m" (ulAddress)
912              :"eax");
913              break;
914         case 1:
915             __asm__ __volatile__
916             ("\n\t \
917                         mov %0,%%eax\n\t \
918                         mov %%eax,%%dr1\n\t \
919              "
920              :
921              :"m" (ulAddress)
922              :"eax");
923              break;
924         case 2:
925             __asm__ __volatile__
926             ("\n\t \
927                         mov %0,%%eax\n\t \
928                         mov %%eax,%%dr2\n\t \
929              "
930              :
931              :"m" (ulAddress)
932              :"eax");
933              break;
934         case 3:
935             __asm__ __volatile__
936             ("\n\t \
937                         mov %0,%%eax\n\t \
938                         mov %%eax,%%dr3\n\t \
939              "
940              :
941              :"m" (ulAddress)
942              :"eax");
943              break;
944     }
945 }
946
947 //*************************************************************************
948 // SetHardwareBreakPoints()
949 //
950 // install HW breakpoints
951 //*************************************************************************
952 void SetHardwareBreakPoints(void)
953 {
954 ULONG i;
955 ULONG mask;
956 ULONG LinAddr0,LinAddr1,LinAddr2,LinAddr3;
957 PULONG LinAddr[4]={&LinAddr0,&LinAddr1,&LinAddr2,&LinAddr3};
958
959     ENTER_FUNC();
960
961         // cancel all debug activity
962         __asm__("\n\t \
963                 pushl %eax\n\t \
964                 xorl %eax,%eax\n\t \
965                 mov %eax,%dr6\n\t \
966                 mov %eax,%dr7\n\t \
967                 popl %eax");
968         // build DR7 mask
969         for(mask=0,i=0;i<4;i++)
970         {
971                 mask<<=2;
972                 if(Bp[i].Active && Bp[i].Used && !Bp[i].Virtual)
973                 {
974                         mask|=0x03;
975                         *LinAddr[3-i]=Bp[i].LinearAddress;
976                         DPRINT((0,"breakpoint %u at %.8X\n",i,Bp[i].LinearAddress));
977                 }
978         }
979         if(mask)
980         {
981                 __asm__("\n\t \
982                         pushl %%eax\n\t \
983                         movl %0,%%eax\n\t \
984                         andl $0x000000FF,%%eax\n\t \
985                         orl $0x300,%%eax\n\t \
986                         mov %%eax,%%dr7\n\t \
987                         mov %1,%%eax\n\t \
988                         mov %%eax,%%dr0\n\t \
989                         mov %2,%%eax\n\t \
990                         mov %%eax,%%dr1\n\t \
991                         mov %3,%%eax\n\t \
992                         mov %%eax,%%dr2\n\t \
993                         mov %4,%%eax\n\t \
994                         mov %%eax,%%dr3\n\t \
995                         popl %%eax"
996                         :
997                         :"m" (mask),"m" (LinAddr0),"m" (LinAddr1),"m" (LinAddr2),"m" (LinAddr3));
998         }
999
1000     LEAVE_FUNC();
1001 }
1002
1003 //*************************************************************************
1004 // IsCallInstrAtEIP()
1005 //
1006 // check if instruction at CS:EIP changes program flow
1007 //*************************************************************************
1008 BOOLEAN IsCallInstrAtEIP(void)
1009 {
1010 PUCHAR linear;
1011 BOOLEAN result=FALSE;
1012
1013     ENTER_FUNC();
1014         DPRINT((0,"IsCallInstrAtEIP()\n"));
1015
1016         linear=(PUCHAR)GetLinearAddress(CurrentCS,CurrentEIP);
1017         if(IsRangeValid((ULONG)linear,2))
1018         {
1019                 if(*linear== 0xE8 || // call
1020                    (*linear== 0xFF && ( ((*(linear+1)>>3)&0x7)==0x2 || ((*(linear+1)>>3)&0x7)==0x3) ) || // call
1021                    *linear== 0x9A || // call
1022                    *linear== 0xF2 || // REP
1023                    *linear== 0xF3)   // REP
1024                         result=TRUE;
1025         }
1026
1027     LEAVE_FUNC();
1028
1029         return result;
1030 }
1031
1032
1033 //*************************************************************************
1034 // IsRetAtEIP()
1035 //
1036 // check if instruction at CS:EIP is a return instruction
1037 //*************************************************************************
1038 BOOLEAN IsRetAtEIP(void)
1039 {
1040         PUCHAR linear;
1041         BOOLEAN bResult = FALSE;
1042
1043     ENTER_FUNC();
1044         DPRINT((0,"IsRetAtEIP()\n"));
1045
1046         linear=(PUCHAR)GetLinearAddress(CurrentCS,CurrentEIP);
1047
1048     switch(*linear)
1049     {
1050         case 0xc2:
1051         case 0xc3:
1052         case 0xca:
1053         case 0xcb:
1054         case 0xcf: // IRET/IRETD
1055                         bResult = TRUE;
1056             break;
1057     }
1058
1059     LEAVE_FUNC();
1060
1061     return bResult;
1062 }
1063
1064 //*************************************************************************
1065 // VisualizeFlags()
1066 //
1067 // display CPU EFLAGS as string
1068 //*************************************************************************
1069 LPSTR VisualizeFlags(ULONG EFlags)
1070 {
1071     static UCHAR FlagNames[]={'c',0,'p',0,'a',0,'z','s','t','i','d','o'};
1072     ULONG i,j;
1073     static char temp[32];
1074
1075         for(j=0,i=0;i<sizeof(FlagNames);i++)
1076         {
1077                 if(FlagNames[i]!=0)
1078                 {
1079                         if(EFlags&1)
1080                                 temp[j++] = PICE_toupper(FlagNames[i]);
1081                         else
1082                                 temp[j++] = FlagNames[i];
1083                         temp[j++]=' ';
1084                 }
1085                 EFlags>>=1;
1086         }
1087         temp[j]=0;
1088         PICE_strrev(temp);
1089         return temp;
1090 }
1091
1092 //*************************************************************************
1093 // DisplayRegs()
1094 //
1095 // display CPU registers
1096 //*************************************************************************
1097 void DisplayRegs(void)
1098 {
1099     char tempDisplayRegs[48];
1100
1101     ENTER_FUNC();
1102
1103 //      Clear(REGISTER_WINDOW);
1104         Home(REGISTER_WINDOW);
1105         // EAX
1106     Print(REGISTER_WINDOW,"EAX=");
1107         PICE_sprintf(tempDisplayRegs,"%.8X",CurrentEAX);
1108         if(OldEAX!=CurrentEAX)
1109         {
1110                 SetForegroundColor(WHITE);
1111         }
1112         Print(REGISTER_WINDOW,tempDisplayRegs);
1113         if(OldEAX!=CurrentEAX)
1114         {
1115         ResetColor();
1116         }
1117
1118         // EBX
1119     Print(REGISTER_WINDOW," EBX=");
1120         PICE_sprintf(tempDisplayRegs,"%.8X",CurrentEBX);
1121         if(OldEBX!=CurrentEBX)
1122         {
1123                 SetForegroundColor(WHITE);
1124         }
1125         Print(REGISTER_WINDOW,tempDisplayRegs);
1126         if(OldEBX!=CurrentEBX)
1127         {
1128         ResetColor();
1129         }
1130
1131         // ECX
1132     Print(REGISTER_WINDOW," ECX=");
1133         PICE_sprintf(tempDisplayRegs,"%.8X",CurrentECX);
1134         if(OldECX!=CurrentECX)
1135         {
1136                 SetForegroundColor(WHITE);
1137         }
1138         Print(REGISTER_WINDOW,tempDisplayRegs);
1139         if(OldECX!=CurrentECX)
1140         {
1141         ResetColor();
1142         }
1143
1144         // EDX
1145     Print(REGISTER_WINDOW," EDX=");
1146         PICE_sprintf(tempDisplayRegs,"%.8X",CurrentEDX);
1147         if(OldEDX!=CurrentEDX)
1148         {
1149                 SetForegroundColor(COLOR_HILITE);
1150         }
1151         Print(REGISTER_WINDOW,tempDisplayRegs);
1152         if(OldEDX!=CurrentEDX)
1153         {
1154                 ResetColor();
1155         }
1156
1157         // ESI
1158     Print(REGISTER_WINDOW," ESI=");
1159         PICE_sprintf(tempDisplayRegs,"%.8X",CurrentESI);
1160         if(OldESI!=CurrentESI)
1161         {
1162                 SetForegroundColor(COLOR_HILITE);
1163         }
1164         Print(REGISTER_WINDOW,tempDisplayRegs);
1165         if(OldESI!=CurrentESI)
1166         {
1167                 ResetColor();
1168         }
1169
1170         // EDI
1171     Print(REGISTER_WINDOW," EDI=");
1172         PICE_sprintf(tempDisplayRegs,"%.8X\n",CurrentEDI);
1173         if(OldEDI!=CurrentEDI)
1174         {
1175                 SetForegroundColor(COLOR_HILITE);
1176         }
1177         Print(REGISTER_WINDOW,tempDisplayRegs);
1178         if(OldEDI!=CurrentEDI)
1179         {
1180                 ResetColor();
1181         }
1182
1183         // EBP
1184     Print(REGISTER_WINDOW,"EBP=");
1185         PICE_sprintf(tempDisplayRegs,"%.8X",CurrentEBP);
1186         if(OldEBP!=CurrentEBP)
1187         {
1188                 SetForegroundColor(COLOR_HILITE);
1189         }
1190         Print(REGISTER_WINDOW,tempDisplayRegs);
1191         if(OldEBP!=CurrentEBP)
1192         {
1193                 ResetColor();
1194         }
1195
1196         // ESP
1197     Print(REGISTER_WINDOW," ESP=");
1198         PICE_sprintf(tempDisplayRegs,"%.8X",CurrentESP);
1199         if(OldESP!=CurrentESP)
1200         {
1201                 SetForegroundColor(COLOR_HILITE);
1202         }
1203         Print(REGISTER_WINDOW,tempDisplayRegs);
1204         if(OldESP!=CurrentESP)
1205         {
1206                 ResetColor();
1207         }
1208
1209         // EIP
1210     Print(REGISTER_WINDOW," EIP=");
1211         PICE_sprintf(tempDisplayRegs,"%.8X",CurrentEIP);
1212         if(OldEIP!=CurrentEIP)
1213         {
1214                 SetForegroundColor(COLOR_HILITE);
1215         }
1216         Print(REGISTER_WINDOW,tempDisplayRegs);
1217         if(OldEIP!=CurrentEIP)
1218         {
1219                 ResetColor();
1220         }
1221
1222         // EFL
1223     Print(REGISTER_WINDOW," EFLAGS=");
1224         PICE_sprintf(tempDisplayRegs,"%.8X",CurrentEFL);
1225         if(OldEFL!=CurrentEFL)
1226         {
1227                 SetForegroundColor(COLOR_HILITE);
1228         }
1229         Print(REGISTER_WINDOW,tempDisplayRegs);
1230         if(OldEFL!=CurrentEFL)
1231         {
1232                 ResetColor();
1233         }
1234
1235         // visual flags
1236         PICE_sprintf(tempDisplayRegs," %s\n",VisualizeFlags(CurrentEFL));
1237         Print(REGISTER_WINDOW,tempDisplayRegs);
1238
1239         // CS
1240     Print(REGISTER_WINDOW,"CS=");
1241         PICE_sprintf(tempDisplayRegs,"%.4X",CurrentCS);
1242         if(OldCS!=CurrentCS)
1243         {
1244                 SetForegroundColor(COLOR_HILITE);
1245         }
1246         Print(REGISTER_WINDOW,tempDisplayRegs);
1247         if(OldCS!=CurrentCS)
1248         {
1249                 ResetColor();
1250         }
1251
1252         // DS
1253     Print(REGISTER_WINDOW,"  DS=");
1254         PICE_sprintf(tempDisplayRegs,"%.4X",CurrentDS);
1255         if(OldDS!=CurrentDS)
1256         {
1257                 SetForegroundColor(COLOR_HILITE);
1258         }
1259         Print(REGISTER_WINDOW,tempDisplayRegs);
1260         if(OldDS!=CurrentDS)
1261         {
1262                 ResetColor();
1263         }
1264
1265         // ES
1266     Print(REGISTER_WINDOW,"  ES=");
1267         PICE_sprintf(tempDisplayRegs,"%.4X",CurrentES);
1268         if(OldES!=CurrentES)
1269         {
1270                 SetForegroundColor(COLOR_HILITE);
1271         }
1272         Print(REGISTER_WINDOW,tempDisplayRegs);
1273         if(OldES!=CurrentES)
1274         {
1275                 ResetColor();
1276         }
1277
1278         // FS
1279     Print(REGISTER_WINDOW,"  FS=");
1280         PICE_sprintf(tempDisplayRegs,"%.4X",CurrentFS);
1281         if(OldFS!=CurrentFS)
1282         {
1283                 SetForegroundColor(COLOR_HILITE);
1284         }
1285         Print(REGISTER_WINDOW,tempDisplayRegs);
1286         if(OldFS!=CurrentFS)
1287         {
1288                 ResetColor();
1289         }
1290
1291         // GS
1292     Print(REGISTER_WINDOW,"  GS=");
1293         PICE_sprintf(tempDisplayRegs,"%.4X",CurrentGS);
1294         if(OldGS!=CurrentGS)
1295         {
1296                 ResetColor();
1297         }
1298         Print(REGISTER_WINDOW,tempDisplayRegs);
1299         if(OldGS!=CurrentGS)
1300         {
1301                 ResetColor();
1302         }
1303
1304         // SS
1305     Print(REGISTER_WINDOW,"  SS=");
1306         PICE_sprintf(tempDisplayRegs,"%.4X",CurrentSS);
1307         if(OldSS!=CurrentSS)
1308         {
1309                 SetForegroundColor(COLOR_HILITE);
1310         }
1311         Print(REGISTER_WINDOW,tempDisplayRegs);
1312         if(OldSS!=CurrentSS)
1313         {
1314                 ResetColor();
1315         }
1316
1317     LEAVE_FUNC();
1318 }
1319
1320 //*************************************************************************
1321 // SaveOldRegs()
1322 //
1323 //*************************************************************************
1324 void SaveOldRegs(void)
1325 {
1326
1327     ENTER_FUNC();
1328
1329     OldEAX=CurrentEAX;
1330         OldEBX=CurrentEBX;
1331         OldECX=CurrentECX;
1332         OldEDX=CurrentEDX;
1333         OldESI=CurrentESI;
1334         OldEDI=CurrentEDI;
1335         OldEBP=CurrentEBP;
1336         OldESP=CurrentESP;
1337         OldEIP=CurrentEIP;
1338         OldEFL=CurrentEFL;
1339         OldCS=CurrentCS;
1340         OldDS=CurrentDS;
1341         OldES=CurrentES;
1342         OldFS=CurrentFS;
1343         OldGS=CurrentGS;
1344         OldSS=CurrentSS;
1345
1346     LEAVE_FUNC();
1347 }
1348
1349 //*************************************************************************
1350 // GetKeyStatus()
1351 //
1352 //*************************************************************************
1353 UCHAR GetKeyStatus(void)
1354 {
1355     UCHAR ucRet;
1356     ucRet = inb_p((PUCHAR)(I8042_PHYSICAL_BASE + I8042_STATUS_REGISTER_OFFSET));
1357     return ucRet;
1358 }
1359
1360 //*************************************************************************
1361 // GetKeyData()
1362 //
1363 //*************************************************************************
1364 UCHAR GetKeyData(void)
1365 {
1366     UCHAR ucRet;
1367     ucRet = inb_p((PUCHAR)(I8042_PHYSICAL_BASE + I8042_DATA_REGISTER_OFFSET));
1368     return ucRet;
1369 }
1370
1371 //*************************************************************************
1372 // GetKeyPolled
1373 //
1374 //*************************************************************************
1375 UCHAR KeyboardGetKeyPolled(void)
1376 {
1377     UCHAR ucKey;
1378     UCHAR ucStatus;
1379     static BOOLEAN bExtended = FALSE;
1380
1381     while(ucKey=0,(ucStatus=GetKeyStatus())&OUTPUT_BUFFER_FULL)
1382     {
1383         ucKey = 0;
1384         ucKey = GetKeyData();
1385
1386         if(ucStatus&MOUSE_OUTPUT_BUFFER_FULL)
1387             continue;
1388
1389         DPRINT((1,"GetKeyPolled(): key = %x bExtended=%s\n",ucKey,bExtended?"TRUE":"FALSE"));
1390
1391         if(SCANCODE_EXTENDED == ucKey)
1392         {
1393             DPRINT((1,"extended switched ON\n"));
1394             bExtended = TRUE;
1395             continue;
1396         }
1397         else
1398         {
1399             if(!(ucKey&0x80)) // keypress
1400             {
1401                                 switch(ucKey&0x7f)
1402                                 {
1403                                         case SCANCODE_L_CTRL:
1404                                         case SCANCODE_R_CTRL:
1405                                                 if(!bExtended)
1406                                                         bControl=TRUE;
1407                                                 break;
1408                                         case SCANCODE_L_SHIFT:
1409                                         case SCANCODE_R_SHIFT:
1410                                                 if(!bExtended)
1411                                                         bShift=TRUE;
1412                                                 break;
1413                                         case SCANCODE_L_ALT:
1414                                         case SCANCODE_R_ALT:
1415                             if(!bExtended)
1416                                     bAlt=TRUE;
1417                                                 break;
1418                                         default:
1419                                         DPRINT((0,"GetKeyPolled(): control = %u shift = %u alt = %u\n",bControl,bShift,bAlt));
1420                                                 return ucKey;
1421                 }
1422             }
1423                     else
1424                     {
1425                                 switch(ucKey&0x7f)
1426                                 {
1427                                         case SCANCODE_L_CTRL:
1428                                         case SCANCODE_R_CTRL:
1429                                                 if(!bExtended)
1430                                                         bControl=FALSE;
1431                                                 break;
1432                                         case SCANCODE_L_SHIFT:
1433                                         case SCANCODE_R_SHIFT:
1434                                                 if(!bExtended)
1435                                                         bShift=FALSE;
1436                                                 break;
1437                                         case SCANCODE_L_ALT:
1438                                         case SCANCODE_R_ALT:
1439                             if(!bExtended)
1440                                     bAlt=FALSE;
1441                                                 break;
1442                 }
1443                     }
1444         }
1445         bExtended=FALSE;
1446     }
1447
1448     return ucKey;
1449 }
1450
1451 //*************************************************************************
1452 // KeyboardFlushKeyboardQueue()
1453 //
1454 //*************************************************************************
1455 void KeyboardFlushKeyboardQueue(void)
1456 {
1457         //__udelay(10);
1458         KeStallExecutionProcessor(10);
1459     while(GetKeyStatus()&OUTPUT_BUFFER_FULL)
1460     {
1461         GetKeyData();
1462                 //__udelay(10);
1463                 KeStallExecutionProcessor(10);
1464     }
1465 }
1466
1467 //*************************************************************************
1468 // CheckLoadAbort()
1469 //
1470 //*************************************************************************
1471 BOOLEAN CheckLoadAbort(void)
1472 {
1473 ULONG i;
1474 UCHAR ucKey;
1475
1476         MaskIrqs();
1477
1478     SaveGraphicsState();
1479
1480         FlushKeyboardQueue();
1481
1482     PrintLogo(TRUE);
1483
1484     for(i=0;i<5000;i++)
1485     {
1486                 if(!(i%1000) )
1487                 {
1488                         PICE_sprintf(tempUtil,"\n LOAD WILL CONTINUE IN %u SEC (HIT 'C' TO CONTINUE OR ANY OTHER KEY TO ABORT)\n",5-i/1000);
1489                         Clear(REGISTER_WINDOW);
1490                         Print(REGISTER_WINDOW,tempUtil);
1491             PrintLogo(TRUE);
1492                 }
1493
1494         ucKey = GetKeyPolled();
1495
1496         if(ucKey)
1497         {
1498             if((ucKey&0x7f)!=46)
1499             {
1500                 RestoreGraphicsState();
1501                                 UnmaskIrqs();
1502                                 return FALSE;
1503             }
1504             else
1505                 goto load;
1506         }
1507         KeStallExecutionProcessor(1000);
1508     }
1509 load:
1510         Clear(REGISTER_WINDOW);
1511     PrintLogo(TRUE);
1512
1513         tempUtil[0] = 0;
1514         FlushKeyboardQueue();
1515
1516     RestoreGraphicsState();
1517
1518         UnmaskIrqs();
1519
1520     return TRUE;
1521 }
1522
1523
1524
1525
1526 //*************************************************************************
1527 // IntelStackWalk()
1528 //
1529 //*************************************************************************
1530 void IntelStackWalk(ULONG pc,ULONG ebp,ULONG esp)
1531 {
1532     PULONG pFrame, pPrevFrame;
1533     LPSTR pSymbolName;
1534
1535     DPRINT((0,"IntelStackWalk(): pc = %X ebp = %X esp = %X\n",pc,ebp,esp));
1536
1537     pFrame = pPrevFrame = (PULONG)ebp;
1538
1539     PutStatusText("EIP      FRAME    NAME\n");
1540     while(1)
1541     {
1542         DPRINT((0,"IntelStackWalk(): pFrame = %X pPrevFrame = %X pc =%X\n",(ULONG)pFrame,(ULONG)pPrevFrame,pc));
1543         if ( ( (ULONG)pFrame & 3 )    ||
1544              ( (pFrame <= pPrevFrame) ) )
1545         {
1546             DPRINT((0,"IntelStackWalk(): pFrame is either unaligned or not less than previous\n"));
1547             if( !IsRangeValid((ULONG)pFrame, sizeof(PVOID)*2) )
1548             {
1549                 DPRINT((0,"IntelStackWalk(): pFrame not valid pointer!\n"));
1550                 break;
1551             }
1552         }
1553
1554         if((pSymbolName = FindFunctionByAddress(pc,NULL,NULL)) )
1555                     PICE_sprintf(tempUtil,"%08X %08X %s\n",pc, (ULONG)pFrame,pSymbolName);
1556                 else
1557                     PICE_sprintf(tempUtil,"%08X %08X\n",pc, (ULONG)pFrame);
1558         Print(OUTPUT_WINDOW,tempUtil);
1559         if(WaitForKey()==FALSE)break;
1560
1561         pc = pFrame[1];
1562
1563         pPrevFrame = pFrame;
1564
1565         pFrame = (PULONG)pFrame[0]; // proceed to next higher frame on stack
1566     }
1567 }
1568
1569 //*************************************************************************
1570 // FindPteForLinearAddress()
1571 //
1572 //*************************************************************************
1573 PULONG FindPteForLinearAddress(ULONG address)
1574 {
1575         PULONG pPGD;
1576         PULONG pPTE;
1577         BOOLEAN bResult = FALSE;
1578         PEPROCESS my_current = IoGetCurrentProcess();
1579
1580     ENTER_FUNC();
1581
1582         address &= (~(_PAGE_SIZE-1));
1583
1584         if(my_current)
1585         {
1586                 pPGD = ADDR_TO_PDE(address);
1587         if(pPGD && ((*pPGD)&_PAGE_PRESENT))
1588         {
1589             // not large page
1590             if(!((*pPGD)&_PAGE_4M))
1591                         {
1592                                 pPTE = ADDR_TO_PTE(address);
1593                                 if(pPTE)
1594                                 {
1595                     LEAVE_FUNC();
1596                                         return pPTE;
1597                                 }
1598                         }
1599                         // large page
1600                         else
1601                         {
1602                 LEAVE_FUNC();
1603                                 return NULL;
1604                         }
1605                 }
1606         }
1607
1608     LEAVE_FUNC();
1609         return NULL;
1610 }
1611
1612 //*************************************************************************
1613 // InvalidateLB()
1614 //
1615 //*************************************************************************
1616 void InvalidateLB(void)
1617 {
1618         ENTER_FUNC();
1619     __asm__ __volatile__
1620         (
1621                 "wbinvd\n\t \
1622                 mov %%cr3,%%ecx\n\t \
1623         mov %%ecx,%%cr3"
1624         :::"ecx"
1625     );
1626         LEAVE_FUNC();
1627 }
1628
1629 //*************************************************************************
1630 // ReadPhysMem()
1631 //
1632 //*************************************************************************
1633 ULONG ReadPhysMem(ULONG Address,ULONG ulSize)
1634 {
1635     ULONG Page = ((ULONG)TwoPagesForPhysMem+_PAGE_SIZE)&~(_PAGE_SIZE-1);
1636     PULONG pPTE;
1637         ULONG temp = 0;
1638         ULONG oldPTE;
1639
1640     ENTER_FUNC();
1641     DPRINT((0,"ReadPhysMem(%.8X,%u)\n",Address,ulSize));
1642     DPRINT((0,"ReadPhysMem(): Page = %.8X\n",Page));
1643     pPTE = (PULONG)FindPteForLinearAddress(Page);
1644     DPRINT((0,"ReadPhysMem(): pPTE = %.8X\n",pPTE));
1645         if(pPTE)
1646         {
1647                 oldPTE = *pPTE;
1648         DPRINT((0,"ReadPhysMem(): oldPTE = %.8X\n",oldPTE));
1649                 temp = (Address & ~(_PAGE_SIZE-1));
1650         DPRINT((0,"ReadPhysMem(): page-aligned Address = %.8X\n",temp));
1651                 *pPTE = temp|0x1;
1652         DPRINT((0,"ReadPhysMem(): new PTE = %.8X\n",*pPTE));
1653         InvalidateLB();
1654                 switch(ulSize)
1655                 {
1656                         case sizeof(UCHAR): // BYTE
1657                                 temp = *(PUCHAR)(Page + (Address & (_PAGE_SIZE-1)));
1658                                 temp = (UCHAR)temp;
1659                                 break;
1660                         case sizeof(USHORT): // WORD
1661                                 temp = *(PUSHORT)(Page + (Address & (_PAGE_SIZE-1)));
1662                                 temp = (USHORT)temp;
1663                                 break;
1664                         case sizeof(ULONG): // DWORD
1665                                 temp = *(PULONG)(Page + (Address & (_PAGE_SIZE-1)));
1666                                 break;
1667                 }
1668                 *pPTE = oldPTE;
1669         InvalidateLB();
1670         }
1671     LEAVE_FUNC();
1672
1673     return temp;
1674 }
1675
1676 //*************************************************************************
1677 // WritePhysMem()
1678 //
1679 //*************************************************************************
1680 void WritePhysMem(ULONG Address,ULONG Datum,ULONG ulSize)
1681 {
1682     ULONG Page = ((ULONG)TwoPagesForPhysMem+_PAGE_SIZE)&~(_PAGE_SIZE-1);
1683     PULONG pPTE;
1684         ULONG temp;
1685         ULONG oldPTE;
1686
1687     pPTE = (PULONG)FindPteForLinearAddress(Page);
1688         if(pPTE)
1689         {
1690                 oldPTE = *pPTE;
1691                 temp = (Address & ~(_PAGE_SIZE-1));
1692                 *pPTE = temp | 0x3; // present and writable
1693         InvalidateLB();
1694                 switch(ulSize)
1695                 {
1696                         case sizeof(UCHAR): // BYTE
1697                                 *(PUCHAR)(Page + (Address & (_PAGE_SIZE-1))) = (UCHAR)Datum;
1698                                 break;
1699                         case sizeof(USHORT): // WORD
1700                                 *(PUSHORT)(Page + (Address & (_PAGE_SIZE-1))) = (USHORT)Datum;
1701                                 break;
1702                         case sizeof(ULONG): // DWORD
1703                                 *(PULONG)(Page + (Address & (_PAGE_SIZE-1))) = Datum;
1704                                 break;
1705                 }
1706                 *pPTE = oldPTE;
1707         InvalidateLB();
1708         }
1709 }
1710
1711 /////////////////////////////////////////////////////////////////////////////
1712 unsigned long simple_strtoul(const char *cp,char **endp,unsigned int base)
1713 {
1714         unsigned long result = 0,value;
1715
1716         if (!base) {
1717                 base = 10;
1718                 if (*cp == '0') {
1719                         base = 8;
1720                         cp++;
1721                         if ((*cp == 'x') && PICE_isxdigit(cp[1])) {
1722                                 cp++;
1723                                 base = 16;
1724                         }
1725                 }
1726         }
1727         while (PICE_isxdigit(*cp) && (value = PICE_isdigit(*cp) ? *cp-'0' : (PICE_islower(*cp)
1728             ? PICE_toupper(*cp) : *cp)-'A'+10) < base) {
1729                 result = result*base + value;
1730                 cp++;
1731         }
1732         if (endp)
1733                 *endp = (char *)cp;
1734         return result;
1735 }
1736
1737 long simple_strtol(const char *cp,char **endp,unsigned int base)
1738 {
1739         if(*cp=='-')
1740                 return -simple_strtoul(cp+1,endp,base);
1741         return simple_strtoul(cp,endp,base);
1742 }
1743
1744 /* we use this so that we can do without the ctype library */
1745 #define is_digit(c)     ((c) >= '0' && (c) <= '9')
1746
1747 static int skip_atoi(const char **s)
1748 {
1749         int i=0;
1750
1751         while (is_digit(**s))
1752                 i = i*10 + *((*s)++) - '0';
1753         return i;
1754 }
1755
1756 size_t PICE_strnlen(const char * s, size_t count)
1757 {
1758          const char *sc;
1759
1760          for (sc = s; count-- && IsAddressValid((ULONG)sc) && *sc != '\0'; ++sc)
1761                  /* nothing */;
1762          return sc - s;
1763 }
1764
1765
1766 #define NUM_ZEROPAD     1               /* pad with zero */
1767 #define NUM_SIGN        2               /* unsigned/signed long */
1768 #define NUM_PLUS        4               /* show plus */
1769 #define NUM_SPACE       8               /* space if plus */
1770 #define NUM_LEFT        16              /* left justified */
1771 #define NUM_SPECIAL     32              /* 0x */
1772 #define NUM_LARGE       64              /* use 'ABCDEF' instead of 'abcdef' */
1773
1774 #define do_div(n,base) ({ \
1775 int __res; \
1776 __res = ((unsigned long) n) % (unsigned) base; \
1777 n = ((unsigned long) n) / (unsigned) base; \
1778 __res; })
1779
1780 static char * PICE_number(char * str, long num, int base, int size, int precision
1781         ,int type)
1782 {
1783         char c,sign,tmp[66];
1784         const char *digits="0123456789abcdefghijklmnopqrstuvwxyz";
1785         int i;
1786
1787         if (type & NUM_LARGE)
1788                 digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
1789         if (type & NUM_LEFT)
1790                 type &= ~NUM_ZEROPAD;
1791         if (base < 2 || base > 36)
1792                 return 0;
1793         c = (type & NUM_ZEROPAD) ? '0' : ' ';
1794         sign = 0;
1795         if (type & NUM_SIGN) {
1796                 if (num < 0) {
1797                         sign = '-';
1798                         num = -num;
1799                         size--;
1800                 } else if (type & NUM_PLUS) {
1801                         sign = '+';
1802                         size--;
1803                 } else if (type & NUM_SPACE) {
1804                         sign = ' ';
1805                         size--;
1806                 }
1807         }
1808         if (type & NUM_SPECIAL) {
1809                 if (base == 16)
1810                         size -= 2;
1811                 else if (base == 8)
1812                         size--;
1813         }
1814         i = 0;
1815         if (num == 0)
1816                 tmp[i++]='0';
1817         else while (num != 0)
1818                 tmp[i++] = digits[do_div(num,base)];
1819         if (i > precision)
1820                 precision = i;
1821         size -= precision;
1822         if (!(type&(NUM_ZEROPAD+NUM_LEFT)))
1823                 while(size-->0)
1824                         *str++ = ' ';
1825         if (sign)
1826                 *str++ = sign;
1827         if (type & NUM_SPECIAL) {
1828                 if (base==8)
1829                         *str++ = '0';
1830                 else if (base==16) {
1831                         *str++ = '0';
1832                         *str++ = digits[33];
1833                 }
1834         }
1835         if (!(type & NUM_LEFT))
1836                 while (size-- > 0)
1837                         *str++ = c;
1838         while (i < precision--)
1839                 *str++ = '0';
1840         while (i-- > 0)
1841                 *str++ = tmp[i];
1842         while (size-- > 0)
1843                 *str++ = ' ';
1844         return str;
1845 }
1846
1847 /* Forward decl. needed for IP address printing stuff... */
1848 int PICE_sprintf(char * buf, const char *fmt, ...);
1849
1850 int PICE_vsprintf(char *buf, const char *fmt, va_list args)
1851 {
1852         int len;
1853         unsigned long num;
1854         int i, base;
1855         char * str;
1856         const char *s;
1857         const wchar_t *sw;
1858
1859         int flags;              /* flags to PICE_number() */
1860
1861         int field_width;        /* width of output field */
1862         int precision;          /* min. # of digits for integers; max
1863                                    PICE_number of chars for from string */
1864         int qualifier;          /* 'h', 'l', or 'L' for integer fields */
1865
1866         for (str=buf ; *fmt ; ++fmt) {
1867                 if (*fmt != '%') {
1868                         *str++ = *fmt;
1869                         continue;
1870                 }
1871
1872                 /* process flags */
1873                 flags = 0;
1874                 repeat:
1875                         ++fmt;          /* this also skips first '%' */
1876                         switch (*fmt) {
1877                                 case '-': flags |= NUM_LEFT; goto repeat;
1878                                 case '+': flags |= NUM_PLUS; goto repeat;
1879                                 case ' ': flags |= NUM_SPACE; goto repeat;
1880                                 case '#': flags |= NUM_SPECIAL; goto repeat;
1881                                 case '0': flags |= NUM_ZEROPAD; goto repeat;
1882                                 }
1883
1884                 /* get field width */
1885                 field_width = -1;
1886                 if (is_digit(*fmt))
1887                         field_width = skip_atoi(&fmt);
1888                 else if (*fmt == '*') {
1889                         ++fmt;
1890                         /* it's the next argument */
1891                         field_width = va_arg(args, int);
1892                         if (field_width < 0) {
1893                                 field_width = -field_width;
1894                                 flags |= NUM_LEFT;
1895                         }
1896                 }
1897
1898                 /* get the precision */
1899                 precision = -1;
1900                 if (*fmt == '.') {
1901                         ++fmt;
1902                         if (is_digit(*fmt))
1903                                 precision = skip_atoi(&fmt);
1904                         else if (*fmt == '*') {
1905                                 ++fmt;
1906                                 /* it's the next argument */
1907                                 precision = va_arg(args, int);
1908                         }
1909                         if (precision < 0)
1910                                 precision = 0;
1911                 }
1912
1913                 /* get the conversion qualifier */
1914                 qualifier = -1;
1915                 if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L') {
1916                         qualifier = *fmt;
1917                         ++fmt;
1918                 }
1919
1920                 /* default base */
1921                 base = 10;
1922
1923                 switch (*fmt) {
1924                 case 'c':
1925                         if (!(flags & NUM_LEFT))
1926                                 while (--field_width > 0)
1927                                         *str++ = ' ';
1928                         *str++ = (unsigned char) va_arg(args, int);
1929                         while (--field_width > 0)
1930                                 *str++ = ' ';
1931                         continue;
1932
1933                 case 's':
1934                         s = va_arg(args, char *);
1935                         if (!s)
1936                                 s = "<NULL>";
1937
1938                         len = PICE_strnlen(s, precision);
1939
1940                         if (!(flags & NUM_LEFT))
1941                                 while (len < field_width--)
1942                                         *str++ = ' ';
1943                         for (i = 0; i < len; ++i)
1944                                 *str++ = *s++;
1945                         while (len < field_width--)
1946                                 *str++ = ' ';
1947                         continue;
1948
1949                 case 'S':
1950                         if (qualifier == 'h') {
1951                                 /* print ascii string */
1952                                 s = va_arg(args, char *);
1953                                 if (s == NULL)
1954                                         s = "<NULL>";
1955
1956                                 len = PICE_strlen (s);
1957                                 if ((unsigned int)len > (unsigned int)precision)
1958                                         len = precision;
1959
1960                                 if (!(flags & NUM_LEFT))
1961                                         while (len < field_width--)
1962                                                 *str++ = ' ';
1963                                 for (i = 0; i < len; ++i)
1964                                         *str++ = *s++;
1965                                 while (len < field_width--)
1966                                         *str++ = ' ';
1967                         } else {
1968                                 /* print unicode string */
1969                                 sw = va_arg(args, wchar_t *);
1970                                 if (sw == NULL)
1971                                         sw = L"<NULL>";
1972
1973                                 len = wcslen (sw);
1974                                 if ((unsigned int)len > (unsigned int)precision)
1975                                         len = precision;
1976
1977                                 if (!(flags & NUM_LEFT))
1978                                         while (len < field_width--)
1979                                                 *str++ = ' ';
1980                                 for (i = 0; i < len; ++i)
1981                                         *str++ = (unsigned char)(*sw++);
1982                                 while (len < field_width--)
1983                                         *str++ = ' ';
1984                         }
1985                         continue;
1986
1987                 case 'p':
1988                         if (field_width == -1) {
1989                                 field_width = 2*sizeof(void *);
1990                                 flags |= NUM_ZEROPAD;
1991                         }
1992                         str = PICE_number(str,
1993                                 (unsigned long) va_arg(args, void *), 16,
1994                                 field_width, precision, flags);
1995                         continue;
1996
1997
1998                 case 'n':
1999                         if (qualifier == 'l') {
2000                                 long * ip = va_arg(args, long *);
2001                                 *ip = (str - buf);
2002                         } else {
2003                                 int * ip = va_arg(args, int *);
2004                                 *ip = (str - buf);
2005                         }
2006                         continue;
2007
2008                 case '%':
2009                         *str++ = '%';
2010                         continue;
2011
2012                 /* integer PICE_number formats - set up the flags and "break" */
2013                 case 'o':
2014                         base = 8;
2015                         break;
2016
2017                 case 'X':
2018                         flags |= NUM_LARGE;
2019                 case 'x':
2020                         base = 16;
2021                         break;
2022
2023                 case 'd':
2024                 case 'i':
2025                         flags |= NUM_SIGN;
2026                 case 'u':
2027                         break;
2028
2029                 default:
2030                         *str++ = '%';
2031                         if (*fmt)
2032                                 *str++ = *fmt;
2033                         else
2034                                 --fmt;
2035                         continue;
2036                 }
2037                 if (qualifier == 'l')
2038                         num = va_arg(args, unsigned long);
2039                 else if (qualifier == 'h') {
2040                         num = (unsigned short) va_arg(args, int);
2041                         if (flags & NUM_SIGN)
2042                                 num = (short) num;
2043                 } else if (flags & NUM_SIGN)
2044                         num = va_arg(args, int);
2045                 else
2046                         num = va_arg(args, unsigned int);
2047                 str = PICE_number(str, num, base, field_width, precision, flags);
2048         }
2049         *str = '\0';
2050         return str-buf;
2051 }
2052
2053 int PICE_sprintf(char * buf, const char *fmt, ...)
2054 {
2055         va_list args;
2056         int i;
2057
2058         va_start(args, fmt);
2059         i = PICE_vsprintf(buf,fmt,args);
2060         va_end(args);
2061         return i;
2062 }
2063
2064 //*************************************************************************
2065 // AsciiFromScan()
2066 //
2067 // Convert Scancode to ASCII
2068 //*************************************************************************
2069 UCHAR AsciiFromScan(UCHAR s)
2070 {
2071   PSCANTOASCII table;
2072   ULONG i;
2073
2074   ENTER_FUNC();
2075
2076   if (bShift)
2077     {
2078       table = GetKeyboardLayout()->shifted;
2079     }
2080   else if(bAlt)
2081     {
2082       table = GetKeyboardLayout()->alted;
2083     }
2084   else
2085     {
2086       table = GetKeyboardLayout()->normal;
2087     }
2088
2089
2090   if (table)
2091     {
2092           for(i=0;table[i].s != 0;i++)
2093             {
2094               if(table[i].s==s)
2095                 {
2096                           LEAVE_FUNC();
2097                           return table[i].a;
2098                 }
2099             }
2100     }
2101
2102   DPRINT((0,"AsciiFromScan(): no translation for key\n"));
2103   LEAVE_FUNC();
2104   return 0;
2105 }
2106
2107
2108 //*************************************************************************
2109 // AsciiToScan()
2110 //
2111 // Convert Scancode to ASCII
2112 //*************************************************************************
2113 UCHAR AsciiToScan(UCHAR s)
2114 {
2115   PSCANTOASCII table;
2116   ULONG i;
2117
2118   ENTER_FUNC();
2119
2120   if (bShift)
2121     {
2122       table = GetKeyboardLayout()->shifted;
2123     }
2124   else if(bAlt)
2125     {
2126       table = GetKeyboardLayout()->alted;
2127     }
2128   else
2129     {
2130       table = GetKeyboardLayout()->normal;
2131     }
2132
2133   if (table)
2134     {
2135                   for(i=0;table[i].s != 0;i++)
2136                     {
2137                       if(table[i].a==s)
2138                         {
2139                                   LEAVE_FUNC();
2140                                   return table[i].s;
2141                         }
2142                     }
2143     }
2144
2145   DPRINT((0,"AsciiToScan(): no translation for ASCII code\n"));
2146   LEAVE_FUNC();
2147         return 0;
2148 }
2149
2150 //************************************************************************
2151 // outportb()
2152 //
2153 //************************************************************************
2154 void outportb(PUCHAR port,UCHAR data)
2155 {
2156     WRITE_PORT_UCHAR((PUCHAR)port, data);
2157 }
2158
2159 void outb_p(UCHAR data, PUCHAR port)
2160 {
2161         WRITE_PORT_UCHAR((PUCHAR)port, data);
2162 }
2163
2164 VOID  outl(ULONG data, PULONG port)
2165 {
2166         WRITE_PORT_ULONG(port, data);
2167 }
2168
2169
2170 //************************************************************************
2171 // inportb()
2172 //
2173 //************************************************************************
2174 UCHAR inportb(PUCHAR port)
2175 {
2176     return READ_PORT_UCHAR((PUCHAR)port);
2177 }
2178
2179 UCHAR inb_p(PUCHAR port)
2180 {
2181     return READ_PORT_UCHAR((PUCHAR)port);
2182 }
2183
2184 ULONG  inl(PULONG port)
2185 {
2186         return READ_PORT_ULONG(port);
2187 }
2188
2189 //*************************************************************************
2190 // EnablePassThrough()
2191 //
2192 // enable MDA passthrough on AGP chipset
2193 //*************************************************************************
2194 void EnablePassThrough(void)
2195 {
2196         ULONG oldCF8,flags;
2197
2198         save_flags(flags);
2199         cli();
2200
2201         oldCF8 = inl((PULONG)0xcf8);
2202         outl(0x80000050,(PULONG)0xcf8);
2203         outl(inl((PULONG)0xcfc)|0x00000020,(PULONG)0xcfc);
2204         outl(oldCF8,(PULONG)0xcf8);
2205
2206         restore_flags(flags);
2207 }
2208
2209 //***********************************************************************************
2210 //      Pice_malloc - allocate memory from paged or non-paged pool
2211 //***********************************************************************************
2212 void * PICE_malloc( size_t numBytes, BOOLEAN fromPaged )
2213 {
2214         void* res = ExAllocatePool( (fromPaged)?PagedPool:NonPagedPool, numBytes );
2215         ASSERT(res);
2216         return res;
2217 }
2218
2219 //***********************************************************************************
2220 //      PICE_free - free memory allocated by PICE_malloc
2221 //***********************************************************************************
2222 void PICE_free( void* p )
2223 {
2224         ASSERT( p );
2225         ExFreePool( p );
2226 }
2227
2228 long PICE_read(HANDLE hFile, LPVOID lpBuffer, long lBytes)
2229 {
2230         DWORD   NumberOfBytesRead;
2231         IO_STATUS_BLOCK  iosb;
2232
2233         ASSERT( lpBuffer );
2234
2235         if (!NT_SUCCESS(NtReadFile(
2236                 (HANDLE) hFile,
2237                 NULL, NULL, NULL, &iosb,
2238                 (LPVOID) lpBuffer,
2239                 (DWORD) lBytes,
2240                 NULL,
2241                 NULL
2242                 )))
2243         {
2244                 return -1;
2245         }
2246         NumberOfBytesRead = iosb.Information;
2247         return NumberOfBytesRead;
2248 }
2249
2250 HANDLE PICE_open (LPCWSTR       lpPathName,     int     iReadWrite)
2251 {
2252         DWORD dwAccessMask = 0;
2253         DWORD dwShareMode = 0;
2254         UNICODE_STRING TmpFileName;
2255         OBJECT_ATTRIBUTES ObjectAttributes;
2256         HANDLE hfile;
2257         NTSTATUS status;
2258
2259
2260         DPRINT((0,"PICE_open: %S\n", lpPathName));
2261
2262         if ( (iReadWrite & OF_READWRITE ) == OF_READWRITE )
2263                 dwAccessMask = GENERIC_READ | GENERIC_WRITE;
2264         else if ( (iReadWrite & OF_READ ) == OF_READ )
2265                 dwAccessMask = GENERIC_READ;
2266         else if ( (iReadWrite & OF_WRITE ) == OF_WRITE )
2267                 dwAccessMask = GENERIC_WRITE;
2268
2269         if ((iReadWrite & OF_SHARE_COMPAT) == OF_SHARE_COMPAT )
2270                 dwShareMode = FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE;
2271         else if ((iReadWrite & OF_SHARE_DENY_NONE) == OF_SHARE_DENY_NONE)
2272                 dwShareMode = FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE;
2273         else if ((iReadWrite & OF_SHARE_DENY_READ) == OF_SHARE_DENY_READ)
2274                 dwShareMode = FILE_SHARE_WRITE | FILE_SHARE_DELETE;
2275         else if ((iReadWrite & OF_SHARE_DENY_WRITE) == OF_SHARE_DENY_WRITE )
2276                 dwShareMode = FILE_SHARE_READ | FILE_SHARE_DELETE;
2277         else if ((iReadWrite & OF_SHARE_EXCLUSIVE) == OF_SHARE_EXCLUSIVE)
2278                 dwShareMode = 0;
2279
2280         RtlInitUnicodeString (&TmpFileName, lpPathName);
2281         InitializeObjectAttributes(&ObjectAttributes,
2282                              &TmpFileName,
2283                              0,
2284                              NULL,
2285                              NULL);
2286
2287         status = NtOpenFile( &hfile,
2288                       dwAccessMask,
2289                       &ObjectAttributes,
2290                       NULL, dwShareMode, FILE_NO_INTERMEDIATE_BUFFERING);
2291         //BUG BUG check status!!!
2292         if( !NT_SUCCESS( status ) ){
2293                 DPRINT((0,"PICE_open: NtOpenFile error: %x\n", status));
2294                 return 0;
2295         }
2296         return hfile;
2297 }
2298
2299 int PICE_close (HANDLE  hFile)
2300 {
2301         if (NT_SUCCESS( ZwClose((HANDLE)hFile)))
2302         {
2303                 return 0;
2304         }
2305         DPRINT((0,"ZwClose failed:\n"));
2306         return -1;
2307 }
2308
2309 size_t PICE_len( HANDLE hFile )
2310 {
2311         FILE_STANDARD_INFORMATION fs;
2312         IO_STATUS_BLOCK  iosb;
2313         NTSTATUS status;
2314
2315         status = ZwQueryInformationFile( hFile, &iosb, &fs, sizeof fs, FileStandardInformation );
2316         if( !NT_SUCCESS( status ) ){
2317                 DPRINT((0,"PICE_len: ZwQueryInformationFile error: %x\n", status));
2318                 return 0;
2319         }
2320         //ASSERT(fs.EndOfFile.u.HighPart == 0);
2321         return (size_t)fs.EndOfFile.u.LowPart;
2322 }
2323
2324 /* From kernel32
2325  * NOTE
2326  *      A raw converter for now. It assumes lpMultiByteStr is
2327  *      NEVER multi-byte (that is each input character is
2328  *      8-bit ASCII) and is ALWAYS NULL terminated.
2329  *      FIXME-FIXME-FIXME-FIXME
2330  */
2331
2332 INT
2333 STDCALL
2334 PICE_MultiByteToWideChar (
2335         UINT    CodePage,
2336         DWORD   dwFlags,
2337         LPCSTR  lpMultiByteStr,
2338         int     cchMultiByte,
2339         LPWSTR  lpWideCharStr,
2340         int     cchWideChar
2341         )
2342 {
2343         int     InStringLength = 0;
2344         BOOL    InIsNullTerminated = TRUE;
2345         PCHAR   r;
2346         PWCHAR  w;
2347         int     cchConverted;
2348
2349         /*
2350          * Check the parameters.
2351          */
2352         if (    /* --- CODE PAGE --- */
2353                 (       (CP_ACP != CodePage)
2354                         && (CP_MACCP != CodePage)
2355                         && (CP_OEMCP != CodePage))
2356                 /* --- FLAGS --- */
2357                 /*|| (dwFlags ^ (       MB_PRECOMPOSED
2358                                 | MB_COMPOSITE
2359                                 | MB_ERR_INVALID_CHARS
2360                                 | MB_USEGLYPHCHARS
2361                                 )
2362                         )*/
2363                 /* --- INPUT BUFFER --- */
2364                 || (NULL == lpMultiByteStr)
2365                 )
2366         {
2367                 DPRINT((0,"ERROR_INVALID_PARAMETER\n"));
2368                 return 0;
2369         }
2370         /*
2371          * Compute the input buffer length.
2372          */
2373         if (-1 == cchMultiByte)
2374         {
2375                 InStringLength = PICE_strlen(lpMultiByteStr);
2376         }
2377         else
2378         {
2379                 InIsNullTerminated = FALSE;
2380                 InStringLength = cchMultiByte;
2381         }
2382         /*
2383          * Does caller query for output
2384          * buffer size?
2385          */
2386         if (0 == cchWideChar)
2387         {
2388                 DPRINT((0,"ERROR_SUCCESS\n"));
2389                 return InStringLength;
2390         }
2391         /*
2392          * Is space provided for the translated
2393          * string enough?
2394          */
2395         if (cchWideChar < InStringLength)
2396         {
2397                 DPRINT((0,"ERROR_INSUFFICIENT_BUFFER: cchWideChar: %d, InStringLength: %d\n", cchWideChar, InStringLength));
2398                 return 0;
2399         }
2400         /*
2401          * Raw 8- to 16-bit conversion.
2402          */
2403         for (   cchConverted = 0,
2404                 r = (PCHAR) lpMultiByteStr,
2405                 w = (PWCHAR) lpWideCharStr;
2406
2407                 ((*r) && (cchConverted < cchWideChar));
2408
2409                 r++, w++,
2410                 cchConverted++
2411                 )
2412         {
2413                 *w = (WCHAR) *r;
2414         }
2415         /*
2416          * Is the input string NULL terminated?
2417          */
2418         if (TRUE == InIsNullTerminated)
2419         {
2420                 *w = L'\0';
2421                 ++cchConverted;
2422         }
2423         /*
2424          * Return how many characters we
2425          * wrote in the output buffer.
2426          */
2427         return cchConverted;
2428 }
2429