[USETUP][ROSAPPS][EXT2LIB] NtReadFile() calls: Remove unused 'ByteOffset = 0', Use...
[reactos.git] / modules / rosapps / applications / sysutils / 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 hFile,
2237 NULL, NULL, NULL, &iosb,
2238 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 IO_STATUS_BLOCK StatusBlock;
2257 HANDLE hfile;
2258 NTSTATUS status;
2259
2260
2261 DPRINT((0,"PICE_open: %S\n", lpPathName));
2262
2263 if ( (iReadWrite & OF_READWRITE ) == OF_READWRITE )
2264 dwAccessMask = GENERIC_READ | GENERIC_WRITE;
2265 else if ( (iReadWrite & OF_READ ) == OF_READ )
2266 dwAccessMask = GENERIC_READ;
2267 else if ( (iReadWrite & OF_WRITE ) == OF_WRITE )
2268 dwAccessMask = GENERIC_WRITE;
2269
2270 if ((iReadWrite & OF_SHARE_COMPAT) == OF_SHARE_COMPAT )
2271 dwShareMode = FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE;
2272 else if ((iReadWrite & OF_SHARE_DENY_NONE) == OF_SHARE_DENY_NONE)
2273 dwShareMode = FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE;
2274 else if ((iReadWrite & OF_SHARE_DENY_READ) == OF_SHARE_DENY_READ)
2275 dwShareMode = FILE_SHARE_WRITE | FILE_SHARE_DELETE;
2276 else if ((iReadWrite & OF_SHARE_DENY_WRITE) == OF_SHARE_DENY_WRITE )
2277 dwShareMode = FILE_SHARE_READ | FILE_SHARE_DELETE;
2278 else if ((iReadWrite & OF_SHARE_EXCLUSIVE) == OF_SHARE_EXCLUSIVE)
2279 dwShareMode = 0;
2280
2281 RtlInitUnicodeString (&TmpFileName, lpPathName);
2282 InitializeObjectAttributes(&ObjectAttributes,
2283 &TmpFileName,
2284 0,
2285 NULL,
2286 NULL);
2287
2288 status = NtOpenFile( &hfile,
2289 dwAccessMask,
2290 &ObjectAttributes,
2291 &StatusBlock, dwShareMode, FILE_NO_INTERMEDIATE_BUFFERING);
2292 //BUG BUG check status!!!
2293 if( !NT_SUCCESS( status ) ){
2294 DPRINT((0,"PICE_open: NtOpenFile error: %x\n", status));
2295 return 0;
2296 }
2297 return hfile;
2298 }
2299
2300 int PICE_close (HANDLE hFile)
2301 {
2302 if (NT_SUCCESS( ZwClose((HANDLE)hFile)))
2303 {
2304 return 0;
2305 }
2306 DPRINT((0,"ZwClose failed:\n"));
2307 return -1;
2308 }
2309
2310 size_t PICE_len( HANDLE hFile )
2311 {
2312 FILE_STANDARD_INFORMATION fs;
2313 IO_STATUS_BLOCK iosb;
2314 NTSTATUS status;
2315
2316 status = ZwQueryInformationFile( hFile, &iosb, &fs, sizeof fs, FileStandardInformation );
2317 if( !NT_SUCCESS( status ) ){
2318 DPRINT((0,"PICE_len: ZwQueryInformationFile error: %x\n", status));
2319 return 0;
2320 }
2321 //ASSERT(fs.EndOfFile.u.HighPart == 0);
2322 return (size_t)fs.EndOfFile.u.LowPart;
2323 }
2324
2325 /* From kernel32
2326 * NOTE
2327 * A raw converter for now. It assumes lpMultiByteStr is
2328 * NEVER multi-byte (that is each input character is
2329 * 8-bit ASCII) and is ALWAYS NULL terminated.
2330 * FIXME-FIXME-FIXME-FIXME
2331 */
2332
2333 INT
2334 WINAPI
2335 PICE_MultiByteToWideChar (
2336 UINT CodePage,
2337 DWORD dwFlags,
2338 LPCSTR lpMultiByteStr,
2339 int cchMultiByte,
2340 LPWSTR lpWideCharStr,
2341 int cchWideChar
2342 )
2343 {
2344 int InStringLength = 0;
2345 BOOL InIsNullTerminated = TRUE;
2346 PCHAR r;
2347 PWCHAR w;
2348 int cchConverted;
2349
2350 /*
2351 * Check the parameters.
2352 */
2353 if ( /* --- CODE PAGE --- */
2354 ( (CP_ACP != CodePage)
2355 && (CP_MACCP != CodePage)
2356 && (CP_OEMCP != CodePage))
2357 /* --- FLAGS --- */
2358 /*|| (dwFlags ^ ( MB_PRECOMPOSED
2359 | MB_COMPOSITE
2360 | MB_ERR_INVALID_CHARS
2361 | MB_USEGLYPHCHARS
2362 )
2363 )*/
2364 /* --- INPUT BUFFER --- */
2365 || (NULL == lpMultiByteStr)
2366 )
2367 {
2368 DPRINT((0,"ERROR_INVALID_PARAMETER\n"));
2369 return 0;
2370 }
2371 /*
2372 * Compute the input buffer length.
2373 */
2374 if (-1 == cchMultiByte)
2375 {
2376 InStringLength = PICE_strlen(lpMultiByteStr);
2377 }
2378 else
2379 {
2380 InIsNullTerminated = FALSE;
2381 InStringLength = cchMultiByte;
2382 }
2383 /*
2384 * Does caller query for output
2385 * buffer size?
2386 */
2387 if (0 == cchWideChar)
2388 {
2389 DPRINT((0,"ERROR_SUCCESS\n"));
2390 return InStringLength;
2391 }
2392 /*
2393 * Is space provided for the translated
2394 * string enough?
2395 */
2396 if (cchWideChar < InStringLength)
2397 {
2398 DPRINT((0,"ERROR_INSUFFICIENT_BUFFER: cchWideChar: %d, InStringLength: %d\n", cchWideChar, InStringLength));
2399 return 0;
2400 }
2401 /*
2402 * Raw 8- to 16-bit conversion.
2403 */
2404 for ( cchConverted = 0,
2405 r = (PCHAR) lpMultiByteStr,
2406 w = (PWCHAR) lpWideCharStr;
2407
2408 ((*r) && (cchConverted < cchWideChar));
2409
2410 r++, w++,
2411 cchConverted++
2412 )
2413 {
2414 *w = (WCHAR) *r;
2415 }
2416 /*
2417 * Is the input string NULL terminated?
2418 */
2419 if (TRUE == InIsNullTerminated)
2420 {
2421 *w = L'\0';
2422 ++cchConverted;
2423 }
2424 /*
2425 * Return how many characters we
2426 * wrote in the output buffer.
2427 */
2428 return cchConverted;
2429 }
2430